mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-04-13 05:43:18 -07:00
vkd3d-shader/hlsl: Parse InputPatch and OutputPatch objects.
This commit is contained in:
Notes:
Henri Verbeet
2025-01-29 18:04:29 +01:00
Approved-by: Henri Verbeet (@hverbeet) Approved-by: Francisco Casas (@fcasas) Approved-by: Elizabeth Figura (@zfigura) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1355
@@ -297,6 +297,12 @@ bool hlsl_type_is_shader(const struct hlsl_type *type)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hlsl_type_is_patch_array(const struct hlsl_type *type)
|
||||||
|
{
|
||||||
|
return type->class == HLSL_CLASS_ARRAY && (type->e.array.array_type == HLSL_ARRAY_PATCH_INPUT
|
||||||
|
|| type->e.array.array_type == HLSL_ARRAY_PATCH_OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
/* Only intended to be used for derefs (after copies have been lowered to components or vectors) or
|
/* Only intended to be used for derefs (after copies have been lowered to components or vectors) or
|
||||||
* resources, since for both their data types span across a single regset. */
|
* resources, since for both their data types span across a single regset. */
|
||||||
static enum hlsl_regset type_get_regset(const struct hlsl_type *type)
|
static enum hlsl_regset type_get_regset(const struct hlsl_type *type)
|
||||||
@@ -891,7 +897,8 @@ struct hlsl_type *hlsl_get_element_type_from_path_index(struct hlsl_ctx *ctx, co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *basic_type, unsigned int array_size)
|
struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *basic_type,
|
||||||
|
unsigned int array_size, enum hlsl_array_type array_type)
|
||||||
{
|
{
|
||||||
struct hlsl_type *type;
|
struct hlsl_type *type;
|
||||||
|
|
||||||
@@ -902,6 +909,7 @@ struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *ba
|
|||||||
type->modifiers = basic_type->modifiers;
|
type->modifiers = basic_type->modifiers;
|
||||||
type->e.array.elements_count = array_size;
|
type->e.array.elements_count = array_size;
|
||||||
type->e.array.type = basic_type;
|
type->e.array.type = basic_type;
|
||||||
|
type->e.array.array_type = array_type;
|
||||||
type->sampler_dim = basic_type->sampler_dim;
|
type->sampler_dim = basic_type->sampler_dim;
|
||||||
hlsl_type_calculate_reg_size(ctx, type);
|
hlsl_type_calculate_reg_size(ctx, type);
|
||||||
|
|
||||||
@@ -1172,6 +1180,7 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2
|
|||||||
|
|
||||||
case HLSL_CLASS_ARRAY:
|
case HLSL_CLASS_ARRAY:
|
||||||
return t1->e.array.elements_count == t2->e.array.elements_count
|
return t1->e.array.elements_count == t2->e.array.elements_count
|
||||||
|
&& t1->e.array.array_type == t2->e.array.array_type
|
||||||
&& hlsl_types_are_equal(t1->e.array.type, t2->e.array.type);
|
&& hlsl_types_are_equal(t1->e.array.type, t2->e.array.type);
|
||||||
|
|
||||||
case HLSL_CLASS_TECHNIQUE:
|
case HLSL_CLASS_TECHNIQUE:
|
||||||
@@ -1251,6 +1260,7 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
type->e.array.elements_count = old->e.array.elements_count;
|
type->e.array.elements_count = old->e.array.elements_count;
|
||||||
|
type->e.array.array_type = old->e.array.array_type;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HLSL_CLASS_STRUCT:
|
case HLSL_CLASS_STRUCT:
|
||||||
@@ -2833,22 +2843,32 @@ static void hlsl_dump_type(struct vkd3d_string_buffer *buffer, const struct hlsl
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case HLSL_CLASS_ARRAY:
|
case HLSL_CLASS_ARRAY:
|
||||||
{
|
if (hlsl_type_is_patch_array(type))
|
||||||
const struct hlsl_type *t;
|
|
||||||
|
|
||||||
for (t = type; t->class == HLSL_CLASS_ARRAY; t = t->e.array.type)
|
|
||||||
;
|
|
||||||
|
|
||||||
hlsl_dump_type(buffer, t);
|
|
||||||
for (t = type; t->class == HLSL_CLASS_ARRAY; t = t->e.array.type)
|
|
||||||
{
|
{
|
||||||
if (t->e.array.elements_count == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT)
|
if (type->e.array.array_type == HLSL_ARRAY_PATCH_INPUT)
|
||||||
vkd3d_string_buffer_printf(buffer, "[]");
|
vkd3d_string_buffer_printf(buffer, "InputPatch<");
|
||||||
else
|
else
|
||||||
vkd3d_string_buffer_printf(buffer, "[%u]", t->e.array.elements_count);
|
vkd3d_string_buffer_printf(buffer, "OutputPatch<");
|
||||||
|
hlsl_dump_type(buffer, type->e.array.type);
|
||||||
|
vkd3d_string_buffer_printf(buffer, ", %u>", type->e.array.elements_count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const struct hlsl_type *t;
|
||||||
|
|
||||||
|
for (t = type; t->class == HLSL_CLASS_ARRAY; t = t->e.array.type)
|
||||||
|
;
|
||||||
|
|
||||||
|
hlsl_dump_type(buffer, t);
|
||||||
|
for (t = type; t->class == HLSL_CLASS_ARRAY; t = t->e.array.type)
|
||||||
|
{
|
||||||
|
if (t->e.array.elements_count == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT)
|
||||||
|
vkd3d_string_buffer_printf(buffer, "[]");
|
||||||
|
else
|
||||||
|
vkd3d_string_buffer_printf(buffer, "[%u]", t->e.array.elements_count);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
case HLSL_CLASS_STRUCT:
|
case HLSL_CLASS_STRUCT:
|
||||||
vkd3d_string_buffer_printf(buffer, "<anonymous struct>");
|
vkd3d_string_buffer_printf(buffer, "<anonymous struct>");
|
||||||
|
@@ -145,6 +145,13 @@ enum hlsl_regset
|
|||||||
HLSL_REGSET_LAST = HLSL_REGSET_NUMERIC,
|
HLSL_REGSET_LAST = HLSL_REGSET_NUMERIC,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum hlsl_array_type
|
||||||
|
{
|
||||||
|
HLSL_ARRAY_GENERIC,
|
||||||
|
HLSL_ARRAY_PATCH_INPUT,
|
||||||
|
HLSL_ARRAY_PATCH_OUTPUT,
|
||||||
|
};
|
||||||
|
|
||||||
/* An HLSL source-level data type, including anonymous structs and typedefs. */
|
/* An HLSL source-level data type, including anonymous structs and typedefs. */
|
||||||
struct hlsl_type
|
struct hlsl_type
|
||||||
{
|
{
|
||||||
@@ -195,6 +202,7 @@ struct hlsl_type
|
|||||||
struct hlsl_type *type;
|
struct hlsl_type *type;
|
||||||
/* Array length, or HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT if it is not known yet at parse time. */
|
/* Array length, or HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT if it is not known yet at parse time. */
|
||||||
unsigned int elements_count;
|
unsigned int elements_count;
|
||||||
|
enum hlsl_array_type array_type;
|
||||||
} array;
|
} array;
|
||||||
/* Additional information if the class is HLSL_CLASS_TEXTURE or
|
/* Additional information if the class is HLSL_CLASS_TEXTURE or
|
||||||
* HLSL_CLASS_UAV. */
|
* HLSL_CLASS_UAV. */
|
||||||
@@ -1527,7 +1535,8 @@ struct hlsl_type *hlsl_get_element_type_from_path_index(struct hlsl_ctx *ctx, co
|
|||||||
|
|
||||||
const char *hlsl_jump_type_to_string(enum hlsl_ir_jump_type type);
|
const char *hlsl_jump_type_to_string(enum hlsl_ir_jump_type type);
|
||||||
|
|
||||||
struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *basic_type, unsigned int array_size);
|
struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *basic_type,
|
||||||
|
unsigned int array_size, enum hlsl_array_type array_type);
|
||||||
struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1,
|
struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1,
|
||||||
struct hlsl_ir_node *arg2);
|
struct hlsl_ir_node *arg2);
|
||||||
struct hlsl_ir_node *hlsl_new_bool_constant(struct hlsl_ctx *ctx, bool b, const struct vkd3d_shader_location *loc);
|
struct hlsl_ir_node *hlsl_new_bool_constant(struct hlsl_ctx *ctx, bool b, const struct vkd3d_shader_location *loc);
|
||||||
@@ -1659,6 +1668,7 @@ unsigned int hlsl_type_major_size(const struct hlsl_type *type);
|
|||||||
unsigned int hlsl_type_element_count(const struct hlsl_type *type);
|
unsigned int hlsl_type_element_count(const struct hlsl_type *type);
|
||||||
bool hlsl_type_is_resource(const struct hlsl_type *type);
|
bool hlsl_type_is_resource(const struct hlsl_type *type);
|
||||||
bool hlsl_type_is_shader(const struct hlsl_type *type);
|
bool hlsl_type_is_shader(const struct hlsl_type *type);
|
||||||
|
bool hlsl_type_is_patch_array(const struct hlsl_type *type);
|
||||||
unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int offset);
|
unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int offset);
|
||||||
bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2);
|
bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2);
|
||||||
|
|
||||||
|
@@ -104,6 +104,7 @@ if {return KW_IF; }
|
|||||||
in {return KW_IN; }
|
in {return KW_IN; }
|
||||||
inline {return KW_INLINE; }
|
inline {return KW_INLINE; }
|
||||||
inout {return KW_INOUT; }
|
inout {return KW_INOUT; }
|
||||||
|
InputPatch {return KW_INPUTPATCH; }
|
||||||
LineStream {return KW_LINESTREAM; }
|
LineStream {return KW_LINESTREAM; }
|
||||||
linear {return KW_LINEAR; }
|
linear {return KW_LINEAR; }
|
||||||
matrix {return KW_MATRIX; }
|
matrix {return KW_MATRIX; }
|
||||||
@@ -112,6 +113,7 @@ nointerpolation {return KW_NOINTERPOLATION; }
|
|||||||
noperspective {return KW_NOPERSPECTIVE; }
|
noperspective {return KW_NOPERSPECTIVE; }
|
||||||
NULL {return KW_NULL; }
|
NULL {return KW_NULL; }
|
||||||
out {return KW_OUT; }
|
out {return KW_OUT; }
|
||||||
|
OutputPatch {return KW_OUTPUTPATCH; }
|
||||||
packoffset {return KW_PACKOFFSET; }
|
packoffset {return KW_PACKOFFSET; }
|
||||||
pass {return KW_PASS; }
|
pass {return KW_PASS; }
|
||||||
PixelShader {return KW_PIXELSHADER; }
|
PixelShader {return KW_PIXELSHADER; }
|
||||||
|
@@ -415,7 +415,7 @@ static bool add_explicit_conversion(struct hlsl_ctx *ctx, struct hlsl_block *blo
|
|||||||
dst_type = ctx->builtin_types.error;
|
dst_type = ctx->builtin_types.error;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
dst_type = hlsl_new_array_type(ctx, dst_type, arrays->sizes[i]);
|
dst_type = hlsl_new_array_type(ctx, dst_type, arrays->sizes[i], HLSL_ARRAY_GENERIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instr->data_type->class == HLSL_CLASS_ERROR)
|
if (instr->data_type->class == HLSL_CLASS_ERROR)
|
||||||
@@ -1118,7 +1118,7 @@ static bool gen_struct_fields(struct hlsl_ctx *ctx, struct parse_fields *fields,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
field->type = hlsl_new_array_type(ctx, field->type, v->arrays.sizes[k]);
|
field->type = hlsl_new_array_type(ctx, field->type, v->arrays.sizes[k], HLSL_ARRAY_GENERIC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1214,7 +1214,7 @@ static bool add_typedef(struct hlsl_ctx *ctx, struct hlsl_type *const orig_type,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(type = hlsl_new_array_type(ctx, type, v->arrays.sizes[i])))
|
if (!(type = hlsl_new_array_type(ctx, type, v->arrays.sizes[i], HLSL_ARRAY_GENERIC)))
|
||||||
{
|
{
|
||||||
free_parse_variable_def(v);
|
free_parse_variable_def(v);
|
||||||
ret = false;
|
ret = false;
|
||||||
@@ -2669,7 +2669,7 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v)
|
|||||||
v->arrays.sizes[i] = size / elem_components;
|
v->arrays.sizes[i] = size / elem_components;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
type = hlsl_new_array_type(ctx, type, v->arrays.sizes[i]);
|
type = hlsl_new_array_type(ctx, type, v->arrays.sizes[i], HLSL_ARRAY_GENERIC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7007,6 +7007,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim,
|
|||||||
enum hlsl_buffer_type buffer_type;
|
enum hlsl_buffer_type buffer_type;
|
||||||
enum hlsl_sampler_dim sampler_dim;
|
enum hlsl_sampler_dim sampler_dim;
|
||||||
enum hlsl_so_object_type so_type;
|
enum hlsl_so_object_type so_type;
|
||||||
|
enum hlsl_array_type patch_type;
|
||||||
struct hlsl_attribute *attr;
|
struct hlsl_attribute *attr;
|
||||||
struct parse_attribute_list attr_list;
|
struct parse_attribute_list attr_list;
|
||||||
struct hlsl_ir_switch_case *switch_case;
|
struct hlsl_ir_switch_case *switch_case;
|
||||||
@@ -7049,6 +7050,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim,
|
|||||||
%token KW_IN
|
%token KW_IN
|
||||||
%token KW_INLINE
|
%token KW_INLINE
|
||||||
%token KW_INOUT
|
%token KW_INOUT
|
||||||
|
%token KW_INPUTPATCH
|
||||||
%token KW_LINEAR
|
%token KW_LINEAR
|
||||||
%token KW_LINESTREAM
|
%token KW_LINESTREAM
|
||||||
%token KW_MATRIX
|
%token KW_MATRIX
|
||||||
@@ -7057,6 +7059,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim,
|
|||||||
%token KW_NOPERSPECTIVE
|
%token KW_NOPERSPECTIVE
|
||||||
%token KW_NULL
|
%token KW_NULL
|
||||||
%token KW_OUT
|
%token KW_OUT
|
||||||
|
%token KW_OUTPUTPATCH
|
||||||
%token KW_PACKOFFSET
|
%token KW_PACKOFFSET
|
||||||
%token KW_PASS
|
%token KW_PASS
|
||||||
%token KW_PIXELSHADER
|
%token KW_PIXELSHADER
|
||||||
@@ -7238,6 +7241,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim,
|
|||||||
%type <reg_reservation> packoffset_reservation
|
%type <reg_reservation> packoffset_reservation
|
||||||
|
|
||||||
%type <sampler_dim> texture_type texture_ms_type uav_type rov_type
|
%type <sampler_dim> texture_type texture_ms_type uav_type rov_type
|
||||||
|
%type <patch_type> patch_type
|
||||||
|
|
||||||
%type <semantic> semantic
|
%type <semantic> semantic
|
||||||
|
|
||||||
@@ -8147,7 +8151,7 @@ parameter_decl:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
type = hlsl_new_array_type(ctx, type, $4.sizes[i]);
|
type = hlsl_new_array_type(ctx, type, $4.sizes[i], HLSL_ARRAY_GENERIC);
|
||||||
}
|
}
|
||||||
vkd3d_free($4.sizes);
|
vkd3d_free($4.sizes);
|
||||||
|
|
||||||
@@ -8290,6 +8294,16 @@ resource_format:
|
|||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
patch_type:
|
||||||
|
KW_INPUTPATCH
|
||||||
|
{
|
||||||
|
$$ = HLSL_ARRAY_PATCH_INPUT;
|
||||||
|
}
|
||||||
|
| KW_OUTPUTPATCH
|
||||||
|
{
|
||||||
|
$$ = HLSL_ARRAY_PATCH_OUTPUT;
|
||||||
|
}
|
||||||
|
|
||||||
type_no_void:
|
type_no_void:
|
||||||
KW_VECTOR '<' type ',' C_INTEGER '>'
|
KW_VECTOR '<' type ',' C_INTEGER '>'
|
||||||
{
|
{
|
||||||
@@ -8428,6 +8442,20 @@ type_no_void:
|
|||||||
{
|
{
|
||||||
$$ = hlsl_new_stream_output_type(ctx, $1, $3);
|
$$ = hlsl_new_stream_output_type(ctx, $1, $3);
|
||||||
}
|
}
|
||||||
|
| patch_type '<' type ',' C_INTEGER '>'
|
||||||
|
{
|
||||||
|
struct hlsl_type *type;
|
||||||
|
|
||||||
|
if ($5 < 1)
|
||||||
|
{
|
||||||
|
hlsl_error(ctx, &@5, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE,
|
||||||
|
"Control point size %d is not positive.", $5);
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
type = hlsl_new_array_type(ctx, $3, $5, $1);
|
||||||
|
$$ = hlsl_type_clone(ctx, type, 0, HLSL_MODIFIER_CONST);
|
||||||
|
}
|
||||||
| KW_RWBYTEADDRESSBUFFER
|
| KW_RWBYTEADDRESSBUFFER
|
||||||
{
|
{
|
||||||
$$ = hlsl_new_uav_type(ctx, HLSL_SAMPLER_DIM_RAW_BUFFER, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), false);
|
$$ = hlsl_new_uav_type(ctx, HLSL_SAMPLER_DIM_RAW_BUFFER, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), false);
|
||||||
|
@@ -2968,7 +2968,7 @@ static struct hlsl_type *clone_texture_array_as_combined_sampler_array(struct hl
|
|||||||
if (!(sampler_type = clone_texture_array_as_combined_sampler_array(ctx, type->e.array.type)))
|
if (!(sampler_type = clone_texture_array_as_combined_sampler_array(ctx, type->e.array.type)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return hlsl_new_array_type(ctx, sampler_type, type->e.array.elements_count);
|
return hlsl_new_array_type(ctx, sampler_type, type->e.array.elements_count, HLSL_ARRAY_GENERIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx->builtin_types.sampler[type->sampler_dim];
|
return ctx->builtin_types.sampler[type->sampler_dim];
|
||||||
@@ -3132,7 +3132,8 @@ static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in
|
|||||||
for (i = 0; i < load->resource.path_len; ++i)
|
for (i = 0; i < load->resource.path_len; ++i)
|
||||||
{
|
{
|
||||||
VKD3D_ASSERT(arr_type->class == HLSL_CLASS_ARRAY);
|
VKD3D_ASSERT(arr_type->class == HLSL_CLASS_ARRAY);
|
||||||
texture_array_type = hlsl_new_array_type(ctx, texture_array_type, arr_type->e.array.elements_count);
|
texture_array_type = hlsl_new_array_type(ctx, texture_array_type,
|
||||||
|
arr_type->e.array.elements_count, HLSL_ARRAY_GENERIC);
|
||||||
arr_type = arr_type->e.array.type;
|
arr_type = arr_type->e.array.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12189,6 +12190,10 @@ static void process_entry_function(struct hlsl_ctx *ctx,
|
|||||||
else
|
else
|
||||||
prepend_uniform_copy(ctx, body, var);
|
prepend_uniform_copy(ctx, body, var);
|
||||||
}
|
}
|
||||||
|
else if (hlsl_type_is_patch_array(var->data_type))
|
||||||
|
{
|
||||||
|
hlsl_fixme(ctx, &var->loc, "InputPatch/OutputPatch function parameters.");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (hlsl_get_multiarray_element_type(var->data_type)->class != HLSL_CLASS_STRUCT
|
if (hlsl_get_multiarray_element_type(var->data_type)->class != HLSL_CLASS_STRUCT
|
||||||
|
Reference in New Issue
Block a user