mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
vkd3d-shader/hlsl: Parse GetDimensions() method.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
This commit is contained in:
parent
18731d71a6
commit
d50b5fe767
Notes:
Alexandre Julliard
2023-07-31 21:18:46 +09:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Zebediah Figura (@zfigura) Approved-by: Francisco Casas (@fcasas) Approved-by: Henri Verbeet (@hverbeet) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/218
@ -2544,6 +2544,8 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru
|
||||
[HLSL_RESOURCE_GATHER_GREEN] = "gather_green",
|
||||
[HLSL_RESOURCE_GATHER_BLUE] = "gather_blue",
|
||||
[HLSL_RESOURCE_GATHER_ALPHA] = "gather_alpha",
|
||||
[HLSL_RESOURCE_SAMPLE_INFO] = "sample_info",
|
||||
[HLSL_RESOURCE_RESINFO] = "resinfo",
|
||||
};
|
||||
|
||||
assert(load->load_type < ARRAY_SIZE(type_names));
|
||||
@ -2551,8 +2553,11 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru
|
||||
dump_deref(buffer, &load->resource);
|
||||
vkd3d_string_buffer_printf(buffer, ", sampler = ");
|
||||
dump_deref(buffer, &load->sampler);
|
||||
vkd3d_string_buffer_printf(buffer, ", coords = ");
|
||||
dump_src(buffer, &load->coords);
|
||||
if (load->coords.node)
|
||||
{
|
||||
vkd3d_string_buffer_printf(buffer, ", coords = ");
|
||||
dump_src(buffer, &load->coords);
|
||||
}
|
||||
if (load->sample_index.node)
|
||||
{
|
||||
vkd3d_string_buffer_printf(buffer, ", sample index = ");
|
||||
|
@ -634,6 +634,8 @@ enum hlsl_resource_load_type
|
||||
HLSL_RESOURCE_GATHER_GREEN,
|
||||
HLSL_RESOURCE_GATHER_BLUE,
|
||||
HLSL_RESOURCE_GATHER_ALPHA,
|
||||
HLSL_RESOURCE_SAMPLE_INFO,
|
||||
HLSL_RESOURCE_RESINFO,
|
||||
};
|
||||
|
||||
struct hlsl_ir_resource_load
|
||||
|
@ -3670,6 +3670,13 @@ static int intrinsic_function_name_compare(const void *a, const void *b)
|
||||
return strcmp(a, func->name);
|
||||
}
|
||||
|
||||
static struct hlsl_ir_node *hlsl_new_void_expr(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0};
|
||||
|
||||
return hlsl_new_expr(ctx, HLSL_OP0_VOID, operands, ctx->builtin_types.Void, loc);
|
||||
}
|
||||
|
||||
static struct hlsl_block *add_call(struct hlsl_ctx *ctx, const char *name,
|
||||
struct parse_initializer *args, const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
@ -3744,10 +3751,9 @@ static struct hlsl_block *add_call(struct hlsl_ctx *ctx, const char *name,
|
||||
}
|
||||
else
|
||||
{
|
||||
struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0};
|
||||
struct hlsl_ir_node *expr;
|
||||
|
||||
if (!(expr = hlsl_new_expr(ctx, HLSL_OP0_VOID, operands, ctx->builtin_types.Void, loc)))
|
||||
if (!(expr = hlsl_new_void_expr(ctx, loc)))
|
||||
goto fail;
|
||||
hlsl_block_add_instr(args->instrs, expr);
|
||||
}
|
||||
@ -4179,6 +4185,182 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool add_assignment_from_component(struct hlsl_ctx *ctx, struct hlsl_block *instrs, struct hlsl_ir_node *dest,
|
||||
struct hlsl_ir_node *src, unsigned int component, const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
struct hlsl_ir_node *load;
|
||||
|
||||
if (!dest)
|
||||
return true;
|
||||
|
||||
if (!(load = hlsl_add_load_component(ctx, block_to_list(instrs), src, component, loc)))
|
||||
return false;
|
||||
|
||||
if (!add_assignment(ctx, instrs, dest, ASSIGN_OP_ASSIGN, load))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool add_getdimensions_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, 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;
|
||||
bool uint_resinfo, has_uint_arg, has_float_arg;
|
||||
struct hlsl_resource_load_params load_params;
|
||||
struct hlsl_ir_node *sample_info, *res_info;
|
||||
struct hlsl_ir_node *zero = NULL, *void_ret;
|
||||
struct hlsl_type *uint_type, *float_type;
|
||||
unsigned int i, j;
|
||||
enum func_argument
|
||||
{
|
||||
ARG_MIP_LEVEL,
|
||||
ARG_WIDTH,
|
||||
ARG_HEIGHT,
|
||||
ARG_ELEMENT_COUNT,
|
||||
ARG_LEVEL_COUNT,
|
||||
ARG_SAMPLE_COUNT,
|
||||
ARG_MAX_ARGS,
|
||||
};
|
||||
struct hlsl_ir_node *args[ARG_MAX_ARGS] = { 0 };
|
||||
static const struct overload
|
||||
{
|
||||
enum hlsl_sampler_dim sampler_dim;
|
||||
unsigned int args_count;
|
||||
enum func_argument args[ARG_MAX_ARGS];
|
||||
}
|
||||
overloads[] =
|
||||
{
|
||||
{ HLSL_SAMPLER_DIM_1D, 1, { ARG_WIDTH } },
|
||||
{ HLSL_SAMPLER_DIM_1D, 3, { ARG_MIP_LEVEL, ARG_WIDTH, ARG_LEVEL_COUNT } },
|
||||
{ HLSL_SAMPLER_DIM_1DARRAY, 2, { ARG_WIDTH, ARG_ELEMENT_COUNT } },
|
||||
{ HLSL_SAMPLER_DIM_1DARRAY, 4, { ARG_MIP_LEVEL, ARG_WIDTH, ARG_ELEMENT_COUNT, ARG_LEVEL_COUNT } },
|
||||
{ HLSL_SAMPLER_DIM_2D, 2, { ARG_WIDTH, ARG_HEIGHT } },
|
||||
{ HLSL_SAMPLER_DIM_2D, 4, { ARG_MIP_LEVEL, ARG_WIDTH, ARG_HEIGHT, ARG_LEVEL_COUNT } },
|
||||
{ HLSL_SAMPLER_DIM_2DARRAY, 3, { ARG_WIDTH, ARG_HEIGHT, ARG_ELEMENT_COUNT } },
|
||||
{ HLSL_SAMPLER_DIM_2DARRAY, 5, { ARG_MIP_LEVEL, ARG_WIDTH, ARG_HEIGHT, ARG_ELEMENT_COUNT, ARG_LEVEL_COUNT } },
|
||||
{ HLSL_SAMPLER_DIM_3D, 3, { ARG_WIDTH, ARG_HEIGHT, ARG_ELEMENT_COUNT } },
|
||||
{ HLSL_SAMPLER_DIM_3D, 5, { ARG_MIP_LEVEL, ARG_WIDTH, ARG_HEIGHT, ARG_ELEMENT_COUNT, ARG_LEVEL_COUNT } },
|
||||
{ HLSL_SAMPLER_DIM_CUBE, 2, { ARG_WIDTH, ARG_HEIGHT } },
|
||||
{ HLSL_SAMPLER_DIM_CUBE, 4, { ARG_MIP_LEVEL, ARG_WIDTH, ARG_HEIGHT, ARG_LEVEL_COUNT } },
|
||||
{ HLSL_SAMPLER_DIM_CUBEARRAY, 3, { ARG_WIDTH, ARG_HEIGHT, ARG_ELEMENT_COUNT } },
|
||||
{ HLSL_SAMPLER_DIM_CUBEARRAY, 5, { ARG_MIP_LEVEL, ARG_WIDTH, ARG_HEIGHT, ARG_ELEMENT_COUNT, ARG_LEVEL_COUNT } },
|
||||
{ HLSL_SAMPLER_DIM_2DMS, 3, { ARG_WIDTH, ARG_HEIGHT, ARG_SAMPLE_COUNT } },
|
||||
{ HLSL_SAMPLER_DIM_2DMSARRAY, 4, { ARG_WIDTH, ARG_HEIGHT, ARG_ELEMENT_COUNT, ARG_SAMPLE_COUNT } },
|
||||
};
|
||||
const struct overload *o = NULL;
|
||||
|
||||
if (object_type->sampler_dim > HLSL_SAMPLER_DIM_LAST_TEXTURE)
|
||||
{
|
||||
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "GetDimensions() is not defined for this type.");
|
||||
}
|
||||
|
||||
uint_type = hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT);
|
||||
float_type = hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT);
|
||||
has_uint_arg = has_float_arg = false;
|
||||
for (i = 0; i < ARRAY_SIZE(overloads); ++i)
|
||||
{
|
||||
const struct overload *iter = &overloads[i];
|
||||
|
||||
if (iter->sampler_dim == object_type->sampler_dim && iter->args_count == params->args_count)
|
||||
{
|
||||
for (j = 0; j < params->args_count; ++j)
|
||||
{
|
||||
args[iter->args[j]] = params->args[j];
|
||||
|
||||
/* Input parameter. */
|
||||
if (iter->args[j] == ARG_MIP_LEVEL)
|
||||
{
|
||||
if (!(args[ARG_MIP_LEVEL] = add_implicit_conversion(ctx, block, args[ARG_MIP_LEVEL],
|
||||
hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
has_float_arg |= hlsl_types_are_equal(params->args[j]->data_type, float_type);
|
||||
has_uint_arg |= hlsl_types_are_equal(params->args[j]->data_type, uint_type);
|
||||
|
||||
if (params->args[j]->data_type->class != HLSL_CLASS_SCALAR)
|
||||
{
|
||||
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Expected scalar arguments.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
o = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
uint_resinfo = !has_float_arg && has_uint_arg;
|
||||
|
||||
if (!o)
|
||||
{
|
||||
struct vkd3d_string_buffer *string;
|
||||
|
||||
if ((string = hlsl_type_to_string(ctx, object_type)))
|
||||
{
|
||||
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX,
|
||||
"Unexpected number of arguments %u for %s.%s().", params->args_count, string->buffer, name);
|
||||
hlsl_release_string_buffer(ctx, string);
|
||||
}
|
||||
}
|
||||
|
||||
if (!args[ARG_MIP_LEVEL])
|
||||
{
|
||||
if (!(zero = hlsl_new_uint_constant(ctx, 0, loc)))
|
||||
return false;
|
||||
hlsl_block_add_instr(block, zero);
|
||||
args[ARG_MIP_LEVEL] = zero;
|
||||
}
|
||||
|
||||
memset(&load_params, 0, sizeof(load_params));
|
||||
load_params.type = HLSL_RESOURCE_RESINFO;
|
||||
load_params.resource = object;
|
||||
load_params.lod = args[ARG_MIP_LEVEL];
|
||||
load_params.format = hlsl_get_vector_type(ctx, uint_resinfo ? HLSL_TYPE_UINT : HLSL_TYPE_FLOAT, 4);
|
||||
|
||||
if (!(res_info = hlsl_new_resource_load(ctx, &load_params, loc)))
|
||||
return false;
|
||||
hlsl_block_add_instr(block, res_info);
|
||||
|
||||
if (!add_assignment_from_component(ctx, block, args[ARG_WIDTH], res_info, 0, loc))
|
||||
return false;
|
||||
|
||||
if (!add_assignment_from_component(ctx, block, args[ARG_HEIGHT], res_info, 1, loc))
|
||||
return false;
|
||||
|
||||
if (!add_assignment_from_component(ctx, block, args[ARG_ELEMENT_COUNT], res_info,
|
||||
object_type->sampler_dim == HLSL_SAMPLER_DIM_1DARRAY ? 1 : 2, loc))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!add_assignment_from_component(ctx, block, args[ARG_LEVEL_COUNT], res_info, 3, loc))
|
||||
return false;
|
||||
|
||||
if (args[ARG_SAMPLE_COUNT])
|
||||
{
|
||||
memset(&load_params, 0, sizeof(load_params));
|
||||
load_params.type = HLSL_RESOURCE_SAMPLE_INFO;
|
||||
load_params.resource = object;
|
||||
load_params.format = args[ARG_SAMPLE_COUNT]->data_type;
|
||||
if (!(sample_info = hlsl_new_resource_load(ctx, &load_params, loc)))
|
||||
return false;
|
||||
hlsl_block_add_instr(block, sample_info);
|
||||
|
||||
if (!add_assignment(ctx, block, args[ARG_SAMPLE_COUNT], ASSIGN_OP_ASSIGN, sample_info))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(void_ret = hlsl_new_void_expr(ctx, loc)))
|
||||
return false;
|
||||
hlsl_block_add_instr(block, void_ret);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object,
|
||||
const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
@ -4334,6 +4516,8 @@ object_methods[] =
|
||||
{ "GatherGreen", add_gather_method_call },
|
||||
{ "GatherRed", add_gather_method_call },
|
||||
|
||||
{ "GetDimensions", add_getdimensions_method_call },
|
||||
|
||||
{ "Load", add_load_method_call },
|
||||
|
||||
{ "Sample", add_sample_method_call },
|
||||
|
@ -2118,9 +2118,11 @@ static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in
|
||||
case HLSL_RESOURCE_GATHER_GREEN:
|
||||
case HLSL_RESOURCE_GATHER_BLUE:
|
||||
case HLSL_RESOURCE_GATHER_ALPHA:
|
||||
case HLSL_RESOURCE_RESINFO:
|
||||
case HLSL_RESOURCE_SAMPLE_CMP:
|
||||
case HLSL_RESOURCE_SAMPLE_CMP_LZ:
|
||||
case HLSL_RESOURCE_SAMPLE_GRAD:
|
||||
case HLSL_RESOURCE_SAMPLE_INFO:
|
||||
return false;
|
||||
|
||||
case HLSL_RESOURCE_SAMPLE:
|
||||
@ -2974,7 +2976,8 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop
|
||||
load->sampler.offset.node->last_read = last_read;
|
||||
}
|
||||
|
||||
load->coords.node->last_read = last_read;
|
||||
if (load->coords.node)
|
||||
load->coords.node->last_read = last_read;
|
||||
if (load->texel_offset.node)
|
||||
load->texel_offset.node->last_read = last_read;
|
||||
if (load->lod.node)
|
||||
|
@ -5117,6 +5117,11 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx,
|
||||
write_sm4_gather(ctx, buffer, &load->node, &load->resource, &load->sampler, coords,
|
||||
HLSL_SWIZZLE(W, W, W, W), texel_offset);
|
||||
break;
|
||||
|
||||
case HLSL_RESOURCE_SAMPLE_INFO:
|
||||
case HLSL_RESOURCE_RESINFO:
|
||||
hlsl_fixme(ctx, &load->node.loc, "Unsupported load type %u.\n", load->load_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user