mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
vkd3d-shader: Introduce struct vkd3d_shader_parser_ops.
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
f5c6f2ea0e
commit
28316b2694
@ -960,90 +960,7 @@ static enum vkd3d_data_type map_data_type(char t)
|
||||
}
|
||||
}
|
||||
|
||||
static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t *byte_code,
|
||||
size_t byte_code_size, const char *source_name, const struct vkd3d_shader_signature *output_signature,
|
||||
struct vkd3d_shader_message_context *message_context)
|
||||
{
|
||||
struct vkd3d_shader_version version;
|
||||
uint32_t version_token, token_count;
|
||||
unsigned int i;
|
||||
|
||||
if (byte_code_size / sizeof(*byte_code) < 2)
|
||||
{
|
||||
WARN("Invalid byte code size %lu.\n", (long)byte_code_size);
|
||||
return false;
|
||||
}
|
||||
|
||||
version_token = byte_code[0];
|
||||
TRACE("Version: 0x%08x.\n", version_token);
|
||||
token_count = byte_code[1];
|
||||
TRACE("Token count: %u.\n", token_count);
|
||||
|
||||
if (token_count < 2 || byte_code_size / sizeof(*byte_code) < token_count)
|
||||
{
|
||||
WARN("Invalid token count %u.\n", token_count);
|
||||
return false;
|
||||
}
|
||||
|
||||
sm4->start = &byte_code[2];
|
||||
sm4->end = &byte_code[token_count];
|
||||
|
||||
switch (version_token >> 16)
|
||||
{
|
||||
case VKD3D_SM4_PS:
|
||||
version.type = VKD3D_SHADER_TYPE_PIXEL;
|
||||
break;
|
||||
|
||||
case VKD3D_SM4_VS:
|
||||
version.type = VKD3D_SHADER_TYPE_VERTEX;
|
||||
break;
|
||||
|
||||
case VKD3D_SM4_GS:
|
||||
version.type = VKD3D_SHADER_TYPE_GEOMETRY;
|
||||
break;
|
||||
|
||||
case VKD3D_SM5_HS:
|
||||
version.type = VKD3D_SHADER_TYPE_HULL;
|
||||
break;
|
||||
|
||||
case VKD3D_SM5_DS:
|
||||
version.type = VKD3D_SHADER_TYPE_DOMAIN;
|
||||
break;
|
||||
|
||||
case VKD3D_SM5_CS:
|
||||
version.type = VKD3D_SHADER_TYPE_COMPUTE;
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Unrecognised shader type %#x.\n", version_token >> 16);
|
||||
}
|
||||
version.major = VKD3D_SM4_VERSION_MAJOR(version_token);
|
||||
version.minor = VKD3D_SM4_VERSION_MINOR(version_token);
|
||||
|
||||
vkd3d_shader_parser_init(&sm4->p, message_context, source_name, &version);
|
||||
sm4->p.ptr = sm4->start;
|
||||
|
||||
memset(sm4->output_map, 0xff, sizeof(sm4->output_map));
|
||||
for (i = 0; i < output_signature->element_count; ++i)
|
||||
{
|
||||
struct vkd3d_shader_signature_element *e = &output_signature->elements[i];
|
||||
|
||||
if (e->register_index >= ARRAY_SIZE(sm4->output_map))
|
||||
{
|
||||
WARN("Invalid output index %u.\n", e->register_index);
|
||||
continue;
|
||||
}
|
||||
|
||||
sm4->output_map[e->register_index] = e->semantic_index;
|
||||
}
|
||||
|
||||
list_init(&sm4->src_free);
|
||||
list_init(&sm4->src);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void shader_sm4_free(struct vkd3d_shader_parser *parser)
|
||||
static void shader_sm4_destroy(struct vkd3d_shader_parser *parser)
|
||||
{
|
||||
struct vkd3d_shader_sm4_parser *sm4 = vkd3d_shader_sm4_parser(parser);
|
||||
struct vkd3d_shader_src_param_entry *e1, *e2;
|
||||
@ -1521,7 +1438,7 @@ static void shader_sm4_read_instruction_modifier(DWORD modifier, struct vkd3d_sh
|
||||
}
|
||||
}
|
||||
|
||||
void shader_sm4_read_instruction(struct vkd3d_shader_parser *parser, struct vkd3d_shader_instruction *ins)
|
||||
static void shader_sm4_read_instruction(struct vkd3d_shader_parser *parser, struct vkd3d_shader_instruction *ins)
|
||||
{
|
||||
struct vkd3d_shader_sm4_parser *sm4 = vkd3d_shader_sm4_parser(parser);
|
||||
const struct vkd3d_sm4_opcode_info *opcode_info;
|
||||
@ -1643,14 +1560,14 @@ fail:
|
||||
return;
|
||||
}
|
||||
|
||||
bool shader_sm4_is_end(struct vkd3d_shader_parser *parser)
|
||||
static bool shader_sm4_is_end(struct vkd3d_shader_parser *parser)
|
||||
{
|
||||
struct vkd3d_shader_sm4_parser *sm4 = vkd3d_shader_sm4_parser(parser);
|
||||
|
||||
return parser->ptr == sm4->end;
|
||||
}
|
||||
|
||||
void shader_sm4_reset(struct vkd3d_shader_parser *parser)
|
||||
static void shader_sm4_reset(struct vkd3d_shader_parser *parser)
|
||||
{
|
||||
struct vkd3d_shader_sm4_parser *sm4 = vkd3d_shader_sm4_parser(parser);
|
||||
|
||||
@ -1658,6 +1575,97 @@ void shader_sm4_reset(struct vkd3d_shader_parser *parser)
|
||||
parser->failed = false;
|
||||
}
|
||||
|
||||
static const struct vkd3d_shader_parser_ops shader_sm4_parser_ops =
|
||||
{
|
||||
.parser_reset = shader_sm4_reset,
|
||||
.parser_destroy = shader_sm4_destroy,
|
||||
.parser_read_instruction = shader_sm4_read_instruction,
|
||||
.parser_is_end = shader_sm4_is_end,
|
||||
};
|
||||
|
||||
static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t *byte_code,
|
||||
size_t byte_code_size, const char *source_name, const struct vkd3d_shader_signature *output_signature,
|
||||
struct vkd3d_shader_message_context *message_context)
|
||||
{
|
||||
struct vkd3d_shader_version version;
|
||||
uint32_t version_token, token_count;
|
||||
unsigned int i;
|
||||
|
||||
if (byte_code_size / sizeof(*byte_code) < 2)
|
||||
{
|
||||
WARN("Invalid byte code size %lu.\n", (long)byte_code_size);
|
||||
return false;
|
||||
}
|
||||
|
||||
version_token = byte_code[0];
|
||||
TRACE("Version: 0x%08x.\n", version_token);
|
||||
token_count = byte_code[1];
|
||||
TRACE("Token count: %u.\n", token_count);
|
||||
|
||||
if (token_count < 2 || byte_code_size / sizeof(*byte_code) < token_count)
|
||||
{
|
||||
WARN("Invalid token count %u.\n", token_count);
|
||||
return false;
|
||||
}
|
||||
|
||||
sm4->start = &byte_code[2];
|
||||
sm4->end = &byte_code[token_count];
|
||||
|
||||
switch (version_token >> 16)
|
||||
{
|
||||
case VKD3D_SM4_PS:
|
||||
version.type = VKD3D_SHADER_TYPE_PIXEL;
|
||||
break;
|
||||
|
||||
case VKD3D_SM4_VS:
|
||||
version.type = VKD3D_SHADER_TYPE_VERTEX;
|
||||
break;
|
||||
|
||||
case VKD3D_SM4_GS:
|
||||
version.type = VKD3D_SHADER_TYPE_GEOMETRY;
|
||||
break;
|
||||
|
||||
case VKD3D_SM5_HS:
|
||||
version.type = VKD3D_SHADER_TYPE_HULL;
|
||||
break;
|
||||
|
||||
case VKD3D_SM5_DS:
|
||||
version.type = VKD3D_SHADER_TYPE_DOMAIN;
|
||||
break;
|
||||
|
||||
case VKD3D_SM5_CS:
|
||||
version.type = VKD3D_SHADER_TYPE_COMPUTE;
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Unrecognised shader type %#x.\n", version_token >> 16);
|
||||
}
|
||||
version.major = VKD3D_SM4_VERSION_MAJOR(version_token);
|
||||
version.minor = VKD3D_SM4_VERSION_MINOR(version_token);
|
||||
|
||||
vkd3d_shader_parser_init(&sm4->p, message_context, source_name, &version, &shader_sm4_parser_ops);
|
||||
sm4->p.ptr = sm4->start;
|
||||
|
||||
memset(sm4->output_map, 0xff, sizeof(sm4->output_map));
|
||||
for (i = 0; i < output_signature->element_count; ++i)
|
||||
{
|
||||
struct vkd3d_shader_signature_element *e = &output_signature->elements[i];
|
||||
|
||||
if (e->register_index >= ARRAY_SIZE(sm4->output_map))
|
||||
{
|
||||
WARN("Invalid output index %u.\n", e->register_index);
|
||||
continue;
|
||||
}
|
||||
|
||||
sm4->output_map[e->register_index] = e->semantic_index;
|
||||
}
|
||||
|
||||
list_init(&sm4->src_free);
|
||||
list_init(&sm4->src);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compile_info,
|
||||
struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser)
|
||||
{
|
||||
|
@ -99,9 +99,9 @@ int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *generator,
|
||||
vkd3d_string_buffer_printf(&generator->buffer, "#version 440\n\n");
|
||||
vkd3d_string_buffer_printf(&generator->buffer, "void main()\n{\n");
|
||||
|
||||
while (!shader_sm4_is_end(parser))
|
||||
while (!vkd3d_shader_parser_is_end(parser))
|
||||
{
|
||||
shader_sm4_read_instruction(parser, &ins);
|
||||
vkd3d_shader_parser_read_instruction(parser, &ins);
|
||||
|
||||
if (ins.handler_idx == VKD3DSIH_INVALID)
|
||||
{
|
||||
|
@ -1889,12 +1889,12 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(struct vkd3d_shader_parser *parser,
|
||||
shader_version->minor, compiler.colours.reset);
|
||||
|
||||
indent = 0;
|
||||
shader_sm4_reset(parser);
|
||||
while (!shader_sm4_is_end(parser))
|
||||
vkd3d_shader_parser_reset(parser);
|
||||
while (!vkd3d_shader_parser_is_end(parser))
|
||||
{
|
||||
struct vkd3d_shader_instruction ins;
|
||||
|
||||
shader_sm4_read_instruction(parser, &ins);
|
||||
vkd3d_shader_parser_read_instruction(parser, &ins);
|
||||
if (ins.handler_idx == VKD3DSIH_INVALID)
|
||||
{
|
||||
WARN("Skipping unrecognized instruction.\n");
|
||||
|
@ -364,18 +364,14 @@ void vkd3d_shader_dump_shader(enum vkd3d_shader_source_type source_type,
|
||||
|
||||
void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
|
||||
struct vkd3d_shader_message_context *message_context, const char *source_name,
|
||||
const struct vkd3d_shader_version *version)
|
||||
const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops)
|
||||
{
|
||||
parser->message_context = message_context;
|
||||
parser->location.source_name = source_name;
|
||||
parser->location.line = 1;
|
||||
parser->location.column = 0;
|
||||
parser->shader_version = *version;
|
||||
}
|
||||
|
||||
static void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parser)
|
||||
{
|
||||
shader_sm4_free(parser);
|
||||
parser->ops = ops;
|
||||
}
|
||||
|
||||
void VKD3D_PRINTF_FUNC(3, 4) vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser,
|
||||
@ -946,12 +942,12 @@ static int scan_dxbc(const struct vkd3d_shader_compile_info *compile_info,
|
||||
if (TRACE_ON())
|
||||
{
|
||||
vkd3d_shader_trace(parser);
|
||||
shader_sm4_reset(parser);
|
||||
vkd3d_shader_parser_reset(parser);
|
||||
}
|
||||
|
||||
while (!shader_sm4_is_end(parser))
|
||||
while (!vkd3d_shader_parser_is_end(parser))
|
||||
{
|
||||
shader_sm4_read_instruction(parser, &instruction);
|
||||
vkd3d_shader_parser_read_instruction(parser, &instruction);
|
||||
|
||||
if (instruction.handler_idx == VKD3DSIH_INVALID)
|
||||
{
|
||||
@ -1081,9 +1077,9 @@ static int compile_dxbc_tpf(const struct vkd3d_shader_compile_info *compile_info
|
||||
return VKD3D_ERROR;
|
||||
}
|
||||
|
||||
while (!shader_sm4_is_end(parser))
|
||||
while (!vkd3d_shader_parser_is_end(parser))
|
||||
{
|
||||
shader_sm4_read_instruction(parser, &instruction);
|
||||
vkd3d_shader_parser_read_instruction(parser, &instruction);
|
||||
|
||||
if (instruction.handler_idx == VKD3DSIH_INVALID)
|
||||
{
|
||||
|
@ -902,25 +902,48 @@ struct vkd3d_shader_parser
|
||||
struct vkd3d_shader_desc shader_desc;
|
||||
struct vkd3d_shader_version shader_version;
|
||||
const uint32_t *ptr;
|
||||
const struct vkd3d_shader_parser_ops *ops;
|
||||
};
|
||||
|
||||
struct vkd3d_shader_parser_ops
|
||||
{
|
||||
void (*parser_reset)(struct vkd3d_shader_parser *parser);
|
||||
void (*parser_destroy)(struct vkd3d_shader_parser *parser);
|
||||
void (*parser_read_instruction)(struct vkd3d_shader_parser *parser, struct vkd3d_shader_instruction *instruction);
|
||||
bool (*parser_is_end)(struct vkd3d_shader_parser *parser);
|
||||
};
|
||||
|
||||
void vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser,
|
||||
enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4);
|
||||
void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
|
||||
struct vkd3d_shader_message_context *message_context, const char *source_name,
|
||||
const struct vkd3d_shader_version *version);
|
||||
const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops);
|
||||
|
||||
static inline void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parser)
|
||||
{
|
||||
parser->ops->parser_destroy(parser);
|
||||
}
|
||||
|
||||
static inline bool vkd3d_shader_parser_is_end(struct vkd3d_shader_parser *parser)
|
||||
{
|
||||
return parser->ops->parser_is_end(parser);
|
||||
}
|
||||
|
||||
static inline void vkd3d_shader_parser_read_instruction(struct vkd3d_shader_parser *parser,
|
||||
struct vkd3d_shader_instruction *instruction)
|
||||
{
|
||||
parser->ops->parser_read_instruction(parser, instruction);
|
||||
}
|
||||
|
||||
static inline void vkd3d_shader_parser_reset(struct vkd3d_shader_parser *parser)
|
||||
{
|
||||
parser->ops->parser_reset(parser);
|
||||
}
|
||||
|
||||
void vkd3d_shader_trace(struct vkd3d_shader_parser *parser);
|
||||
|
||||
const char *shader_get_type_prefix(enum vkd3d_shader_type type);
|
||||
|
||||
struct vkd3d_shader_message_context;
|
||||
|
||||
void shader_sm4_free(struct vkd3d_shader_parser *parser);
|
||||
void shader_sm4_read_instruction(struct vkd3d_shader_parser *parser, struct vkd3d_shader_instruction *ins);
|
||||
bool shader_sm4_is_end(struct vkd3d_shader_parser *parser);
|
||||
void shader_sm4_reset(struct vkd3d_shader_parser *parser);
|
||||
|
||||
struct vkd3d_string_buffer
|
||||
{
|
||||
char *buffer;
|
||||
|
Loading…
Reference in New Issue
Block a user