vkd3d-shader/hlsl: Validate "numthreads" attribute values.

This commit is contained in:
Elizabeth Figura
2025-03-28 15:35:44 -05:00
committed by Henri Verbeet
parent cfb59828f3
commit e16176672a
Notes: Henri Verbeet 2025-05-14 15:28:33 +02:00
Approved-by: Francisco Casas (@fcasas)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1498
2 changed files with 15 additions and 14 deletions

View File

@@ -7154,7 +7154,7 @@ struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_dere
} }
static bool get_integral_argument_value(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr, static bool get_integral_argument_value(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr,
unsigned int i, enum hlsl_base_type *base_type, int *value) unsigned int i, int *value)
{ {
const struct hlsl_ir_node *instr = attr->args[i].node; const struct hlsl_ir_node *instr = attr->args[i].node;
const struct hlsl_type *type = instr->data_type; const struct hlsl_type *type = instr->data_type;
@@ -7178,7 +7178,6 @@ static bool get_integral_argument_value(struct hlsl_ctx *ctx, const struct hlsl_
return false; return false;
} }
*base_type = type->e.numeric.type;
*value = hlsl_ir_constant(instr)->value.u[0].i; *value = hlsl_ir_constant(instr)->value.u[0].i;
return true; return true;
} }
@@ -7205,6 +7204,7 @@ static const char *get_string_argument_value(struct hlsl_ctx *ctx, const struct
static void parse_numthreads_attribute(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr) static void parse_numthreads_attribute(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr)
{ {
static const unsigned int limits[3] = {1024, 1024, 64};
unsigned int i; unsigned int i;
ctx->found_numthreads = 1; ctx->found_numthreads = 1;
@@ -7218,18 +7218,21 @@ static void parse_numthreads_attribute(struct hlsl_ctx *ctx, const struct hlsl_a
for (i = 0; i < attr->args_count; ++i) for (i = 0; i < attr->args_count; ++i)
{ {
enum hlsl_base_type base_type;
int value; int value;
if (!get_integral_argument_value(ctx, attr, i, &base_type, &value)) if (!get_integral_argument_value(ctx, attr, i, &value))
return; return;
if ((base_type == HLSL_TYPE_INT && value <= 0) || (base_type == HLSL_TYPE_UINT && !value)) if (value < 1 || value > limits[i])
hlsl_error(ctx, &attr->args[i].node->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_THREAD_COUNT, hlsl_error(ctx, &attr->args[i].node->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_THREAD_COUNT,
"Thread count must be a positive integer."); "Dimension %u of the thread count must be between 1 and %u.", i, limits[i]);
ctx->thread_count[i] = value; ctx->thread_count[i] = value;
} }
if (ctx->thread_count[0] * ctx->thread_count[1] * ctx->thread_count[2] > 1024)
hlsl_error(ctx, &attr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_THREAD_COUNT,
"Product of thread count parameters cannot exceed 1024.");
} }
static void parse_domain_attribute(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr) static void parse_domain_attribute(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr)
@@ -7260,7 +7263,6 @@ static void parse_domain_attribute(struct hlsl_ctx *ctx, const struct hlsl_attri
static void parse_outputcontrolpoints_attribute(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr) static void parse_outputcontrolpoints_attribute(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr)
{ {
enum hlsl_base_type base_type;
int value; int value;
if (attr->args_count != 1) if (attr->args_count != 1)
@@ -7270,7 +7272,7 @@ static void parse_outputcontrolpoints_attribute(struct hlsl_ctx *ctx, const stru
return; return;
} }
if (!get_integral_argument_value(ctx, attr, 0, &base_type, &value)) if (!get_integral_argument_value(ctx, attr, 0, &value))
return; return;
if (value < 0 || value > 32) if (value < 0 || value > 32)
@@ -7373,7 +7375,6 @@ static void parse_patchconstantfunc_attribute(struct hlsl_ctx *ctx, const struct
static void parse_maxvertexcount_attribute(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr) static void parse_maxvertexcount_attribute(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr)
{ {
enum hlsl_base_type base_type;
int value; int value;
if (attr->args_count != 1) if (attr->args_count != 1)
@@ -7383,7 +7384,7 @@ static void parse_maxvertexcount_attribute(struct hlsl_ctx *ctx, const struct hl
return; return;
} }
if (!get_integral_argument_value(ctx, attr, 0, &base_type, &value)) if (!get_integral_argument_value(ctx, attr, 0, &value))
return; return;
if (value < 1 || value > 1024) if (value < 1 || value > 1024)

View File

@@ -177,19 +177,19 @@ size (2d, 2, 2)
% The product must not exceed 1024, and the third dimension cannot exceed 64. % The product must not exceed 1024, and the third dimension cannot exceed 64.
[compute shader fail todo] [compute shader fail]
[numthreads(1025,1,1)] [numthreads(1025,1,1)]
void main() {} void main() {}
[compute shader fail todo] [compute shader fail]
[numthreads(1,1025,1)] [numthreads(1,1025,1)]
void main() {} void main() {}
[compute shader fail todo] [compute shader fail]
[numthreads(1,1,65)] [numthreads(1,1,65)]
void main() {} void main() {}
[compute shader fail todo] [compute shader fail]
[numthreads(41,25,25)] [numthreads(41,25,25)]
void main() {} void main() {}