microsoft/compiler: For store_output from HS, use storePatchConstant

In HS, store_per_vertex_output maps to storeOutput in DXIL. The data
that isn't per-vertex is patch constants.

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Bill Kristiansen <billkris@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14399>
This commit is contained in:
Jesse Natalie 2022-01-02 09:56:08 -08:00 committed by Marge Bot
parent 97b6ea71a0
commit cc6104dd3f
2 changed files with 27 additions and 4 deletions

View file

@ -84,6 +84,7 @@ static struct predefined_func_descr predefined_funcs[] = {
{"dx.op.evalCentroid", "O", "iiic", DXIL_ATTR_KIND_READ_NONE},
{"dx.op.evalSampleIndex", "O", "iiici", DXIL_ATTR_KIND_READ_NONE},
{"dx.op.coverage", "i", "i", DXIL_ATTR_KIND_READ_NONE},
{"dx.op.storePatchConstant", "v", "iiicO", DXIL_ATTR_KIND_NO_UNWIND},
};
struct func_descr {

View file

@ -288,6 +288,7 @@ enum dxil_intr {
DXIL_INTR_MAKE_DOUBLE = 101,
DXIL_INTR_SPLIT_DOUBLE = 102,
DXIL_INTR_STORE_PATCH_CONSTANT = 106,
DXIL_INTR_OUTPUT_CONTROL_POINT_ID = 107,
DXIL_INTR_PRIMITIVE_ID = 108,
@ -2996,23 +2997,44 @@ emit_store_output_via_intrinsic(struct ntd_context *ctx, nir_intrinsic_instr *in
{
assert(intr->intrinsic == nir_intrinsic_store_output ||
ctx->mod.shader_kind == DXIL_HULL_SHADER);
bool is_patch_constant = intr->intrinsic == nir_intrinsic_store_output &&
ctx->mod.shader_kind == DXIL_HULL_SHADER;
nir_alu_type out_type = nir_intrinsic_src_type(intr);
enum overload_type overload = get_overload(out_type, intr->src[0].ssa->bit_size);
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.storeOutput", overload);
const struct dxil_func *func = dxil_get_function(&ctx->mod, is_patch_constant ?
"dx.op.storePatchConstant" : "dx.op.storeOutput",
overload);
if (!func)
return false;
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_STORE_OUTPUT);
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, is_patch_constant ?
DXIL_INTR_STORE_PATCH_CONSTANT : DXIL_INTR_STORE_OUTPUT);
const struct dxil_value *output_id = dxil_module_get_int32_const(&ctx->mod, nir_intrinsic_base(intr));
unsigned row_index = intr->intrinsic == nir_intrinsic_store_output ? 1 : 2;
const struct dxil_value *row = get_src(ctx, &intr->src[row_index], 0, nir_type_int);
/* NIR has these as 1 row, N cols, but DXIL wants them as N rows, 1 col. We muck with these in the signature
* generation, so muck with them here too.
*/
nir_io_semantics semantics = nir_intrinsic_io_semantics(intr);
bool is_tess_level = semantics.location == VARYING_SLOT_TESS_LEVEL_INNER ||
semantics.location == VARYING_SLOT_TESS_LEVEL_OUTER;
const struct dxil_value *row = NULL;
const struct dxil_value *col = NULL;
if (is_tess_level)
col = dxil_module_get_int8_const(&ctx->mod, 0);
else
row = get_src(ctx, &intr->src[row_index], 0, nir_type_int);
bool success = true;
uint32_t writemask = nir_intrinsic_write_mask(intr);
for (unsigned i = 0; i < intr->num_components && success; ++i) {
if (writemask & (1 << i)) {
const struct dxil_value *col = dxil_module_get_int8_const(&ctx->mod, i + nir_intrinsic_component(intr));
if (is_tess_level)
row = dxil_module_get_int32_const(&ctx->mod, i + nir_intrinsic_component(intr));
else
col = dxil_module_get_int8_const(&ctx->mod, i + nir_intrinsic_component(intr));
const struct dxil_value *value = get_src(ctx, &intr->src[0], i, out_type);
if (!col || !value)
return false;