Module: vkd3d Branch: master Commit: 3e553aaaa7a5cba0dec4b23148c13a05d3920ee4 URL: https://gitlab.winehq.org/wine/vkd3d/-/commit/3e553aaaa7a5cba0dec4b23148c13a...
Author: Conor McCarthy cmccarthy@codeweavers.com Date: Mon May 22 16:21:46 2023 +1000
vkd3d-shader/dxil: Emit the shader instructions.
Sufficient for compiling a no-op pixel shader.
---
libs/vkd3d-shader/dxil.c | 47 ++++++++++++++++++++++++++++++++ libs/vkd3d-shader/ir.c | 2 +- libs/vkd3d-shader/vkd3d_shader_private.h | 2 ++ 3 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 7011cd56..9dee9c40 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -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; diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 11c2da5b..d74f81af 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -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; diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 49ad7b3e..233f3c86 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -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;