mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
vkd3d-shader/fx: Implement parsing shader objects.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
This commit is contained in:
parent
96c13aeb97
commit
1a8e9ff94e
Notes:
Henri Verbeet
2024-10-29 14:59:43 +01:00
Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1231
@ -499,7 +499,15 @@ enum fx_4_type_constants
|
|||||||
FX_4_NUMERIC_COLUMN_MAJOR_MASK = 0x4000,
|
FX_4_NUMERIC_COLUMN_MAJOR_MASK = 0x4000,
|
||||||
|
|
||||||
/* Object types */
|
/* Object types */
|
||||||
FX_4_OBJECT_TYPE_STRING = 1,
|
FX_4_OBJECT_TYPE_STRING = 0x1,
|
||||||
|
FX_4_OBJECT_TYPE_PIXEL_SHADER = 0x5,
|
||||||
|
FX_4_OBJECT_TYPE_VERTEX_SHADER = 0x6,
|
||||||
|
FX_4_OBJECT_TYPE_GEOMETRY_SHADER = 0x7,
|
||||||
|
FX_4_OBJECT_TYPE_GEOMETRY_SHADER_SO = 0x8,
|
||||||
|
FX_5_OBJECT_TYPE_GEOMETRY_SHADER = 0x1b,
|
||||||
|
FX_5_OBJECT_TYPE_COMPUTE_SHADER = 0x1c,
|
||||||
|
FX_5_OBJECT_TYPE_HULL_SHADER = 0x1d,
|
||||||
|
FX_5_OBJECT_TYPE_DOMAIN_SHADER = 0x1e,
|
||||||
|
|
||||||
/* Types */
|
/* Types */
|
||||||
FX_4_TYPE_CLASS_NUMERIC = 1,
|
FX_4_TYPE_CLASS_NUMERIC = 1,
|
||||||
@ -807,11 +815,11 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
|
|||||||
}
|
}
|
||||||
else if (element_type->class == HLSL_CLASS_PIXEL_SHADER)
|
else if (element_type->class == HLSL_CLASS_PIXEL_SHADER)
|
||||||
{
|
{
|
||||||
put_u32_unaligned(buffer, 5);
|
put_u32_unaligned(buffer, FX_4_OBJECT_TYPE_PIXEL_SHADER);
|
||||||
}
|
}
|
||||||
else if (element_type->class == HLSL_CLASS_VERTEX_SHADER)
|
else if (element_type->class == HLSL_CLASS_VERTEX_SHADER)
|
||||||
{
|
{
|
||||||
put_u32_unaligned(buffer, 6);
|
put_u32_unaligned(buffer, FX_4_OBJECT_TYPE_VERTEX_SHADER);
|
||||||
}
|
}
|
||||||
else if (element_type->class == HLSL_CLASS_RASTERIZER_STATE)
|
else if (element_type->class == HLSL_CLASS_RASTERIZER_STATE)
|
||||||
{
|
{
|
||||||
@ -836,15 +844,15 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
|
|||||||
}
|
}
|
||||||
else if (element_type->class == HLSL_CLASS_COMPUTE_SHADER)
|
else if (element_type->class == HLSL_CLASS_COMPUTE_SHADER)
|
||||||
{
|
{
|
||||||
put_u32_unaligned(buffer, 28);
|
put_u32_unaligned(buffer, FX_5_OBJECT_TYPE_COMPUTE_SHADER);
|
||||||
}
|
}
|
||||||
else if (element_type->class == HLSL_CLASS_HULL_SHADER)
|
else if (element_type->class == HLSL_CLASS_HULL_SHADER)
|
||||||
{
|
{
|
||||||
put_u32_unaligned(buffer, 29);
|
put_u32_unaligned(buffer, FX_5_OBJECT_TYPE_HULL_SHADER);
|
||||||
}
|
}
|
||||||
else if (element_type->class == HLSL_CLASS_DOMAIN_SHADER)
|
else if (element_type->class == HLSL_CLASS_DOMAIN_SHADER)
|
||||||
{
|
{
|
||||||
put_u32_unaligned(buffer, 30);
|
put_u32_unaligned(buffer, FX_5_OBJECT_TYPE_DOMAIN_SHADER);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2919,19 +2927,28 @@ static int fx_2_parse(struct fx_parser *parser)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fx_parser_read_unstructured(struct fx_parser *parser, void *dst, uint32_t offset, size_t size)
|
static const void *fx_parser_get_unstructured_ptr(struct fx_parser *parser, uint32_t offset, size_t size)
|
||||||
{
|
{
|
||||||
const uint8_t *ptr = parser->unstructured.ptr;
|
const uint8_t *ptr = parser->unstructured.ptr;
|
||||||
|
|
||||||
memset(dst, 0, size);
|
|
||||||
if (offset >= parser->unstructured.size
|
if (offset >= parser->unstructured.size
|
||||||
|| size > parser->unstructured.size - offset)
|
|| size > parser->unstructured.size - offset)
|
||||||
{
|
{
|
||||||
parser->failed = true;
|
parser->failed = true;
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr += offset;
|
return &ptr[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fx_parser_read_unstructured(struct fx_parser *parser, void *dst, uint32_t offset, size_t size)
|
||||||
|
{
|
||||||
|
const uint8_t *ptr;
|
||||||
|
|
||||||
|
memset(dst, 0, size);
|
||||||
|
if (!(ptr = fx_parser_get_unstructured_ptr(parser, offset, size)))
|
||||||
|
return;
|
||||||
|
|
||||||
memcpy(dst, ptr, size);
|
memcpy(dst, ptr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3161,6 +3178,123 @@ static void fx_parse_buffers(struct fx_parser *parser)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fx_4_parse_shader_initializer(struct fx_parser *parser, unsigned int object_type)
|
||||||
|
{
|
||||||
|
struct vkd3d_shader_compile_info info = { 0 };
|
||||||
|
struct vkd3d_shader_code output;
|
||||||
|
uint32_t data_size, offset;
|
||||||
|
const void *data = NULL;
|
||||||
|
const char *p, *q, *end;
|
||||||
|
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;
|
||||||
|
} shader5;
|
||||||
|
struct fx_4_gs_so
|
||||||
|
{
|
||||||
|
uint32_t offset;
|
||||||
|
uint32_t sodecl;
|
||||||
|
} gs_so;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
static const struct vkd3d_shader_compile_option options[] =
|
||||||
|
{
|
||||||
|
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_13},
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (object_type)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
data = fx_parser_get_unstructured_ptr(parser, offset + 4, data_size);
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO;
|
||||||
|
info.source.code = data;
|
||||||
|
info.source.size = data_size;
|
||||||
|
info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
|
||||||
|
info.target_type = VKD3D_SHADER_TARGET_D3D_ASM;
|
||||||
|
info.options = options;
|
||||||
|
info.option_count = ARRAY_SIZE(options);
|
||||||
|
info.log_level = VKD3D_SHADER_LOG_INFO;
|
||||||
|
|
||||||
|
if ((ret = vkd3d_shader_compile(&info, &output, NULL)) < 0)
|
||||||
|
{
|
||||||
|
fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA,
|
||||||
|
"Failed to disassemble shader blob.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
parse_fx_print_indent(parser);
|
||||||
|
vkd3d_string_buffer_printf(&parser->buffer, "asm {\n");
|
||||||
|
|
||||||
|
parse_fx_start_indent(parser);
|
||||||
|
|
||||||
|
end = (const char *)output.code + output.size;
|
||||||
|
for (p = output.code; p < end; p = q)
|
||||||
|
{
|
||||||
|
if (!(q = memchr(p, '\n', end - p)))
|
||||||
|
q = end;
|
||||||
|
else
|
||||||
|
++q;
|
||||||
|
|
||||||
|
parse_fx_print_indent(parser);
|
||||||
|
vkd3d_string_buffer_printf(&parser->buffer, "%.*s", (int)(q - p), p);
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_fx_end_indent(parser);
|
||||||
|
|
||||||
|
parse_fx_print_indent(parser);
|
||||||
|
vkd3d_string_buffer_printf(&parser->buffer, "}");
|
||||||
|
if (object_type == FX_4_OBJECT_TYPE_GEOMETRY_SHADER && gs_so.sodecl)
|
||||||
|
{
|
||||||
|
vkd3d_string_buffer_printf(&parser->buffer, "\n/* Stream output declaration: \"%s\" */",
|
||||||
|
fx_4_get_string(parser, gs_so.sodecl));
|
||||||
|
}
|
||||||
|
else if (object_type == FX_5_OBJECT_TYPE_GEOMETRY_SHADER)
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < ARRAY_SIZE(shader5.sodecl); ++i)
|
||||||
|
{
|
||||||
|
if (shader5.sodecl[i])
|
||||||
|
vkd3d_string_buffer_printf(&parser->buffer, "\n/* Stream output %u declaration: \"%s\" */",
|
||||||
|
i, fx_4_get_string(parser, shader5.sodecl[i]));
|
||||||
|
}
|
||||||
|
if (shader5.sodecl_count)
|
||||||
|
vkd3d_string_buffer_printf(&parser->buffer, "\n/* Rasterized stream %u */", shader5.rast_stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
vkd3d_shader_free_shader_code(&output);
|
||||||
|
}
|
||||||
|
|
||||||
static void fx_4_parse_objects(struct fx_parser *parser)
|
static void fx_4_parse_objects(struct fx_parser *parser)
|
||||||
{
|
{
|
||||||
struct fx_4_object_variable
|
struct fx_4_object_variable
|
||||||
@ -3199,6 +3333,18 @@ static void fx_4_parse_objects(struct fx_parser *parser)
|
|||||||
value = fx_parser_read_u32(parser);
|
value = fx_parser_read_u32(parser);
|
||||||
fx_4_parse_string_initializer(parser, value);
|
fx_4_parse_string_initializer(parser, value);
|
||||||
break;
|
break;
|
||||||
|
case FX_4_OBJECT_TYPE_PIXEL_SHADER:
|
||||||
|
case FX_4_OBJECT_TYPE_VERTEX_SHADER:
|
||||||
|
case FX_4_OBJECT_TYPE_GEOMETRY_SHADER:
|
||||||
|
case FX_4_OBJECT_TYPE_GEOMETRY_SHADER_SO:
|
||||||
|
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:
|
||||||
|
parse_fx_start_indent(parser);
|
||||||
|
fx_4_parse_shader_initializer(parser, type.typeinfo);
|
||||||
|
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,
|
||||||
"Parsing object type %u is not implemented.\n", type.typeinfo);
|
"Parsing object type %u is not implemented.\n", type.typeinfo);
|
||||||
@ -3207,6 +3353,7 @@ static void fx_4_parse_objects(struct fx_parser *parser)
|
|||||||
vkd3d_string_buffer_printf(&parser->buffer, ",\n");
|
vkd3d_string_buffer_printf(&parser->buffer, ",\n");
|
||||||
}
|
}
|
||||||
vkd3d_string_buffer_printf(&parser->buffer, "};\n");
|
vkd3d_string_buffer_printf(&parser->buffer, "};\n");
|
||||||
|
fx_parse_fx_4_annotations(parser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user