mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
vkd3d-shader/d3dbc: Parse the shader into a vsir program in vkd3d_shader_sm1_parser_create().
This commit is contained in:
parent
efe9dfd73a
commit
402b96ef3b
Notes:
Alexandre Julliard
2024-05-16 23:13:19 +02:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Henri Verbeet (@hverbeet) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/869
@ -396,11 +396,6 @@ static const enum vkd3d_shader_resource_type resource_type_table[] =
|
|||||||
/* VKD3D_SM1_RESOURCE_TEXTURE_3D */ VKD3D_SHADER_RESOURCE_TEXTURE_3D,
|
/* VKD3D_SM1_RESOURCE_TEXTURE_3D */ VKD3D_SHADER_RESOURCE_TEXTURE_3D,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct vkd3d_shader_sm1_parser *vkd3d_shader_sm1_parser(struct vkd3d_shader_parser *parser)
|
|
||||||
{
|
|
||||||
return CONTAINING_RECORD(parser, struct vkd3d_shader_sm1_parser, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t read_u32(const uint32_t **ptr)
|
static uint32_t read_u32(const uint32_t **ptr)
|
||||||
{
|
{
|
||||||
return *(*ptr)++;
|
return *(*ptr)++;
|
||||||
@ -887,11 +882,6 @@ static void shader_sm1_skip_opcode(const struct vkd3d_shader_sm1_parser *sm1, co
|
|||||||
|
|
||||||
static void shader_sm1_destroy(struct vkd3d_shader_parser *parser)
|
static void shader_sm1_destroy(struct vkd3d_shader_parser *parser)
|
||||||
{
|
{
|
||||||
struct vkd3d_shader_sm1_parser *sm1 = vkd3d_shader_sm1_parser(parser);
|
|
||||||
|
|
||||||
vsir_program_cleanup(parser->program);
|
|
||||||
vkd3d_free(parser->program);
|
|
||||||
vkd3d_free(sm1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shader_sm1_read_src_param(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr,
|
static void shader_sm1_read_src_param(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr,
|
||||||
@ -1235,14 +1225,13 @@ const struct vkd3d_shader_parser_ops shader_sm1_parser_ops =
|
|||||||
.parser_destroy = shader_sm1_destroy,
|
.parser_destroy = shader_sm1_destroy,
|
||||||
};
|
};
|
||||||
|
|
||||||
static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1,
|
static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, struct vsir_program *program,
|
||||||
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context)
|
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context)
|
||||||
{
|
{
|
||||||
const struct vkd3d_shader_location location = {.source_name = compile_info->source_name};
|
const struct vkd3d_shader_location location = {.source_name = compile_info->source_name};
|
||||||
const uint32_t *code = compile_info->source.code;
|
const uint32_t *code = compile_info->source.code;
|
||||||
size_t code_size = compile_info->source.size;
|
size_t code_size = compile_info->source.size;
|
||||||
struct vkd3d_shader_version version;
|
struct vkd3d_shader_version version;
|
||||||
struct vsir_program *program;
|
|
||||||
uint16_t shader_type;
|
uint16_t shader_type;
|
||||||
size_t token_count;
|
size_t token_count;
|
||||||
|
|
||||||
@ -1290,14 +1279,9 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1,
|
|||||||
sm1->start = &code[1];
|
sm1->start = &code[1];
|
||||||
sm1->end = &code[token_count];
|
sm1->end = &code[token_count];
|
||||||
|
|
||||||
if (!(program = vkd3d_malloc(sizeof(*program))))
|
|
||||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
||||||
/* Estimate instruction count to avoid reallocation in most shaders. */
|
/* Estimate instruction count to avoid reallocation in most shaders. */
|
||||||
if (!vsir_program_init(program, &version, code_size != ~(size_t)0 ? token_count / 4u + 4 : 16))
|
if (!vsir_program_init(program, &version, code_size != ~(size_t)0 ? token_count / 4u + 4 : 16))
|
||||||
{
|
|
||||||
vkd3d_free(program);
|
|
||||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
|
||||||
|
|
||||||
vkd3d_shader_parser_init(&sm1->p, program, message_context, compile_info->source_name, &shader_sm1_parser_ops);
|
vkd3d_shader_parser_init(&sm1->p, program, message_context, compile_info->source_name, &shader_sm1_parser_ops);
|
||||||
sm1->ptr = sm1->start;
|
sm1->ptr = sm1->start;
|
||||||
@ -1322,70 +1306,59 @@ static uint32_t get_external_constant_count(struct vkd3d_shader_sm1_parser *sm1,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
|
int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
|
||||||
struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser)
|
struct vkd3d_shader_message_context *message_context, struct vsir_program *program)
|
||||||
{
|
{
|
||||||
struct vkd3d_shader_instruction_array *instructions;
|
struct vkd3d_shader_instruction_array *instructions;
|
||||||
|
struct vkd3d_shader_sm1_parser sm1 = {0};
|
||||||
struct vkd3d_shader_instruction *ins;
|
struct vkd3d_shader_instruction *ins;
|
||||||
struct vkd3d_shader_sm1_parser *sm1;
|
|
||||||
struct vsir_program *program;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!(sm1 = vkd3d_calloc(1, sizeof(*sm1))))
|
if ((ret = shader_sm1_init(&sm1, program, compile_info, message_context)) < 0)
|
||||||
{
|
|
||||||
ERR("Failed to allocate parser.\n");
|
|
||||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = shader_sm1_init(sm1, compile_info, message_context)) < 0)
|
|
||||||
{
|
{
|
||||||
WARN("Failed to initialise shader parser, ret %d.\n", ret);
|
WARN("Failed to initialise shader parser, ret %d.\n", ret);
|
||||||
vkd3d_free(sm1);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
program = sm1->p.program;
|
|
||||||
instructions = &program->instructions;
|
instructions = &program->instructions;
|
||||||
while (!shader_sm1_is_end(sm1))
|
while (!shader_sm1_is_end(&sm1))
|
||||||
{
|
{
|
||||||
if (!shader_instruction_array_reserve(instructions, instructions->count + 1))
|
if (!shader_instruction_array_reserve(instructions, instructions->count + 1))
|
||||||
{
|
{
|
||||||
ERR("Failed to allocate instructions.\n");
|
ERR("Failed to allocate instructions.\n");
|
||||||
vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, "Out of memory.");
|
vkd3d_shader_parser_error(&sm1.p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, "Out of memory.");
|
||||||
shader_sm1_destroy(&sm1->p);
|
vsir_program_cleanup(program);
|
||||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
ins = &instructions->elements[instructions->count];
|
ins = &instructions->elements[instructions->count];
|
||||||
shader_sm1_read_instruction(sm1, ins);
|
shader_sm1_read_instruction(&sm1, ins);
|
||||||
|
|
||||||
if (ins->handler_idx == VKD3DSIH_INVALID)
|
if (ins->handler_idx == VKD3DSIH_INVALID)
|
||||||
{
|
{
|
||||||
WARN("Encountered unrecognized or invalid instruction.\n");
|
WARN("Encountered unrecognized or invalid instruction.\n");
|
||||||
shader_sm1_destroy(&sm1->p);
|
vsir_program_cleanup(program);
|
||||||
return VKD3D_ERROR_INVALID_SHADER;
|
return VKD3D_ERROR_INVALID_SHADER;
|
||||||
}
|
}
|
||||||
++instructions->count;
|
++instructions->count;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(program->flat_constant_count); ++i)
|
for (i = 0; i < ARRAY_SIZE(program->flat_constant_count); ++i)
|
||||||
program->flat_constant_count[i] = get_external_constant_count(sm1, i);
|
program->flat_constant_count[i] = get_external_constant_count(&sm1, i);
|
||||||
|
|
||||||
if (!sm1->p.failed)
|
if (!sm1.p.failed)
|
||||||
ret = vkd3d_shader_parser_validate(&sm1->p, config_flags);
|
ret = vkd3d_shader_parser_validate(&sm1.p, config_flags);
|
||||||
|
|
||||||
if (sm1->p.failed && ret >= 0)
|
if (sm1.p.failed && ret >= 0)
|
||||||
ret = VKD3D_ERROR_INVALID_SHADER;
|
ret = VKD3D_ERROR_INVALID_SHADER;
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
WARN("Failed to parse shader.\n");
|
WARN("Failed to parse shader.\n");
|
||||||
shader_sm1_destroy(&sm1->p);
|
vsir_program_cleanup(program);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
*parser = &sm1->p;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3994,25 +3994,31 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
|
|||||||
uint64_t config_flags = vkd3d_shader_init_config_flags();
|
uint64_t config_flags = vkd3d_shader_init_config_flags();
|
||||||
struct vkd3d_shader_compile_info info = *compile_info;
|
struct vkd3d_shader_compile_info info = *compile_info;
|
||||||
struct vkd3d_shader_parser *parser;
|
struct vkd3d_shader_parser *parser;
|
||||||
|
struct vsir_program program, *p;
|
||||||
|
|
||||||
if (profile->major_version < 4)
|
if (profile->major_version < 4)
|
||||||
{
|
{
|
||||||
if ((ret = hlsl_emit_bytecode(&ctx, entry_func, VKD3D_SHADER_TARGET_D3D_BYTECODE, &info.source)) < 0)
|
if ((ret = hlsl_emit_bytecode(&ctx, entry_func, VKD3D_SHADER_TARGET_D3D_BYTECODE, &info.source)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
info.source_type = VKD3D_SHADER_SOURCE_D3D_BYTECODE;
|
info.source_type = VKD3D_SHADER_SOURCE_D3D_BYTECODE;
|
||||||
ret = vkd3d_shader_sm1_parser_create(&info, config_flags, message_context, &parser);
|
ret = d3dbc_parse(&info, config_flags, message_context, &program);
|
||||||
|
p = &program;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((ret = hlsl_emit_bytecode(&ctx, entry_func, VKD3D_SHADER_TARGET_DXBC_TPF, &info.source)) < 0)
|
if ((ret = hlsl_emit_bytecode(&ctx, entry_func, VKD3D_SHADER_TARGET_DXBC_TPF, &info.source)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
|
info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
|
||||||
ret = vkd3d_shader_sm4_parser_create(&info, config_flags, message_context, &parser);
|
if ((ret = vkd3d_shader_sm4_parser_create(&info, config_flags, message_context, &parser)) >= 0)
|
||||||
|
p = parser->program;
|
||||||
}
|
}
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
{
|
{
|
||||||
ret = vsir_program_compile(parser->program, config_flags, &info, out, message_context);
|
ret = vsir_program_compile(p, config_flags, &info, out, message_context);
|
||||||
vkd3d_shader_parser_destroy(parser);
|
if (p == &program)
|
||||||
|
vsir_program_cleanup(&program);
|
||||||
|
else
|
||||||
|
vkd3d_shader_parser_destroy(parser);
|
||||||
}
|
}
|
||||||
vkd3d_shader_free_shader_code(&info.source);
|
vkd3d_shader_free_shader_code(&info.source);
|
||||||
}
|
}
|
||||||
|
@ -1516,19 +1516,23 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
|
|||||||
{
|
{
|
||||||
uint64_t config_flags = vkd3d_shader_init_config_flags();
|
uint64_t config_flags = vkd3d_shader_init_config_flags();
|
||||||
struct vkd3d_shader_parser *parser;
|
struct vkd3d_shader_parser *parser;
|
||||||
|
struct vsir_program program, *p;
|
||||||
|
|
||||||
switch (compile_info->source_type)
|
switch (compile_info->source_type)
|
||||||
{
|
{
|
||||||
case VKD3D_SHADER_SOURCE_D3D_BYTECODE:
|
case VKD3D_SHADER_SOURCE_D3D_BYTECODE:
|
||||||
ret = vkd3d_shader_sm1_parser_create(compile_info, config_flags, &message_context, &parser);
|
ret = d3dbc_parse(compile_info, config_flags, &message_context, &program);
|
||||||
|
p = &program;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VKD3D_SHADER_SOURCE_DXBC_TPF:
|
case VKD3D_SHADER_SOURCE_DXBC_TPF:
|
||||||
ret = vkd3d_shader_sm4_parser_create(compile_info, config_flags, &message_context, &parser);
|
if ((ret = vkd3d_shader_sm4_parser_create(compile_info, config_flags, &message_context, &parser)) >= 0)
|
||||||
|
p = parser->program;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VKD3D_SHADER_SOURCE_DXBC_DXIL:
|
case VKD3D_SHADER_SOURCE_DXBC_DXIL:
|
||||||
ret = vkd3d_shader_sm6_parser_create(compile_info, config_flags, &message_context, &parser);
|
if ((ret = vkd3d_shader_sm6_parser_create(compile_info, config_flags, &message_context, &parser)) >= 0)
|
||||||
|
p = parser->program;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1543,8 +1547,11 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret = vsir_program_scan(parser->program, compile_info, &message_context, NULL);
|
ret = vsir_program_scan(p, compile_info, &message_context, NULL);
|
||||||
vkd3d_shader_parser_destroy(parser);
|
if (p == &program)
|
||||||
|
vsir_program_cleanup(&program);
|
||||||
|
else
|
||||||
|
vkd3d_shader_parser_destroy(parser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1638,19 +1645,23 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
|
|||||||
{
|
{
|
||||||
uint64_t config_flags = vkd3d_shader_init_config_flags();
|
uint64_t config_flags = vkd3d_shader_init_config_flags();
|
||||||
struct vkd3d_shader_parser *parser;
|
struct vkd3d_shader_parser *parser;
|
||||||
|
struct vsir_program program, *p;
|
||||||
|
|
||||||
switch (compile_info->source_type)
|
switch (compile_info->source_type)
|
||||||
{
|
{
|
||||||
case VKD3D_SHADER_SOURCE_D3D_BYTECODE:
|
case VKD3D_SHADER_SOURCE_D3D_BYTECODE:
|
||||||
ret = vkd3d_shader_sm1_parser_create(compile_info, config_flags, &message_context, &parser);
|
ret = d3dbc_parse(compile_info, config_flags, &message_context, &program);
|
||||||
|
p = &program;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VKD3D_SHADER_SOURCE_DXBC_TPF:
|
case VKD3D_SHADER_SOURCE_DXBC_TPF:
|
||||||
ret = vkd3d_shader_sm4_parser_create(compile_info, config_flags, &message_context, &parser);
|
if ((ret = vkd3d_shader_sm4_parser_create(compile_info, config_flags, &message_context, &parser)) >= 0)
|
||||||
|
p = parser->program;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VKD3D_SHADER_SOURCE_DXBC_DXIL:
|
case VKD3D_SHADER_SOURCE_DXBC_DXIL:
|
||||||
ret = vkd3d_shader_sm6_parser_create(compile_info, config_flags, &message_context, &parser);
|
if ((ret = vkd3d_shader_sm6_parser_create(compile_info, config_flags, &message_context, &parser)) >= 0)
|
||||||
|
p = parser->program;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1665,8 +1676,11 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret = vsir_program_compile(parser->program, config_flags, compile_info, out, &message_context);
|
ret = vsir_program_compile(p, config_flags, compile_info, out, &message_context);
|
||||||
vkd3d_shader_parser_destroy(parser);
|
if (p == &program)
|
||||||
|
vsir_program_cleanup(&program);
|
||||||
|
else
|
||||||
|
vkd3d_shader_parser_destroy(parser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1554,8 +1554,8 @@ void vkd3d_shader_trace_text_(const char *text, size_t size, const char *functio
|
|||||||
#define vkd3d_shader_trace_text(text, size) \
|
#define vkd3d_shader_trace_text(text, size) \
|
||||||
vkd3d_shader_trace_text_(text, size, __FUNCTION__)
|
vkd3d_shader_trace_text_(text, size, __FUNCTION__)
|
||||||
|
|
||||||
int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
|
int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
|
||||||
struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser);
|
struct vkd3d_shader_message_context *message_context, struct vsir_program *program);
|
||||||
int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
|
int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
|
||||||
struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser);
|
struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser);
|
||||||
int vkd3d_shader_sm6_parser_create(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
|
int vkd3d_shader_sm6_parser_create(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user