vkd3d-shader/dxil: Emit the shader instructions.

Sufficient for compiling a no-op pixel shader.
This commit is contained in:
Conor McCarthy 2023-05-22 16:21:46 +10:00 committed by Alexandre Julliard
parent f26d47585f
commit 3e553aaaa7
Notes: Alexandre Julliard 2023-07-20 22:57:52 +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/278
3 changed files with 50 additions and 1 deletions

View File

@ -1737,6 +1737,27 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
return VKD3D_OK;
}
static struct vkd3d_shader_instruction *sm6_parser_require_space(struct sm6_parser *sm6, size_t extra)
{
if (!shader_instruction_array_reserve(&sm6->p.instructions, sm6->p.instructions.count + extra))
{
ERR("Failed to allocate instruction.\n");
return NULL;
}
return &sm6->p.instructions.elements[sm6->p.instructions.count];
}
/* Space should be reserved before calling this. It is intended to require no checking of the returned pointer. */
static struct vkd3d_shader_instruction *sm6_parser_add_instruction(struct sm6_parser *sm6,
enum vkd3d_shader_opcode handler_idx)
{
struct vkd3d_shader_instruction *ins = sm6_parser_require_space(sm6, 1);
assert(ins);
shader_instruction_init(ins, handler_idx);
++sm6->p.instructions.count;
return ins;
}
static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6)
{
const struct dxil_block *block = &sm6->root_block;
@ -1932,6 +1953,21 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
return VKD3D_OK;
}
static bool sm6_block_emit_instructions(struct sm6_block *block, struct sm6_parser *sm6)
{
struct vkd3d_shader_instruction *ins = sm6_parser_require_space(sm6, block->instruction_count + 1);
if (!ins)
return false;
memcpy(ins, block->instructions, block->instruction_count * sizeof(*block->instructions));
sm6->p.instructions.count += block->instruction_count;
sm6_parser_add_instruction(sm6, VKD3DSIH_RET);
return true;
}
static enum vkd3d_result sm6_parser_module_init(struct sm6_parser *sm6, const struct dxil_block *block,
unsigned int level)
{
@ -2066,6 +2102,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t
struct vkd3d_shader_version version;
struct dxil_block *block;
enum vkd3d_result ret;
unsigned int i;
count = byte_code_size / sizeof(*byte_code);
if (count < 6)
@ -2255,6 +2292,16 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t
return ret;
}
for (i = 0; i < sm6->function_count; ++i)
{
if (!sm6_block_emit_instructions(sm6->functions[i].blocks[0], sm6))
{
vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
"Out of memory emitting shader instructions.");
return VKD3D_ERROR_OUT_OF_MEMORY;
}
}
dxil_block_destroy(&sm6->root_block);
return VKD3D_OK;

View File

@ -247,7 +247,7 @@ static void shader_register_init(struct vkd3d_shader_register *reg, enum vkd3d_s
reg->immconst_type = VKD3D_IMMCONST_SCALAR;
}
static void shader_instruction_init(struct vkd3d_shader_instruction *ins, enum vkd3d_shader_opcode handler_idx)
void shader_instruction_init(struct vkd3d_shader_instruction *ins, enum vkd3d_shader_opcode handler_idx)
{
memset(ins, 0, sizeof(*ins));
ins->handler_idx = handler_idx;

View File

@ -976,6 +976,8 @@ struct vkd3d_shader_instruction
} declaration;
};
void shader_instruction_init(struct vkd3d_shader_instruction *ins, enum vkd3d_shader_opcode handler_idx);
static inline bool vkd3d_shader_instruction_has_texel_offset(const struct vkd3d_shader_instruction *ins)
{
return ins->texel_offset.u || ins->texel_offset.v || ins->texel_offset.w;