Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- We still use the first index to uniquely identify the register in vkd3d_symbol, only changing which field is used to declare it.
One alternative to the "resource_idx" field of struct vkd3d_shader_register could be to store that long with "register_space", and pass it as an extra parameter to vkd3d_dxbc_compiler_get_descriptor_binding().
More generally, there may be something to be said for exposing fields with specific meaning from vkd3d_shader_register, instead of a flat array idx[3], so as to hide the differences between SM5 and SM5.1 from spirv.c. If an SM1-3 frontend is added as well, this may be an even greater help (mostly considering constant buffers.) In that case, resource_idx could become one such field.
This patch does not handle descriptor arrays.
libs/vkd3d-shader/dxbc.c | 15 +++++++++++++++ libs/vkd3d-shader/spirv.c | 6 +++--- libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 3 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index 5e504dc..6d0d995 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -582,6 +582,14 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ins->declaration.icb = &priv->icb; }
+static void shader_sm4_map_resource_idx(struct vkd3d_shader_register *reg, const struct vkd3d_sm4_data *priv) +{ + if (shader_is_sm_5_1(priv)) + reg->u.resource_idx = reg->idx[1].offset; + else + reg->u.resource_idx = reg->idx[0].offset; +} + static void shader_sm4_read_dcl_resource(struct vkd3d_shader_instruction *ins, DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, struct vkd3d_sm4_data *priv) @@ -604,6 +612,7 @@ static void shader_sm4_read_dcl_resource(struct vkd3d_shader_instruction *ins, } reg_data_type = opcode == VKD3D_SM4_OP_DCL_RESOURCE ? VKD3D_DATA_RESOURCE : VKD3D_DATA_UAV; shader_sm4_read_dst_param(priv, &tokens, end, reg_data_type, &ins->declaration.semantic.reg); + shader_sm4_map_resource_idx(&ins->declaration.semantic.reg.reg, priv);
components = *tokens++; if ((components & 0xfff0) != (components & 0xf) * 0x1110) @@ -633,6 +642,7 @@ static void shader_sm4_read_dcl_constant_buffer(struct vkd3d_shader_instruction const DWORD *end = &tokens[token_count];
shader_sm4_read_src_param(priv, &tokens, end, VKD3D_DATA_FLOAT, &ins->declaration.cb.src); + shader_sm4_map_resource_idx(&ins->declaration.cb.src.reg, priv); if (opcode_token & VKD3D_SM4_INDEX_TYPE_MASK) ins->flags |= VKD3DSI_INDEXED_DYNAMIC;
@@ -662,6 +672,7 @@ static void shader_sm4_read_dcl_sampler(struct vkd3d_shader_instruction *ins, if (ins->flags & ~VKD3D_SM4_SAMPLER_COMPARISON) FIXME("Unhandled sampler mode %#x.\n", ins->flags); shader_sm4_read_src_param(priv, &tokens, end, VKD3D_DATA_SAMPLER, &ins->declaration.sampler.src); + shader_sm4_map_resource_idx(&ins->declaration.sampler.src.reg, priv); shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.sampler.register_space); }
@@ -861,6 +872,7 @@ static void shader_sm5_read_dcl_uav_raw(struct vkd3d_shader_instruction *ins, const DWORD *end = &tokens[token_count];
shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UAV, &ins->declaration.raw_resource.dst); + shader_sm4_map_resource_idx(&ins->declaration.raw_resource.dst.reg, priv); ins->flags = (opcode_token & VKD3D_SM5_UAV_FLAGS_MASK) >> VKD3D_SM5_UAV_FLAGS_SHIFT; shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.raw_resource.register_space); } @@ -872,6 +884,7 @@ static void shader_sm5_read_dcl_uav_structured(struct vkd3d_shader_instruction * const DWORD *end = &tokens[token_count];
shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UAV, &ins->declaration.structured_resource.reg); + shader_sm4_map_resource_idx(&ins->declaration.structured_resource.reg.reg, priv); ins->flags = (opcode_token & VKD3D_SM5_UAV_FLAGS_MASK) >> VKD3D_SM5_UAV_FLAGS_SHIFT; ins->declaration.structured_resource.byte_stride = *tokens++; if (ins->declaration.structured_resource.byte_stride % 4) @@ -908,6 +921,7 @@ static void shader_sm5_read_dcl_resource_structured(struct vkd3d_shader_instruct const DWORD *end = &tokens[token_count];
shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_RESOURCE, &ins->declaration.structured_resource.reg); + shader_sm4_map_resource_idx(&ins->declaration.structured_resource.reg.reg, priv); ins->declaration.structured_resource.byte_stride = *tokens++; if (ins->declaration.structured_resource.byte_stride % 4) FIXME("Byte stride %u is not multiple of 4.\n", ins->declaration.structured_resource.byte_stride); @@ -921,6 +935,7 @@ static void shader_sm5_read_dcl_resource_raw(struct vkd3d_shader_instruction *in const DWORD *end = &tokens[token_count];
shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_RESOURCE, &ins->declaration.dst); + shader_sm4_map_resource_idx(&ins->declaration.dst.reg, priv); shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.raw_resource.register_space); }
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index ba21113..a8b2a50 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -2233,7 +2233,7 @@ static bool vkd3d_dxbc_compiler_check_shader_visibility(const struct vkd3d_dxbc_ static struct vkd3d_push_constant_buffer_binding *vkd3d_dxbc_compiler_find_push_constant_buffer( const struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_register *reg) { - unsigned int reg_idx = reg->idx[0].offset; + unsigned int reg_idx = reg->u.resource_idx; unsigned int i;
for (i = 0; i < compiler->shader_interface.push_constant_buffer_count; ++i) @@ -2280,13 +2280,13 @@ static bool vkd3d_dxbc_compiler_has_combined_sampler(const struct vkd3d_dxbc_com
static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor_binding( struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_register *reg, - enum vkd3d_shader_resource_type resource_type, bool is_uav_counter) + unsigned int register_space, enum vkd3d_shader_resource_type resource_type, bool is_uav_counter) { const struct vkd3d_shader_interface_info *shader_interface = &compiler->shader_interface; enum vkd3d_shader_descriptor_type descriptor_type; enum vkd3d_shader_binding_flag resource_type_flag; struct vkd3d_shader_descriptor_binding binding; - unsigned int reg_idx = reg->idx[0].offset; + unsigned int reg_idx = reg->u.resource_idx; unsigned int i;
descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_UNKNOWN; diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 100d515..9157a5a 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -565,6 +565,7 @@ struct vkd3d_shader_register DWORD immconst_uint[VKD3D_VEC4_SIZE]; float immconst_float[VKD3D_VEC4_SIZE]; unsigned fp_body_idx; + unsigned int resource_idx; } u; };
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/dxbc.c | 4 ++++ libs/vkd3d-shader/spirv.c | 2 +- libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 3 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index 6d0d995..298132d 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -1600,6 +1600,10 @@ static bool shader_sm4_read_param(struct vkd3d_sm4_data *priv, const DWORD **ptr break; } } + else if (register_type == VKD3D_SM4_RT_CONSTBUFFER) + { + param->u.cb_offset_param = shader_is_sm_5_1(priv) ? 2 : 1; + }
map_register(priv, param);
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index a8b2a50..2b5853f 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -2832,7 +2832,7 @@ static void vkd3d_dxbc_compiler_emit_dereference_register(struct vkd3d_dxbc_comp { assert(!reg->idx[0].rel_addr); indexes[index_count++] = vkd3d_dxbc_compiler_get_constant_uint(compiler, register_info->member_idx); - indexes[index_count++] = vkd3d_dxbc_compiler_emit_register_addressing(compiler, ®->idx[1]); + indexes[index_count++] = vkd3d_dxbc_compiler_emit_register_addressing(compiler, ®->idx[reg->u.cb_offset_param]); } else if (reg->type == VKD3DSPR_IMMCONSTBUFFER) { diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 9157a5a..36db3bb 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -566,6 +566,7 @@ struct vkd3d_shader_register float immconst_float[VKD3D_VEC4_SIZE]; unsigned fp_body_idx; unsigned int resource_idx; + unsigned int cb_offset_param; } u; };
On Sat, 23 May 2020 at 00:58, Zebediah Figura zfigura@codeweavers.com wrote:
@@ -1600,6 +1600,10 @@ static bool shader_sm4_read_param(struct vkd3d_sm4_data *priv, const DWORD **ptr break; } }
- else if (register_type == VKD3D_SM4_RT_CONSTBUFFER)
- {
param->u.cb_offset_param = shader_is_sm_5_1(priv) ? 2 : 1;
- }
This isn't really a property of the register, it's the same for all the VKD3D_SM4_RT_CONSTBUFFER registers in the shader. If we're going this way, I'd probably store it in the vkd3d_dxbc_compiler structure instead. However, there's also an argument to be made that instead of dealing with "cb_offset_param" in spirv.c, we should simply fix this up in the parser. (I.e., as far as spirv.c would be concerned we'd always have a SM 5.1 shader.)
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/spirv.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 2b5853f..43a3a1a 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -2029,6 +2029,7 @@ struct vkd3d_push_constant_buffer_binding { struct vkd3d_shader_register reg; struct vkd3d_shader_push_constant_buffer pc; + unsigned int size; };
struct vkd3d_shader_phase @@ -4892,7 +4893,7 @@ static void vkd3d_dxbc_compiler_emit_push_constant_buffers(struct vkd3d_dxbc_com const SpvStorageClass storage_class = SpvStorageClassPushConstant; uint32_t vec4_id, length_id, struct_id, pointer_type_id, var_id; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - unsigned int i, j, count, reg_idx, cb_size; + unsigned int i, j, count, reg_idx; struct vkd3d_symbol reg_symbol; uint32_t *member_ids;
@@ -4918,8 +4919,7 @@ static void vkd3d_dxbc_compiler_emit_push_constant_buffers(struct vkd3d_dxbc_com if (!cb->reg.type) continue;
- cb_size = cb->reg.idx[1].offset; - length_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, cb_size); + length_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, cb->size); member_ids[j] = vkd3d_spirv_build_op_type_array(builder, vec4_id, length_id); vkd3d_spirv_build_op_decorate1(builder, member_ids[j], SpvDecorationArrayStride, 16);
@@ -4979,6 +4979,7 @@ static void vkd3d_dxbc_compiler_emit_dcl_constant_buffer(struct vkd3d_dxbc_compi */ unsigned int cb_size_in_bytes = cb->size * VKD3D_VEC4_SIZE * sizeof(uint32_t); push_cb->reg = *reg; + push_cb->size = cb->size; if (cb_size_in_bytes > push_cb->pc.size) { WARN("Constant buffer size %u exceeds push constant size %u.\n",
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/spirv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 43a3a1a..3e4f9f4 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -2868,7 +2868,7 @@ static void vkd3d_dxbc_compiler_emit_dereference_register(struct vkd3d_dxbc_comp FIXME("Relative addressing not implemented.\n");
/* Handle arrayed registers, e.g. v[3][0]. */ - if (reg->idx[1].offset != ~0u) + if (reg->idx[1].offset != ~0u && (vkd3d_shader_register_is_input(reg) || vkd3d_shader_register_is_output(reg))) indexes[index_count++] = vkd3d_dxbc_compiler_emit_register_addressing(compiler, ®->idx[0]); }
On Sat, 23 May 2020 at 00:57, Zebediah Figura zfigura@codeweavers.com wrote:
Subject: [PATCH vkd3d 4/8] vkd3d-shader: Allow only input and output registers to be treated as arrayed.
That's somewhat misleading, we (still) handle other types of arrayed registers earlier in the same function. Given the rest of the series, I suspect this is specifically about indexing descriptors. Perhaps it makes sense to specifically check for those?
On 5/25/20 2:09 PM, Henri Verbeet wrote:
On Sat, 23 May 2020 at 00:57, Zebediah Figura zfigura@codeweavers.com wrote:
Subject: [PATCH vkd3d 4/8] vkd3d-shader: Allow only input and output registers to be treated as arrayed.
That's somewhat misleading, we (still) handle other types of arrayed registers earlier in the same function. Given the rest of the series, I suspect this is specifically about indexing descriptors. Perhaps it makes sense to specifically check for those?
I guess the comment there is also misleading in that case; I was assuming "arrayed" meant something more specific than just needing more than one index...
Either way works, though checking for just semantics seemed easier, as I understand that's the only thing we need to check for here.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- include/vkd3d_shader.h | 3 +++ libs/vkd3d-shader/spirv.c | 57 +++++++++++++++++---------------------- libs/vkd3d/state.c | 5 ++++ 3 files changed, 32 insertions(+), 33 deletions(-)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index 327b788..67d4562 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -138,6 +138,7 @@ struct vkd3d_shader_parameter struct vkd3d_shader_resource_binding { enum vkd3d_shader_descriptor_type type; + unsigned int register_space; unsigned int register_index; enum vkd3d_shader_visibility shader_visibility; unsigned int flags; /* vkd3d_shader_binding_flags */ @@ -159,6 +160,7 @@ struct vkd3d_shader_combined_resource_sampler
struct vkd3d_shader_uav_counter_binding { + unsigned int register_space; unsigned int register_index; /* u# */ enum vkd3d_shader_visibility shader_visibility;
@@ -168,6 +170,7 @@ struct vkd3d_shader_uav_counter_binding
struct vkd3d_shader_push_constant_buffer { + unsigned int register_space; unsigned int register_index; enum vkd3d_shader_visibility shader_visibility;
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 3e4f9f4..695de73 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -2232,9 +2232,10 @@ static bool vkd3d_dxbc_compiler_check_shader_visibility(const struct vkd3d_dxbc_ }
static struct vkd3d_push_constant_buffer_binding *vkd3d_dxbc_compiler_find_push_constant_buffer( - const struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_register *reg) + const struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_constant_buffer *cb) { - unsigned int reg_idx = reg->u.resource_idx; + unsigned int reg_idx = cb->src.reg.u.resource_idx; + unsigned int register_space = cb->register_space; unsigned int i;
for (i = 0; i < compiler->shader_interface.push_constant_buffer_count; ++i) @@ -2244,7 +2245,7 @@ static struct vkd3d_push_constant_buffer_binding *vkd3d_dxbc_compiler_find_push_ if (!vkd3d_dxbc_compiler_check_shader_visibility(compiler, current->pc.shader_visibility)) continue;
- if (current->pc.register_index == reg_idx) + if (current->pc.register_space == register_space && current->pc.register_index == reg_idx) return current; }
@@ -2318,11 +2319,11 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor if (current->offset) FIXME("Atomic counter offsets are not supported yet.\n");
- if (current->register_index == reg_idx) + if (current->register_space == register_space && current->register_index == reg_idx) return current->binding; } if (shader_interface->uav_counter_count) - FIXME("Could not find descriptor binding for UAV counter %u.\n", reg_idx); + FIXME("Could not find descriptor binding for UAV counter %u, space %u.\n", reg_idx, register_space); } else if (descriptor_type != VKD3D_SHADER_DESCRIPTOR_TYPE_UNKNOWN) { @@ -2336,12 +2337,13 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor if (!vkd3d_dxbc_compiler_check_shader_visibility(compiler, current->shader_visibility)) continue;
- if (current->type == descriptor_type && current->register_index == reg_idx) + if (current->type == descriptor_type && current->register_space == register_space + && current->register_index == reg_idx) return current->binding; } if (shader_interface->binding_count) - FIXME("Could not find binding for type %#x, register %u, shader type %#x.\n", - descriptor_type, reg_idx, compiler->shader_type); + FIXME("Could not find binding for type %#x, space %u, register %u, shader type %#x.\n", + descriptor_type, register_space, reg_idx, compiler->shader_type); }
binding.set = 0; @@ -2359,12 +2361,12 @@ static void vkd3d_dxbc_compiler_emit_descriptor_binding(struct vkd3d_dxbc_compil }
static void vkd3d_dxbc_compiler_emit_descriptor_binding_for_reg(struct vkd3d_dxbc_compiler *compiler, - uint32_t variable_id, const struct vkd3d_shader_register *reg, + uint32_t variable_id, const struct vkd3d_shader_register *reg, unsigned int register_space, enum vkd3d_shader_resource_type resource_type, bool is_uav_counter) { struct vkd3d_shader_descriptor_binding binding;
- binding = vkd3d_dxbc_compiler_get_descriptor_binding(compiler, reg, resource_type, is_uav_counter); + binding = vkd3d_dxbc_compiler_get_descriptor_binding(compiler, reg, register_space, resource_type, is_uav_counter); vkd3d_dxbc_compiler_emit_descriptor_binding(compiler, variable_id, &binding); }
@@ -4969,10 +4971,7 @@ static void vkd3d_dxbc_compiler_emit_dcl_constant_buffer(struct vkd3d_dxbc_compi
assert(!(instruction->flags & ~VKD3DSI_INDEXED_DYNAMIC));
- if (cb->register_space) - FIXME("Unhandled register space %u.\n", cb->register_space); - - if ((push_cb = vkd3d_dxbc_compiler_find_push_constant_buffer(compiler, reg))) + if ((push_cb = vkd3d_dxbc_compiler_find_push_constant_buffer(compiler, cb))) { /* Push constant buffers are handled in * vkd3d_dxbc_compiler_emit_push_constant_buffers(). @@ -5003,7 +5002,7 @@ static void vkd3d_dxbc_compiler_emit_dcl_constant_buffer(struct vkd3d_dxbc_compi pointer_type_id, storage_class, 0);
vkd3d_dxbc_compiler_emit_descriptor_binding_for_reg(compiler, - var_id, reg, VKD3D_SHADER_RESOURCE_BUFFER, false); + var_id, reg, cb->register_space, VKD3D_SHADER_RESOURCE_BUFFER, false);
vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, reg);
@@ -5055,9 +5054,6 @@ static void vkd3d_dxbc_compiler_emit_dcl_sampler(struct vkd3d_dxbc_compiler *com uint32_t type_id, ptr_type_id, var_id; struct vkd3d_symbol reg_symbol;
- if (instruction->declaration.sampler.register_space) - FIXME("Unhandled register space %u.\n", instruction->declaration.sampler.register_space); - if (vkd3d_dxbc_compiler_has_combined_sampler(compiler, NULL, reg)) return;
@@ -5066,8 +5062,8 @@ static void vkd3d_dxbc_compiler_emit_dcl_sampler(struct vkd3d_dxbc_compiler *com var_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream, ptr_type_id, storage_class, 0);
- vkd3d_dxbc_compiler_emit_descriptor_binding_for_reg(compiler, - var_id, reg, VKD3D_SHADER_RESOURCE_NONE, false); + vkd3d_dxbc_compiler_emit_descriptor_binding_for_reg(compiler, var_id, reg, + instruction->declaration.sampler.register_space, VKD3D_SHADER_RESOURCE_NONE, false);
vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, reg);
@@ -5198,8 +5194,9 @@ static void vkd3d_dxbc_compiler_emit_combined_sampler_declarations(struct vkd3d_ }
static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_compiler *compiler, - const struct vkd3d_shader_register *reg, enum vkd3d_shader_resource_type resource_type, - enum vkd3d_data_type resource_data_type, unsigned int structure_stride, bool raw) + const struct vkd3d_shader_register *reg, unsigned int register_space, + enum vkd3d_shader_resource_type resource_type, enum vkd3d_data_type resource_data_type, + unsigned int structure_stride, bool raw) { uint32_t counter_type_id, type_id, ptr_type_id, var_id, counter_var_id = 0; const struct vkd3d_shader_scan_info *scan_info = compiler->scan_info; @@ -5233,7 +5230,7 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp var_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream, ptr_type_id, storage_class, 0);
- vkd3d_dxbc_compiler_emit_descriptor_binding_for_reg(compiler, var_id, reg, resource_type, false); + vkd3d_dxbc_compiler_emit_descriptor_binding_for_reg(compiler, var_id, reg, register_space, resource_type, false);
vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, reg);
@@ -5256,7 +5253,7 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp ptr_type_id, storage_class, 0);
vkd3d_dxbc_compiler_emit_descriptor_binding_for_reg(compiler, - counter_var_id, reg, resource_type, true); + counter_var_id, reg, register_space, resource_type, true);
vkd3d_spirv_build_op_name(builder, counter_var_id, "u%u_counter", reg->idx[0].offset); } @@ -5277,12 +5274,10 @@ static void vkd3d_dxbc_compiler_emit_dcl_resource(struct vkd3d_dxbc_compiler *co { const struct vkd3d_shader_semantic *semantic = &instruction->declaration.semantic;
- if (semantic->register_space) - FIXME("Unhandled register space %u.\n", semantic->register_space); if (instruction->flags) FIXME("Unhandled UAV flags %#x.\n", instruction->flags);
- vkd3d_dxbc_compiler_emit_resource_declaration(compiler, &semantic->reg.reg, + vkd3d_dxbc_compiler_emit_resource_declaration(compiler, &semantic->reg.reg, semantic->register_space, semantic->resource_type, semantic->resource_data_type, 0, false); }
@@ -5291,12 +5286,10 @@ static void vkd3d_dxbc_compiler_emit_dcl_resource_raw(struct vkd3d_dxbc_compiler { const struct vkd3d_shader_raw_resource *resource = &instruction->declaration.raw_resource;
- if (resource->register_space) - FIXME("Unhandled register space %u.\n", resource->register_space); if (instruction->flags) FIXME("Unhandled UAV flags %#x.\n", instruction->flags);
- vkd3d_dxbc_compiler_emit_resource_declaration(compiler, &resource->dst.reg, + vkd3d_dxbc_compiler_emit_resource_declaration(compiler, &resource->dst.reg, resource->register_space, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, 0, true); }
@@ -5307,12 +5300,10 @@ static void vkd3d_dxbc_compiler_emit_dcl_resource_structured(struct vkd3d_dxbc_c const struct vkd3d_shader_register *reg = &resource->reg.reg; unsigned int stride = resource->byte_stride;
- if (resource->register_space) - FIXME("Unhandled register space %u.\n", resource->register_space); if (instruction->flags) FIXME("Unhandled UAV flags %#x.\n", instruction->flags);
- vkd3d_dxbc_compiler_emit_resource_declaration(compiler, reg, + vkd3d_dxbc_compiler_emit_resource_declaration(compiler, reg, resource->register_space, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, stride / 4, false); }
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index e1f7da9..3233654 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -510,6 +510,7 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat ? push_constants[0].stageFlags : stage_flags_from_visibility(p->ShaderVisibility); root_constant->offset = offset;
+ root_signature->root_constants[j].register_space = 0; root_signature->root_constants[j].register_index = p->u.Constants.ShaderRegister; root_signature->root_constants[j].shader_visibility = vkd3d_shader_visibility_from_d3d12(p->ShaderVisibility); @@ -541,6 +542,7 @@ static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature * = &root_signature->descriptor_mapping[context->descriptor_index++];
mapping->type = descriptor_type; + mapping->register_space = 0; mapping->register_index = register_idx; mapping->shader_visibility = shader_visibility; mapping->flags = buffer_descriptor ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE; @@ -1451,6 +1453,7 @@ static HRESULT d3d12_pipeline_state_init_compute_uav_counters(struct d3d12_pipel if (!(shader_info->uav_counter_mask & (1u << i))) continue;
+ state->uav_counters[j].register_space = 0; state->uav_counters[j].register_index = i; state->uav_counters[j].shader_visibility = VKD3D_SHADER_VISIBILITY_COMPUTE; state->uav_counters[j].binding.set = context.set_index; @@ -2910,6 +2913,7 @@ HRESULT vkd3d_uav_clear_state_init(struct vkd3d_uav_clear_state *state, struct d set_binding.pImmutableSamplers = NULL;
binding.type = VKD3D_SHADER_DESCRIPTOR_TYPE_UAV; + binding.register_space = 0; binding.register_index = 0; binding.shader_visibility = VKD3D_SHADER_VISIBILITY_COMPUTE; binding.binding.set = 0; @@ -2919,6 +2923,7 @@ HRESULT vkd3d_uav_clear_state_init(struct vkd3d_uav_clear_state *state, struct d push_constant_range.offset = 0; push_constant_range.size = sizeof(struct vkd3d_uav_clear_args);
+ push_constant.register_space = 0; push_constant.register_index = 0; push_constant.shader_visibility = VKD3D_SHADER_VISIBILITY_COMPUTE; push_constant.offset = 0;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d/state.c | 40 +++++++++------------------------------- 1 file changed, 9 insertions(+), 31 deletions(-)
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 3233654..a7b6251 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -308,13 +308,6 @@ static bool vk_binding_from_d3d12_descriptor_range(struct VkDescriptorSetLayoutB binding_desc->descriptorType = vk_descriptor_type_from_d3d12_range_type(descriptor_range->RangeType, is_buffer); binding_desc->descriptorCount = 1; - - if (descriptor_range->RegisterSpace) - { - FIXME("Unhandled register space %u.\n", descriptor_range->RegisterSpace); - return false; - } - binding_desc->stageFlags = stage_flags_from_visibility(shader_visibility); binding_desc->pImmutableSamplers = NULL;
@@ -495,12 +488,6 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat if (p->ParameterType != D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS) continue;
- if (p->u.Constants.RegisterSpace) - { - FIXME("Unhandled register space %u for parameter %u.\n", p->u.Constants.RegisterSpace, i); - return E_NOTIMPL; - } - idx = push_constant_count == 1 ? 0 : p->ShaderVisibility; offset = push_constants_offset[idx]; push_constants_offset[idx] += p->u.Constants.Num32BitValues * sizeof(uint32_t); @@ -510,7 +497,7 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat ? push_constants[0].stageFlags : stage_flags_from_visibility(p->ShaderVisibility); root_constant->offset = offset;
- root_signature->root_constants[j].register_space = 0; + root_signature->root_constants[j].register_space = p->u.Constants.RegisterSpace; root_signature->root_constants[j].register_index = p->u.Constants.ShaderRegister; root_signature->root_constants[j].shader_visibility = vkd3d_shader_visibility_from_d3d12(p->ShaderVisibility); @@ -534,7 +521,7 @@ struct vkd3d_descriptor_set_context };
static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature *root_signature, - enum vkd3d_shader_descriptor_type descriptor_type, unsigned int register_idx, + enum vkd3d_shader_descriptor_type descriptor_type, unsigned int register_space, unsigned int register_idx, bool buffer_descriptor, enum vkd3d_shader_visibility shader_visibility, struct vkd3d_descriptor_set_context *context) { @@ -542,7 +529,7 @@ static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature * = &root_signature->descriptor_mapping[context->descriptor_index++];
mapping->type = descriptor_type; - mapping->register_space = 0; + mapping->register_space = register_space; mapping->register_index = register_idx; mapping->shader_visibility = shader_visibility; mapping->flags = buffer_descriptor ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE; @@ -551,7 +538,7 @@ static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature * }
static uint32_t d3d12_root_signature_assign_vk_bindings(struct d3d12_root_signature *root_signature, - enum vkd3d_shader_descriptor_type descriptor_type, unsigned int base_register_idx, + enum vkd3d_shader_descriptor_type descriptor_type, unsigned int register_space, unsigned int base_register_idx, unsigned int binding_count, bool is_buffer_descriptor, bool duplicate_descriptors, enum vkd3d_shader_visibility shader_visibility, struct vkd3d_descriptor_set_context *context) { @@ -567,10 +554,10 @@ static uint32_t d3d12_root_signature_assign_vk_bindings(struct d3d12_root_signat for (i = 0; i < binding_count; ++i) { if (duplicate_descriptors) - d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, + d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, register_space, base_register_idx + i, true, shader_visibility, context);
- d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, + d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, register_space, base_register_idx + i, is_buffer_descriptor, shader_visibility, context); } return first_binding; @@ -627,7 +614,7 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
vk_binding = d3d12_root_signature_assign_vk_bindings(root_signature, vkd3d_descriptor_type_from_d3d12_range_type(range->RangeType), - range->BaseShaderRegister, range->NumDescriptors, false, true, + range->RegisterSpace, range->BaseShaderRegister, range->NumDescriptors, false, true, vkd3d_shader_visibility_from_d3d12(p->ShaderVisibility), context);
/* Unroll descriptor range. */ @@ -685,15 +672,9 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign
root_signature->push_descriptor_mask |= 1u << i;
- if (p->u.Descriptor.RegisterSpace) - { - FIXME("Unhandled register space %u for parameter %u.\n", p->u.Descriptor.RegisterSpace, i); - return E_NOTIMPL; - } - cur_binding->binding = d3d12_root_signature_assign_vk_bindings(root_signature, vkd3d_descriptor_type_from_d3d12_root_parameter_type(p->ParameterType), - p->u.Descriptor.ShaderRegister, 1, true, false, + p->u.Descriptor.RegisterSpace, p->u.Descriptor.ShaderRegister, 1, true, false, vkd3d_shader_visibility_from_d3d12(p->ShaderVisibility), context); cur_binding->descriptorType = vk_descriptor_type_from_d3d12_root_parameter(p->ParameterType); cur_binding->descriptorCount = 1; @@ -723,14 +704,11 @@ static HRESULT d3d12_root_signature_init_static_samplers(struct d3d12_root_signa { const D3D12_STATIC_SAMPLER_DESC *s = &desc->pStaticSamplers[i];
- if (s->RegisterSpace) - FIXME("Unhandled register space %u for static sampler %u.\n", s->RegisterSpace, i); - if (FAILED(hr = vkd3d_create_static_sampler(device, s, &root_signature->static_samplers[i]))) return hr;
cur_binding->binding = d3d12_root_signature_assign_vk_bindings(root_signature, - VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, s->ShaderRegister, 1, false, false, + VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, s->RegisterSpace, s->ShaderRegister, 1, false, false, vkd3d_shader_visibility_from_d3d12(s->ShaderVisibility), context); cur_binding->descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; cur_binding->descriptorCount = 1;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- tests/d3d12.c | 212 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+)
diff --git a/tests/d3d12.c b/tests/d3d12.c index 323ef23..dcec8ed 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -646,6 +646,18 @@ static void check_sub_resource_uvec4_(unsigned int line, ID3D12Resource *texture expected_value->x, expected_value->y, expected_value->z, expected_value->w, x, y); }
+#define check_buffer_uint(a, b, c, d, e) check_buffer_uint_(__LINE__, a, b, c, d, e) +static void check_buffer_uint_(unsigned int line, ID3D12Resource *buffer, + ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list, + unsigned int expected, unsigned int max_diff) +{ + struct resource_readback rb; + + get_buffer_readback_with_command_list(buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list); + check_readback_data_uint_(line, &rb, NULL, expected, max_diff); + release_resource_readback(&rb); +} + static bool broken_on_warp(bool condition) { return broken(use_warp_device && condition); @@ -32811,6 +32823,205 @@ static void test_write_buffer_immediate(void) destroy_test_context(&context); }
+static void test_register_space(void) +{ + ID3D12Resource *input_buffers[6], *output_buffers[8]; + D3D12_ROOT_SIGNATURE_DESC root_signature_desc; + D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc; + D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc; + ID3D12GraphicsCommandList *command_list; + struct test_context context; + ID3D12DescriptorHeap *heap; + ID3D12CommandQueue *queue; + ID3D12Device *device; + unsigned int i; + HRESULT hr; + + static const D3D12_DESCRIPTOR_RANGE descriptor_ranges[] = + { + {D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 1, 2, 0}, + {D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 1, 1, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND}, + {D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 2, 1, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND}, + {D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 2, 2, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND}, + {D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 3, 1, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND}, + {D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 3, 2, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND}, + + {D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 1, 1, 1, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND}, + {D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 1, 1, 2, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND}, + {D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 1, 2, 1, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND}, + {D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 1, 2, 2, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND}, + {D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 1, 3, 1, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND}, + {D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 1, 3, 2, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND}, + {D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 1, 3, 4, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND}, + {D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 1, 3, 3, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND}, + }; + + static const D3D12_ROOT_PARAMETER root_parameters[] = + { + {D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, + .DescriptorTable = {ARRAY_SIZE(descriptor_ranges), descriptor_ranges}}, + {D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS, .Constants = {1, 1, 1}}, + {D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS, .Constants = {1, 2, 1}}, + }; + + static const DWORD cs_code[] = + { +#if 0 + cbuffer cb1 : register(b1, space1) + { + uint c1; + } + cbuffer cb2 : register(b1, space2) + { + uint c2; + } + + ByteAddressBuffer t1 : register(t1, space2); + ByteAddressBuffer t2 : register(t1, space1); + + Buffer<uint> t3 : register(t2, space1); + Buffer<uint> t4 : register(t2, space2); + + StructuredBuffer<uint> t5 : register(t3, space1); + StructuredBuffer<uint> t6 : register(t3, space2); + + RWByteAddressBuffer u1 : register(u1, space1); + RWByteAddressBuffer u2 : register(u1, space2); + RWByteAddressBuffer u3 : register(u2, space1); + RWByteAddressBuffer u4 : register(u2, space2); + + RWBuffer<uint> u5 : register(u3, space1); + RWBuffer<uint> u6 : register(u3, space2); + + RWStructuredBuffer<uint> u7 : register(u3, space4); + RWStructuredBuffer<uint> u8 : register(u3, space3); + + [numthreads(1, 1, 1)] + void main() + { + u1.Store(0, t1.Load(0)); + u2.Store(0, t2.Load(0)); + u3.Store(0, t3.Load(0)); + u4.Store(0, t4.Load(0)); + u5[0] = t5.Load(0); + u6[0] = t6.Load(0); + u7[0] = c1; + u8[0] = c2; + } +#endif + 0x43425844, 0x073b3de1, 0x527d26fc, 0xa46f417c, 0x4d9f338c, 0x00000001, 0x00000444, 0x00000003, + 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000003f0, 0x00050051, 0x000000fc, 0x0100086a, + 0x07000059, 0x00308e46, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x07000059, + 0x00308e46, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x060000a1, 0x00307e46, + 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x07000858, 0x00307e46, 0x00000001, 0x00000002, + 0x00000002, 0x00004444, 0x00000001, 0x070000a2, 0x00307e46, 0x00000002, 0x00000003, 0x00000003, + 0x00000004, 0x00000001, 0x060000a1, 0x00307e46, 0x00000003, 0x00000001, 0x00000001, 0x00000002, + 0x07000858, 0x00307e46, 0x00000004, 0x00000002, 0x00000002, 0x00004444, 0x00000002, 0x070000a2, + 0x00307e46, 0x00000005, 0x00000003, 0x00000003, 0x00000004, 0x00000002, 0x0600009d, 0x0031ee46, + 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x0600009d, 0x0031ee46, 0x00000001, 0x00000002, + 0x00000002, 0x00000001, 0x0700089c, 0x0031ee46, 0x00000002, 0x00000003, 0x00000003, 0x00004444, + 0x00000001, 0x0600009d, 0x0031ee46, 0x00000003, 0x00000001, 0x00000001, 0x00000002, 0x0600009d, + 0x0031ee46, 0x00000004, 0x00000002, 0x00000002, 0x00000002, 0x0700089c, 0x0031ee46, 0x00000005, + 0x00000003, 0x00000003, 0x00004444, 0x00000002, 0x0700009e, 0x0031ee46, 0x00000006, 0x00000003, + 0x00000003, 0x00000004, 0x00000003, 0x0700009e, 0x0031ee46, 0x00000007, 0x00000003, 0x00000003, + 0x00000004, 0x00000004, 0x02000068, 0x00000001, 0x0400009b, 0x00000001, 0x00000001, 0x00000001, + 0x080000a5, 0x00100012, 0x00000000, 0x00004001, 0x00000000, 0x00207006, 0x00000003, 0x00000001, + 0x080000a6, 0x0021e012, 0x00000000, 0x00000001, 0x00004001, 0x00000000, 0x0010000a, 0x00000000, + 0x080000a5, 0x00100012, 0x00000000, 0x00004001, 0x00000000, 0x00207006, 0x00000000, 0x00000001, + 0x080000a6, 0x0021e012, 0x00000003, 0x00000001, 0x00004001, 0x00000000, 0x0010000a, 0x00000000, + 0x0b00002d, 0x00100012, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00207e46, 0x00000001, 0x00000002, 0x080000a6, 0x0021e012, 0x00000001, 0x00000002, 0x00004001, + 0x00000000, 0x0010000a, 0x00000000, 0x0b00002d, 0x00100012, 0x00000000, 0x00004002, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00207e46, 0x00000004, 0x00000002, 0x080000a6, 0x0021e012, + 0x00000004, 0x00000002, 0x00004001, 0x00000000, 0x0010000a, 0x00000000, 0x0a0000a7, 0x00100012, + 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x00207006, 0x00000002, 0x00000003, + 0x0b0000a4, 0x0021e0f2, 0x00000002, 0x00000003, 0x00004002, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00100006, 0x00000000, 0x0a0000a7, 0x00100012, 0x00000000, 0x00004001, 0x00000000, + 0x00004001, 0x00000000, 0x00207006, 0x00000005, 0x00000003, 0x0b0000a4, 0x0021e0f2, 0x00000005, + 0x00000003, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00100006, 0x00000000, + 0x0c0000a8, 0x0021e012, 0x00000007, 0x00000003, 0x00004001, 0x00000000, 0x00004001, 0x00000000, + 0x0030800a, 0x00000000, 0x00000001, 0x00000000, 0x0c0000a8, 0x0021e012, 0x00000006, 0x00000003, + 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x0030800a, 0x00000001, 0x00000001, 0x00000000, + 0x0100003e, + }; + static const uint32_t srv_data[] = {100, 200, 300, 400, 500, 600}; + + if (!init_compute_test_context(&context)) + return; + device = context.device; + command_list = context.list; + queue = context.queue; + + memset(&root_signature_desc, 0, sizeof(root_signature_desc)); + root_signature_desc.NumParameters = ARRAY_SIZE(root_parameters); + root_signature_desc.pParameters = root_parameters; + hr = create_root_signature(device, &root_signature_desc, &context.root_signature); + ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr); + + heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, ARRAY_SIZE(descriptor_ranges)); + + for (i = 0; i < ARRAY_SIZE(input_buffers); ++i) + { + input_buffers[i] = create_default_buffer(device, sizeof(uint32_t), + D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST); + upload_buffer_data(input_buffers[i], 0, sizeof(srv_data[i]), &srv_data[i], queue, command_list); + reset_command_list(command_list, context.allocator); + transition_resource_state(command_list, input_buffers[i], + D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); + + memset(&srv_desc, 0, sizeof(srv_desc)); + srv_desc.Format = DXGI_FORMAT_R32_UINT; + srv_desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER; + srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + srv_desc.Buffer.FirstElement = 0; + srv_desc.Buffer.NumElements = 1; + ID3D12Device_CreateShaderResourceView(device, input_buffers[i], &srv_desc, + get_cpu_descriptor_handle(&context, heap, i)); + } + + for (i = 0; i < ARRAY_SIZE(output_buffers); ++i) + { + output_buffers[i] = create_default_buffer(device, sizeof(uint32_t), + D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + + memset(&uav_desc, 0, sizeof(uav_desc)); + uav_desc.Format = DXGI_FORMAT_R32_UINT; + uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER; + uav_desc.Buffer.FirstElement = 0; + uav_desc.Buffer.NumElements = 1; + ID3D12Device_CreateUnorderedAccessView(device, output_buffers[i], NULL, &uav_desc, + get_cpu_descriptor_handle(&context, heap, ARRAY_SIZE(input_buffers) + i)); + } + + context.pipeline_state = create_compute_pipeline_state(device, context.root_signature, + shader_bytecode(cs_code, sizeof(cs_code))); + + ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state); + ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature); + ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, + 0, get_gpu_descriptor_handle(&context, heap, 0)); + ID3D12GraphicsCommandList_SetComputeRoot32BitConstant(command_list, 1, 700, 0); + ID3D12GraphicsCommandList_SetComputeRoot32BitConstant(command_list, 2, 800, 0); + + ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1); + + for (i = 0; i < ARRAY_SIZE(output_buffers); ++i) + { + transition_sub_resource_state(command_list, output_buffers[i], 0, + D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); + check_buffer_uint(output_buffers[i], queue, command_list, (i + 1) * 100, 0); + reset_command_list(command_list, context.allocator); + } + + for (i = 0; i < ARRAY_SIZE(input_buffers); ++i) + ID3D12Resource_Release(input_buffers[i]); + for (i = 0; i < ARRAY_SIZE(output_buffers); ++i) + ID3D12Resource_Release(output_buffers[i]); + ID3D12DescriptorHeap_Release(heap); + destroy_test_context(&context); +} + START_TEST(d3d12) { parse_args(argc, argv); @@ -32975,4 +33186,5 @@ START_TEST(d3d12) run_test(test_conditional_rendering); run_test(test_bufinfo_instruction); run_test(test_write_buffer_immediate); + run_test(test_register_space); }
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- tests/d3d12.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+)
diff --git a/tests/d3d12.c b/tests/d3d12.c index dcec8ed..c4ec41a 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -33022,6 +33022,131 @@ static void test_register_space(void) destroy_test_context(&context); }
+static void test_sampler_register_space(void) +{ + static const struct test_context_desc desc = {.no_root_signature = true}; + ID3D12DescriptorHeap *heap, *sampler_heap, *heaps[2]; + D3D12_ROOT_SIGNATURE_DESC root_signature_desc; + ID3D12GraphicsCommandList *command_list; + D3D12_SAMPLER_DESC sampler_desc; + D3D12_SUBRESOURCE_DATA data; + struct test_context context; + ID3D12CommandQueue *queue; + ID3D12Resource *texture; + ID3D12Device *device; + HRESULT hr; + + static const D3D12_DESCRIPTOR_RANGE descriptor_ranges[] = + { + {D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0, 0, 0}, + }; + + static const D3D12_DESCRIPTOR_RANGE sampler_ranges[] = + { + {D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 1, 1, 0}, + {D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 1, 2, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND}, + }; + + static const D3D12_ROOT_PARAMETER root_parameters[] = + { + {D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, + .DescriptorTable = {ARRAY_SIZE(descriptor_ranges), descriptor_ranges}}, + {D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, + .DescriptorTable = {ARRAY_SIZE(sampler_ranges), sampler_ranges}}, + }; + + static const DWORD ps_code[] = + { +#if 0 + Texture2D<float> t; + SamplerState s1 : register(s1, space1); + SamplerState s2 : register(s1, space2); + + float4 main() : SV_Target + { + float2 coords = float2(0.5, 0.5); + return float4(t.Sample(s1, coords), t.Sample(s2, coords), 0, 1); + } +#endif + 0x43425844, 0xa29c83c7, 0xd4c8eeff, 0x7b73ff7b, 0x6463d58c, 0x00000001, 0x0000018c, 0x00000003, + 0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, + 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000114, 0x00000051, 0x00000045, + 0x0100086a, 0x0600005a, 0x00306e46, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x0600005a, + 0x00306e46, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x07001858, 0x00307e46, 0x00000000, + 0x00000000, 0x00000000, 0x00005555, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, + 0x00000001, 0x0e000045, 0x00100012, 0x00000000, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, + 0x00000000, 0x00207e46, 0x00000000, 0x00000000, 0x00206000, 0x00000000, 0x00000001, 0x0e000045, + 0x00100022, 0x00000000, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00207e16, + 0x00000000, 0x00000000, 0x00206000, 0x00000001, 0x00000001, 0x05000036, 0x00102032, 0x00000000, + 0x00100046, 0x00000000, 0x08000036, 0x001020c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x0100003e, + }; + static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)}; + static const float texture_data[4] = {0.0, 1.0, 0.0, 1.0}; + static const float blue[] = {0.0f, 0.0f, 1.0f, 1.0f}; + + if (!init_test_context(&context, &desc)) + return; + device = context.device; + command_list = context.list; + queue = context.queue; + + memset(&root_signature_desc, 0, sizeof(root_signature_desc)); + root_signature_desc.NumParameters = ARRAY_SIZE(root_parameters); + root_signature_desc.pParameters = root_parameters; + hr = create_root_signature(device, &root_signature_desc, &context.root_signature); + ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr); + + heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, ARRAY_SIZE(descriptor_ranges)); + sampler_heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, ARRAY_SIZE(sampler_ranges)); + + texture = create_default_texture(device, 2, 2, DXGI_FORMAT_R32_FLOAT, 0, D3D12_RESOURCE_STATE_COPY_DEST); + data.pData = texture_data; + data.SlicePitch = data.RowPitch = 2 * sizeof(*texture_data); + upload_texture_data(texture, &data, 1, queue, command_list); + reset_command_list(command_list, context.allocator); + transition_resource_state(command_list, texture, + D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + ID3D12Device_CreateShaderResourceView(device, texture, NULL, get_cpu_descriptor_handle(&context, heap, 0)); + + memset(&sampler_desc, 0, sizeof(sampler_desc)); + sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; + sampler_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + sampler_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + ID3D12Device_CreateSampler(device, &sampler_desc, get_cpu_sampler_handle(&context, sampler_heap, 0)); + sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; + ID3D12Device_CreateSampler(device, &sampler_desc, get_cpu_sampler_handle(&context, sampler_heap, 1)); + + context.pipeline_state = create_pipeline_state(device, context.root_signature, + context.render_target_desc.Format, NULL, &ps, NULL); + + ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, blue, 0, NULL); + ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL); + ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature); + ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state); + heaps[0] = heap; heaps[1] = sampler_heap; + ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, ARRAY_SIZE(heaps), heaps); + ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, + 0, get_gpu_descriptor_handle(&context, heap, 0)); + ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, + 1, get_gpu_sampler_handle(&context, sampler_heap, 0)); + ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport); + ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect); + ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0); + + transition_resource_state(command_list, context.render_target, + D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); + check_sub_resource_uint(context.render_target, 0, queue, command_list, 0x0000ff80, 1); + + ID3D12Resource_Release(texture); + ID3D12DescriptorHeap_Release(heap); + ID3D12DescriptorHeap_Release(sampler_heap); + destroy_test_context(&context); +} + START_TEST(d3d12) { parse_args(argc, argv); @@ -33187,4 +33312,5 @@ START_TEST(d3d12) run_test(test_bufinfo_instruction); run_test(test_write_buffer_immediate); run_test(test_register_space); + run_test(test_sampler_register_space); }
On Sat, 23 May 2020 at 00:56, Zebediah Figura zfigura@codeweavers.com wrote:
We still use the first index to uniquely identify the register in vkd3d_symbol, only changing which field is used to declare it.
One alternative to the "resource_idx" field of struct vkd3d_shader_register could be to store that long with "register_space", and pass it as an extra parameter to vkd3d_dxbc_compiler_get_descriptor_binding().
The way I understand shader model 5.1 resource/sampler declarations, they essentially assign an unique ID to a slice of a register space. In that sense, the most appropriate place for this would indeed be in the "declaration" part of struct vkd3d_shader_instruction, like the register space. I think the fact that "resource_idx" is unused outside of declaration instructions is consistent with that.
More generally, there may be something to be said for exposing fields with specific meaning from vkd3d_shader_register, instead of a flat array idx[3], so as to hide the differences between SM5 and SM5.1 from spirv.c. If an SM1-3 frontend is added as well, this may be an even greater help (mostly considering constant buffers.) In that case, resource_idx could become one such field.
In general, maybe. For this specific case, see above; I think it makes more sense to think of "resource_idx" as part of the declaration than as part of the register. The fact that SM 5.1 bytecode stores it as part of a register token seems like it should largely just be an interesting detail.
static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor_binding( struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_register *reg,
enum vkd3d_shader_resource_type resource_type, bool is_uav_counter)
unsigned int register_space, enum vkd3d_shader_resource_type resource_type, bool is_uav_counter)
That looks like it should be in 5/8.
On 5/25/20 2:08 PM, Henri Verbeet wrote:
On Sat, 23 May 2020 at 00:56, Zebediah Figura zfigura@codeweavers.com wrote:
We still use the first index to uniquely identify the register in vkd3d_symbol, only changing which field is used to declare it.
One alternative to the "resource_idx" field of struct vkd3d_shader_register could be to store that long with "register_space", and pass it as an extra parameter to vkd3d_dxbc_compiler_get_descriptor_binding().
The way I understand shader model 5.1 resource/sampler declarations, they essentially assign an unique ID to a slice of a register space. In that sense, the most appropriate place for this would indeed be in the "declaration" part of struct vkd3d_shader_instruction, like the register space. I think the fact that "resource_idx" is unused outside of declaration instructions is consistent with that.
More generally, there may be something to be said for exposing fields with specific meaning from vkd3d_shader_register, instead of a flat array idx[3], so as to hide the differences between SM5 and SM5.1 from spirv.c. If an SM1-3 frontend is added as well, this may be an even greater help (mostly considering constant buffers.) In that case, resource_idx could become one such field.
In general, maybe. For this specific case, see above; I think it makes more sense to think of "resource_idx" as part of the declaration than as part of the register. The fact that SM 5.1 bytecode stores it as part of a register token seems like it should largely just be an interesting detail.
Sure, that makes sense.
I guess the idea was motivated not only by dcl_* instructions but also by generic source accesses, whence also patches 2/8 and 4/8. Of course, as you suggested in review of 2/8, normalizing offsets to 5.1 in dxbc.c without bothering to give symbolic names also works...
static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor_binding( struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_register *reg,
enum vkd3d_shader_resource_type resource_type, bool is_uav_counter)
unsigned int register_space, enum vkd3d_shader_resource_type resource_type, bool is_uav_counter)
That looks like it should be in 5/8.