Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/HansKristian-Work/vkd3d-proton.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg Lehmann <dadschoorse@gmail.com>2022-10-05 22:14:44 +0300
committerHans-Kristian Arntzen <post@arntzen-software.no>2022-10-06 11:59:56 +0300
commita23862e658a674625759dec80f49646e61ede159 (patch)
tree9b5cfcf7e39bbab9d9301f4b6b207fd25e440c39
parent556c70a9b0e18f3c37b69fa297fbce9869fd3c90 (diff)
vkd3d-shader: Return -1 for FIRSTBIT_(S)HI when we have to.
With the added benefit that vulkan drivers can optimize this to the native dxbc instruction. Signed-off-by: Georg Lehmann <dadschoorse@gmail.com>
-rw-r--r--libs/vkd3d-shader/spirv.c22
-rw-r--r--tests/d3d12_shaders.c2
2 files changed, 18 insertions, 6 deletions
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 74917fa8..319e6cb0 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -7873,11 +7873,11 @@ static enum GLSLstd450 vkd3d_dxbc_compiler_map_ext_glsl_instruction(
static void vkd3d_dxbc_compiler_emit_ext_glsl_instruction(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{
+ uint32_t instr_set_id, type_id, val_id, sub_id, bool_id, cmp_id;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
const struct vkd3d_shader_dst_param *dst = instruction->dst;
const struct vkd3d_shader_src_param *src = instruction->src;
uint32_t src_id[VKD3D_DXBC_MAX_SOURCE_COUNT];
- uint32_t instr_set_id, type_id, val_id;
enum GLSLstd450 glsl_inst;
unsigned int i;
@@ -7904,11 +7904,23 @@ static void vkd3d_dxbc_compiler_emit_ext_glsl_instruction(struct vkd3d_dxbc_comp
if (instruction->handler_idx == VKD3DSIH_FIRSTBIT_HI
|| instruction->handler_idx == VKD3DSIH_FIRSTBIT_SHI)
{
- /* In D3D bits are numbered from the most significant bit. */
- val_id = vkd3d_spirv_build_op_isub(builder, type_id,
- vkd3d_dxbc_compiler_get_constant_uint_vector(compiler, 31,
+ /* In dxbc bits are numbered from the most significant bit.
+ * Emit (findMSB(x) == -1) ? findMSB(x) : 31 - findMSB(x)
+ * because the result needs to stay -1 if it was -1.
+ */
+ sub_id = vkd3d_spirv_build_op_isub(builder, type_id,
+ vkd3d_dxbc_compiler_get_constant_uint_vector(compiler, 31,
vkd3d_write_mask_component_count(dst->write_mask)),
- val_id);
+ val_id);
+
+ bool_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_BOOL,
+ vkd3d_write_mask_component_count(dst->write_mask));
+
+ cmp_id = vkd3d_spirv_build_op_iequal(builder, bool_id, val_id,
+ vkd3d_dxbc_compiler_get_constant_uint_vector(compiler,
+ -1, vkd3d_write_mask_component_count(dst->write_mask)));
+
+ val_id = vkd3d_spirv_build_op_select(builder, type_id, cmp_id, val_id, sub_id);
}
if (glsl_inst == GLSLstd450Fma && (instruction->flags & VKD3DSI_PRECISE_XYZW))
diff --git a/tests/d3d12_shaders.c b/tests/d3d12_shaders.c
index 0f5c5594..7291ab14 100644
--- a/tests/d3d12_shaders.c
+++ b/tests/d3d12_shaders.c
@@ -2677,7 +2677,7 @@ void test_shader_instructions(void)
{&ps_bfrev, {{{0xffff0000}}}, {{0x0000ffff, 0xffff0000, 0x00000000, 0xffff0000}}},
{&ps_bfrev, {{{0xffffffff}}}, {{0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000}}},
- {&ps_bits, {{{ 0, 0}}}, {{ 0, ~0u, ~0u, ~0u}}, false, false, true},
+ {&ps_bits, {{{ 0, 0}}}, {{ 0, ~0u, ~0u, ~0u}}},
{&ps_bits, {{{ ~0u, ~0u}}}, {{32, 0, 0, ~0u}}},
{&ps_bits, {{{0x7fffffff, 0x7fffffff}}}, {{31, 0, 1, 30}}},
{&ps_bits, {{{0x80000000, 0x80000000}}}, {{ 1, 31, 0, 30}}},