vkd3d-shader/hlsl: Add support for ConstantBuffer<> type.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
This commit is contained in:
Nikolay Sivov 2024-05-28 00:31:51 +02:00 committed by Henri Verbeet
parent 44725a651b
commit 48ff7de8ef
Notes: Henri Verbeet 2024-07-08 18:18:40 +02:00
Approved-by: Elizabeth Figura (@zfigura)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/906
9 changed files with 117 additions and 7 deletions

View File

@ -1504,6 +1504,7 @@ D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type)
case HLSL_CLASS_TECHNIQUE: case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_UAV: case HLSL_CLASS_UAV:
case HLSL_CLASS_VOID: case HLSL_CLASS_VOID:
case HLSL_CLASS_CONSTANT_BUFFER:
break; break;
} }
@ -1600,6 +1601,7 @@ D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type)
case HLSL_CLASS_TECHNIQUE: case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_UAV: case HLSL_CLASS_UAV:
case HLSL_CLASS_VOID: case HLSL_CLASS_VOID:
case HLSL_CLASS_CONSTANT_BUFFER:
break; break;
} }

View File

@ -464,6 +464,7 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
case HLSL_CLASS_EFFECT_GROUP: case HLSL_CLASS_EFFECT_GROUP:
case HLSL_CLASS_PASS: case HLSL_CLASS_PASS:
case HLSL_CLASS_TECHNIQUE: case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_CONSTANT_BUFFER:
vkd3d_unreachable(); vkd3d_unreachable();
case HLSL_CLASS_STRING: case HLSL_CLASS_STRING:
@ -862,6 +863,7 @@ static bool is_type_supported_fx_2(struct hlsl_ctx *ctx, const struct hlsl_type
case HLSL_CLASS_EFFECT_GROUP: case HLSL_CLASS_EFFECT_GROUP:
case HLSL_CLASS_PASS: case HLSL_CLASS_PASS:
case HLSL_CLASS_TECHNIQUE: case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_CONSTANT_BUFFER:
/* This cannot appear as an extern variable. */ /* This cannot appear as an extern variable. */
break; break;
} }

View File

@ -378,6 +378,7 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type
case HLSL_CLASS_TECHNIQUE: case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_VERTEX_SHADER: case HLSL_CLASS_VERTEX_SHADER:
case HLSL_CLASS_VOID: case HLSL_CLASS_VOID:
case HLSL_CLASS_CONSTANT_BUFFER:
break; break;
} }
} }
@ -452,6 +453,7 @@ static bool type_is_single_component(const struct hlsl_type *type)
case HLSL_CLASS_MATRIX: case HLSL_CLASS_MATRIX:
case HLSL_CLASS_STRUCT: case HLSL_CLASS_STRUCT:
case HLSL_CLASS_ARRAY: case HLSL_CLASS_ARRAY:
case HLSL_CLASS_CONSTANT_BUFFER:
return false; return false;
case HLSL_CLASS_EFFECT_GROUP: case HLSL_CLASS_EFFECT_GROUP:
@ -530,6 +532,12 @@ static unsigned int traverse_path_from_component_index(struct hlsl_ctx *ctx,
vkd3d_unreachable(); vkd3d_unreachable();
} }
case HLSL_CLASS_CONSTANT_BUFFER:
{
*type_ptr = type->e.resource.format;
return traverse_path_from_component_index(ctx, type_ptr, index_ptr);
}
default: default:
vkd3d_unreachable(); vkd3d_unreachable();
} }
@ -597,6 +605,7 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty
case HLSL_CLASS_TECHNIQUE: case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_VOID: case HLSL_CLASS_VOID:
case HLSL_CLASS_SCALAR: case HLSL_CLASS_SCALAR:
case HLSL_CLASS_CONSTANT_BUFFER:
vkd3d_unreachable(); vkd3d_unreachable();
} }
type = next_type; type = next_type;
@ -870,6 +879,20 @@ struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim
return type; return type;
} }
struct hlsl_type *hlsl_new_cb_type(struct hlsl_ctx *ctx, struct hlsl_type *format)
{
struct hlsl_type *type;
if (!(type = hlsl_alloc(ctx, sizeof(*type))))
return NULL;
type->class = HLSL_CLASS_CONSTANT_BUFFER;
type->dimy = 1;
type->e.resource.format = format;
hlsl_type_calculate_reg_size(ctx, type);
list_add_tail(&ctx->types, &type->entry);
return type;
}
static const char * get_case_insensitive_typename(const char *name) static const char * get_case_insensitive_typename(const char *name)
{ {
static const char *const names[] = static const char *const names[] =
@ -961,6 +984,9 @@ unsigned int hlsl_type_component_count(const struct hlsl_type *type)
case HLSL_CLASS_ARRAY: case HLSL_CLASS_ARRAY:
return hlsl_type_component_count(type->e.array.type) * type->e.array.elements_count; return hlsl_type_component_count(type->e.array.type) * type->e.array.elements_count;
case HLSL_CLASS_CONSTANT_BUFFER:
return hlsl_type_component_count(type->e.resource.format);
case HLSL_CLASS_DEPTH_STENCIL_VIEW: case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_PIXEL_SHADER: case HLSL_CLASS_PIXEL_SHADER:
case HLSL_CLASS_RENDER_TARGET_VIEW: case HLSL_CLASS_RENDER_TARGET_VIEW:
@ -1043,6 +1069,9 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2
case HLSL_CLASS_TECHNIQUE: case HLSL_CLASS_TECHNIQUE:
return t1->e.version == t2->e.version; return t1->e.version == t2->e.version;
case HLSL_CLASS_CONSTANT_BUFFER:
return hlsl_types_are_equal(t1->e.resource.format, t2->e.resource.format);
case HLSL_CLASS_DEPTH_STENCIL_VIEW: case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_EFFECT_GROUP: case HLSL_CLASS_EFFECT_GROUP:
case HLSL_CLASS_PASS: case HLSL_CLASS_PASS:
@ -2413,6 +2442,15 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru
} }
return string; return string;
case HLSL_CLASS_CONSTANT_BUFFER:
vkd3d_string_buffer_printf(string, "ConstantBuffer");
if ((inner_string = hlsl_type_to_string(ctx, type->e.resource.format)))
{
vkd3d_string_buffer_printf(string, "<%s>", inner_string->buffer);
hlsl_release_string_buffer(ctx, inner_string);
}
return string;
case HLSL_CLASS_DEPTH_STENCIL_VIEW: case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_EFFECT_GROUP: case HLSL_CLASS_EFFECT_GROUP:
case HLSL_CLASS_PASS: case HLSL_CLASS_PASS:

