From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/d3dbc.c | 2 ++ libs/vkd3d-shader/hlsl.h | 1 + libs/vkd3d-shader/hlsl.y | 40 ++++++++++++++++++++++++++++++-- libs/vkd3d-shader/hlsl_codegen.c | 1 + libs/vkd3d-shader/tpf.c | 3 +++ 5 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c index d5104ae9..90d7c4cc 100644 --- a/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d-shader/d3dbc.c @@ -2289,6 +2289,8 @@ static void write_sm1_resource_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_
.src_count = 2, }; + if (load->load_type == HLSL_RESOURCE_SAMPLE_PROJ) + sm1_instr.opcode |= VKD3DSI_TEXLD_PROJECT << VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT;
assert(instr->reg.allocated);
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 04e681a9..beb5547b 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -637,6 +637,7 @@ enum hlsl_resource_load_type HLSL_RESOURCE_SAMPLE_LOD, HLSL_RESOURCE_SAMPLE_LOD_BIAS, HLSL_RESOURCE_SAMPLE_GRAD, + HLSL_RESOURCE_SAMPLE_PROJ, HLSL_RESOURCE_GATHER_RED, HLSL_RESOURCE_GATHER_GREEN, HLSL_RESOURCE_GATHER_BLUE, diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index fb6d485e..bc59f84d 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3427,8 +3427,9 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * const struct vkd3d_shader_location *loc, const char *name, enum hlsl_sampler_dim dim) { struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_SAMPLE}; + struct hlsl_ir_node *coords, *load, *divisor; const struct hlsl_type *sampler_type; - struct hlsl_ir_node *coords, *load; + unsigned int coords_dim;
if (params->args_count != 2 && params->args_count != 4) { @@ -3455,12 +3456,40 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * hlsl_release_string_buffer(ctx, string); }
+ if (!strcmp(name, "tex2Dproj")) + { + coords_dim = 4; + load_params.type = HLSL_RESOURCE_SAMPLE_PROJ; + } + else + { + coords_dim = hlsl_sampler_dim_count(dim); + } + if (!(coords = add_implicit_conversion(ctx, params->instrs, params->args[1], - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, hlsl_sampler_dim_count(dim)), loc))) + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, coords_dim), loc))) { return false; }
+ if (load_params.type == HLSL_RESOURCE_SAMPLE_PROJ && shader_profile_version_ge(ctx, 4, 0)) + { + coords_dim = hlsl_sampler_dim_count(dim); + + if (!(divisor = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(W, W, W, W), coords_dim, coords, loc))) + return false; + hlsl_block_add_instr(params->instrs, divisor); + + if (!(coords = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), coords_dim, coords, loc))) + return false; + hlsl_block_add_instr(params->instrs, coords); + + if (!(coords = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_DIV, coords, divisor, loc))) + return false; + + load_params.type = HLSL_RESOURCE_SAMPLE; + } + /* tex1D() functions never produce 1D resource declarations. For newer profiles half offset is used for the second coordinate, while older ones appear to replicate first coordinate.*/ if (dim == HLSL_SAMPLER_DIM_1D) @@ -3517,6 +3546,12 @@ static bool intrinsic_tex2D(struct hlsl_ctx *ctx, return intrinsic_tex(ctx, params, loc, "tex2D", HLSL_SAMPLER_DIM_2D); }
+static bool intrinsic_tex2Dproj(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + return intrinsic_tex(ctx, params, loc, "tex2Dproj", HLSL_SAMPLER_DIM_2D); +} + static bool intrinsic_tex3D(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -3699,6 +3734,7 @@ intrinsic_functions[] = {"step", 2, true, intrinsic_step}, {"tex1D", -1, false, intrinsic_tex1D}, {"tex2D", -1, false, intrinsic_tex2D}, + {"tex2Dproj", 2, false, intrinsic_tex2Dproj}, {"tex3D", -1, false, intrinsic_tex3D}, {"texCUBE", -1, false, intrinsic_texCUBE}, {"transpose", 1, true, intrinsic_transpose}, diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index be024842..cb22049c 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -2173,6 +2173,7 @@ static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in case HLSL_RESOURCE_SAMPLE: case HLSL_RESOURCE_SAMPLE_LOD: case HLSL_RESOURCE_SAMPLE_LOD_BIAS: + case HLSL_RESOURCE_SAMPLE_PROJ: break; } if (load->sampler.var) diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index 045fb6c5..fb293c22 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -5389,6 +5389,9 @@ static void write_sm4_resource_load(const struct tpf_writer *tpf, const struct h case HLSL_RESOURCE_RESINFO: write_sm4_resinfo(tpf, load); break; + + case HLSL_RESOURCE_SAMPLE_PROJ: + vkd3d_unreachable(); } }