-- v7: 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 | 39 ++++++++++++++++++++++++++++++++ libs/vkd3d-shader/tpf.c | 3 +++ 5 files changed, 67 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c index 9a147e3d..8eb2980c 100644 --- a/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d-shader/d3dbc.c @@ -2287,6 +2287,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 b1427c1d..6497ef17 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -627,9 +627,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 0695f786..e39739dc 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3433,9 +3433,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) { @@ -3462,8 +3463,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, 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; @@ -3483,6 +3495,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) { @@ -3658,6 +3676,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 4f5a5b02..0ac61eb6 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -2128,6 +2128,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) @@ -2754,6 +2755,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) @@ -4310,6 +4345,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); + }
hlsl_transform_ir(ctx, validate_static_object_references, body, NULL); hlsl_transform_ir(ctx, track_object_components_sampler_dim, body, NULL); diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index f3ca223c..dbac193d 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -5172,6 +5172,9 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx, case HLSL_RESOURCE_RESINFO: write_sm4_resinfo(ctx, buffer, load); break; + + case HLSL_RESOURCE_SAMPLE_PROJ: + vkd3d_unreachable(); } }
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: 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 e39739dc..ffa0c722 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3463,7 +3463,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; @@ -3489,6 +3493,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) { @@ -3675,6 +3685,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 0ac61eb6..0b9a4611 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -2789,6 +2789,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) @@ -4348,6 +4397,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); }
hlsl_transform_ir(ctx, validate_static_object_references, body, NULL);
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 ffa0c722..9a2670fc 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3467,7 +3467,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; @@ -3517,6 +3518,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) { @@ -3689,6 +3696,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 8eb2980c..8d900b11 100644 --- a/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d-shader/d3dbc.c @@ -1981,10 +1981,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
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 9a2670fc..031f3857 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3468,7 +3468,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; @@ -3524,6 +3525,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) { @@ -3697,6 +3704,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}, };