From: Józef Kucia jkucia@codeweavers.com
We can address SPIR-V arrays dynamically.
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- libs/vkd3d-shader/dxbc.c | 4 +- libs/vkd3d-shader/spirv.c | 74 ++++++++++++++++++++++-- libs/vkd3d-shader/trace.c | 4 +- libs/vkd3d-shader/vkd3d_shader_private.h | 4 +- 4 files changed, 76 insertions(+), 10 deletions(-)
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index 49116681dbab..7cc11e7586ac 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -619,8 +619,8 @@ static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins struct vkd3d_sm4_data *priv) { shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_OPAQUE, - &ins->declaration.index_range.first_register); - ins->declaration.index_range.last_register = *tokens; + &ins->declaration.index_range.dst); + ins->declaration.index_range.register_count = *tokens; }
static void shader_sm4_read_dcl_output_topology(struct vkd3d_shader_instruction *ins, diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index afed8a27050a..52c22fee33cc 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -2568,14 +2568,17 @@ static void vkd3d_dxbc_compiler_emit_dereference_register(struct vkd3d_dxbc_comp } else if (register_info->is_aggregate) { - if (reg->idx[0].rel_addr || reg->idx[1].rel_addr) + if (reg->idx[1].rel_addr) FIXME("Relative addressing not implemented.\n");
- indexes[index_count++] = vkd3d_dxbc_compiler_get_constant_uint(compiler, register_info->member_idx); + if (reg->idx[0].rel_addr) + indexes[index_count++] = vkd3d_dxbc_compiler_emit_register_addressing(compiler, ®->idx[0]); + else + indexes[index_count++] = vkd3d_dxbc_compiler_get_constant_uint(compiler, register_info->member_idx); } else { - if (reg->idx[1].rel_addr) + if (reg->idx[1].rel_addr || (reg->idx[1].offset == ~0u && reg->idx[0].rel_addr)) FIXME("Relative addressing not implemented.\n");
/* Handle arrayed registers, e.g. v[3][0]. */ @@ -4754,6 +4757,64 @@ static void vkd3d_dxbc_compiler_emit_dcl_output_siv(struct vkd3d_dxbc_compiler * vkd3d_dxbc_compiler_emit_output(compiler, dst, sysval); }
+static bool vkd3d_dxbc_compiler_check_index_range(struct vkd3d_dxbc_compiler *compiler, + const struct vkd3d_shader_index_range *range) +{ + const struct vkd3d_shader_register *reg = &range->dst.reg; + struct vkd3d_shader_register_info reg_info; + struct vkd3d_shader_register current_reg; + struct vkd3d_symbol reg_symbol; + unsigned int i; + uint32_t id; + + current_reg = *reg; + vkd3d_symbol_make_register(®_symbol, ¤t_reg); + if (!vkd3d_dxbc_compiler_get_register_info(compiler, ¤t_reg, ®_info)) + { + ERR("Failed to get register info.\n"); + return false; + } + + /* FIXME: We should check if it's an array. */ + if (!reg_info.is_aggregate) + { + FIXME("Unhandled register %#x.\n", reg->type); + return false; + } + id = reg_info.id; + + for (i = reg->idx[0].offset; i < reg->idx[0].offset + range->register_count; ++i) + { + current_reg.idx[0].offset = i; + vkd3d_symbol_make_register(®_symbol, ¤t_reg); + + if (range->dst.write_mask != reg_info.write_mask + || vkd3d_write_mask_component_count(reg_info.write_mask) != 1) + { + FIXME("Unhandled index range write mask %#x (%#x).\n", + range->dst.write_mask, reg_info.write_mask); + return false; + } + + if (reg_info.id != id) + { + FIXME("Unhandled index range %#x, %u.\n", reg->type, i); + return false; + } + } + + return true; +} + +static void vkd3d_dxbc_compiler_emit_dcl_index_range(struct vkd3d_dxbc_compiler *compiler, + const struct vkd3d_shader_instruction *instruction) +{ + const struct vkd3d_shader_index_range *range = &instruction->declaration.index_range; + + if (!vkd3d_dxbc_compiler_check_index_range(compiler, range)) + FIXME("Ignoring dcl_index_range %#x %u.\n", range->dst.reg.type, range->register_count); +} + static void vkd3d_dxbc_compiler_emit_dcl_stream(struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { @@ -7388,6 +7449,9 @@ int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, case VKD3DSIH_DCL_OUTPUT_SIV: vkd3d_dxbc_compiler_emit_dcl_output_siv(compiler, instruction); break; + case VKD3DSIH_DCL_INDEX_RANGE: + vkd3d_dxbc_compiler_emit_dcl_index_range(compiler, instruction); + break; case VKD3DSIH_DCL_STREAM: vkd3d_dxbc_compiler_emit_dcl_stream(compiler, instruction); break; @@ -7730,7 +7794,6 @@ static void vkd3d_dxbc_compiler_emit_shader_epilogue_function(struct vkd3d_dxbc_
vkd3d_spirv_build_op_function(builder, void_id, function_id, SpvFunctionControlMaskNone, function_type_id); - vkd3d_spirv_build_op_name(builder, function_id, "epilogue");
for (i = 0; i < ARRAY_SIZE(compiler->private_output_variable); ++i) { @@ -7789,7 +7852,10 @@ int vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler, }
if (compiler->epilogue_function_id) + { + vkd3d_spirv_build_op_name(builder, compiler->epilogue_function_id, "epilogue"); vkd3d_dxbc_compiler_emit_shader_epilogue_function(compiler); + }
if (compiler->options & VKD3D_SHADER_STRIP_DEBUG) vkd3d_spirv_stream_clear(&builder->debug_stream); diff --git a/libs/vkd3d-shader/trace.c b/libs/vkd3d-shader/trace.c index 6375e714c1fc..bb0e6ad5a3d0 100644 --- a/libs/vkd3d-shader/trace.c +++ b/libs/vkd3d-shader/trace.c @@ -1389,8 +1389,8 @@ static void shader_dump_instruction(struct vkd3d_string_buffer *buffer,
case VKD3DSIH_DCL_INDEX_RANGE: shader_addline(buffer, "%s ", shader_opcode_names[ins->handler_idx]); - shader_dump_dst_param(buffer, &ins->declaration.index_range.first_register, shader_version); - shader_addline(buffer, " %u", ins->declaration.index_range.last_register); + shader_dump_dst_param(buffer, &ins->declaration.index_range.dst, shader_version); + shader_addline(buffer, " %u", ins->declaration.index_range.register_count); break;
case VKD3DSIH_DCL_INDEXABLE_TEMP: diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 6b095a9cbba6..7ffcdd9c5e77 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -584,8 +584,8 @@ struct vkd3d_shader_src_param
struct vkd3d_shader_index_range { - struct vkd3d_shader_dst_param first_register; - unsigned int last_register; + struct vkd3d_shader_dst_param dst; + unsigned int register_count; };
enum vkd3d_decl_usage