diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 3547c3c0..47d2bbb5 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -1170,6 +1170,9 @@ static bool vkd3d_dxbc_compiler_get_register_name(char *buffer,const struct vkd3 case VKD3DSPR_COLOROUT: sprintf(buffer, "o%u", reg->idx[0].offset); break; + case VKD3DSPR_THREADID: + sprintf(buffer, "vThreadID"); + break; default: FIXME("Unhandled register %#x.\n", reg->type); sprintf(buffer, "unrecognized_%#x", reg->type); @@ -1556,9 +1559,36 @@ static void vkd3d_dxbc_compiler_emit_store_dst(struct vkd3d_dxbc_compiler *compi vkd3d_dxbc_compiler_emit_store_reg(compiler, &dst->reg, dst->write_mask, val_id); } -static unsigned int vkd3d_dxbc_compiler_get_sysval_component_count( +static enum vkd3d_component_type vkd3d_component_type_for_register(enum vkd3d_shader_register_type reg_type, enum vkd3d_shader_input_sysval_semantic sysval) { + if (reg_type == VKD3DSPR_THREADID) + return VKD3D_TYPE_INT; + + switch (sysval) + { + case VKD3D_SIV_NONE: + case VKD3D_SIV_POSITION: + return VKD3D_TYPE_FLOAT; + case VKD3D_SIV_VERTEX_ID: + return VKD3D_TYPE_INT; + default: + FIXME("Unhandled builtin (register type %#x, semantic %#x).\n", reg_type, sysval); + return VKD3D_TYPE_FLOAT; + } +} + +static unsigned int vkd3d_component_count_for_register(enum vkd3d_shader_register_type reg_type, + enum vkd3d_shader_input_sysval_semantic sysval) +{ + /* The Vulkan spec says: + * + * "The variable decorated with GlobalInvocationId must be declared as a + * three-component vector of 32-bit integers." + */ + if (reg_type == VKD3DSPR_THREADID) + return 3; + switch (sysval) { case VKD3D_SIV_NONE: @@ -1581,13 +1611,14 @@ static unsigned int vkd3d_dxbc_compiler_get_sysval_component_count( */ return 1; default: - FIXME("Unhandled semantic %#x.\n", sysval); + FIXME("Unhandled builtin (register type %#x, semantic %#x).\n", reg_type, sysval); return 0; } } -static void vkd3d_dxbc_compiler_decorate_sysval(struct vkd3d_dxbc_compiler *compiler, - uint32_t target_id, enum vkd3d_shader_input_sysval_semantic sysval) +static void vkd3d_dxbc_compiler_decorate_builtin(struct vkd3d_dxbc_compiler *compiler, + uint32_t target_id, enum vkd3d_shader_register_type reg_type, + enum vkd3d_shader_input_sysval_semantic sysval) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; SpvBuiltIn builtin; @@ -1604,8 +1635,16 @@ static void vkd3d_dxbc_compiler_decorate_sysval(struct vkd3d_dxbc_compiler *comp builtin = SpvBuiltInVertexIndex; break; default: - FIXME("Unhandled semantic %#x.\n", sysval); - return; + if (reg_type == VKD3DSPR_THREADID) + { + builtin = SpvBuiltInGlobalInvocationId; + } + else + { + FIXME("Unhandled builtin (register type %#x, semantic %#x).\n", reg_type, sysval); + return; + } + break; } vkd3d_spirv_build_op_decorate1(builder, target_id, SpvDecorationBuiltIn, builtin); @@ -1614,34 +1653,39 @@ static void vkd3d_dxbc_compiler_decorate_sysval(struct vkd3d_dxbc_compiler *comp static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_dst_param *dst, enum vkd3d_shader_input_sysval_semantic sysval) { - enum vkd3d_component_type component_type = vkd3d_component_type_for_semantic(sysval); unsigned int component_idx, component_count, input_component_count; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - uint32_t val_id, input_id, var_id; + enum vkd3d_component_type component_type; + uint32_t val_id = 0, input_id, var_id; struct vkd3d_symbol reg_symbol; SpvStorageClass storage_class; struct rb_entry *entry = NULL; + bool use_private_var = false; + component_idx = vkd3d_write_mask_get_component_idx(dst->write_mask); component_count = vkd3d_write_mask_component_count(dst->write_mask); + component_type = vkd3d_component_type_for_register(dst->reg.type, sysval); /* vThreadIDInGroupFlattened is declared with no write mask in shader * bytecode generated by fxc. */ if (!dst->write_mask) component_count = 1; - if (!(input_component_count = vkd3d_dxbc_compiler_get_sysval_component_count(sysval))) + if (!(input_component_count = vkd3d_component_count_for_register(dst->reg.type, sysval))) input_component_count = component_count; + assert(component_count <= input_component_count); storage_class = SpvStorageClassInput; input_id = vkd3d_dxbc_compiler_emit_variable(compiler, &builder->global_stream, storage_class, component_type, input_component_count); vkd3d_spirv_add_iface_variable(builder, input_id); - if (sysval) + if (dst->reg.type == VKD3DSPR_THREADID || sysval) { - vkd3d_dxbc_compiler_decorate_sysval(compiler, input_id, sysval); + vkd3d_dxbc_compiler_decorate_builtin(compiler, input_id, dst->reg.type, sysval); + if (component_idx) + FIXME("Unhandled component index %u.\n", component_idx); } else { vkd3d_spirv_build_op_decorate1(builder, input_id, SpvDecorationLocation, dst->reg.idx[0].offset); - component_idx = vkd3d_write_mask_get_component_idx(dst->write_mask); if (component_idx) vkd3d_spirv_build_op_decorate1(builder, input_id, SpvDecorationComponent, component_idx); } @@ -1649,29 +1693,30 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi if (component_type != VKD3D_TYPE_FLOAT) { uint32_t float_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, input_component_count); - assert(component_count == 1 && input_component_count == 1); val_id = vkd3d_spirv_build_op_bitcast(builder, float_type_id, input_id); + + use_private_var = true; } else if (component_count != VKD3D_VEC4_SIZE) { uint32_t type_id = vkd3d_spirv_get_type_id(builder, component_type, input_component_count); val_id = vkd3d_spirv_build_op_load(builder, type_id, input_id, SpvMemoryAccessMaskNone); + + use_private_var = true; } vkd3d_symbol_make_register(®_symbol, &dst->reg); - if ((component_count != VKD3D_VEC4_SIZE || component_type != VKD3D_TYPE_FLOAT) - && !(entry = rb_get(&compiler->symbol_table, ®_symbol))) + if (!use_private_var) + { + var_id = input_id; + } + else if (!(entry = rb_get(&compiler->symbol_table, ®_symbol))) { storage_class = SpvStorageClassPrivate; var_id = vkd3d_dxbc_compiler_emit_variable(compiler, &builder->global_stream, storage_class, VKD3D_TYPE_FLOAT, VKD3D_VEC4_SIZE); } - else - { - var_id = input_id; - } - if (!entry) { reg_symbol.id = var_id; @@ -1681,8 +1726,11 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, &dst->reg); } - if (component_count != VKD3D_VEC4_SIZE || component_type != VKD3D_TYPE_FLOAT) + if (use_private_var) + { + assert(val_id); vkd3d_dxbc_compiler_emit_store_reg(compiler, &dst->reg, dst->write_mask, val_id); + } return input_id; } @@ -1702,7 +1750,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *comp storage_class, VKD3D_TYPE_FLOAT, VKD3D_VEC4_SIZE); vkd3d_spirv_add_iface_variable(builder, id); if (sysval) - vkd3d_dxbc_compiler_decorate_sysval(compiler, id, sysval); + vkd3d_dxbc_compiler_decorate_builtin(compiler, id, dst->reg.type, sysval); else vkd3d_spirv_build_op_decorate1(builder, id, SpvDecorationLocation, reg->idx[0].offset); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index beac8983..e97c23d1 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -829,22 +829,6 @@ bool vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler, struct vkd3d_shader_code *spirv) DECLSPEC_HIDDEN; void vkd3d_dxbc_compiler_destroy(struct vkd3d_dxbc_compiler *compiler) DECLSPEC_HIDDEN; -static inline enum vkd3d_component_type vkd3d_component_type_for_semantic( - enum vkd3d_shader_input_sysval_semantic sysval) -{ - switch (sysval) - { - case VKD3D_SIV_NONE: - case VKD3D_SIV_POSITION: - return VKD3D_TYPE_FLOAT; - case VKD3D_SIV_VERTEX_ID: - return VKD3D_TYPE_INT; - default: - FIXME("Unhandled semantic %#x.\n", sysval); - return VKD3D_TYPE_FLOAT; - } -} - static inline enum vkd3d_component_type vkd3d_component_type_from_data_type( enum vkd3d_data_type data_type) {