mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-09-12 18:50:22 -07:00
vkd3d-shader/fx: Implement parsing inline shader blobs.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
This commit is contained in:
committed by
Henri Verbeet
parent
0f362ab720
commit
3784919213
Notes:
Henri Verbeet
2024-11-24 00:10:58 +01:00
Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1272
@@ -36,6 +36,16 @@ struct fx_4_binary_type
|
|||||||
uint32_t typeinfo;
|
uint32_t typeinfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct fx_5_shader
|
||||||
|
{
|
||||||
|
uint32_t offset;
|
||||||
|
uint32_t sodecl[4];
|
||||||
|
uint32_t sodecl_count;
|
||||||
|
uint32_t rast_stream;
|
||||||
|
uint32_t iface_bindings_count;
|
||||||
|
uint32_t iface_bindings;
|
||||||
|
};
|
||||||
|
|
||||||
struct string_entry
|
struct string_entry
|
||||||
{
|
{
|
||||||
struct rb_entry entry;
|
struct rb_entry entry;
|
||||||
@@ -550,6 +560,8 @@ enum fx_4_type_constants
|
|||||||
FX_4_ASSIGNMENT_VARIABLE = 0x2,
|
FX_4_ASSIGNMENT_VARIABLE = 0x2,
|
||||||
FX_4_ASSIGNMENT_ARRAY_CONSTANT_INDEX = 0x3,
|
FX_4_ASSIGNMENT_ARRAY_CONSTANT_INDEX = 0x3,
|
||||||
FX_4_ASSIGNMENT_ARRAY_VARIABLE_INDEX = 0x4,
|
FX_4_ASSIGNMENT_ARRAY_VARIABLE_INDEX = 0x4,
|
||||||
|
FX_4_ASSIGNMENT_INLINE_SHADER = 0x7,
|
||||||
|
FX_5_ASSIGNMENT_INLINE_SHADER = 0x8,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint32_t fx_4_numeric_base_types[] =
|
static const uint32_t fx_4_numeric_base_types[] =
|
||||||
@@ -1836,6 +1848,7 @@ enum state_property_component_type
|
|||||||
FX_BLEND,
|
FX_BLEND,
|
||||||
FX_VERTEXSHADER,
|
FX_VERTEXSHADER,
|
||||||
FX_PIXELSHADER,
|
FX_PIXELSHADER,
|
||||||
|
FX_GEOMETRYSHADER,
|
||||||
FX_COMPONENT_TYPE_COUNT,
|
FX_COMPONENT_TYPE_COUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2067,6 +2080,7 @@ fx_4_states[] =
|
|||||||
|
|
||||||
{ "VertexShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_VERTEXSHADER, 1, 1, 6 },
|
{ "VertexShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_VERTEXSHADER, 1, 1, 6 },
|
||||||
{ "PixelShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_PIXELSHADER, 1, 1, 7 },
|
{ "PixelShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_PIXELSHADER, 1, 1, 7 },
|
||||||
|
{ "GeometryShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_GEOMETRYSHADER, 1, 1, 8 },
|
||||||
{ "DS_StencilRef", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 9 },
|
{ "DS_StencilRef", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 9 },
|
||||||
{ "AB_BlendFactor", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 10 },
|
{ "AB_BlendFactor", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 10 },
|
||||||
{ "AB_SampleMask", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 11 },
|
{ "AB_SampleMask", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 11 },
|
||||||
@@ -3212,27 +3226,13 @@ static void fx_parse_buffers(struct fx_parser *parser)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fx_4_parse_shader_initializer(struct fx_parser *parser, unsigned int object_type)
|
static void fx_4_parse_shader_blob(struct fx_parser *parser, unsigned int object_type, const struct fx_5_shader *shader)
|
||||||
{
|
{
|
||||||
struct vkd3d_shader_compile_info info = { 0 };
|
struct vkd3d_shader_compile_info info = { 0 };
|
||||||
struct vkd3d_shader_code output;
|
struct vkd3d_shader_code output;
|
||||||
uint32_t data_size, offset;
|
|
||||||
const void *data = NULL;
|
const void *data = NULL;
|
||||||
const char *p, *q, *end;
|
const char *p, *q, *end;
|
||||||
struct fx_5_shader
|
uint32_t data_size;
|
||||||
{
|
|
||||||
uint32_t offset;
|
|
||||||
uint32_t sodecl[4];
|
|
||||||
uint32_t sodecl_count;
|
|
||||||
uint32_t rast_stream;
|
|
||||||
uint32_t iface_bindings_count;
|
|
||||||
uint32_t iface_bindings;
|
|
||||||
} shader5;
|
|
||||||
struct fx_4_gs_so
|
|
||||||
{
|
|
||||||
uint32_t offset;
|
|
||||||
uint32_t sodecl;
|
|
||||||
} gs_so;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
static const struct vkd3d_shader_compile_option options[] =
|
static const struct vkd3d_shader_compile_option options[] =
|
||||||
@@ -3240,35 +3240,9 @@ static void fx_4_parse_shader_initializer(struct fx_parser *parser, unsigned int
|
|||||||
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_14},
|
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_14},
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (object_type)
|
fx_parser_read_unstructured(parser, &data_size, shader->offset, sizeof(data_size));
|
||||||
{
|
|
||||||
case FX_4_OBJECT_TYPE_PIXEL_SHADER:
|
|
||||||
case FX_4_OBJECT_TYPE_VERTEX_SHADER:
|
|
||||||
case FX_4_OBJECT_TYPE_GEOMETRY_SHADER:
|
|
||||||
offset = fx_parser_read_u32(parser);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FX_4_OBJECT_TYPE_GEOMETRY_SHADER_SO:
|
|
||||||
fx_parser_read_u32s(parser, &gs_so, sizeof(gs_so));
|
|
||||||
offset = gs_so.offset;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FX_5_OBJECT_TYPE_GEOMETRY_SHADER:
|
|
||||||
case FX_5_OBJECT_TYPE_COMPUTE_SHADER:
|
|
||||||
case FX_5_OBJECT_TYPE_HULL_SHADER:
|
|
||||||
case FX_5_OBJECT_TYPE_DOMAIN_SHADER:
|
|
||||||
fx_parser_read_u32s(parser, &shader5, sizeof(shader5));
|
|
||||||
offset = shader5.offset;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
parser->failed = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fx_parser_read_unstructured(parser, &data_size, offset, sizeof(data_size));
|
|
||||||
if (data_size)
|
if (data_size)
|
||||||
data = fx_parser_get_unstructured_ptr(parser, offset + 4, data_size);
|
data = fx_parser_get_unstructured_ptr(parser, shader->offset + 4, data_size);
|
||||||
|
|
||||||
if (!data)
|
if (!data)
|
||||||
return;
|
return;
|
||||||
@@ -3309,26 +3283,58 @@ static void fx_4_parse_shader_initializer(struct fx_parser *parser, unsigned int
|
|||||||
|
|
||||||
parse_fx_print_indent(parser);
|
parse_fx_print_indent(parser);
|
||||||
vkd3d_string_buffer_printf(&parser->buffer, "}");
|
vkd3d_string_buffer_printf(&parser->buffer, "}");
|
||||||
if (object_type == FX_4_OBJECT_TYPE_GEOMETRY_SHADER_SO && gs_so.sodecl)
|
if (object_type == FX_4_OBJECT_TYPE_GEOMETRY_SHADER_SO && shader->sodecl[0])
|
||||||
{
|
{
|
||||||
vkd3d_string_buffer_printf(&parser->buffer, "\n/* Stream output declaration: \"%s\" */",
|
vkd3d_string_buffer_printf(&parser->buffer, "\n/* Stream output declaration: \"%s\" */",
|
||||||
fx_4_get_string(parser, gs_so.sodecl));
|
fx_4_get_string(parser, shader->sodecl[0]));
|
||||||
}
|
}
|
||||||
else if (object_type == FX_5_OBJECT_TYPE_GEOMETRY_SHADER)
|
else if (object_type == FX_5_OBJECT_TYPE_GEOMETRY_SHADER)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < ARRAY_SIZE(shader5.sodecl); ++i)
|
for (unsigned int i = 0; i < ARRAY_SIZE(shader->sodecl); ++i)
|
||||||
{
|
{
|
||||||
if (shader5.sodecl[i])
|
if (shader->sodecl[i])
|
||||||
vkd3d_string_buffer_printf(&parser->buffer, "\n/* Stream output %u declaration: \"%s\" */",
|
vkd3d_string_buffer_printf(&parser->buffer, "\n/* Stream output %u declaration: \"%s\" */",
|
||||||
i, fx_4_get_string(parser, shader5.sodecl[i]));
|
i, fx_4_get_string(parser, shader->sodecl[i]));
|
||||||
}
|
}
|
||||||
if (shader5.sodecl_count)
|
if (shader->sodecl_count)
|
||||||
vkd3d_string_buffer_printf(&parser->buffer, "\n/* Rasterized stream %u */", shader5.rast_stream);
|
vkd3d_string_buffer_printf(&parser->buffer, "\n/* Rasterized stream %u */", shader->rast_stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
vkd3d_shader_free_shader_code(&output);
|
vkd3d_shader_free_shader_code(&output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fx_4_parse_shader_initializer(struct fx_parser *parser, unsigned int object_type)
|
||||||
|
{
|
||||||
|
struct fx_5_shader shader = { 0 };
|
||||||
|
|
||||||
|
switch (object_type)
|
||||||
|
{
|
||||||
|
case FX_4_OBJECT_TYPE_PIXEL_SHADER:
|
||||||
|
case FX_4_OBJECT_TYPE_VERTEX_SHADER:
|
||||||
|
case FX_4_OBJECT_TYPE_GEOMETRY_SHADER:
|
||||||
|
shader.offset = fx_parser_read_u32(parser);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FX_4_OBJECT_TYPE_GEOMETRY_SHADER_SO:
|
||||||
|
shader.offset = fx_parser_read_u32(parser);
|
||||||
|
shader.sodecl[0] = fx_parser_read_u32(parser);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FX_5_OBJECT_TYPE_GEOMETRY_SHADER:
|
||||||
|
case FX_5_OBJECT_TYPE_COMPUTE_SHADER:
|
||||||
|
case FX_5_OBJECT_TYPE_HULL_SHADER:
|
||||||
|
case FX_5_OBJECT_TYPE_DOMAIN_SHADER:
|
||||||
|
fx_parser_read_u32s(parser, &shader, sizeof(shader));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
parser->failed = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_4_parse_shader_blob(parser, object_type, &shader);
|
||||||
|
}
|
||||||
|
|
||||||
static bool fx_4_object_has_initializer(const struct fx_4_binary_type *type)
|
static bool fx_4_object_has_initializer(const struct fx_4_binary_type *type)
|
||||||
{
|
{
|
||||||
switch (type->typeinfo)
|
switch (type->typeinfo)
|
||||||
@@ -3392,6 +3398,8 @@ static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32
|
|||||||
[FX_UINT8] = "byte",
|
[FX_UINT8] = "byte",
|
||||||
};
|
};
|
||||||
const struct rhs_named_value *named_value;
|
const struct rhs_named_value *named_value;
|
||||||
|
struct fx_5_shader shader = { 0 };
|
||||||
|
unsigned int shader_type = 0;
|
||||||
uint32_t i, j, comp_count;
|
uint32_t i, j, comp_count;
|
||||||
struct fx_4_state *state;
|
struct fx_4_state *state;
|
||||||
|
|
||||||
@@ -3488,6 +3496,35 @@ static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32
|
|||||||
vkd3d_string_buffer_printf(&parser->buffer, "%s[%s]", fx_4_get_string(parser, index.name),
|
vkd3d_string_buffer_printf(&parser->buffer, "%s[%s]", fx_4_get_string(parser, index.name),
|
||||||
fx_4_get_string(parser, index.index));
|
fx_4_get_string(parser, index.index));
|
||||||
break;
|
break;
|
||||||
|
case FX_4_ASSIGNMENT_INLINE_SHADER:
|
||||||
|
case FX_5_ASSIGNMENT_INLINE_SHADER:
|
||||||
|
{
|
||||||
|
bool shader5 = entry.type == FX_5_ASSIGNMENT_INLINE_SHADER;
|
||||||
|
|
||||||
|
if (shader5)
|
||||||
|
fx_parser_read_unstructured(parser, &shader, entry.value, sizeof(shader));
|
||||||
|
else
|
||||||
|
fx_parser_read_unstructured(parser, &shader, entry.value, 2 * sizeof(uint32_t));
|
||||||
|
|
||||||
|
if (state->type == FX_PIXELSHADER)
|
||||||
|
shader_type = FX_4_OBJECT_TYPE_PIXEL_SHADER;
|
||||||
|
else if (state->type == FX_VERTEXSHADER)
|
||||||
|
shader_type = FX_4_OBJECT_TYPE_VERTEX_SHADER;
|
||||||
|
else if (state->type == FX_GEOMETRYSHADER)
|
||||||
|
shader_type = shader5 ? FX_5_OBJECT_TYPE_GEOMETRY_SHADER : FX_4_OBJECT_TYPE_GEOMETRY_SHADER_SO;
|
||||||
|
else if (state->type == FX_HULLSHADER)
|
||||||
|
shader_type = FX_5_OBJECT_TYPE_HULL_SHADER;
|
||||||
|
else if (state->type == FX_DOMAINSHADER)
|
||||||
|
shader_type = FX_5_OBJECT_TYPE_DOMAIN_SHADER;
|
||||||
|
else if (state->type == FX_COMPUTESHADER)
|
||||||
|
shader_type = FX_5_OBJECT_TYPE_COMPUTE_SHADER;
|
||||||
|
|
||||||
|
vkd3d_string_buffer_printf(&parser->buffer, "\n");
|
||||||
|
parse_fx_start_indent(parser);
|
||||||
|
fx_4_parse_shader_blob(parser, shader_type, &shader);
|
||||||
|
parse_fx_end_indent(parser);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_NOT_IMPLEMENTED,
|
fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_NOT_IMPLEMENTED,
|
||||||
"Unsupported assignment type %u.\n", entry.type);
|
"Unsupported assignment type %u.\n", entry.type);
|
||||||
|
Reference in New Issue
Block a user