View File

@ -89,6 +89,7 @@ enum hlsl_type_class
HLSL_CLASS_TEXTURE, HLSL_CLASS_TEXTURE,
HLSL_CLASS_UAV, HLSL_CLASS_UAV,
HLSL_CLASS_VERTEX_SHADER, HLSL_CLASS_VERTEX_SHADER,
HLSL_CLASS_CONSTANT_BUFFER,
HLSL_CLASS_VOID, HLSL_CLASS_VOID,
}; };
@ -1391,6 +1392,7 @@ struct hlsl_type *hlsl_new_texture_type(struct hlsl_ctx *ctx, enum hlsl_sampler_
unsigned int sample_count); unsigned int sample_count);
struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim,
struct hlsl_type *format, bool rasteriser_ordered); struct hlsl_type *format, bool rasteriser_ordered);
struct hlsl_type *hlsl_new_cb_type(struct hlsl_ctx *ctx, struct hlsl_type *format);
struct hlsl_ir_node *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n, struct hlsl_ir_node *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n,
const struct vkd3d_shader_location *loc); const struct vkd3d_shader_location *loc);
struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg,

View File

@ -198,7 +198,9 @@ while {return KW_WHILE; }
struct hlsl_ctx *ctx = yyget_extra(yyscanner); struct hlsl_ctx *ctx = yyget_extra(yyscanner);
yylval->name = hlsl_strdup(ctx, yytext); yylval->name = hlsl_strdup(ctx, yytext);
if (hlsl_get_var(ctx->cur_scope, yytext) || hlsl_get_function(ctx, yytext)) if (hlsl_version_ge(ctx, 5, 1) && !strcmp(yytext, "ConstantBuffer"))
return KW_CONSTANTBUFFER;
else if (hlsl_get_var(ctx->cur_scope, yytext) || hlsl_get_function(ctx, yytext))
return VAR_IDENTIFIER; return VAR_IDENTIFIER;
else if (hlsl_get_type(ctx->cur_scope, yytext, true, true)) else if (hlsl_get_type(ctx->cur_scope, yytext, true, true))
return TYPE_IDENTIFIER; return TYPE_IDENTIFIER;

View File

@ -2376,6 +2376,7 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v)
struct hlsl_semantic new_semantic; struct hlsl_semantic new_semantic;
uint32_t modifiers = v->modifiers; uint32_t modifiers = v->modifiers;
bool unbounded_res_array = false; bool unbounded_res_array = false;
bool constant_buffer = false;
struct hlsl_ir_var *var; struct hlsl_ir_var *var;
struct hlsl_type *type; struct hlsl_type *type;
bool local = true; bool local = true;
@ -2395,6 +2396,12 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v)
unbounded_res_array |= (v->arrays.sizes[i] == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT); unbounded_res_array |= (v->arrays.sizes[i] == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT);
} }
if (type->class == HLSL_CLASS_CONSTANT_BUFFER)
{
type = type->e.resource.format;
constant_buffer = true;
}
if (unbounded_res_array) if (unbounded_res_array)
{ {
if (v->arrays.count == 1) if (v->arrays.count == 1)
@ -2476,7 +2483,16 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v)
return; return;
} }
var->buffer = ctx->cur_buffer; if (constant_buffer && ctx->cur_scope == ctx->globals)
{
if (!(var_name = vkd3d_strdup(v->name)))
return;
var->buffer = hlsl_new_buffer(ctx, HLSL_BUFFER_CONSTANT, var_name, modifiers, &v->reg_reservation, NULL, &v->loc);
}
else
{
var->buffer = ctx->cur_buffer;
}
if (var->buffer == ctx->globals_buffer) if (var->buffer == ctx->globals_buffer)
{ {
@ -5723,6 +5739,7 @@ static bool state_block_add_entry(struct hlsl_state_block *state_block, struct h
%token KW_BREAK %token KW_BREAK
%token KW_BUFFER %token KW_BUFFER
%token KW_CASE %token KW_CASE
%token KW_CONSTANTBUFFER
%token KW_CBUFFER %token KW_CBUFFER
%token KW_CENTROID %token KW_CENTROID
%token KW_COLUMN_MAJOR %token KW_COLUMN_MAJOR
@ -7069,6 +7086,13 @@ type_no_void:
{ {
$$ = hlsl_get_type(ctx->cur_scope, "PixelShader", true, true); $$ = hlsl_get_type(ctx->cur_scope, "PixelShader", true, true);
} }
| KW_CONSTANTBUFFER '<' type '>'
{
if ($3->class != HLSL_CLASS_STRUCT)
hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
"ConstantBuffer<...> requires user-defined structure type.");
$$ = hlsl_new_cb_type(ctx, $3);
}
type: type:
type_no_void type_no_void

View File

@ -1643,6 +1643,7 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx,
case HLSL_CLASS_MATRIX: case HLSL_CLASS_MATRIX:
case HLSL_CLASS_ARRAY: case HLSL_CLASS_ARRAY:
case HLSL_CLASS_STRUCT: case HLSL_CLASS_STRUCT:
case HLSL_CLASS_CONSTANT_BUFFER:
/* FIXME: Actually we shouldn't even get here, but we don't split /* FIXME: Actually we shouldn't even get here, but we don't split
* matrices yet. */ * matrices yet. */
return false; return false;

View File

@ -2997,6 +2997,7 @@ static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type)
case HLSL_CLASS_UAV: case HLSL_CLASS_UAV:
case HLSL_CLASS_VERTEX_SHADER: case HLSL_CLASS_VERTEX_SHADER:
case HLSL_CLASS_VOID: case HLSL_CLASS_VOID:
case HLSL_CLASS_CONSTANT_BUFFER:
break; break;
} }
vkd3d_unreachable(); vkd3d_unreachable();

View File

@ -864,7 +864,7 @@ probe (0, 0) rgba (124.0, 135.0, 146.0, 150.5)
[require] [require]
shader model >= 5.1 shader model >= 5.1
[pixel shader fail todo] [pixel shader fail]
float4 ConstantBuffer; float4 ConstantBuffer;
float4 main() : sv_target float4 main() : sv_target
@ -886,7 +886,7 @@ float4 main() : sv_target
return 0; return 0;
} }
[pixel shader fail(sm>=6) todo] [pixel shader fail(sm>=6)]
struct s struct s
{ {
float4 m; float4 m;
@ -903,10 +903,32 @@ float4 main() : sv_target
} }
[test] [test]
todo draw quad todo(glsl) draw quad
probe (0, 0) rgba (1.1, 1.1, 1.1, 1.1) probe (0, 0) rgba (1.1, 1.1, 1.1, 1.1)
[pixel shader fail] [pixel shader]
struct s
{
float4 m;
};
ConstantBuffer<s> cb;
float4 func(s arg)
{
return arg.m;
}
float4 main() : sv_target
{
return func(cb);
}
[test]
uniform 0 float4 1.0 2.0 3.0 4.0
todo(glsl) draw quad
probe (0, 0) rgba (1.0, 2.0, 3.0, 4.0)
[pixel shader fail todo]
struct s struct s
{ {
float4 m; float4 m;
@ -919,7 +941,7 @@ float4 main() : sv_target
return cb.m; return cb.m;
} }
[pixel shader todo] [pixel shader]
struct s struct s
{ {
float4 m; float4 m;
@ -938,6 +960,22 @@ float4 main() : sv_target
return 0; return 0;
} }
[pixel shader fail todo]
struct s
{
float4 m;
};
ConstantBuffer<s> func(s arg)
{
return arg;
}
float4 main() : sv_target
{
return 0;
}
[require] [require]
shader model >= 2.0 shader model >= 2.0
shader model < 5.1 shader model < 5.1