-- v4: vkd3d-shader/hlsl: Implement texCUBEproj(). vkd3d-shader/d3dbc: Disallow 1D sampler types when writing sampler declaration. vkd3d-shader/hlsl: Implement tex3Dproj(). vkd3d-shader/hlsl: Implement tex1Dproj(). vkd3d-shader/hlsl: Implement tex2Dproj().
From: Nikolay Sivov nsivov@codeweavers.com
--- libs/vkd3d-shader/d3dbc.c | 2 ++ libs/vkd3d-shader/hlsl.h | 3 ++- libs/vkd3d-shader/hlsl.y | 23 +++++++++++++++++-- libs/vkd3d-shader/hlsl_codegen.c | 38 ++++++++++++++++++++++++++++++++ libs/vkd3d-shader/tpf.c | 3 +++ 5 files changed, 66 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c index d2a4666a..7d156bf5 100644 --- a/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d-shader/d3dbc.c @@ -2202,6 +2202,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 28c7c691..eed2a837 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -620,9 +620,10 @@ enum hlsl_resource_load_type HLSL_RESOURCE_SAMPLE, HLSL_RESOURCE_SAMPLE_CMP, HLSL_RESOURCE_SAMPLE_CMP_LZ, + HLSL_RESOURCE_SAMPLE_GRAD, 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 60d6514c..816b514b 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3350,9 +3350,10 @@ static bool intrinsic_step(struct hlsl_ctx *ctx, static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *params, 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_resource_load_params load_params = { 0 }; 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) { @@ -3379,8 +3380,19 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * hlsl_release_string_buffer(ctx, string); }
+ if (!strcmp(name, "tex2Dproj")) + { + load_params.type = HLSL_RESOURCE_SAMPLE_PROJ; + coords_dim = 4; + } + else + { + load_params.type = HLSL_RESOURCE_SAMPLE; + coords_dim = hlsl_sampler_dim_count(dim); + } + if (!(coords = add_implicit_conversion(ctx, block_to_list(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))) coords = params->args[1];
load_params.coords = coords; @@ -3400,6 +3412,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) { @@ -3571,6 +3589,7 @@ intrinsic_functions[] = {"sqrt", 1, true, intrinsic_sqrt}, {"step", 2, true, intrinsic_step}, {"tex2D", -1, false, intrinsic_tex2D}, + {"tex2Dproj", 2, false, intrinsic_tex2Dproj}, {"tex3D", -1, false, intrinsic_tex3D}, {"transpose", 1, true, intrinsic_transpose}, {"trunc", 1, true, intrinsic_trunc}, diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index b980ed56..373c98a4 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -2639,6 +2639,40 @@ static bool lower_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, return true; }
+/* For SM4 turn HLSL_RESOURCE_SAMPLE_PROJ to HLSL_RESOURCE_SAMPLE + DIV */ +static bool lower_tex_proj(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_node *divisor, *c, *coords; + struct hlsl_ir_resource_load *load; + unsigned int dim_count; + + if (instr->type != HLSL_IR_RESOURCE_LOAD) + return false; + load = hlsl_ir_resource_load(instr); + if (load->load_type != HLSL_RESOURCE_SAMPLE_PROJ) + return false; + + dim_count = hlsl_sampler_dim_count(load->sampling_dim); + if (!(divisor = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(W, W, W, W), dim_count, load->coords.node, &instr->loc))) + return false; + list_add_before(&instr->entry, &divisor->entry); + + if (!(c = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), dim_count, load->coords.node, &instr->loc))) + return false; + list_add_before(&instr->entry, &c->entry); + + if (!(coords = hlsl_new_binary_expr(ctx, HLSL_OP2_DIV, c, divisor))) + return false; + list_add_before(&instr->entry, &coords->entry); + + load->load_type = HLSL_RESOURCE_SAMPLE; + + hlsl_src_remove(&load->coords); + hlsl_src_from_node(&load->coords, coords); + + return true; +} + static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { switch (instr->type) @@ -4159,6 +4193,10 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry hlsl_transform_ir(ctx, lower_nonconstant_vector_derefs, body, NULL); hlsl_transform_ir(ctx, lower_casts_to_bool, body, NULL); hlsl_transform_ir(ctx, lower_int_dot, body, NULL); + if (profile->major_version >= 4) + { + hlsl_transform_ir(ctx, lower_tex_proj, body, NULL); + }
if (profile->major_version < 4) { diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index 677243e1..487c2063 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -4989,6 +4989,9 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx, write_sm4_gather(ctx, buffer, resource_type, &load->node, &load->resource, &load->sampler, coords, HLSL_SWIZZLE(W, W, W, W), texel_offset); break; + + case HLSL_RESOURCE_SAMPLE_PROJ: + vkd3d_unreachable(); } }
From: Nikolay Sivov nsivov@codeweavers.com
--- libs/vkd3d-shader/hlsl.y | 13 ++++++++- libs/vkd3d-shader/hlsl_codegen.c | 50 ++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 816b514b..0513fde1 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3380,7 +3380,11 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * hlsl_release_string_buffer(ctx, string); }
- if (!strcmp(name, "tex2Dproj")) + if (ctx->profile->major_version < 4 && dim == HLSL_SAMPLER_DIM_1D) + dim = HLSL_SAMPLER_DIM_2D; + + if (!strcmp(name, "tex1Dproj") + || !strcmp(name, "tex2Dproj")) { load_params.type = HLSL_RESOURCE_SAMPLE_PROJ; coords_dim = 4; @@ -3406,6 +3410,12 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * return true; }
+static bool intrinsic_tex1Dproj(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + return intrinsic_tex(ctx, params, loc, "tex1Dproj", HLSL_SAMPLER_DIM_1D); +} + static bool intrinsic_tex2D(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -3588,6 +3598,7 @@ intrinsic_functions[] = {"smoothstep", 3, true, intrinsic_smoothstep}, {"sqrt", 1, true, intrinsic_sqrt}, {"step", 2, true, intrinsic_step}, + {"tex1Dproj", 2, false, intrinsic_tex1Dproj}, {"tex2D", -1, false, intrinsic_tex2D}, {"tex2Dproj", 2, false, intrinsic_tex2Dproj}, {"tex3D", -1, false, intrinsic_tex3D}, diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 373c98a4..d035c02c 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -2673,6 +2673,55 @@ static bool lower_tex_proj(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, voi return true; }
+static bool lower_tex_1d(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_node *store, *half, *x; + struct hlsl_ir_resource_load *load; + struct hlsl_deref coords_deref; + struct hlsl_ir_load *var_load; + struct hlsl_ir_var *coords; + + if (instr->type != HLSL_IR_RESOURCE_LOAD) + return false; + load = hlsl_ir_resource_load(instr); + if (load->sampler.var) + return false; + if (load->sampling_dim != HLSL_SAMPLER_DIM_1D) + return false; + + if (!(half = hlsl_new_float_constant(ctx, 0.5f, &instr->loc))) + return false; + list_add_before(&instr->entry, &half->entry); + + if (!(coords = hlsl_new_synthetic_var(ctx, "coords", + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 2), &instr->loc))) + return false; + + if (!(x = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), 1, load->coords.node, &instr->loc))) + return false; + list_add_before(&instr->entry, &x->entry); + + hlsl_init_simple_deref_from_var(&coords_deref, coords); + if (!(store = hlsl_new_store_index(ctx, &coords_deref, NULL, x, 0, &instr->loc))) + return false; + list_add_before(&instr->entry, &store->entry); + + if (!(store = hlsl_new_store_index(ctx, &coords_deref, NULL, half, 1 << 1, &instr->loc))) + return false; + list_add_before(&instr->entry, &store->entry); + + if (!(var_load = hlsl_new_var_load(ctx, coords, &instr->loc))) + return false; + list_add_before(&instr->entry, &var_load->node.entry); + + load->sampling_dim = HLSL_SAMPLER_DIM_2D; + + hlsl_src_remove(&load->coords); + hlsl_src_from_node(&load->coords, &var_load->node); + + return true; +} + static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { switch (instr->type) @@ -4196,6 +4245,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry if (profile->major_version >= 4) { hlsl_transform_ir(ctx, lower_tex_proj, body, NULL); + hlsl_transform_ir(ctx, lower_tex_1d, body, NULL); }
if (profile->major_version < 4)
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 0513fde1..8ff1ae46 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3384,7 +3384,8 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * dim = HLSL_SAMPLER_DIM_2D;
if (!strcmp(name, "tex1Dproj") - || !strcmp(name, "tex2Dproj")) + || !strcmp(name, "tex2Dproj") + || !strcmp(name, "tex3Dproj")) { load_params.type = HLSL_RESOURCE_SAMPLE_PROJ; coords_dim = 4; @@ -3434,6 +3435,12 @@ static bool intrinsic_tex3D(struct hlsl_ctx *ctx, return intrinsic_tex(ctx, params, loc, "tex3D", HLSL_SAMPLER_DIM_3D); }
+static bool intrinsic_tex3Dproj(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + return intrinsic_tex(ctx, params, loc, "tex3Dproj", HLSL_SAMPLER_DIM_3D); +} + static bool intrinsic_transpose(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -3602,6 +3609,7 @@ intrinsic_functions[] = {"tex2D", -1, false, intrinsic_tex2D}, {"tex2Dproj", 2, false, intrinsic_tex2Dproj}, {"tex3D", -1, false, intrinsic_tex3D}, + {"tex3Dproj", 2, false, intrinsic_tex3Dproj}, {"transpose", 1, true, intrinsic_transpose}, {"trunc", 1, true, intrinsic_trunc}, };
From: Nikolay Sivov nsivov@codeweavers.com
It should not be used in this context.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/d3dbc.c | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c index 7d156bf5..f677536b 100644 --- a/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d-shader/d3dbc.c @@ -1896,10 +1896,6 @@ static void write_sm1_sampler_dcl(struct hlsl_ctx *ctx, struct vkd3d_bytecode_bu
switch (sampler_dim) { - case HLSL_SAMPLER_DIM_1D: - res_type = VKD3D_SM1_RESOURCE_TEXTURE_1D; - break; - case HLSL_SAMPLER_DIM_2D: res_type = VKD3D_SM1_RESOURCE_TEXTURE_2D; break;
From: Nikolay Sivov nsivov@codeweavers.com
--- libs/vkd3d-shader/hlsl.y | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 8ff1ae46..e382e678 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3385,7 +3385,8 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
if (!strcmp(name, "tex1Dproj") || !strcmp(name, "tex2Dproj") - || !strcmp(name, "tex3Dproj")) + || !strcmp(name, "tex3Dproj") + || !strcmp(name, "texCUBEproj")) { load_params.type = HLSL_RESOURCE_SAMPLE_PROJ; coords_dim = 4; @@ -3441,6 +3442,12 @@ static bool intrinsic_tex3Dproj(struct hlsl_ctx *ctx, return intrinsic_tex(ctx, params, loc, "tex3Dproj", HLSL_SAMPLER_DIM_3D); }
+static bool intrinsic_texCUBEproj(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + return intrinsic_tex(ctx, params, loc, "texCUBEproj", HLSL_SAMPLER_DIM_CUBE); +} + static bool intrinsic_transpose(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -3610,6 +3617,7 @@ intrinsic_functions[] = {"tex2Dproj", 2, false, intrinsic_tex2Dproj}, {"tex3D", -1, false, intrinsic_tex3D}, {"tex3Dproj", 2, false, intrinsic_tex3Dproj}, + {"texCUBEproj", 2, false, intrinsic_texCUBEproj}, {"transpose", 1, true, intrinsic_transpose}, {"trunc", 1, true, intrinsic_trunc}, };