From 42ce82160356c52bd444b8cea5a6be4cdf7f6d1a Mon Sep 17 00:00:00 2001 From: Francisco Casas Date: Fri, 8 Nov 2024 01:29:20 -0300 Subject: [PATCH] vkd3d-shader/hlsl: Store SM4 HLSL_RESOURCE_SAMPLEs in the vsir program. --- libs/vkd3d-shader/hlsl_codegen.c | 97 +++++++++++++++++++++++++++++ libs/vkd3d-shader/tpf.c | 103 ++++--------------------------- 2 files changed, 109 insertions(+), 91 deletions(-) diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index cc0b0016..385badd7 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -9009,6 +9009,93 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, return true; } +static bool sm4_generate_vsir_instr_sample(struct hlsl_ctx *ctx, + struct vsir_program *program, const struct hlsl_ir_resource_load *load) +{ + const struct hlsl_ir_node *texel_offset = load->texel_offset.node; + const struct hlsl_ir_node *coords = load->coords.node; + const struct hlsl_deref *resource = &load->resource; + const struct hlsl_deref *sampler = &load->sampler; + const struct hlsl_ir_node *instr = &load->node; + struct vkd3d_shader_instruction *ins; + enum vkd3d_shader_opcode opcode; + unsigned int src_count; + + switch (load->load_type) + { + case HLSL_RESOURCE_SAMPLE: + opcode = VKD3DSIH_SAMPLE; + src_count = 3; + break; + + case HLSL_RESOURCE_SAMPLE_CMP: + opcode = VKD3DSIH_SAMPLE_C; + src_count = 4; + break; + + case HLSL_RESOURCE_SAMPLE_CMP_LZ: + opcode = VKD3DSIH_SAMPLE_C_LZ; + src_count = 4; + break; + + case HLSL_RESOURCE_SAMPLE_LOD: + opcode = VKD3DSIH_SAMPLE_LOD; + src_count = 4; + break; + + case HLSL_RESOURCE_SAMPLE_LOD_BIAS: + opcode = VKD3DSIH_SAMPLE_B; + src_count = 4; + break; + + case HLSL_RESOURCE_SAMPLE_GRAD: + opcode = VKD3DSIH_SAMPLE_GRAD; + src_count = 5; + break; + + default: + vkd3d_unreachable(); + } + + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, opcode, 1, src_count))) + return false; + + if (texel_offset && !sm4_generate_vsir_validate_texel_offset_aoffimmi(texel_offset)) + { + hlsl_error(ctx, &texel_offset->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TEXEL_OFFSET, + "Offset must resolve to integer literal in the range -8 to 7."); + return false; + } + sm4_generate_vsir_encode_texel_offset_as_aoffimmi(ins, texel_offset); + + vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr); + + vsir_src_from_hlsl_node(&ins->src[0], ctx, coords, VKD3DSP_WRITEMASK_ALL); + + if (!sm4_generate_vsir_init_src_param_from_deref(ctx, program, &ins->src[1], + resource, ins->dst[0].write_mask, &instr->loc)) + return false; + + if (!sm4_generate_vsir_init_src_param_from_deref(ctx, program, &ins->src[2], + sampler, VKD3DSP_WRITEMASK_ALL, &instr->loc)) + return false; + + if (opcode == VKD3DSIH_SAMPLE_LOD || opcode == VKD3DSIH_SAMPLE_B) + { + vsir_src_from_hlsl_node(&ins->src[3], ctx, load->lod.node, VKD3DSP_WRITEMASK_ALL); + } + else if (opcode == VKD3DSIH_SAMPLE_C || opcode == VKD3DSIH_SAMPLE_C_LZ) + { + vsir_src_from_hlsl_node(&ins->src[3], ctx, load->cmp.node, VKD3DSP_WRITEMASK_ALL); + } + else if (opcode == VKD3DSIH_SAMPLE_GRAD) + { + vsir_src_from_hlsl_node(&ins->src[3], ctx, load->ddx.node, VKD3DSP_WRITEMASK_ALL); + vsir_src_from_hlsl_node(&ins->src[4], ctx, load->ddy.node, VKD3DSP_WRITEMASK_ALL); + } + return true; +} + static bool sm4_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx, struct vsir_program *program, const struct hlsl_ir_resource_load *load) { @@ -9029,6 +9116,16 @@ static bool sm4_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx, case HLSL_RESOURCE_LOAD: return sm4_generate_vsir_instr_ld(ctx, program, load); + case HLSL_RESOURCE_SAMPLE: + case HLSL_RESOURCE_SAMPLE_CMP: + case HLSL_RESOURCE_SAMPLE_CMP_LZ: + case HLSL_RESOURCE_SAMPLE_LOD: + case HLSL_RESOURCE_SAMPLE_LOD_BIAS: + case HLSL_RESOURCE_SAMPLE_GRAD: + /* Combined sample expressions were lowered. */ + VKD3D_ASSERT(load->sampler.var); + return sm4_generate_vsir_instr_sample(ctx, program, load); + case HLSL_RESOURCE_SAMPLE_PROJ: vkd3d_unreachable(); diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index 1a752a2a..df18b198 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -5034,86 +5034,6 @@ static void write_sm4_ret(const struct tpf_compiler *tpf) write_sm4_instruction(tpf, &instr); } -static void write_sm4_sample(const struct tpf_compiler *tpf, const struct hlsl_ir_resource_load *load) -{ - const struct hlsl_ir_node *texel_offset = load->texel_offset.node; - const struct hlsl_ir_node *coords = load->coords.node; - const struct hlsl_deref *resource = &load->resource; - const struct hlsl_deref *sampler = &load->sampler; - const struct hlsl_ir_node *dst = &load->node; - struct sm4_instruction instr; - - memset(&instr, 0, sizeof(instr)); - switch (load->load_type) - { - case HLSL_RESOURCE_SAMPLE: - instr.opcode = VKD3D_SM4_OP_SAMPLE; - break; - - case HLSL_RESOURCE_SAMPLE_CMP: - instr.opcode = VKD3D_SM4_OP_SAMPLE_C; - break; - - case HLSL_RESOURCE_SAMPLE_CMP_LZ: - instr.opcode = VKD3D_SM4_OP_SAMPLE_C_LZ; - break; - - case HLSL_RESOURCE_SAMPLE_LOD: - instr.opcode = VKD3D_SM4_OP_SAMPLE_LOD; - break; - - case HLSL_RESOURCE_SAMPLE_LOD_BIAS: - instr.opcode = VKD3D_SM4_OP_SAMPLE_B; - break; - - case HLSL_RESOURCE_SAMPLE_GRAD: - instr.opcode = VKD3D_SM4_OP_SAMPLE_GRAD; - break; - - default: - vkd3d_unreachable(); - } - - if (texel_offset) - { - if (!encode_texel_offset_as_aoffimmi(&instr, texel_offset)) - { - hlsl_error(tpf->ctx, &texel_offset->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TEXEL_OFFSET, - "Offset must resolve to integer literal in the range -8 to 7."); - return; - } - } - - sm4_dst_from_node(&instr.dsts[0], dst); - instr.dst_count = 1; - - sm4_src_from_node(tpf, &instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL); - sm4_src_from_deref(tpf, &instr.srcs[1], resource, instr.dsts[0].write_mask, &instr); - sm4_src_from_deref(tpf, &instr.srcs[2], sampler, VKD3DSP_WRITEMASK_ALL, &instr); - instr.src_count = 3; - - if (load->load_type == HLSL_RESOURCE_SAMPLE_LOD - || load->load_type == HLSL_RESOURCE_SAMPLE_LOD_BIAS) - { - sm4_src_from_node(tpf, &instr.srcs[3], load->lod.node, VKD3DSP_WRITEMASK_ALL); - ++instr.src_count; - } - else if (load->load_type == HLSL_RESOURCE_SAMPLE_GRAD) - { - sm4_src_from_node(tpf, &instr.srcs[3], load->ddx.node, VKD3DSP_WRITEMASK_ALL); - sm4_src_from_node(tpf, &instr.srcs[4], load->ddy.node, VKD3DSP_WRITEMASK_ALL); - instr.src_count += 2; - } - else if (load->load_type == HLSL_RESOURCE_SAMPLE_CMP - || load->load_type == HLSL_RESOURCE_SAMPLE_CMP_LZ) - { - sm4_src_from_node(tpf, &instr.srcs[3], load->cmp.node, VKD3DSP_WRITEMASK_ALL); - ++instr.src_count; - } - - write_sm4_instruction(tpf, &instr); -} - static void write_sm4_sampleinfo(const struct tpf_compiler *tpf, const struct hlsl_ir_resource_load *load) { const struct hlsl_deref *resource = &load->resource; @@ -5308,17 +5228,6 @@ static void write_sm4_resource_load(const struct tpf_compiler *tpf, const struct switch (load->load_type) { - case HLSL_RESOURCE_SAMPLE: - case HLSL_RESOURCE_SAMPLE_CMP: - case HLSL_RESOURCE_SAMPLE_CMP_LZ: - case HLSL_RESOURCE_SAMPLE_LOD: - case HLSL_RESOURCE_SAMPLE_LOD_BIAS: - case HLSL_RESOURCE_SAMPLE_GRAD: - /* Combined sample expressions were lowered. */ - VKD3D_ASSERT(load->sampler.var); - write_sm4_sample(tpf, load); - break; - case HLSL_RESOURCE_GATHER_RED: write_sm4_gather(tpf, &load->node, &load->resource, &load->sampler, coords, VKD3D_SHADER_SWIZZLE(X, X, X, X), texel_offset); @@ -5347,6 +5256,12 @@ static void write_sm4_resource_load(const struct tpf_compiler *tpf, const struct write_sm4_resinfo(tpf, load); break; + case HLSL_RESOURCE_SAMPLE: + case HLSL_RESOURCE_SAMPLE_CMP: + case HLSL_RESOURCE_SAMPLE_CMP_LZ: + case HLSL_RESOURCE_SAMPLE_LOD: + case HLSL_RESOURCE_SAMPLE_LOD_BIAS: + case HLSL_RESOURCE_SAMPLE_GRAD: case HLSL_RESOURCE_LOAD: case HLSL_RESOURCE_SAMPLE_PROJ: vkd3d_unreachable(); @@ -5552,7 +5467,13 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ case VKD3DSIH_ROUND_PI: case VKD3DSIH_ROUND_Z: case VKD3DSIH_RSQ: + case VKD3DSIH_SAMPLE: + case VKD3DSIH_SAMPLE_B: + case VKD3DSIH_SAMPLE_C: + case VKD3DSIH_SAMPLE_C_LZ: + case VKD3DSIH_SAMPLE_GRAD: case VKD3DSIH_SAMPLE_INFO: + case VKD3DSIH_SAMPLE_LOD: case VKD3DSIH_SINCOS: case VKD3DSIH_SQRT: case VKD3DSIH_STORE_RAW: