Module: Mesa Branch: main Commit: 6126dd29a40655c323c30687034d6307e5853e79 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=6126dd29a40655c323c30687034d6307e5853e79
Author: Jesse Natalie <[email protected]> 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 <[email protected]> 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); } _______________________________________________ mesa-commit mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-commit
