Commit 6126dd29 authored by Jesse Natalie's avatar Jesse Natalie
Browse files

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's avatarEnrico Galli <enrico.galli@intel.com>
Part-of: <!10163>
parent 7bcb2236
......@@ -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,
},
......
......@@ -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, &params);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment