Mesa (main): microsoft/compiler: Implement texture loads from UAVs
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Thu Jul 29 22:13:58 UTC 2021
Module: Mesa
Branch: main
Commit: 6126dd29a40655c323c30687034d6307e5853e79
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=6126dd29a40655c323c30687034d6307e5853e79
Author: Jesse Natalie <jenatali at microsoft.com>
Date: Sun Apr 11 14:11:07 2021 -0700
microsoft/compiler: Implement texture loads from UAVs
This comes to the backend as image_load rather than txf but the
DXIL intrinsic is the same at the end of the day.
Reviewed-by: Enrico Galli <enrico.galli at intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10163>
---
src/microsoft/clc/clc_compiler.c | 1 +
src/microsoft/compiler/nir_to_dxil.c | 105 ++++++++++++++++++++++++++++++++---
2 files changed, 99 insertions(+), 7 deletions(-)
diff --git a/src/microsoft/clc/clc_compiler.c b/src/microsoft/clc/clc_compiler.c
index b82db218278..248c63654eb 100644
--- a/src/microsoft/clc/clc_compiler.c
+++ b/src/microsoft/clc/clc_compiler.c
@@ -1053,6 +1053,7 @@ clc_to_dxil(struct clc_context *ctx,
.int64 = true,
.kernel = true,
.kernel_image = true,
+ .kernel_image_read_write = true,
.literal_sampler = true,
.printf = true,
},
diff --git a/src/microsoft/compiler/nir_to_dxil.c b/src/microsoft/compiler/nir_to_dxil.c
index a19f4f8a16f..300efbaabf7 100644
--- a/src/microsoft/compiler/nir_to_dxil.c
+++ b/src/microsoft/compiler/nir_to_dxil.c
@@ -581,9 +581,10 @@ emit_groupid_call(struct ntd_context *ctx, const struct dxil_value *comp)
static const struct dxil_value *
emit_bufferload_call(struct ntd_context *ctx,
const struct dxil_value *handle,
- const struct dxil_value *coord[2])
+ const struct dxil_value *coord[2],
+ enum overload_type overload)
{
- const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.bufferLoad", DXIL_I32);
+ const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.bufferLoad", overload);
if (!func)
return NULL;
@@ -619,6 +620,28 @@ emit_bufferstore_call(struct ntd_context *ctx,
args, ARRAY_SIZE(args));
}
+static const struct dxil_value *
+emit_textureload_call(struct ntd_context *ctx,
+ const struct dxil_value *handle,
+ const struct dxil_value *coord[3],
+ enum overload_type overload)
+{
+ const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.textureLoad", overload);
+ if (!func)
+ return NULL;
+ const struct dxil_type *int_type = dxil_module_get_int_type(&ctx->mod, 32);
+ const struct dxil_value *int_undef = dxil_module_get_undef(&ctx->mod, int_type);
+
+ const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod,
+ DXIL_INTR_TEXTURE_LOAD);
+ const struct dxil_value *args[] = { opcode, handle,
+ /*lod_or_sample*/ int_undef,
+ coord[0], coord[1], coord[2],
+ /* offsets */ int_undef, int_undef, int_undef};
+
+ return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
+}
+
static bool
emit_texturestore_call(struct ntd_context *ctx,
const struct dxil_value *handle,
@@ -2406,7 +2429,7 @@ emit_load_ssbo(struct ntd_context *ctx, nir_intrinsic_instr *intr)
int32_undef
};
- const struct dxil_value *load = emit_bufferload_call(ctx, handle, coord);
+ const struct dxil_value *load = emit_bufferload_call(ctx, handle, coord, DXIL_I32);
if (!load)
return false;
@@ -3090,6 +3113,72 @@ emit_image_store(struct ntd_context *ctx, nir_intrinsic_instr *intr)
return emit_texturestore_call(ctx, handle, coord, value, write_mask, overload);
}
+static bool
+emit_image_load(struct ntd_context *ctx, nir_intrinsic_instr *intr)
+{
+ const struct dxil_value *handle;
+ bool is_array = false;
+ if (ctx->opts->vulkan_environment) {
+ assert(intr->intrinsic == nir_intrinsic_image_deref_load);
+ handle = get_src_ssa(ctx, intr->src[0].ssa, 0);
+ is_array = glsl_sampler_type_is_array(nir_src_as_deref(intr->src[0])->type);
+ } else {
+ assert(intr->intrinsic == nir_intrinsic_image_load);
+ int binding = nir_src_as_int(intr->src[0]);
+ is_array = nir_intrinsic_image_array(intr);
+ handle = ctx->uav_handles[binding];
+ }
+ if (!handle)
+ return false;
+
+ const struct dxil_value *int32_undef = get_int32_undef(&ctx->mod);
+ if (!int32_undef)
+ return false;
+
+ const struct dxil_value *coord[3] = { int32_undef, int32_undef, int32_undef };
+ enum glsl_sampler_dim image_dim = intr->intrinsic == nir_intrinsic_image_load ?
+ nir_intrinsic_image_dim(intr) :
+ glsl_get_sampler_dim(nir_src_as_deref(intr->src[0])->type);
+ unsigned num_coords = glsl_get_sampler_dim_coordinate_components(image_dim);
+ if (is_array)
+ ++num_coords;
+
+ assert(num_coords <= nir_src_num_components(intr->src[1]));
+ for (unsigned i = 0; i < num_coords; ++i) {
+ coord[i] = get_src(ctx, &intr->src[1], i, nir_type_uint);
+ if (!coord[i])
+ return false;
+ }
+
+ nir_alu_type out_type = nir_intrinsic_dest_type(intr);
+ enum overload_type overload = get_overload(out_type, 32);
+
+ const struct dxil_value *load_result;
+ if (image_dim == GLSL_SAMPLER_DIM_BUF) {
+ coord[1] = int32_undef;
+ load_result = emit_bufferload_call(ctx, handle, coord, overload);
+ } else
+ load_result = emit_textureload_call(ctx, handle, coord, overload);
+
+ if (!load_result)
+ return false;
+
+ assert(nir_dest_bit_size(intr->dest) == 32);
+ unsigned num_components = nir_dest_num_components(intr->dest);
+ assert(num_components <= 4);
+ for (unsigned i = 0; i < num_components; ++i) {
+ const struct dxil_value *component = dxil_emit_extractval(&ctx->mod, load_result, i);
+ if (!component)
+ return false;
+ store_dest(ctx, &intr->dest, i, component, out_type);
+ }
+
+ if (num_components > 1)
+ ctx->mod.feats.typed_uav_load_additional_formats = true;
+
+ return true;
+}
+
struct texop_parameters {
const struct dxil_value *tex;
const struct dxil_value *sampler;
@@ -3483,8 +3572,11 @@ emit_intrinsic(struct ntd_context *ctx, nir_intrinsic_instr *intr)
case nir_intrinsic_image_store:
case nir_intrinsic_image_deref_store:
return emit_image_store(ctx, intr);
- case nir_intrinsic_image_deref_size:
+ case nir_intrinsic_image_load:
+ case nir_intrinsic_image_deref_load:
+ return emit_image_load(ctx, intr);
case nir_intrinsic_image_size:
+ case nir_intrinsic_image_deref_size:
return emit_image_size(ctx, intr);
case nir_intrinsic_get_ssbo_size:
return emit_get_ssbo_size(ctx, intr);
@@ -3988,9 +4080,8 @@ emit_tex(struct ntd_context *ctx, nir_tex_instr *instr)
case nir_texop_txf_ms:
if (instr->sampler_dim == GLSL_SAMPLER_DIM_BUF) {
params.coord[1] = int_undef;
- sample = emit_bufferload_call(ctx, params.tex, params.coord);
- }
- else {
+ sample = emit_bufferload_call(ctx, params.tex, params.coord, params.overload);
+ } else {
PAD_SRC(ctx, params.coord, coord_components, int_undef);
sample = emit_texel_fetch(ctx, ¶ms);
}
More information about the mesa-commit
mailing list