-- v5: vkd3d-shader/hlsl: Implement SampleBias() method.
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 484 +++++++++++++++++++++------------------ 1 file changed, 256 insertions(+), 228 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index b9e03325..b54caf52 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3565,287 +3565,315 @@ static unsigned int hlsl_offset_dim_count(enum hlsl_sampler_dim dim) } }
-static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, +static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { const struct hlsl_type *object_type = object->data_type; + const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); + const unsigned int offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); + struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_LOAD}; + struct hlsl_ir_resource_load *load; + bool multisampled;
- if (object_type->class != HLSL_CLASS_OBJECT || object_type->base_type != HLSL_TYPE_TEXTURE - || object_type->sampler_dim == HLSL_SAMPLER_DIM_GENERIC) - { - struct vkd3d_string_buffer *string; + multisampled = object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS + || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY;
- if ((string = hlsl_type_to_string(ctx, object_type))) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Type '%s' does not have methods.", string->buffer); - hlsl_release_string_buffer(ctx, string); + if (params->args_count < 1 + multisampled || params->args_count > 3 + multisampled) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to method 'Load': expected between %u and %u, but got %u.", + 1 + multisampled, 3 + multisampled, params->args_count); return false; } - - if (!strcmp(name, "Load") - && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBE - && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBEARRAY) + if (multisampled) { - const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); - const unsigned int offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); - struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_LOAD}; - struct hlsl_ir_resource_load *load; - bool multisampled; - - multisampled = object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS - || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY; + hlsl_fixme(ctx, loc, "Load() sampling index parameter."); + }
- if (params->args_count < 1 + multisampled || params->args_count > 3 + multisampled) - { - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, - "Wrong number of arguments to method 'Load': expected between %u and %u, but got %u.", - 1 + multisampled, 3 + multisampled, params->args_count); + assert(offset_dim); + if (params->args_count > 1 + multisampled) + { + if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[1 + multisampled], + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; - } - if (multisampled) - { - hlsl_fixme(ctx, loc, "Load() sampling index parameter."); - } + } + if (params->args_count > 2 + multisampled) + { + hlsl_fixme(ctx, loc, "Tiled resource status argument."); + }
- assert(offset_dim); - if (params->args_count > 1 + multisampled) - { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[1 + multisampled], - hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) - return false; - } - if (params->args_count > 2 + multisampled) - { - hlsl_fixme(ctx, loc, "Tiled resource status argument."); - } + /* +1 for the mipmap level */ + if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[0], + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim + 1), loc))) + return false;
- /* +1 for the mipmap level */ - if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[0], - hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim + 1), loc))) - return false; + load_params.format = object_type->e.resource_format; + load_params.resource = object;
- load_params.format = object_type->e.resource_format; - load_params.resource = object; + if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) + return false; + list_add_tail(instrs, &load->node.entry); + return true; +}
- if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) - return false; - list_add_tail(instrs, &load->node.entry); - return true; +static bool add_sample_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, + const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + const struct hlsl_type *object_type = object->data_type; + const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); + const unsigned int offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); + struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_SAMPLE}; + const struct hlsl_type *sampler_type; + struct hlsl_ir_resource_load *load; + + if (params->args_count < 2 || params->args_count > 4 + !!offset_dim) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to method 'Sample': expected from 2 to %u, but got %u.", + 4 + !!offset_dim, params->args_count); + return false; } - else if (!strcmp(name, "Sample") - && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS - && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) + + sampler_type = params->args[0]->data_type; + if (sampler_type->class != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER + || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC) { - const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); - const unsigned int offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); - struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_SAMPLE}; - const struct hlsl_type *sampler_type; - struct hlsl_ir_resource_load *load; + struct vkd3d_string_buffer *string;
- if (params->args_count < 2 || params->args_count > 4 + !!offset_dim) - { - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, - "Wrong number of arguments to method 'Sample': expected from 2 to %u, but got %u.", - 4 + !!offset_dim, params->args_count); - return false; - } + if ((string = hlsl_type_to_string(ctx, sampler_type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Wrong type for argument 0 of Sample(): expected 'sampler', but got '%s'.", string->buffer); + hlsl_release_string_buffer(ctx, string); + return false; + }
- sampler_type = params->args[0]->data_type; - if (sampler_type->class != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER - || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC) - { - struct vkd3d_string_buffer *string; + if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) + return false;
- if ((string = hlsl_type_to_string(ctx, sampler_type))) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Wrong type for argument 0 of Sample(): expected 'sampler', but got '%s'.", string->buffer); - hlsl_release_string_buffer(ctx, string); + if (offset_dim && params->args_count > 2) + { + if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[2], + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; - } + }
- if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) - return false; + if (params->args_count > 2 + !!offset_dim) + hlsl_fixme(ctx, loc, "Sample() clamp parameter."); + if (params->args_count > 3 + !!offset_dim) + hlsl_fixme(ctx, loc, "Tiled resource status argument.");
- if (offset_dim && params->args_count > 2) - { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[2], - hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) - return false; - } + load_params.format = object_type->e.resource_format; + load_params.resource = object; + load_params.sampler = params->args[0];
- if (params->args_count > 2 + !!offset_dim) - hlsl_fixme(ctx, loc, "Sample() clamp parameter."); - if (params->args_count > 3 + !!offset_dim) - hlsl_fixme(ctx, loc, "Tiled resource status argument."); + if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) + return false; + list_add_tail(instrs, &load->node.entry);
- load_params.format = object_type->e.resource_format; - load_params.resource = object; - load_params.sampler = params->args[0]; + return true; +}
- if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) - return false; - list_add_tail(instrs, &load->node.entry); +static bool add_gather_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, + const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + const struct hlsl_type *object_type = object->data_type; + const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); + const unsigned int offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); + struct hlsl_resource_load_params load_params = {0}; + const struct hlsl_type *sampler_type; + struct hlsl_ir_resource_load *load; + unsigned int read_channel;
- return true; + if (!strcmp(name, "GatherGreen")) + { + load_params.type = HLSL_RESOURCE_GATHER_GREEN; + read_channel = 1; } - else if ((!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue") - || !strcmp(name, "GatherGreen") || !strcmp(name, "GatherAlpha")) - && (object_type->sampler_dim == HLSL_SAMPLER_DIM_2D - || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DARRAY - || object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBE - || object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBEARRAY)) + else if (!strcmp(name, "GatherBlue")) { - const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); - const unsigned int offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); - struct hlsl_resource_load_params load_params = {0}; - const struct hlsl_type *sampler_type; - struct hlsl_ir_resource_load *load; - unsigned int read_channel; - - if (!strcmp(name, "GatherGreen")) - { - load_params.type = HLSL_RESOURCE_GATHER_GREEN; - read_channel = 1; - } - else if (!strcmp(name, "GatherBlue")) - { - load_params.type = HLSL_RESOURCE_GATHER_BLUE; - read_channel = 2; - } - else if (!strcmp(name, "GatherAlpha")) - { - load_params.type = HLSL_RESOURCE_GATHER_ALPHA; - read_channel = 3; - } - else - { - load_params.type = HLSL_RESOURCE_GATHER_RED; - read_channel = 0; - } + load_params.type = HLSL_RESOURCE_GATHER_BLUE; + read_channel = 2; + } + else if (!strcmp(name, "GatherAlpha")) + { + load_params.type = HLSL_RESOURCE_GATHER_ALPHA; + read_channel = 3; + } + else + { + load_params.type = HLSL_RESOURCE_GATHER_RED; + read_channel = 0; + }
- if (!strcmp(name, "Gather") || !offset_dim) - { - if (params->args_count < 2 || params->args_count > 3 + !!offset_dim) - { - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, - "Wrong number of arguments to method '%s': expected from 2 to %u, but got %u.", - name, 3 + !!offset_dim, params->args_count); - return false; - } - } - else if (params->args_count < 2 || params->args_count == 5 || params->args_count > 7) + if (!strcmp(name, "Gather") || !offset_dim) + { + if (params->args_count < 2 || params->args_count > 3 + !!offset_dim) { hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, - "Wrong number of arguments to method '%s': expected 2, 3, 4, 6 or 7, but got %u.", - name, params->args_count); + "Wrong number of arguments to method '%s': expected from 2 to %u, but got %u.", + name, 3 + !!offset_dim, params->args_count); return false; } + } + else if (params->args_count < 2 || params->args_count == 5 || params->args_count > 7) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to method '%s': expected 2, 3, 4, 6 or 7, but got %u.", + name, params->args_count); + return false; + }
- if (params->args_count == 3 + !!offset_dim || params->args_count == 7) - hlsl_fixme(ctx, loc, "Tiled resource status argument."); - - if (params->args_count == 6 || params->args_count == 7) - { - hlsl_fixme(ctx, loc, "Multiple %s() offset parameters.", name); - } - else if (offset_dim && params->args_count > 2) - { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[2], - hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) - return false; - } - - sampler_type = params->args[0]->data_type; - if (sampler_type->class != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER - || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC) - { - struct vkd3d_string_buffer *string; + if (params->args_count == 3 + !!offset_dim || params->args_count == 7) + hlsl_fixme(ctx, loc, "Tiled resource status argument.");
- if ((string = hlsl_type_to_string(ctx, sampler_type))) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Wrong type for argument 1 of %s(): expected 'sampler', but got '%s'.", name, string->buffer); - hlsl_release_string_buffer(ctx, string); + if (params->args_count == 6 || params->args_count == 7) + { + hlsl_fixme(ctx, loc, "Multiple %s() offset parameters.", name); + } + else if (offset_dim && params->args_count > 2) + { + if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[2], + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; - } + }
- if (read_channel >= object_type->e.resource_format->dimx) - { + sampler_type = params->args[0]->data_type; + if (sampler_type->class != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER + || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, sampler_type))) hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Method %s() requires at least %u channels.", name, read_channel + 1); - return false; - } + "Wrong type for argument 1 of %s(): expected 'sampler', but got '%s'.", name, string->buffer); + hlsl_release_string_buffer(ctx, string); + return false; + }
- if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) - return false; + if (read_channel >= object_type->e.resource_format->dimx) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Method %s() requires at least %u channels.", name, read_channel + 1); + return false; + } + + if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) + return false;
- load_params.format = hlsl_get_vector_type(ctx, object_type->e.resource_format->base_type, 4); - load_params.resource = object; - load_params.sampler = params->args[0]; + load_params.format = hlsl_get_vector_type(ctx, object_type->e.resource_format->base_type, 4); + load_params.resource = object; + load_params.sampler = params->args[0];
- if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) - return false; - list_add_tail(instrs, &load->node.entry); - return true; + if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) + return false; + list_add_tail(instrs, &load->node.entry); + return true; +} + +static bool add_sample_level_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, + const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + const struct hlsl_type *object_type = object->data_type; + struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_SAMPLE_LOD}; + const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); + const unsigned int offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); + const struct hlsl_type *sampler_type; + struct hlsl_ir_resource_load *load; + + if (params->args_count < 3 || params->args_count > 4 + !!offset_dim) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to method 'SampleLevel': expected from 3 to %u, but got %u.", + 4 + !!offset_dim, params->args_count); + return false; } - else if (!strcmp(name, "SampleLevel") - && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS - && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) + + sampler_type = params->args[0]->data_type; + if (sampler_type->class != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER + || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC) { - struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_SAMPLE_LOD}; - const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); - const unsigned int offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); - const struct hlsl_type *sampler_type; - struct hlsl_ir_resource_load *load; + struct vkd3d_string_buffer *string;
- if (params->args_count < 3 || params->args_count > 4 + !!offset_dim) - { - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, - "Wrong number of arguments to method 'SampleLevel': expected from 3 to %u, but got %u.", - 4 + !!offset_dim, params->args_count); - return false; - } + if ((string = hlsl_type_to_string(ctx, sampler_type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Wrong type for argument 0 of SampleLevel(): expected 'sampler', but got '%s'.", string->buffer); + hlsl_release_string_buffer(ctx, string); + return false; + }
- sampler_type = params->args[0]->data_type; - if (sampler_type->class != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER - || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC) - { - struct vkd3d_string_buffer *string; + if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) + load_params.coords = params->args[1];
- if ((string = hlsl_type_to_string(ctx, sampler_type))) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Wrong type for argument 0 of SampleLevel(): expected 'sampler', but got '%s'.", string->buffer); - hlsl_release_string_buffer(ctx, string); + if (!(load_params.lod = add_implicit_conversion(ctx, instrs, params->args[2], + hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) + load_params.lod = params->args[2]; + + if (offset_dim && params->args_count > 3) + { + if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[3], + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; - } + }
- if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) - load_params.coords = params->args[1]; + if (params->args_count > 3 + !!offset_dim) + hlsl_fixme(ctx, loc, "Tiled resource status argument.");
- if (!(load_params.lod = add_implicit_conversion(ctx, instrs, params->args[2], - hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) - load_params.lod = params->args[2]; + load_params.format = object_type->e.resource_format; + load_params.resource = object; + load_params.sampler = params->args[0];
- if (offset_dim && params->args_count > 3) - { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[3], - hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) - return false; - } + if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) + return false; + list_add_tail(instrs, &load->node.entry); + return true; +}
- if (params->args_count > 3 + !!offset_dim) - hlsl_fixme(ctx, loc, "Tiled resource status argument."); +static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, + const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + const struct hlsl_type *object_type = object->data_type;
- load_params.format = object_type->e.resource_format; - load_params.resource = object; - load_params.sampler = params->args[0]; + if (object_type->class != HLSL_CLASS_OBJECT || object_type->base_type != HLSL_TYPE_TEXTURE + || object_type->sampler_dim == HLSL_SAMPLER_DIM_GENERIC) + { + struct vkd3d_string_buffer *string;
- if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) - return false; - list_add_tail(instrs, &load->node.entry); - return true; + if ((string = hlsl_type_to_string(ctx, object_type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Type '%s' does not have methods.", string->buffer); + hlsl_release_string_buffer(ctx, string); + return false; + } + + if (!strcmp(name, "Load") + && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBE + && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBEARRAY) + { + return add_load_method_call(ctx, instrs, object, name, params, loc); + } + else if (!strcmp(name, "Sample") + && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS + && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) + { + return add_sample_method_call(ctx, instrs, object, name, params, loc); + } + else if ((!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue") + || !strcmp(name, "GatherGreen") || !strcmp(name, "GatherAlpha")) + && (object_type->sampler_dim == HLSL_SAMPLER_DIM_2D + || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DARRAY + || object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBE + || object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBEARRAY)) + { + return add_gather_method_call(ctx, instrs, object, name, params, loc); + } + else if (!strcmp(name, "SampleLevel") + && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS + && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) + { + return add_sample_level_method_call(ctx, instrs, object, name, params, loc); } else {
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 1 + libs/vkd3d-shader/hlsl.h | 1 + libs/vkd3d-shader/hlsl.y | 23 +++++++++++++++++------ libs/vkd3d-shader/tpf.c | 34 ++++++++++++++++++++++++++++------ tests/sampler.shader_test | 13 +++++++++++++ 5 files changed, 60 insertions(+), 12 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 32511590..f0b6a5ef 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -2383,6 +2383,7 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru [HLSL_RESOURCE_LOAD] = "load_resource", [HLSL_RESOURCE_SAMPLE] = "sample", [HLSL_RESOURCE_SAMPLE_LOD] = "sample_lod", + [HLSL_RESOURCE_SAMPLE_LOD_BIAS] = "sample_biased", [HLSL_RESOURCE_GATHER_RED] = "gather_red", [HLSL_RESOURCE_GATHER_GREEN] = "gather_green", [HLSL_RESOURCE_GATHER_BLUE] = "gather_blue", diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 86f35df2..4552c6d1 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -588,6 +588,7 @@ enum hlsl_resource_load_type HLSL_RESOURCE_LOAD, HLSL_RESOURCE_SAMPLE, HLSL_RESOURCE_SAMPLE_LOD, + HLSL_RESOURCE_SAMPLE_LOD_BIAS, 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 b54caf52..3c55a5ca 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3772,21 +3772,26 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct list *instrs, st return true; }
-static bool add_sample_level_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, +static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { const struct hlsl_type *object_type = object->data_type; - struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_SAMPLE_LOD}; + struct hlsl_resource_load_params load_params = { 0 }; const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); const unsigned int offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); const struct hlsl_type *sampler_type; struct hlsl_ir_resource_load *load;
+ if (!strcmp(name, "SampleLevel")) + load_params.type = HLSL_RESOURCE_SAMPLE_LOD; + else + load_params.type = HLSL_RESOURCE_SAMPLE_LOD_BIAS; + if (params->args_count < 3 || params->args_count > 4 + !!offset_dim) { hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, - "Wrong number of arguments to method 'SampleLevel': expected from 3 to %u, but got %u.", - 4 + !!offset_dim, params->args_count); + "Wrong number of arguments to method '%s': expected from 3 to %u, but got %u.", + name, 4 + !!offset_dim, params->args_count); return false; }
@@ -3798,7 +3803,7 @@ static bool add_sample_level_method_call(struct hlsl_ctx *ctx, struct list *inst
if ((string = hlsl_type_to_string(ctx, sampler_type))) hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Wrong type for argument 0 of SampleLevel(): expected 'sampler', but got '%s'.", string->buffer); + "Wrong type for argument 0 of %s(): expected 'sampler', but got '%s'.", name, string->buffer); hlsl_release_string_buffer(ctx, string); return false; } @@ -3873,7 +3878,13 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) { - return add_sample_level_method_call(ctx, instrs, object, name, params, loc); + return add_sample_lod_method_call(ctx, instrs, object, name, params, loc); + } + else if (!strcmp(name, "SampleBias") + && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS + && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) + { + return add_sample_lod_method_call(ctx, instrs, object, name, params, loc); } else { diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index 80487060..24c988a5 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -3700,14 +3700,30 @@ static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf }
static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, - const struct hlsl_type *resource_type, const struct hlsl_ir_node *dst, - const struct hlsl_deref *resource, const struct hlsl_deref *sampler, - const struct hlsl_ir_node *coords, const struct hlsl_ir_node *texel_offset) + const struct hlsl_ir_resource_load *load) { + const struct hlsl_type *resource_type = load->resource.var->data_type; + 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)); - instr.opcode = VKD3D_SM4_OP_SAMPLE; + switch (load->load_type) + { + case HLSL_RESOURCE_SAMPLE: + instr.opcode = VKD3D_SM4_OP_SAMPLE; + break; + + case HLSL_RESOURCE_SAMPLE_LOD_BIAS: + instr.opcode = VKD3D_SM4_OP_SAMPLE_B; + break; + + default: + vkd3d_unreachable(); + }
if (texel_offset) { @@ -3727,6 +3743,12 @@ static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer sm4_src_from_deref(ctx, &instr.srcs[2], sampler, sampler->var->data_type, VKD3DSP_WRITEMASK_ALL); instr.src_count = 3;
+ if (load->load_type == HLSL_RESOURCE_SAMPLE_LOD_BIAS) + { + sm4_src_from_node(&instr.srcs[3], load->lod.node, VKD3DSP_WRITEMASK_ALL); + ++instr.src_count; + } + write_sm4_instruction(buffer, &instr); }
@@ -4462,13 +4484,13 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx, break;
case HLSL_RESOURCE_SAMPLE: + case HLSL_RESOURCE_SAMPLE_LOD_BIAS: if (!load->sampler.var) { hlsl_fixme(ctx, &load->node.loc, "SM4 combined sample expression."); return; } - write_sm4_sample(ctx, buffer, resource_type, &load->node, - &load->resource, &load->sampler, coords, texel_offset); + write_sm4_sample(ctx, buffer, load); break;
case HLSL_RESOURCE_GATHER_RED: diff --git a/tests/sampler.shader_test b/tests/sampler.shader_test index 3970fb51..2cb70a0b 100644 --- a/tests/sampler.shader_test +++ b/tests/sampler.shader_test @@ -32,3 +32,16 @@ float4 main() : sv_target [test] draw quad probe all rgba (0.25, 0, 0.25, 0) + +[pixel shader] +SamplerState s; +Texture2D t; + +float4 main() : sv_target +{ + return t.SampleBias(s, float2(0.5, 0.5), 0.0); +} + +[test] +draw quad +probe all rgba (0.25, 0, 0.25, 0)
On Fri Apr 21 10:49:53 2023 +0000, Giovanni Mascellani wrote:
Not necessarily for this MR since it's pre-existing, just a comment: here I'd prefer a positive logic for choosing which object types are allowed, much like `Gather`. Also I wouldn't dislike some more systematic organization like `intrinsic_functions`.
I'd move type checks in the helpers first. For function pointers, I don't know if it matters. Anyway, this is unrelated.
On Fri Apr 21 11:13:30 2023 +0000, Nikolay Sivov wrote:
changed this line in [version 5 of the diff](/wine/vkd3d/-/merge_requests/172/diffs?diff_id=43490&start_sha=2687c07ee14e4ca9f3115bcfe58d7d8f8abe6114#9155b9453b4ec8ea0b9b025dfb55c061bd931610_3835_3785)
Ok, I merged the two.
This merge request was approved by Zebediah Figura.
The documentation says that the bias value should be a floating-point number between -16.0 and 15.99. When the value is constant, the native compiler checks for this and clamps the value. I don't think this is important enough to block the request.
This merge request was approved by Francisco Casas.
Giovanni Mascellani (@giomasce) commented about libs/vkd3d-shader/hlsl.y:
&& object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) {
return add_sample_level_method_call(ctx, instrs, object, name, params, loc);
return add_sample_lod_method_call(ctx, instrs, object, name, params, loc);
- }
- else if (!strcmp(name, "SampleBias")
&& object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS
&& object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY)
- {
return add_sample_lod_method_call(ctx, instrs, object, name, params, loc);
This block could be merged too (like for `Gather`), but it's not a big deal.
This merge request was approved by Giovanni Mascellani.
This merge request was approved by Henri Verbeet.