diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 2a625bc0..6cb58eff 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -9520,6 +9520,47 @@ static void generate_vsir_scan_global_flags(struct hlsl_ctx *ctx, program->global_flags |= VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL; } +static void sm4_generate_vsir_add_dcl_sampler(struct hlsl_ctx *ctx, + struct vsir_program *program, const struct extern_resource *resource) +{ + struct vkd3d_shader_src_param *src_param; + struct vkd3d_shader_instruction *ins; + unsigned int i; + + VKD3D_ASSERT(resource->regset == HLSL_REGSET_SAMPLERS); + VKD3D_ASSERT(hlsl_version_lt(ctx, 5, 1) || resource->bind_count == 1); + + for (i = 0; i < resource->bind_count; ++i) + { + unsigned int array_first = resource->index + i; + unsigned int array_last = resource->index + i; /* FIXME: array end. */ + + if (resource->var && !resource->var->objects_usage[HLSL_REGSET_SAMPLERS][i].used) + continue; + + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &resource->loc, VKD3DSIH_DCL_SAMPLER, 0, 0))) + { + ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; + return; + } + + if (resource->component_type->sampler_dim == HLSL_SAMPLER_DIM_COMPARISON) + ins->flags |= VKD3DSI_SAMPLER_COMPARISON_MODE; + + src_param = &ins->declaration.sampler.src; + vsir_src_param_init(src_param, VKD3DSPR_SAMPLER, VKD3D_DATA_UNUSED, 0); + + ins->declaration.sampler.range.first = array_first; + ins->declaration.sampler.range.last = array_last; + ins->declaration.sampler.range.space = resource->space; + + src_param->reg.idx[0].offset = resource->id; + src_param->reg.idx[1].offset = array_first; + src_param->reg.idx[2].offset = array_last; + src_param->reg.idx_count = 3; + } +} + /* OBJECTIVE: Translate all the information from ctx and entry_func to the * vsir_program, so it can be used as input to tpf_compile() without relying * on ctx and entry_func. */ @@ -9527,6 +9568,8 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl uint64_t config_flags, struct vsir_program *program) { struct vkd3d_shader_version version = {0}; + struct extern_resource *extern_resources; + unsigned int extern_resources_count; version.major = ctx->profile->major_version; version.minor = ctx->profile->minor_version; @@ -9549,6 +9592,16 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl program->thread_group_size.z = ctx->thread_count[2]; } + extern_resources = sm4_get_extern_resources(ctx, &extern_resources_count); + for (unsigned int i = 0; i < extern_resources_count; ++i) + { + const struct extern_resource *resource = &extern_resources[i]; + + if (resource->regset == HLSL_REGSET_SAMPLERS) + sm4_generate_vsir_add_dcl_sampler(ctx, program, resource); + } + sm4_free_extern_resources(extern_resources, extern_resources_count); + if (version.type == VKD3D_SHADER_TYPE_HULL) generate_vsir_add_program_instruction(ctx, program, &ctx->patch_constant_func->loc, VKD3DSIH_HS_CONTROL_POINT_PHASE, 0, 0); diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index d8763052..f6ef1331 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -4349,47 +4349,6 @@ static void write_sm4_dcl_constant_buffer(const struct tpf_compiler *tpf, const write_sm4_instruction(tpf, &instr); } -static void write_sm4_dcl_samplers(const struct tpf_compiler *tpf, const struct extern_resource *resource) -{ - unsigned int i; - struct sm4_instruction instr = - { - .opcode = VKD3D_SM4_OP_DCL_SAMPLER, - - .dsts[0].reg.type = VKD3DSPR_SAMPLER, - .dst_count = 1, - }; - - VKD3D_ASSERT(resource->regset == HLSL_REGSET_SAMPLERS); - - if (resource->component_type->sampler_dim == HLSL_SAMPLER_DIM_COMPARISON) - instr.extra_bits |= VKD3D_SM4_SAMPLER_COMPARISON << VKD3D_SM4_SAMPLER_MODE_SHIFT; - - for (i = 0; i < resource->bind_count; ++i) - { - if (resource->var && !resource->var->objects_usage[HLSL_REGSET_SAMPLERS][i].used) - continue; - - if (hlsl_version_ge(tpf->ctx, 5, 1)) - { - VKD3D_ASSERT(!i); - instr.dsts[0].reg.idx[0].offset = resource->id; - instr.dsts[0].reg.idx[1].offset = resource->index; - instr.dsts[0].reg.idx[2].offset = resource->index; /* FIXME: array end */ - instr.dsts[0].reg.idx_count = 3; - - instr.idx[0] = resource->space; - instr.idx_count = 1; - } - else - { - instr.dsts[0].reg.idx[0].offset = resource->index + i; - instr.dsts[0].reg.idx_count = 1; - } - write_sm4_instruction(tpf, &instr); - } -} - static void write_sm4_dcl_textures(const struct tpf_compiler *tpf, const struct extern_resource *resource, bool uav) { @@ -4561,6 +4520,37 @@ static void tpf_dcl_thread_group(const struct tpf_compiler *tpf, const struct vs write_sm4_instruction(tpf, &instr); } +static void tpf_dcl_sampler(const struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins) +{ + const struct vkd3d_shader_sampler *sampler = &ins->declaration.sampler; + struct sm4_instruction instr = + { + .opcode = VKD3D_SM4_OP_DCL_SAMPLER, + .extra_bits = ins->flags << VKD3D_SM4_SAMPLER_MODE_SHIFT, + + .dsts[0].reg.type = VKD3DSPR_SAMPLER, + .dst_count = 1, + }; + + if (vkd3d_shader_ver_ge(&tpf->program->shader_version, 5, 1)) + { + instr.dsts[0].reg.idx[0].offset = sampler->src.reg.idx[0].offset; + instr.dsts[0].reg.idx[1].offset = sampler->range.first; + instr.dsts[0].reg.idx[2].offset = sampler->range.last; + instr.dsts[0].reg.idx_count = 3; + + instr.idx[0] = ins->declaration.sampler.range.space; + instr.idx_count = 1; + } + else + { + instr.dsts[0].reg.idx[0].offset = sampler->range.first; + instr.dsts[0].reg.idx_count = 1; + } + + write_sm4_instruction(tpf, &instr); +} + static void write_sm4_dcl_global_flags(const struct tpf_compiler *tpf, uint32_t flags) { struct sm4_instruction instr = @@ -4750,6 +4740,10 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_OUTPUT_SIV, &ins->declaration.register_semantic, 0); break; + case VKD3DSIH_DCL_SAMPLER: + tpf_dcl_sampler(tpf, ins); + break; + case VKD3DSIH_ADD: case VKD3DSIH_AND: case VKD3DSIH_BREAK: @@ -4920,9 +4914,7 @@ static void tpf_write_shdr(struct tpf_compiler *tpf, struct hlsl_ir_function_dec { const struct extern_resource *resource = &extern_resources[i]; - if (resource->regset == HLSL_REGSET_SAMPLERS) - write_sm4_dcl_samplers(tpf, resource); - else if (resource->regset == HLSL_REGSET_TEXTURES) + if (resource->regset == HLSL_REGSET_TEXTURES) write_sm4_dcl_textures(tpf, resource, false); else if (resource->regset == HLSL_REGSET_UAVS) write_sm4_dcl_textures(tpf, resource, true);