Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- tests/d3d12.c | 332 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 332 insertions(+)
diff --git a/tests/d3d12.c b/tests/d3d12.c index f289a10d..55c9ca4d 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -41,6 +41,11 @@ struct ivec4 int x, y, z, w; };
+struct dvec2 +{ + double x, y; +}; + static bool compare_uvec4(const struct uvec4* v1, const struct uvec4 *v2) { return v1->x == v2->x && v1->y == v2->y && v1->z == v2->z && v1->w == v2->w; @@ -651,6 +656,21 @@ static bool is_memory_pool_L1_supported(ID3D12Device *device) return !architecture.UMA; }
+static bool is_shader_float64_supported(ID3D12Device *device) +{ + D3D12_FEATURE_DATA_D3D12_OPTIONS options; + HRESULT hr; + + if (FAILED(hr = ID3D12Device_CheckFeatureSupport(device, + D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options)))) + { + trace("Failed to check feature support, hr %#x.\n", hr); + return false; + } + + return options.DoublePrecisionFloatShaderOps; +} + #define create_cb_root_signature(a, b, c, e) create_cb_root_signature_(__LINE__, a, b, c, e) static ID3D12RootSignature *create_cb_root_signature_(unsigned int line, ID3D12Device *device, unsigned int reg_idx, D3D12_SHADER_VISIBILITY shader_visibility, @@ -7510,6 +7530,7 @@ static void test_shader_instructions(void) D3D12_SHADER_BYTECODE shader; struct test_context context; ID3D12CommandQueue *queue; + bool test_shader_float64; ID3D12Resource *cb; unsigned int i; HRESULT hr; @@ -9054,6 +9075,278 @@ static void test_shader_instructions(void) 0x00100e46, 0x00000001, 0x0100003e, }; static struct named_shader ps_swapc5 = {"swapc5", ps_swapc5_code, sizeof(ps_swapc5_code)}; + static const DWORD ps_dmov_code[] = + { +#if 0 + double2 src0; + + void main(out uint4 dst : SV_Target) + { + asuint(-src0.y, dst.x, dst.y); + asuint(-src0.x, dst.z, dst.w); + } +#endif + 0x43425844, 0x16bd7e63, 0x6b535ab7, 0xb7f182c2, 0x6f3819a8, 0x00000001, 0x000000f0, 0x00000004, + 0x00000030, 0x00000040, 0x00000074, 0x000000e0, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000064, 0x00000050, + 0x00000019, 0x0100186a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, + 0x00000000, 0x02000068, 0x00000001, 0x070000c7, 0x001000f2, 0x00000000, 0x802084e6, 0x00000041, + 0x00000000, 0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x0100003e, + 0x30494653, 0x00000008, 0x00000001, 0x00000000, + }; + static struct named_shader ps_dmov = {"dmov", ps_dmov_code, sizeof(ps_dmov_code)}; + static const DWORD ps_dadd_code[] = + { + /* Also test constant double2 vector. */ +#if 0 + double src0; + + void main(out uint4 dst : SV_Target) + { + double2 a = double2(src0 + 1.0000002433080226l, src0 + 2.000000481493771l); + asuint(a.x, dst.x, dst.y); + asuint(a.y, dst.z, dst.w); + } +#endif + 0x43425844, 0x23e20252, 0xf4d2708e, 0x87956944, 0xc61e7052, 0x00000001, 0x00000100, 0x00000004, + 0x00000030, 0x00000040, 0x00000074, 0x000000f0, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000074, 0x00000050, + 0x0000001d, 0x0100186a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, + 0x00000000, 0x02000068, 0x00000001, 0x0b0000bf, 0x001000f2, 0x00000000, 0x00208446, 0x00000000, + 0x00000000, 0x00005002, 0x41500000, 0x3ff00000, 0x40a00000, 0x40000000, 0x05000036, 0x001020f2, + 0x00000000, 0x00100e46, 0x00000000, 0x0100003e, 0x30494653, 0x00000008, 0x00000001, 0x00000000, + }; + static struct named_shader ps_dadd = {"dadd", ps_dadd_code, sizeof(ps_dadd_code)}; + static const DWORD ps_dmin_dmax_code[] = + { +#if 0 + double2 src0; + + void main(out uint4 dst : SV_Target) + { + asuint(min(src0.x, src0.y), dst.x, dst.y); + asuint(max(src0.x, src0.y), dst.z, dst.w); + } +#endif + 0x43425844, 0x6f8b547e, 0x3552757c, 0x92a81fa1, 0x00990b21, 0x00000001, 0x00000130, 0x00000004, + 0x00000030, 0x00000040, 0x00000074, 0x00000120, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000a4, 0x00000050, + 0x00000029, 0x0100186a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, + 0x00000000, 0x02000068, 0x00000001, 0x090000c1, 0x00100032, 0x00000000, 0x00208ee6, 0x00000000, + 0x00000000, 0x00208446, 0x00000000, 0x00000000, 0x05000036, 0x00102032, 0x00000000, 0x00100046, + 0x00000000, 0x090000c0, 0x00100032, 0x00000000, 0x00208ee6, 0x00000000, 0x00000000, 0x00208446, + 0x00000000, 0x00000000, 0x05000036, 0x001020c2, 0x00000000, 0x00100406, 0x00000000, 0x0100003e, + 0x30494653, 0x00000008, 0x00000001, 0x00000000, + }; + static struct named_shader ps_dmin_dmax = {"dmin_dmax", ps_dmin_dmax_code, sizeof(ps_dmin_dmax_code)}; + static const DWORD ps_dmovc_code[] = + { +#if 0 + double src0; + + void main(out uint4 dst : SV_Target) + { + asuint(src0 > 1.0 ? src0 : 4.5, dst.x, dst.y); + dst.zw = 0; + } +#endif + 0x43425844, 0x43c017c3, 0x117edcff, 0xd44d42dc, 0xb3affdd5, 0x00000001, 0x00000154, 0x00000004, + 0x00000030, 0x00000040, 0x00000074, 0x00000144, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000c8, 0x00000050, + 0x00000032, 0x0100186a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, + 0x00000000, 0x02000068, 0x00000001, 0x0b0000c5, 0x00100012, 0x00000000, 0x00005002, 0x00000000, + 0x3ff00000, 0x00000000, 0x00000000, 0x00208446, 0x00000000, 0x00000000, 0x0d0000c8, 0x00100032, + 0x00000000, 0x00100006, 0x00000000, 0x00208446, 0x00000000, 0x00000000, 0x00005002, 0x00000000, + 0x40120000, 0x00000000, 0x00000000, 0x05000036, 0x00102032, 0x00000000, 0x00100046, 0x00000000, + 0x08000036, 0x001020c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x0100003e, 0x30494653, 0x00000008, 0x00000001, 0x00000000, + }; + static struct named_shader ps_dmovc = {"dmovc", ps_dmovc_code, sizeof(ps_dmovc_code)}; + static const DWORD ps_dmodifier_code[] = + { + /* Already tested negation in the dmov test. */ +#if 0 + double src0; + + void main(out uint4 dst : SV_Target) + { + asuint(abs(src0), dst.x, dst.y); + asuint(saturate(src0) + 1.5, dst.z, dst.w); + } +#endif + 0x43425844, 0x15bb537e, 0x47ef3ae3, 0xba88acf7, 0x0b3624e0, 0x00000001, 0x00000144, 0x00000004, + 0x00000030, 0x00000040, 0x00000074, 0x00000134, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000b8, 0x00000050, + 0x0000002e, 0x0100186a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, + 0x00000000, 0x02000068, 0x00000001, 0x060020c7, 0x00100032, 0x00000000, 0x00208446, 0x00000000, + 0x00000000, 0x0a0000bf, 0x00100032, 0x00000000, 0x00100446, 0x00000000, 0x00005002, 0x00000000, + 0x3ff80000, 0x00000000, 0x00000000, 0x05000036, 0x001020c2, 0x00000000, 0x00100406, 0x00000000, + 0x070000c7, 0x00100032, 0x00000000, 0x80208446, 0x00000081, 0x00000000, 0x00000000, 0x05000036, + 0x00102032, 0x00000000, 0x00100046, 0x00000000, 0x0100003e, 0x30494653, 0x00000008, 0x00000001, + 0x00000000, + }; + static struct named_shader ps_dmodifier = {"dmodifier", ps_dmodifier_code, sizeof(ps_dmodifier_code)}; + static const DWORD ps_deq_code[] = + { +#if 0 + double2 src0; + + void main(out uint4 dst : SV_Target) + { + dst = (uint4)0; + if (src0.x == src0.y) + dst.x = 0xffffffff; + } +#endif + 0x43425844, 0x24c9cee6, 0xd38c521f, 0xcde7c8b6, 0xc173a8e3, 0x00000001, 0x00000118, 0x00000004, + 0x00000030, 0x00000040, 0x00000074, 0x00000108, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000008c, 0x00000050, + 0x00000023, 0x0100186a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, + 0x00000000, 0x02000068, 0x00000001, 0x090000c3, 0x00100012, 0x00000000, 0x00208ee6, 0x00000000, + 0x00000000, 0x00208446, 0x00000000, 0x00000000, 0x05000036, 0x00102012, 0x00000000, 0x0010000a, + 0x00000000, 0x08000036, 0x001020e2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x0100003e, 0x30494653, 0x00000008, 0x00000001, 0x00000000, + }; + static struct named_shader ps_deq = {"deq", ps_deq_code, sizeof(ps_deq_code)}; + static const DWORD ps_dne_code[] = + { +#if 0 + double2 src0; + + void main(out uint4 dst : SV_Target) + { + dst = (uint4)0; + if (src0.x != src0.y) + dst.x = 0xffffffff; + } +#endif + 0x43425844, 0x99700929, 0x3b743000, 0xdfc89958, 0xfc2b89ab, 0x00000001, 0x00000118, 0x00000004, + 0x00000030, 0x00000040, 0x00000074, 0x00000108, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000008c, 0x00000050, + 0x00000023, 0x0100186a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, + 0x00000000, 0x02000068, 0x00000001, 0x090000c6, 0x00100012, 0x00000000, 0x00208ee6, 0x00000000, + 0x00000000, 0x00208446, 0x00000000, 0x00000000, 0x05000036, 0x00102012, 0x00000000, 0x0010000a, + 0x00000000, 0x08000036, 0x001020e2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x0100003e, 0x30494653, 0x00000008, 0x00000001, 0x00000000, + }; + static struct named_shader ps_dne = {"dne", ps_dne_code, sizeof(ps_dne_code)}; + static const DWORD ps_dtou_code[] = + { +#if 0 + double src0; + + void main(out uint4 dst : SV_Target) + { + dst = uint4(src0, -src0, 0, 0); + } +#endif + 0x43425844, 0x6ca74abd, 0xe970e02d, 0xa65b35db, 0xd2f58586, 0x00000001, 0x00000128, 0x00000004, + 0x00000030, 0x00000040, 0x00000074, 0x00000118, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000009c, 0x00000050, + 0x00000027, 0x0102186a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, + 0x00000000, 0x02000068, 0x00000001, 0x060000d7, 0x00100012, 0x00000000, 0x00208446, 0x00000000, + 0x00000000, 0x070000d7, 0x00100022, 0x00000000, 0x80208446, 0x00000041, 0x00000000, 0x00000000, + 0x05000036, 0x00102032, 0x00000000, 0x00100046, 0x00000000, 0x08000036, 0x001020c2, 0x00000000, + 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0100003e, 0x30494653, 0x00000008, + 0x00000021, 0x00000000, + }; + static struct named_shader ps_dtou = {"dtou", ps_dtou_code, sizeof(ps_dtou_code)}; + static const DWORD ps_dtoi_code[] = + { +#if 0 + double src0; + + void main(out uint4 dst : SV_Target) + { + dst = int4(src0, -src0, 0, 0); + } +#endif + 0x43425844, 0x38d82727, 0x8666b36c, 0x91954b7e, 0xf376163a, 0x00000001, 0x00000128, 0x00000004, + 0x00000030, 0x00000040, 0x00000074, 0x00000118, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000009c, 0x00000050, + 0x00000027, 0x0102186a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, + 0x00000000, 0x02000068, 0x00000001, 0x060000d6, 0x00100012, 0x00000000, 0x00208446, 0x00000000, + 0x00000000, 0x070000d6, 0x00100022, 0x00000000, 0x80208446, 0x00000041, 0x00000000, 0x00000000, + 0x05000036, 0x00102032, 0x00000000, 0x00100046, 0x00000000, 0x08000036, 0x001020c2, 0x00000000, + 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0100003e, 0x30494653, 0x00000008, + 0x00000021, 0x00000000, + }; + static const struct named_shader ps_dtoi = {"dtoi", ps_dtoi_code, sizeof(ps_dtoi_code)}; + static const DWORD ps_ftod_code[] = + { +#if 0 + float2 src0; + + void main(out uint4 dst : SV_Target) + { + double2 a = double2(src0.x, src0.y); + asuint(a.x, dst.x, dst.y); + asuint(a.y, dst.z, dst.w); + } +#endif + 0x43425844, 0xad43f67d, 0x04a1aba0, 0x253502f1, 0x2c9c1735, 0x00000001, 0x000000ec, 0x00000004, + 0x00000030, 0x00000040, 0x00000074, 0x000000dc, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000060, 0x00000050, + 0x00000018, 0x0100186a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, + 0x00000000, 0x02000068, 0x00000001, 0x060000ca, 0x001000f2, 0x00000000, 0x00208046, 0x00000000, + 0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x0100003e, 0x30494653, + 0x00000008, 0x00000001, 0x00000000, + }; + static struct named_shader ps_ftod = {"ftod", ps_ftod_code, sizeof(ps_ftod_code)}; + static const DWORD ps_ddiv_code[] = + { +#if 0 + double2 src0; + + void main(out uint4 dst : SV_Target) + { + asuint(src0.x / src0.y, dst.x, dst.y); + dst.zw = 0; + } +#endif + 0x43425844, 0x1c8a3236, 0x400a6b3b, 0x5554bf56, 0x4ff834b8, 0x00000001, 0x00000118, 0x00000004, + 0x00000030, 0x00000040, 0x00000074, 0x00000108, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000008c, 0x00000050, + 0x00000023, 0x0102186a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, + 0x00000000, 0x02000068, 0x00000001, 0x090000d2, 0x00100032, 0x00000000, 0x00208446, 0x00000000, + 0x00000000, 0x00208ee6, 0x00000000, 0x00000000, 0x05000036, 0x00102032, 0x00000000, 0x00100046, + 0x00000000, 0x08000036, 0x001020c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x0100003e, 0x30494653, 0x00000008, 0x00000021, 0x00000000, + }; + static const struct named_shader ps_ddiv = {"ddiv", ps_ddiv_code, sizeof(ps_ddiv_code)}; + static const DWORD ps_drcp_code[] = + { +#if 0 + double2 src0; + + void main(out uint4 dst : SV_Target) + { + double2 a = rcp(src0); + asuint(a.x, dst.x, dst.y); + asuint(a.y, dst.z, dst.w); + } +#endif + 0x43425844, 0xdcbd25ba, 0x2d5cccb9, 0x84ed8028, 0x3d62632a, 0x00000001, 0x000000ec, 0x00000004, + 0x00000030, 0x00000040, 0x00000074, 0x000000dc, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000060, 0x00000050, + 0x00000018, 0x0102186a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, + 0x00000000, 0x02000068, 0x00000001, 0x060000d4, 0x001000f2, 0x00000000, 0x00208e46, 0x00000000, + 0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x0100003e, 0x30494653, + 0x00000008, 0x00000021, 0x00000000, + }; + static struct named_shader ps_drcp = {"drcp", ps_drcp_code, sizeof(ps_drcp_code)}; static const struct { const struct named_shader *ps; @@ -9290,13 +9583,21 @@ static void test_shader_instructions(void) struct vec4 src1; struct vec4 src2; } f; + struct + { + struct dvec2 src0; + struct dvec2 src1; + struct dvec2 src2; + } d; } input; union { struct uvec4 u; struct ivec4 i; struct vec4 f; + struct dvec2 d; } output; + bool is_float64; bool skip_on_warp; } uint_tests[] = @@ -9526,6 +9827,29 @@ static void test_shader_instructions(void) {&ps_movc, {{{0, 1, 1, 0}, {1, 2, 3, 4}, {5, 6, 7, 8}}}, {{5, 2, 3, 8}}}, {&ps_movc, {{{1, 1, 1, 1}, {1, 2, 3, 4}, {5, 6, 7, 8}}}, {{1, 2, 3, 4}}},
+ {&ps_dmov, {.d = {{2.5 + 1.0e-9, -3.5 - 1.0e-9}}}, {.d = {3.5 + 1.0e-9, -2.5 - 1.0e-9}}, true}, + {&ps_dadd, {.d = {{2.5, 0.0}}}, {.d = {2.5 + 1.0000002433080226, 2.5 + 2.000000481493771}}, true}, + {&ps_dmin_dmax, {.d = {{-1.0, 1.0}}}, {.d = {-1.0, 1.0}}, true}, + {&ps_dmovc, {.d = {{0.5, 0.0}}}, {.d = {4.5}}, true}, + {&ps_dmovc, {.d = {{1.5, 0.0}}}, {.d = {1.5}}, true}, + {&ps_dmodifier, {.d = {{1.5, 0.0}}}, {.d = {1.5f, 2.5f}}, true}, + {&ps_dmodifier, {.d = {{-1.5, 0.0}}}, {.d = {1.5f, 1.5f}}, true}, + {&ps_deq, {.d = {{0.0, 0.0}}}, {{0xffffffff}}, true}, + {&ps_deq, {.d = {{1.0, 0.0}}}, {{0x00000000}}, true}, + {&ps_dne, {.d = {{0.0, 0.0}}}, {{0x00000000}}, true}, + {&ps_dne, {.d = {{1.0, 0.0}}}, {{0xffffffff}}, true}, + {&ps_dtou, {.d = {{ -NAN}}}, {{ 0, 0 }}, true}, + {&ps_dtou, {.d = {{ NAN}}}, {{ 0, 0 }}, true}, + {&ps_dtou, {.d = {{-INFINITY}}}, {{ 0, ~0u}}, true}, + {&ps_dtou, {.d = {{ INFINITY}}}, {{~0u, 0 }}, true}, + {&ps_dtou, {.d = {{ -1.0}}}, {{ 0, 1 }}, true}, + {&ps_dtou, {.d = {{ 1.0}}}, {{ 1, 0 }}, true}, + {&ps_dtoi, {.d = {{ 1.0}}}, {.i = {1, -1}}, true}, + {&ps_ftod, {.f = {{-2.5f, 2.5f}}}, {.d = {-2.5, 2.5}}, true}, + {&ps_ddiv, {.d = {{ 2.0, 4.0}}}, {.d = {0.5}}, true}, + {&ps_ddiv, {.d = {{ 2.0, -4.0}}}, {.d = {-0.5}}, true}, + {&ps_drcp, {.d = {{ 2.0, -0.5}}}, {.d = {0.5, -2.0}}, true}, + { &ps_swapc0, {{{0, 0, 0, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}}, @@ -9818,6 +10142,8 @@ static void test_shader_instructions(void) return; command_list = context.list; queue = context.queue; + /* Float64 instructions are not supported and pipeline state creation will fail. */ + test_shader_float64 = is_shader_float64_supported(context.device) && vkd3d_test_platform_is_windows();
context.root_signature = create_cb_root_signature(context.device, 0, D3D12_SHADER_VISIBILITY_PIXEL, D3D12_ROOT_SIGNATURE_FLAG_NONE); @@ -9888,6 +10214,12 @@ static void test_shader_instructions(void) continue; }
+ if (uint_tests[i].is_float64 && !test_shader_float64) + { + skip("Skipping shader '%s' float64 test.\n", uint_tests[i].ps->name); + continue; + } + if (current_ps != uint_tests[i].ps) { if (context.pipeline_state)
Based on vkd3d-proton patches. From: Joshua Ashton joshua@froggi.es
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- include/vkd3d_shader.h | 2 ++ libs/vkd3d-shader/dxbc.c | 3 +++ libs/vkd3d-shader/spirv.c | 10 +++++++--- libs/vkd3d-shader/vkd3d_shader_private.h | 14 ++++++++++++++ 4 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index 03225d37..0e011343 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -1177,6 +1177,8 @@ enum vkd3d_shader_component_type VKD3D_SHADER_COMPONENT_FLOAT = 0x3, /** Boolean. */ VKD3D_SHADER_COMPONENT_BOOL = 0x4, + /** 64-bit IEEE floating-point. */ + VKD3D_SHADER_COMPONENT_DOUBLE = 0x5,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPONENT_TYPE), }; diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index d2cf87e3..cd90354a 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -1001,6 +1001,7 @@ static void shader_sm5_read_sync(struct vkd3d_shader_instruction *ins, * R -> VKD3D_DATA_RESOURCE * S -> VKD3D_DATA_SAMPLER * U -> VKD3D_DATA_UAV + * d -> VKD3D_DATA_DOUBLE */ static const struct vkd3d_sm4_opcode_info opcode_table[] = { @@ -1335,6 +1336,8 @@ static enum vkd3d_data_type map_data_type(char t) return VKD3D_DATA_SAMPLER; case 'U': return VKD3D_DATA_UAV; + case 'd': + return VKD3D_DATA_DOUBLE; default: ERR("Invalid data type '%c'.\n", t); return VKD3D_DATA_FLOAT; diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 0e75b0ae..ca523cb5 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -1714,6 +1714,8 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, case VKD3D_SHADER_COMPONENT_BOOL: return vkd3d_spirv_get_op_type_bool(builder); break; + case VKD3D_SHADER_COMPONENT_DOUBLE: + return vkd3d_spirv_get_op_type_float(builder, 64); default: FIXME("Unhandled component type %#x.\n", component_type); return 0; @@ -2680,7 +2682,7 @@ static uint32_t vkd3d_dxbc_compiler_get_type_id_for_reg(struct vkd3d_dxbc_compil
return vkd3d_spirv_get_type_id(builder, vkd3d_component_type_from_data_type(reg->data_type), - vkd3d_write_mask_component_count(write_mask)); + vkd3d_write_mask_component_count_typed(write_mask, reg->data_type)); }
static uint32_t vkd3d_dxbc_compiler_get_type_id_for_dst(struct vkd3d_dxbc_compiler *compiler, @@ -3343,7 +3345,8 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_reg(struct vkd3d_dxbc_compiler *co
if (component_type != reg_info.component_type) { - type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); + type_id = vkd3d_spirv_get_type_id(builder, component_type, + vkd3d_write_mask_component_count_typed(write_mask, reg->data_type)); val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); }
@@ -3532,7 +3535,8 @@ static void vkd3d_dxbc_compiler_emit_store_reg(struct vkd3d_dxbc_compiler *compi component_type = vkd3d_component_type_from_data_type(reg->data_type); if (component_type != reg_info.component_type) { - unsigned int component_count = vkd3d_write_mask_component_count(write_mask); + unsigned int component_count = vkd3d_write_mask_component_count_typed(write_mask, + vkd3d_data_type_from_component_type(reg_info.component_type)); type_id = vkd3d_spirv_get_type_id(builder, reg_info.component_type, component_count); val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); component_type = reg_info.component_type; diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 6d756e40..03bc2e1b 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -965,6 +965,8 @@ static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_ty return VKD3D_SHADER_COMPONENT_UINT; case VKD3D_DATA_INT: return VKD3D_SHADER_COMPONENT_INT; + case VKD3D_DATA_DOUBLE: + return VKD3D_SHADER_COMPONENT_DOUBLE; default: FIXME("Unhandled data type %#x.\n", data_type); return VKD3D_SHADER_COMPONENT_UINT; @@ -982,6 +984,8 @@ static inline enum vkd3d_data_type vkd3d_data_type_from_component_type( return VKD3D_DATA_UINT; case VKD3D_SHADER_COMPONENT_INT: return VKD3D_DATA_INT; + case VKD3D_SHADER_COMPONENT_DOUBLE: + return VKD3D_DATA_DOUBLE; default: FIXME("Unhandled component type %#x.\n", component_type); return VKD3D_DATA_FLOAT; @@ -1010,6 +1014,16 @@ static inline unsigned int vkd3d_write_mask_component_count(DWORD write_mask) return count; }
+static inline unsigned int vkd3d_write_mask_component_count_typed(DWORD write_mask, + enum vkd3d_data_type data_type) +{ + unsigned int component_count = vkd3d_write_mask_component_count(write_mask); + if (data_type == VKD3D_DATA_DOUBLE) + component_count /= 2u; + assert(component_count != 0); + return component_count; +} + static inline unsigned int vkd3d_write_mask_from_component_count(unsigned int component_count) { assert(component_count <= VKD3D_VEC4_SIZE);
On Mon, 14 Jun 2021 at 05:27, Conor McCarthy cmccarthy@codeweavers.com wrote:
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index d2cf87e3..cd90354a 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -1001,6 +1001,7 @@ static void shader_sm5_read_sync(struct vkd3d_shader_instruction *ins,
- R -> VKD3D_DATA_RESOURCE
- S -> VKD3D_DATA_SAMPLER
- U -> VKD3D_DATA_UAV
*/
- d -> VKD3D_DATA_DOUBLE
static const struct vkd3d_sm4_opcode_info opcode_table[] = { @@ -1335,6 +1336,8 @@ static enum vkd3d_data_type map_data_type(char t) return VKD3D_DATA_SAMPLER; case 'U': return VKD3D_DATA_UAV;
case 'd':
return VKD3D_DATA_DOUBLE; default: ERR("Invalid data type '%c'.\n", t); return VKD3D_DATA_FLOAT;
This is unused in this patch.
+static inline unsigned int vkd3d_write_mask_component_count_typed(DWORD write_mask,
enum vkd3d_data_type data_type)
+{
- unsigned int component_count = vkd3d_write_mask_component_count(write_mask);
- if (data_type == VKD3D_DATA_DOUBLE)
component_count /= 2u;
- assert(component_count != 0);
- return component_count;
+}
Having both vkd3d_write_mask_component_count() and vkd3d_write_mask_component_count_typed() isn't very nice. If we're going to handle this in the backend, it would seem best to consistently pass type information to vkd3d_write_mask_component_count().
Alternatively, how hard would it be to fix things up in the frontend so that we would never have to deal with this here?
Based on vkd3d-proton patches. From: Joshua Ashton joshua@froggi.es
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- libs/vkd3d-shader/dxbc.c | 15 +++-- libs/vkd3d-shader/spirv.c | 75 +++++++++++++++++++----- libs/vkd3d-shader/trace.c | 43 +++++++++++++- libs/vkd3d-shader/vkd3d_shader_private.h | 4 ++ 4 files changed, 116 insertions(+), 21 deletions(-)
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index cd90354a..782aed13 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -329,6 +329,7 @@ enum vkd3d_sm4_register_type VKD3D_SM4_RT_OUTPUT = 0x02, VKD3D_SM4_RT_INDEXABLE_TEMP = 0x03, VKD3D_SM4_RT_IMMCONST = 0x04, + VKD3D_SM4_RT_IMMCONST64 = 0x05, VKD3D_SM4_RT_SAMPLER = 0x06, VKD3D_SM4_RT_RESOURCE = 0x07, VKD3D_SM4_RT_CONSTBUFFER = 0x08, @@ -1244,7 +1245,7 @@ static const enum vkd3d_shader_register_type register_type_table[] = /* VKD3D_SM4_RT_OUTPUT */ VKD3DSPR_OUTPUT, /* VKD3D_SM4_RT_INDEXABLE_TEMP */ VKD3DSPR_IDXTEMP, /* VKD3D_SM4_RT_IMMCONST */ VKD3DSPR_IMMCONST, - /* UNKNOWN */ ~0u, + /* VKD3D_SM4_RT_IMMCONST64 */ VKD3DSPR_IMMCONST64, /* VKD3D_SM4_RT_SAMPLER */ VKD3DSPR_SAMPLER, /* VKD3D_SM4_RT_RESOURCE */ VKD3DSPR_RESOURCE, /* VKD3D_SM4_RT_CONSTBUFFER */ VKD3DSPR_CONSTBUFFER, @@ -1618,21 +1619,23 @@ static bool shader_sm4_read_param(struct vkd3d_sm4_data *priv, const DWORD **ptr return false; }
- if (register_type == VKD3D_SM4_RT_IMMCONST) + if (register_type == VKD3D_SM4_RT_IMMCONST || register_type == VKD3D_SM4_RT_IMMCONST64) { enum vkd3d_sm4_dimension dimension = (token & VKD3D_SM4_DIMENSION_MASK) >> VKD3D_SM4_DIMENSION_SHIFT; + unsigned int dword_count;
switch (dimension) { case VKD3D_SM4_DIMENSION_SCALAR: param->immconst_type = VKD3D_IMMCONST_SCALAR; - if (end - *ptr < 1) + dword_count = 1 + (register_type == VKD3D_SM4_RT_IMMCONST64); + if (end - *ptr < dword_count) { WARN("Invalid ptr %p, end %p.\n", *ptr, end); return false; } - memcpy(param->u.immconst_uint, *ptr, 1 * sizeof(DWORD)); - *ptr += 1; + memcpy(param->u.immconst_uint, *ptr, dword_count * sizeof(DWORD)); + *ptr += dword_count; break;
case VKD3D_SM4_DIMENSION_VEC4: @@ -1707,7 +1710,7 @@ static bool shader_sm4_read_src_param(struct vkd3d_sm4_data *priv, const DWORD * return false; }
- if (src_param->reg.type == VKD3DSPR_IMMCONST) + if (src_param->reg.type == VKD3DSPR_IMMCONST || src_param->reg.type == VKD3DSPR_IMMCONST64) { src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE; } diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index ca523cb5..bdbd688d 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -1118,19 +1118,18 @@ static uint32_t vkd3d_spirv_get_op_type_pointer(struct vkd3d_spirv_builder *buil vkd3d_spirv_build_op_type_pointer); }
-/* Types larger than 32-bits are not supported. */ static uint32_t vkd3d_spirv_build_op_constant(struct vkd3d_spirv_builder *builder, - uint32_t result_type, uint32_t value) + uint32_t result_type, const uint32_t *values, unsigned int value_count) { - return vkd3d_spirv_build_op_tr1(builder, &builder->global_stream, - SpvOpConstant, result_type, value); + return vkd3d_spirv_build_op_trv(builder, &builder->global_stream, + SpvOpConstant, result_type, values, value_count); }
static uint32_t vkd3d_spirv_get_op_constant(struct vkd3d_spirv_builder *builder, - uint32_t result_type, uint32_t value) + uint32_t result_type, const uint32_t *values, unsigned int value_count) { - return vkd3d_spirv_build_once2(builder, SpvOpConstant, result_type, value, - vkd3d_spirv_build_op_constant); + return vkd3d_spirv_build_once1v(builder, SpvOpConstant, result_type, values, + value_count, vkd3d_spirv_build_op_constant); }
static uint32_t vkd3d_spirv_build_op_constant_composite(struct vkd3d_spirv_builder *builder, @@ -2608,18 +2607,35 @@ static void vkd3d_dxbc_compiler_put_symbol(struct vkd3d_dxbc_compiler *compiler, } }
+static unsigned int vkd3d_spirv_get_component_value_count(enum vkd3d_shader_component_type component_type) +{ + switch (component_type) + { + case VKD3D_SHADER_COMPONENT_UINT: + case VKD3D_SHADER_COMPONENT_INT: + case VKD3D_SHADER_COMPONENT_FLOAT: + return 1; + case VKD3D_SHADER_COMPONENT_DOUBLE: + return 2; + default: + ERR("Invalid shader component type %u.\n", component_type); + return 1; + } +} + static uint32_t vkd3d_dxbc_compiler_get_constant(struct vkd3d_dxbc_compiler *compiler, enum vkd3d_shader_component_type component_type, unsigned int component_count, const uint32_t *values) { uint32_t type_id, scalar_type_id, component_ids[VKD3D_VEC4_SIZE]; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - unsigned int i; + unsigned int i, value_count;
assert(0 < component_count && component_count <= VKD3D_VEC4_SIZE); type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count);
switch (component_type) { + case VKD3D_SHADER_COMPONENT_DOUBLE: case VKD3D_SHADER_COMPONENT_UINT: case VKD3D_SHADER_COMPONENT_INT: case VKD3D_SHADER_COMPONENT_FLOAT: @@ -2629,15 +2645,17 @@ static uint32_t vkd3d_dxbc_compiler_get_constant(struct vkd3d_dxbc_compiler *com return vkd3d_spirv_build_op_undef(builder, &builder->global_stream, type_id); }
+ value_count = vkd3d_spirv_get_component_value_count(component_type); + if (component_count == 1) { - return vkd3d_spirv_get_op_constant(builder, type_id, *values); + return vkd3d_spirv_get_op_constant(builder, type_id, values, value_count); } else { scalar_type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); for (i = 0; i < component_count; ++i) - component_ids[i] = vkd3d_spirv_get_op_constant(builder, scalar_type_id, values[i]); + component_ids[i] = vkd3d_spirv_get_op_constant(builder, scalar_type_id, &values[i * value_count], value_count); return vkd3d_spirv_get_op_constant_composite(builder, type_id, component_ids, component_count); } } @@ -3011,7 +3029,7 @@ static bool vkd3d_dxbc_compiler_get_register_info(const struct vkd3d_dxbc_compil struct vkd3d_symbol reg_symbol, *symbol; struct rb_entry *entry;
- assert(reg->type != VKD3DSPR_IMMCONST); + assert(reg->type != VKD3DSPR_IMMCONST && reg->type != VKD3DSPR_IMMCONST64);
if (reg->type == VKD3DSPR_TEMP) { @@ -3255,6 +3273,33 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_constant(struct vkd3d_dxbc_compile vkd3d_component_type_from_data_type(reg->data_type), component_count, values); }
+static uint32_t vkd3d_dxbc_compiler_emit_load_constant64(struct vkd3d_dxbc_compiler *compiler, + const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask) +{ + unsigned int component_count = vkd3d_write_mask_component_count_typed(write_mask, VKD3D_DATA_DOUBLE); + uint64_t values[2] = {0}; + unsigned int i, j; + + assert(reg->type == VKD3DSPR_IMMCONST64); + + if (reg->immconst_type == VKD3D_IMMCONST_SCALAR) + { + for (i = 0; i < component_count; ++i) + values[i] = reg->u.immconst_uint64[0]; + } + else + { + for (i = 0, j = 0; i < VKD3D_DVEC2_SIZE; ++i) + { + if (write_mask & (VKD3DSP_WRITEMASK_0 << (i * 2))) + values[j++] = reg->u.immconst_uint64[vkd3d_swizzle_get_component(swizzle, i * 2) / 2u]; + } + } + + return vkd3d_dxbc_compiler_get_constant(compiler, + vkd3d_component_type_from_data_type(reg->data_type), component_count, (const uint32_t*)values); +} + static uint32_t vkd3d_dxbc_compiler_emit_load_scalar(struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask, const struct vkd3d_shader_register_info *reg_info) @@ -3265,7 +3310,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_scalar(struct vkd3d_dxbc_compiler enum vkd3d_shader_component_type component_type; unsigned int skipped_component_mask;
- assert(reg->type != VKD3DSPR_IMMCONST); + assert(reg->type != VKD3DSPR_IMMCONST && reg->type != VKD3DSPR_IMMCONST64); assert(vkd3d_write_mask_component_count(write_mask) == 1);
component_idx = vkd3d_write_mask_get_component_idx(write_mask); @@ -3314,6 +3359,8 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_reg(struct vkd3d_dxbc_compiler *co
if (reg->type == VKD3DSPR_IMMCONST) return vkd3d_dxbc_compiler_emit_load_constant(compiler, reg, swizzle, write_mask); + else if (reg->type == VKD3DSPR_IMMCONST64) + return vkd3d_dxbc_compiler_emit_load_constant64(compiler, reg, swizzle, write_mask);
component_count = vkd3d_write_mask_component_count(write_mask); component_type = vkd3d_component_type_from_data_type(reg->data_type); @@ -3526,7 +3573,7 @@ static void vkd3d_dxbc_compiler_emit_store_reg(struct vkd3d_dxbc_compiler *compi struct vkd3d_shader_register_info reg_info; uint32_t type_id;
- assert(reg->type != VKD3DSPR_IMMCONST); + assert(reg->type != VKD3DSPR_IMMCONST && reg->type != VKD3DSPR_IMMCONST64);
if (!vkd3d_dxbc_compiler_get_register_info(compiler, reg, ®_info)) return; @@ -6637,7 +6684,7 @@ static void vkd3d_dxbc_compiler_emit_mov(struct vkd3d_dxbc_compiler *compiler, uint32_t components[VKD3D_VEC4_SIZE]; unsigned int i, component_count;
- if (src->reg.type == VKD3DSPR_IMMCONST || dst->modifiers || src->modifiers) + if (src->reg.type == VKD3DSPR_IMMCONST || src->reg.type == VKD3DSPR_IMMCONST64 || dst->modifiers || src->modifiers) goto general_implementation;
vkd3d_dxbc_compiler_get_register_info(compiler, &dst->reg, &dst_reg_info); diff --git a/libs/vkd3d-shader/trace.c b/libs/vkd3d-shader/trace.c index 4e355118..859c428c 100644 --- a/libs/vkd3d-shader/trace.c +++ b/libs/vkd3d-shader/trace.c @@ -869,6 +869,10 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const shader_addline(buffer, "l"); break;
+ case VKD3DSPR_IMMCONST64: + shader_addline(buffer, "d"); + break; + case VKD3DSPR_CONSTBUFFER: shader_addline(buffer, "cb"); break; @@ -1038,6 +1042,42 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const } shader_addline(buffer, ")"); } + else if (reg->type == VKD3DSPR_IMMCONST64) + { + shader_addline(buffer, "("); + switch (reg->immconst_type) + { + case VKD3D_IMMCONST_SCALAR: + switch (reg->data_type) + { + case VKD3D_DATA_DOUBLE: + shader_addline(buffer, "%f", reg->u.immconst_double[0]); + break; + default: + shader_addline(buffer, "<unhandled data type %#x>", reg->data_type); + break; + } + break; + + case VKD3D_IMMCONST_VEC4: + switch (reg->data_type) + { + case VKD3D_DATA_DOUBLE: + shader_addline(buffer, "%f, %f", + reg->u.immconst_double[0], reg->u.immconst_double[1]); + break; + default: + shader_addline(buffer, "<unhandled data type %#x>", reg->data_type); + break; + } + break; + + default: + shader_addline(buffer, "<unhandled immconst_type %#x>", reg->immconst_type); + break; + } + shader_addline(buffer, ")"); + } else if (reg->type != VKD3DSPR_RASTOUT && reg->type != VKD3DSPR_MISCTYPE && reg->type != VKD3DSPR_NULL) @@ -1148,7 +1188,8 @@ static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler, default: shader_addline(buffer, "_unknown_modifier(%#x)", src_modifier); }
- if (param->reg.type != VKD3DSPR_IMMCONST && param->reg.type != VKD3DSPR_SAMPLER) + if (param->reg.type != VKD3DSPR_IMMCONST && param->reg.type != VKD3DSPR_IMMCONST64 + && param->reg.type != VKD3DSPR_SAMPLER) { static const char swizzle_chars[] = "xyzw"; DWORD swizzle_x = (swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(0)) & VKD3D_SHADER_SWIZZLE_MASK; diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 03bc2e1b..f56ca183 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -58,6 +58,7 @@ #include <string.h>
#define VKD3D_VEC4_SIZE 4 +#define VKD3D_DVEC2_SIZE 2
enum vkd3d_shader_error { @@ -381,6 +382,7 @@ enum vkd3d_shader_register_type VKD3DSPR_LABEL = 18, VKD3DSPR_PREDICATE = 19, VKD3DSPR_IMMCONST, + VKD3DSPR_IMMCONST64, VKD3DSPR_CONSTBUFFER, VKD3DSPR_IMMCONSTBUFFER, VKD3DSPR_PRIMID, @@ -611,6 +613,8 @@ struct vkd3d_shader_register { DWORD immconst_uint[VKD3D_VEC4_SIZE]; float immconst_float[VKD3D_VEC4_SIZE]; + uint64_t immconst_uint64[VKD3D_DVEC2_SIZE]; + double immconst_double[VKD3D_DVEC2_SIZE]; unsigned fp_body_idx; } u; };
On Mon, 14 Jun 2021 at 05:27, Conor McCarthy cmccarthy@codeweavers.com wrote:
+static unsigned int vkd3d_spirv_get_component_value_count(enum vkd3d_shader_component_type component_type) +{
- switch (component_type)
- {
case VKD3D_SHADER_COMPONENT_UINT:
case VKD3D_SHADER_COMPONENT_INT:
case VKD3D_SHADER_COMPONENT_FLOAT:
return 1;
case VKD3D_SHADER_COMPONENT_DOUBLE:
return 2;
default:
ERR("Invalid shader component type %u.\n", component_type);
return 1;
- }
+}
Given that this is only used by vkd3d_dxbc_compiler_get_constant(), it seems tempting to just integrate this with the existing switch there.
static uint32_t vkd3d_dxbc_compiler_get_constant(struct vkd3d_dxbc_compiler *compiler, enum vkd3d_shader_component_type component_type, unsigned int component_count, const uint32_t *values) { uint32_t type_id, scalar_type_id, component_ids[VKD3D_VEC4_SIZE]; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
- unsigned int i;
unsigned int i, value_count;
assert(0 < component_count && component_count <= VKD3D_VEC4_SIZE); type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count);
switch (component_type) {
case VKD3D_SHADER_COMPONENT_DOUBLE: case VKD3D_SHADER_COMPONENT_UINT: case VKD3D_SHADER_COMPONENT_INT: case VKD3D_SHADER_COMPONENT_FLOAT:
@@ -2629,15 +2645,17 @@ static uint32_t vkd3d_dxbc_compiler_get_constant(struct vkd3d_dxbc_compiler *com return vkd3d_spirv_build_op_undef(builder, &builder->global_stream, type_id); }
- value_count = vkd3d_spirv_get_component_value_count(component_type);
- if (component_count == 1) {
return vkd3d_spirv_get_op_constant(builder, type_id, *values);
} else { scalar_type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); for (i = 0; i < component_count; ++i)return vkd3d_spirv_get_op_constant(builder, type_id, values, value_count);
component_ids[i] = vkd3d_spirv_get_op_constant(builder, scalar_type_id, values[i]);
}component_ids[i] = vkd3d_spirv_get_op_constant(builder, scalar_type_id, &values[i * value_count], value_count); return vkd3d_spirv_get_op_constant_composite(builder, type_id, component_ids, component_count);
}
[...]
+static uint32_t vkd3d_dxbc_compiler_emit_load_constant64(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask)
+{
- unsigned int component_count = vkd3d_write_mask_component_count_typed(write_mask, VKD3D_DATA_DOUBLE);
- uint64_t values[2] = {0};
- unsigned int i, j;
- assert(reg->type == VKD3DSPR_IMMCONST64);
- if (reg->immconst_type == VKD3D_IMMCONST_SCALAR)
- {
for (i = 0; i < component_count; ++i)
values[i] = reg->u.immconst_uint64[0];
- }
- else
- {
for (i = 0, j = 0; i < VKD3D_DVEC2_SIZE; ++i)
{
if (write_mask & (VKD3DSP_WRITEMASK_0 << (i * 2)))
values[j++] = reg->u.immconst_uint64[vkd3d_swizzle_get_component(swizzle, i * 2) / 2u];
}
- }
- return vkd3d_dxbc_compiler_get_constant(compiler,
vkd3d_component_type_from_data_type(reg->data_type), component_count, (const uint32_t*)values);
+}
That's pretty ugly though; it would seem preferable to introduce a vkd3d_dxbc_compiler_get_constant64() that takes uint64_t values, and build on top of that.
Note that the changes in trace.c and dxbc.c don't depend on the changes in spirv.c, and this patch could be split.
@@ -1038,6 +1042,42 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const } shader_addline(buffer, ")"); }
- else if (reg->type == VKD3DSPR_IMMCONST64)
- {
shader_addline(buffer, "(");
switch (reg->immconst_type)
{
case VKD3D_IMMCONST_SCALAR:
switch (reg->data_type)
{
case VKD3D_DATA_DOUBLE:
shader_addline(buffer, "%f", reg->u.immconst_double[0]);
break;
default:
shader_addline(buffer, "<unhandled data type %#x>", reg->data_type);
break;
}
break;
case VKD3D_IMMCONST_VEC4:
switch (reg->data_type)
{
case VKD3D_DATA_DOUBLE:
shader_addline(buffer, "%f, %f",
reg->u.immconst_double[0], reg->u.immconst_double[1]);
break;
default:
shader_addline(buffer, "<unhandled data type %#x>", reg->data_type);
break;
}
break;
This should use a helper along the lines of shader_print_float_literal(). In particular, literals should be printed with "compiler->colours.literal", and %f isn't necessarily sufficient to accurately represent doubles.
You'll need a "compiler->colours.reset" before the "(" above.
Based on vkd3d-proton patches. From: Joshua Ashton joshua@froggi.es
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- libs/vkd3d-shader/spirv.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index bdbd688d..d5152a38 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -2686,11 +2686,20 @@ static uint32_t vkd3d_dxbc_compiler_get_constant_uint_vector(struct vkd3d_dxbc_c }
static uint32_t vkd3d_dxbc_compiler_get_constant_float_vector(struct vkd3d_dxbc_compiler *compiler, - float value, unsigned int component_count) + float value, unsigned int component_count, enum vkd3d_data_type data_type) { - const float values[] = {value, value, value, value}; - return vkd3d_dxbc_compiler_get_constant(compiler, VKD3D_SHADER_COMPONENT_FLOAT, - component_count, (const uint32_t *)values); + if (data_type == VKD3D_DATA_DOUBLE) + { + const double values[] = {value, value}; + return vkd3d_dxbc_compiler_get_constant(compiler, VKD3D_SHADER_COMPONENT_DOUBLE, + component_count, (const uint32_t *)values); + } + else + { + const float values[] = {value, value, value, value}; + return vkd3d_dxbc_compiler_get_constant(compiler, VKD3D_SHADER_COMPONENT_FLOAT, + component_count, (const uint32_t *)values); + } }
static uint32_t vkd3d_dxbc_compiler_get_type_id_for_reg(struct vkd3d_dxbc_compiler *compiler, @@ -3418,15 +3427,12 @@ static void vkd3d_dxbc_compiler_emit_execution_mode1(struct vkd3d_dxbc_compiler static uint32_t vkd3d_dxbc_compiler_emit_abs(struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_register *reg, DWORD write_mask, uint32_t val_id) { - unsigned int component_count = vkd3d_write_mask_component_count(write_mask); struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id;
- if (reg->data_type == VKD3D_DATA_FLOAT) - { - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); + type_id = vkd3d_dxbc_compiler_get_type_id_for_reg(compiler, reg, write_mask); + if (reg->data_type == VKD3D_DATA_FLOAT || reg->data_type == VKD3D_DATA_DOUBLE) return vkd3d_spirv_build_op_glsl_std450_fabs(builder, type_id, val_id); - }
FIXME("Unhandled data type %#x.\n", reg->data_type); return val_id; @@ -3439,7 +3445,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_neg(struct vkd3d_dxbc_compiler *compile uint32_t type_id;
type_id = vkd3d_dxbc_compiler_get_type_id_for_reg(compiler, reg, write_mask); - if (reg->data_type == VKD3D_DATA_FLOAT) + if (reg->data_type == VKD3D_DATA_FLOAT || reg->data_type == VKD3D_DATA_DOUBLE) return vkd3d_spirv_build_op_fnegate(builder, type_id, val_id); else if (reg->data_type == VKD3D_DATA_INT) return vkd3d_spirv_build_op_snegate(builder, type_id, val_id); @@ -3596,15 +3602,15 @@ static void vkd3d_dxbc_compiler_emit_store_reg(struct vkd3d_dxbc_compiler *compi static uint32_t vkd3d_dxbc_compiler_emit_sat(struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_register *reg, DWORD write_mask, uint32_t val_id) { - unsigned int component_count = vkd3d_write_mask_component_count(write_mask); + unsigned int component_count = vkd3d_write_mask_component_count_typed(write_mask, reg->data_type); struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id, zero_id, one_id;
- zero_id = vkd3d_dxbc_compiler_get_constant_float_vector(compiler, 0.0f, component_count); - one_id = vkd3d_dxbc_compiler_get_constant_float_vector(compiler, 1.0f, component_count); + zero_id = vkd3d_dxbc_compiler_get_constant_float_vector(compiler, 0.0f, component_count, reg->data_type); + one_id = vkd3d_dxbc_compiler_get_constant_float_vector(compiler, 1.0f, component_count, reg->data_type);
type_id = vkd3d_dxbc_compiler_get_type_id_for_reg(compiler, reg, write_mask); - if (reg->data_type == VKD3D_DATA_FLOAT) + if (reg->data_type == VKD3D_DATA_FLOAT || reg->data_type == VKD3D_DATA_DOUBLE) return vkd3d_spirv_build_op_glsl_std450_nclamp(builder, type_id, val_id, zero_id, one_id);
FIXME("Unhandled data type %#x.\n", reg->data_type);
On Mon, 14 Jun 2021 at 05:27, Conor McCarthy cmccarthy@codeweavers.com wrote:
libs/vkd3d-shader/spirv.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-)
There's an existing usage of vkd3d_dxbc_compiler_get_constant_float_vector() in vkd3d_dxbc_compiler_emit_rcp() as well.
The neg/abs/sat changes are three separate changes.
static uint32_t vkd3d_dxbc_compiler_get_constant_float_vector(struct vkd3d_dxbc_compiler *compiler,
float value, unsigned int component_count)
float value, unsigned int component_count, enum vkd3d_data_type data_type)
{
- const float values[] = {value, value, value, value};
- return vkd3d_dxbc_compiler_get_constant(compiler, VKD3D_SHADER_COMPONENT_FLOAT,
component_count, (const uint32_t *)values);
- if (data_type == VKD3D_DATA_DOUBLE)
- {
const double values[] = {value, value};
return vkd3d_dxbc_compiler_get_constant(compiler, VKD3D_SHADER_COMPONENT_DOUBLE,
component_count, (const uint32_t *)values);
- }
- else
- {
const float values[] = {value, value, value, value};
return vkd3d_dxbc_compiler_get_constant(compiler, VKD3D_SHADER_COMPONENT_FLOAT,
component_count, (const uint32_t *)values);
- }
}
I think it would be preferable to just introduce vkd3d_dxbc_compiler_get_constant_double_vector(), instead of hacking double support into vkd3d_dxbc_compiler_get_constant_float_vector().
Based on vkd3d-proton patches. From: Joshua Ashton joshua@froggi.es
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- libs/vkd3d-shader/spirv.c | 11 +++++++++++ libs/vkd3d-shader/trace.c | 2 ++ libs/vkd3d-shader/vkd3d_shader_private.h | 4 +++- 3 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index d5152a38..c2826445 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -335,6 +335,7 @@ struct vkd3d_spirv_builder uint64_t capability_mask; uint64_t capability_draw_parameters : 1; uint64_t capability_demote_to_helper_invocation : 1; + uint64_t capability_float_64 : 1; uint32_t ext_instr_set_glsl_450; uint32_t invocation_count; SpvExecutionModel execution_model; @@ -385,6 +386,10 @@ static void vkd3d_spirv_enable_capability(struct vkd3d_spirv_builder *builder, { builder->capability_demote_to_helper_invocation = 1; } + else if (cap == SpvCapabilityFloat64) + { + builder->capability_float_64 = 1; + } else { FIXME("Unhandled capability %#x.\n", cap); @@ -5187,6 +5192,12 @@ static void vkd3d_dxbc_compiler_emit_dcl_global_flags(struct vkd3d_dxbc_compiler flags &= ~VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL; }
+ if (flags & (VKD3DSGF_ENABLE_DOUBLE_PRECISION_FLOAT_OPS | VKD3DSGF_ENABLE_11_1_DOUBLE_EXTENSIONS)) + { + vkd3d_spirv_enable_capability(&compiler->spirv_builder, SpvCapabilityFloat64); + flags &= ~(VKD3DSGF_ENABLE_DOUBLE_PRECISION_FLOAT_OPS | VKD3DSGF_ENABLE_11_1_DOUBLE_EXTENSIONS); + } + if (flags & ~(VKD3DSGF_REFACTORING_ALLOWED | VKD3DSGF_ENABLE_RAW_AND_STRUCTURED_BUFFERS)) FIXME("Unhandled global flags %#x.\n", flags); else diff --git a/libs/vkd3d-shader/trace.c b/libs/vkd3d-shader/trace.c index 859c428c..dd12b896 100644 --- a/libs/vkd3d-shader/trace.c +++ b/libs/vkd3d-shader/trace.c @@ -368,6 +368,8 @@ static void shader_dump_global_flags(struct vkd3d_d3d_asm_compiler *compiler, ui {VKD3DSGF_ENABLE_RAW_AND_STRUCTURED_BUFFERS, "enableRawAndStructuredBuffers"}, {VKD3DSGF_ENABLE_MINIMUM_PRECISION, "enableMinimumPrecision"}, {VKD3DSGF_SKIP_OPTIMIZATION, "skipOptimization"}, + {VKD3DSGF_ENABLE_DOUBLE_PRECISION_FLOAT_OPS, "enableDoublePrecisionFloatOps"}, + {VKD3DSGF_ENABLE_11_1_DOUBLE_EXTENSIONS, "enable11_1DoubleExtensions"}, };
for (i = 0; i < ARRAY_SIZE(global_flag_info); ++i) diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index f56ca183..f7a3c60e 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -485,10 +485,12 @@ enum vkd3d_shader_interpolation_mode enum vkd3d_shader_global_flags { VKD3DSGF_REFACTORING_ALLOWED = 0x01, + VKD3DSGF_ENABLE_DOUBLE_PRECISION_FLOAT_OPS = 0x02, VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL = 0x04, VKD3DSGF_ENABLE_RAW_AND_STRUCTURED_BUFFERS = 0x08, VKD3DSGF_SKIP_OPTIMIZATION = 0x10, - VKD3DSGF_ENABLE_MINIMUM_PRECISION = 0x20 + VKD3DSGF_ENABLE_MINIMUM_PRECISION = 0x20, + VKD3DSGF_ENABLE_11_1_DOUBLE_EXTENSIONS = 0x40, };
enum vkd3d_shader_sync_flags
On Mon, 14 Jun 2021 at 05:27, Conor McCarthy cmccarthy@codeweavers.com wrote:
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index d5152a38..c2826445 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -335,6 +335,7 @@ struct vkd3d_spirv_builder uint64_t capability_mask; uint64_t capability_draw_parameters : 1; uint64_t capability_demote_to_helper_invocation : 1;
- uint64_t capability_float_64 : 1; uint32_t ext_instr_set_glsl_450; uint32_t invocation_count; SpvExecutionModel execution_model;
@@ -385,6 +386,10 @@ static void vkd3d_spirv_enable_capability(struct vkd3d_spirv_builder *builder, { builder->capability_demote_to_helper_invocation = 1; }
- else if (cap == SpvCapabilityFloat64)
- {
builder->capability_float_64 = 1;
- }
This is dead code; SpvCapabilityFloat64 is one of the capabilities < 64, so we'll use the "capability_mask" field, and never set "capability_float_64". If it did get set, we'd need a corresponding vkd3d_spirv_build_op_capability() call in vkd3d_spirv_compile_module().
diff --git a/libs/vkd3d-shader/trace.c b/libs/vkd3d-shader/trace.c index 859c428c..dd12b896 100644 --- a/libs/vkd3d-shader/trace.c +++ b/libs/vkd3d-shader/trace.c @@ -368,6 +368,8 @@ static void shader_dump_global_flags(struct vkd3d_d3d_asm_compiler *compiler, ui {VKD3DSGF_ENABLE_RAW_AND_STRUCTURED_BUFFERS, "enableRawAndStructuredBuffers"}, {VKD3DSGF_ENABLE_MINIMUM_PRECISION, "enableMinimumPrecision"}, {VKD3DSGF_SKIP_OPTIMIZATION, "skipOptimization"},
{VKD3DSGF_ENABLE_DOUBLE_PRECISION_FLOAT_OPS, "enableDoublePrecisionFloatOps"},
{VKD3DSGF_ENABLE_11_1_DOUBLE_EXTENSIONS, "enable11_1DoubleExtensions"},
};
for (i = 0; i < ARRAY_SIZE(global_flag_info); ++i)
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index f56ca183..f7a3c60e 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -485,10 +485,12 @@ enum vkd3d_shader_interpolation_mode enum vkd3d_shader_global_flags { VKD3DSGF_REFACTORING_ALLOWED = 0x01,
- VKD3DSGF_ENABLE_DOUBLE_PRECISION_FLOAT_OPS = 0x02, VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL = 0x04, VKD3DSGF_ENABLE_RAW_AND_STRUCTURED_BUFFERS = 0x08, VKD3DSGF_SKIP_OPTIMIZATION = 0x10,
- VKD3DSGF_ENABLE_MINIMUM_PRECISION = 0x20
- VKD3DSGF_ENABLE_MINIMUM_PRECISION = 0x20,
- VKD3DSGF_ENABLE_11_1_DOUBLE_EXTENSIONS = 0x40,
};
It ends up being not so bad in this case, but as a matter of principle, this patch does three separate things:
- Disassembler support for "enableDoublePrecisionFloatOps". - Disassembler support for "enable11_1DoubleExtensions". - Enabling SpvCapabilityFloat64 when either of those is set.
On 6/15/21 10:53 PM, Henri Verbeet wrote:
On Mon, 14 Jun 2021 at 05:27, Conor McCarthy cmccarthy@codeweavers.com wrote:
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index d5152a38..c2826445 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -335,6 +335,7 @@ struct vkd3d_spirv_builder uint64_t capability_mask; uint64_t capability_draw_parameters : 1; uint64_t capability_demote_to_helper_invocation : 1;
- uint64_t capability_float_64 : 1; uint32_t ext_instr_set_glsl_450; uint32_t invocation_count; SpvExecutionModel execution_model;
@@ -385,6 +386,10 @@ static void vkd3d_spirv_enable_capability(struct vkd3d_spirv_builder *builder, { builder->capability_demote_to_helper_invocation = 1; }
- else if (cap == SpvCapabilityFloat64)
- {
builder->capability_float_64 = 1;
- }
This is dead code; SpvCapabilityFloat64 is one of the capabilities < 64, so we'll use the "capability_mask" field, and never set "capability_float_64". If it did get set, we'd need a corresponding vkd3d_spirv_build_op_capability() call in vkd3d_spirv_compile_module().
Despite this patch having my name on it, it was not submitted by me and has been changed from what I wrote without telling me.
This defect does not exist in the version I made for use in vkd3d-proton.
- Joshie 🐸✨
diff --git a/libs/vkd3d-shader/trace.c b/libs/vkd3d-shader/trace.c index 859c428c..dd12b896 100644 --- a/libs/vkd3d-shader/trace.c +++ b/libs/vkd3d-shader/trace.c @@ -368,6 +368,8 @@ static void shader_dump_global_flags(struct vkd3d_d3d_asm_compiler *compiler, ui {VKD3DSGF_ENABLE_RAW_AND_STRUCTURED_BUFFERS, "enableRawAndStructuredBuffers"}, {VKD3DSGF_ENABLE_MINIMUM_PRECISION, "enableMinimumPrecision"}, {VKD3DSGF_SKIP_OPTIMIZATION, "skipOptimization"},
{VKD3DSGF_ENABLE_DOUBLE_PRECISION_FLOAT_OPS, "enableDoublePrecisionFloatOps"},
{VKD3DSGF_ENABLE_11_1_DOUBLE_EXTENSIONS, "enable11_1DoubleExtensions"}, }; for (i = 0; i < ARRAY_SIZE(global_flag_info); ++i)
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index f56ca183..f7a3c60e 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -485,10 +485,12 @@ enum vkd3d_shader_interpolation_mode enum vkd3d_shader_global_flags { VKD3DSGF_REFACTORING_ALLOWED = 0x01,
- VKD3DSGF_ENABLE_DOUBLE_PRECISION_FLOAT_OPS = 0x02, VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL = 0x04, VKD3DSGF_ENABLE_RAW_AND_STRUCTURED_BUFFERS = 0x08, VKD3DSGF_SKIP_OPTIMIZATION = 0x10,
- VKD3DSGF_ENABLE_MINIMUM_PRECISION = 0x20
- VKD3DSGF_ENABLE_MINIMUM_PRECISION = 0x20,
- VKD3DSGF_ENABLE_11_1_DOUBLE_EXTENSIONS = 0x40, };
It ends up being not so bad in this case, but as a matter of principle, this patch does three separate things:
- Disassembler support for "enableDoublePrecisionFloatOps".
- Disassembler support for "enable11_1DoubleExtensions".
- Enabling SpvCapabilityFloat64 when either of those is set.
Yes, it's based on your work but I modified it to fit how capabilities are handled in vkd3d, and unfortunately added a bug. I mentioned your name to acknowledge that you did the original work. Sorry if that's unclear in the description.
Conor
On Wed, Jun 16, 2021 at 5:21 PM Joshua Ashton joshua@froggi.es wrote:
Despite this patch having my name on it, it was not submitted by me and has been changed from what I wrote without telling me.
This defect does not exist in the version I made for use in vkd3d-proton.
- Joshie 🐸✨
From: Joshua Ashton joshua@froggi.es Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- libs/vkd3d-shader/dxbc.c | 12 ++++++++++++ libs/vkd3d-shader/spirv.c | 23 +++++++++++++++++++---- libs/vkd3d-shader/trace.c | 6 ++++++ libs/vkd3d-shader/vkd3d_shader_private.h | 7 +++++++ 4 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index 782aed13..d23dfcad 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -310,9 +310,15 @@ enum vkd3d_sm4_opcode VKD3D_SM5_OP_IMM_ATOMIC_UMAX = 0xbc, VKD3D_SM5_OP_IMM_ATOMIC_UMIN = 0xbd, VKD3D_SM5_OP_SYNC = 0xbe, + VKD3D_SM5_OP_DADD = 0xbf, + VKD3D_SM5_OP_DMUL = 0xc2, + VKD3D_SM5_OP_DMOV = 0xc7, + VKD3D_SM5_OP_DMOVC = 0xc8, VKD3D_SM5_OP_EVAL_SAMPLE_INDEX = 0xcc, VKD3D_SM5_OP_EVAL_CENTROID = 0xcd, VKD3D_SM5_OP_DCL_GS_INSTANCES = 0xce, + VKD3D_SM5_OP_DDIV = 0xd2, + VKD3D_SM5_OP_DRCP = 0xd4, };
enum vkd3d_sm4_instruction_modifier @@ -1236,6 +1242,12 @@ static const struct vkd3d_sm4_opcode_info opcode_table[] = {VKD3D_SM5_OP_EVAL_CENTROID, VKD3DSIH_EVAL_CENTROID, "f", "f"}, {VKD3D_SM5_OP_DCL_GS_INSTANCES, VKD3DSIH_DCL_GS_INSTANCES, "", "", shader_sm4_read_declaration_count}, + {VKD3D_SM5_OP_DADD, VKD3DSIH_DADD, "d", "dd"}, + {VKD3D_SM5_OP_DMUL, VKD3DSIH_DMUL, "d", "dd"}, + {VKD3D_SM5_OP_DMOV, VKD3DSIH_DMOV, "d", "d"}, + {VKD3D_SM5_OP_DMOVC, VKD3DSIH_DMOVC, "d", "udd"}, + {VKD3D_SM5_OP_DDIV, VKD3DSIH_DDIV, "d", "dd"}, + {VKD3D_SM5_OP_DRCP, VKD3DSIH_DRCP, "d", "d"}, };
static const enum vkd3d_shader_register_type register_type_table[] = diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index c2826445..f4cfd80d 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -6543,10 +6543,12 @@ static SpvOp vkd3d_dxbc_compiler_map_alu_instruction(const struct vkd3d_shader_i } alu_ops[] = { + {VKD3DSIH_DADD, SpvOpFAdd}, {VKD3DSIH_ADD, SpvOpFAdd}, {VKD3DSIH_AND, SpvOpBitwiseAnd}, {VKD3DSIH_BFREV, SpvOpBitReverse}, {VKD3DSIH_COUNTBITS, SpvOpBitCount}, + {VKD3DSIH_DDIV, SpvOpFDiv}, {VKD3DSIH_DIV, SpvOpFDiv}, {VKD3DSIH_FTOI, SpvOpConvertFToS}, {VKD3DSIH_FTOU, SpvOpConvertFToU}, @@ -6555,6 +6557,7 @@ static SpvOp vkd3d_dxbc_compiler_map_alu_instruction(const struct vkd3d_shader_i {VKD3DSIH_ISHL, SpvOpShiftLeftLogical}, {VKD3DSIH_ISHR, SpvOpShiftRightArithmetic}, {VKD3DSIH_ITOF, SpvOpConvertSToF}, + {VKD3DSIH_DMUL, SpvOpFMul}, {VKD3DSIH_MUL, SpvOpFMul}, {VKD3DSIH_NOT, SpvOpNot}, {VKD3DSIH_OR, SpvOpBitwiseOr}, @@ -6758,14 +6761,20 @@ static void vkd3d_dxbc_compiler_emit_movc(struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_dst_param *dst = instruction->dst; const struct vkd3d_shader_src_param *src = instruction->src; uint32_t condition_id, src1_id, src2_id, type_id, val_id; + DWORD condition_mask = dst->write_mask; unsigned int component_count;
- condition_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], dst->write_mask); + if (instruction->handler_idx == VKD3DSIH_DMOVC) + condition_mask = (condition_mask & VKD3DSP_WRITEMASK_0) | ((condition_mask & VKD3DSP_WRITEMASK_2) >> 1); + + condition_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], condition_mask); src1_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[1], dst->write_mask); src2_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[2], dst->write_mask);
component_count = vkd3d_write_mask_component_count(dst->write_mask); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); + component_count = vkd3d_write_mask_component_count_typed(dst->write_mask, dst->reg.data_type); + type_id = vkd3d_dxbc_compiler_get_type_id_for_dst(compiler, dst);
condition_id = vkd3d_dxbc_compiler_emit_int_to_bool(compiler, VKD3D_SHADER_CONDITIONAL_OP_NZ, component_count, condition_id); @@ -6850,12 +6859,12 @@ static void vkd3d_dxbc_compiler_emit_rcp(struct vkd3d_dxbc_compiler *compiler, uint32_t type_id, src_id, val_id; unsigned int component_count;
- component_count = vkd3d_write_mask_component_count(dst->write_mask); + component_count = vkd3d_write_mask_component_count_typed(dst->write_mask, dst->reg.data_type); type_id = vkd3d_dxbc_compiler_get_type_id_for_dst(compiler, dst);
src_id = vkd3d_dxbc_compiler_emit_load_src(compiler, src, dst->write_mask); - val_id = vkd3d_spirv_build_op_fdiv(builder, type_id, - vkd3d_dxbc_compiler_get_constant_float_vector(compiler, 1.0f, component_count), src_id); + val_id = vkd3d_spirv_build_op_fdiv(builder, type_id, vkd3d_dxbc_compiler_get_constant_float_vector(compiler, + 1.0f, component_count, src->reg.data_type), src_id); vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, val_id); }
@@ -9240,19 +9249,23 @@ int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, case VKD3DSIH_HS_JOIN_PHASE: vkd3d_dxbc_compiler_enter_shader_phase(compiler, instruction); break; + case VKD3DSIH_DMOV: case VKD3DSIH_MOV: vkd3d_dxbc_compiler_emit_mov(compiler, instruction); break; + case VKD3DSIH_DMOVC: case VKD3DSIH_MOVC: vkd3d_dxbc_compiler_emit_movc(compiler, instruction); break; case VKD3DSIH_SWAPC: vkd3d_dxbc_compiler_emit_swapc(compiler, instruction); break; + case VKD3DSIH_DADD: case VKD3DSIH_ADD: case VKD3DSIH_AND: case VKD3DSIH_BFREV: case VKD3DSIH_COUNTBITS: + case VKD3DSIH_DDIV: case VKD3DSIH_DIV: case VKD3DSIH_FTOI: case VKD3DSIH_FTOU: @@ -9261,6 +9274,7 @@ int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, case VKD3DSIH_ISHL: case VKD3DSIH_ISHR: case VKD3DSIH_ITOF: + case VKD3DSIH_DMUL: case VKD3DSIH_MUL: case VKD3DSIH_NOT: case VKD3DSIH_OR: @@ -9295,6 +9309,7 @@ int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, case VKD3DSIH_DP2: vkd3d_dxbc_compiler_emit_dot(compiler, instruction); break; + case VKD3DSIH_DRCP: case VKD3DSIH_RCP: vkd3d_dxbc_compiler_emit_rcp(compiler, instruction); break; diff --git a/libs/vkd3d-shader/trace.c b/libs/vkd3d-shader/trace.c index dd12b896..3812b573 100644 --- a/libs/vkd3d-shader/trace.c +++ b/libs/vkd3d-shader/trace.c @@ -268,6 +268,12 @@ static const char * const shader_opcode_names[] = /* VKD3DSIH_USHR */ "ushr", /* VKD3DSIH_UTOF */ "utof", /* VKD3DSIH_XOR */ "xor", + /* VKD3DSIH_DADD */ "dadd", + /* VKD3DSIH_DMUL */ "dmul", + /* VKD3DSIH_DMOV */ "dmov", + /* VKD3DSIH_DMOVC */ "dmovc", + /* VKD3DSIH_DDIV */ "ddiv", + /* VKD3DSIH_DRCP */ "drcp", };
static const struct diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index f7a3c60e..d0fd25ee 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -354,6 +354,13 @@ enum vkd3d_shader_opcode VKD3DSIH_UTOF, VKD3DSIH_XOR,
+ VKD3DSIH_DADD, + VKD3DSIH_DMUL, + VKD3DSIH_DMOV, + VKD3DSIH_DMOVC, + VKD3DSIH_DDIV, + VKD3DSIH_DRCP, + VKD3DSIH_INVALID, };
On Mon, 14 Jun 2021 at 05:27, Conor McCarthy cmccarthy@codeweavers.com wrote:
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index 782aed13..d23dfcad 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -310,9 +310,15 @@ enum vkd3d_sm4_opcode VKD3D_SM5_OP_IMM_ATOMIC_UMAX = 0xbc, VKD3D_SM5_OP_IMM_ATOMIC_UMIN = 0xbd, VKD3D_SM5_OP_SYNC = 0xbe,
- VKD3D_SM5_OP_DADD = 0xbf,
- VKD3D_SM5_OP_DMUL = 0xc2,
- VKD3D_SM5_OP_DMOV = 0xc7,
- VKD3D_SM5_OP_DMOVC = 0xc8, VKD3D_SM5_OP_EVAL_SAMPLE_INDEX = 0xcc, VKD3D_SM5_OP_EVAL_CENTROID = 0xcd, VKD3D_SM5_OP_DCL_GS_INSTANCES = 0xce,
- VKD3D_SM5_OP_DDIV = 0xd2,
- VKD3D_SM5_OP_DRCP = 0xd4,
};
One instruction per patch, please.
@@ -1236,6 +1242,12 @@ static const struct vkd3d_sm4_opcode_info opcode_table[] = {VKD3D_SM5_OP_EVAL_CENTROID, VKD3DSIH_EVAL_CENTROID, "f", "f"}, {VKD3D_SM5_OP_DCL_GS_INSTANCES, VKD3DSIH_DCL_GS_INSTANCES, "", "", shader_sm4_read_declaration_count},
- {VKD3D_SM5_OP_DADD, VKD3DSIH_DADD, "d", "dd"},
- {VKD3D_SM5_OP_DMUL, VKD3DSIH_DMUL, "d", "dd"},
- {VKD3D_SM5_OP_DMOV, VKD3DSIH_DMOV, "d", "d"},
- {VKD3D_SM5_OP_DMOVC, VKD3DSIH_DMOVC, "d", "udd"},
- {VKD3D_SM5_OP_DDIV, VKD3DSIH_DDIV, "d", "dd"},
- {VKD3D_SM5_OP_DRCP, VKD3DSIH_DRCP, "d", "d"},
};
This table is ordered by vkd3d_sm4_opcode value, please keep it that way.
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index f7a3c60e..d0fd25ee 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -354,6 +354,13 @@ enum vkd3d_shader_opcode VKD3DSIH_UTOF, VKD3DSIH_XOR,
- VKD3DSIH_DADD,
- VKD3DSIH_DMUL,
- VKD3DSIH_DMOV,
- VKD3DSIH_DMOVC,
- VKD3DSIH_DDIV,
- VKD3DSIH_DRCP,
- VKD3DSIH_INVALID,
};
The elements in this enumeration are ordered, please keep them that way.
From: Joshua Ashton joshua@froggi.es Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- libs/vkd3d-shader/dxbc.c | 14 +++++++ libs/vkd3d-shader/spirv.c | 51 +++++++++++++++++++++++- libs/vkd3d-shader/trace.c | 7 ++++ libs/vkd3d-shader/vkd3d_shader_private.h | 7 ++++ 4 files changed, 77 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index d23dfcad..1a79da6d 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -311,13 +311,20 @@ enum vkd3d_sm4_opcode VKD3D_SM5_OP_IMM_ATOMIC_UMIN = 0xbd, VKD3D_SM5_OP_SYNC = 0xbe, VKD3D_SM5_OP_DADD = 0xbf, + VKD3D_SM5_OP_DMAX = 0xc0, + VKD3D_SM5_OP_DMIN = 0xc1, VKD3D_SM5_OP_DMUL = 0xc2, + VKD3D_SM5_OP_DEQ = 0xc3, + VKD3D_SM5_OP_DGE = 0xc4, + VKD3D_SM5_OP_DLT = 0xc5, + VKD3D_SM5_OP_DNE = 0xc6, VKD3D_SM5_OP_DMOV = 0xc7, VKD3D_SM5_OP_DMOVC = 0xc8, VKD3D_SM5_OP_EVAL_SAMPLE_INDEX = 0xcc, VKD3D_SM5_OP_EVAL_CENTROID = 0xcd, VKD3D_SM5_OP_DCL_GS_INSTANCES = 0xce, VKD3D_SM5_OP_DDIV = 0xd2, + VKD3D_SM5_OP_DFMA = 0xd3, VKD3D_SM5_OP_DRCP = 0xd4, };
@@ -1243,10 +1250,17 @@ static const struct vkd3d_sm4_opcode_info opcode_table[] = {VKD3D_SM5_OP_DCL_GS_INSTANCES, VKD3DSIH_DCL_GS_INSTANCES, "", "", shader_sm4_read_declaration_count}, {VKD3D_SM5_OP_DADD, VKD3DSIH_DADD, "d", "dd"}, + {VKD3D_SM5_OP_DMAX, VKD3DSIH_DMAX, "d", "dd"}, + {VKD3D_SM5_OP_DMIN, VKD3DSIH_DMIN, "d", "dd"}, {VKD3D_SM5_OP_DMUL, VKD3DSIH_DMUL, "d", "dd"}, + {VKD3D_SM5_OP_DEQ, VKD3DSIH_DEQ, "u", "dd"}, + {VKD3D_SM5_OP_DGE, VKD3DSIH_DGE, "u", "dd"}, + {VKD3D_SM5_OP_DLT, VKD3DSIH_DLT, "u", "dd"}, + {VKD3D_SM5_OP_DNE, VKD3DSIH_DNE, "u", "dd"}, {VKD3D_SM5_OP_DMOV, VKD3DSIH_DMOV, "d", "d"}, {VKD3D_SM5_OP_DMOVC, VKD3DSIH_DMOVC, "d", "udd"}, {VKD3D_SM5_OP_DDIV, VKD3DSIH_DDIV, "d", "dd"}, + {VKD3D_SM5_OP_DFMA, VKD3DSIH_DFMA, "d", "ddd"}, {VKD3D_SM5_OP_DRCP, VKD3DSIH_DRCP, "d", "d"}, };
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index f4cfd80d..6be1fda5 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -6628,8 +6628,11 @@ static enum GLSLstd450 vkd3d_dxbc_compiler_map_ext_glsl_instruction( {VKD3DSIH_IMAX, GLSLstd450SMax}, {VKD3DSIH_IMIN, GLSLstd450SMin}, {VKD3DSIH_LOG, GLSLstd450Log2}, + {VKD3DSIH_DFMA, GLSLstd450Fma}, {VKD3DSIH_MAD, GLSLstd450Fma}, + {VKD3DSIH_DMAX, GLSLstd450NMax}, {VKD3DSIH_MAX, GLSLstd450NMax}, + {VKD3DSIH_DMIN, GLSLstd450NMin}, {VKD3DSIH_MIN, GLSLstd450NMin}, {VKD3DSIH_ROUND_NE, GLSLstd450RoundEven}, {VKD3DSIH_ROUND_NI, GLSLstd450Floor}, @@ -7124,6 +7127,37 @@ static void vkd3d_dxbc_compiler_emit_f32tof16(struct vkd3d_dxbc_compiler *compil dst, vkd3d_component_type_from_data_type(dst->reg.data_type), components); }
+static DWORD vkd3d_dxbc_compiler_cross_type_src_mask(enum vkd3d_data_type src, enum vkd3d_data_type dst, DWORD mask) +{ + unsigned int component_count; + + if (src == dst) + return mask; + + component_count = vkd3d_write_mask_component_count(mask); + + if (src == VKD3D_DATA_DOUBLE) + { + if (component_count >= 2) + return VKD3DSP_WRITEMASK_ALL; + else if (component_count == 1) + return VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1; + else + return 0; + } + else if (dst == VKD3D_DATA_DOUBLE) + { + if (component_count >= 3) + return VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1; + else if (component_count >= 1) + return VKD3DSP_WRITEMASK_0; + else + return 0; + } + + return mask; +} + static void vkd3d_dxbc_compiler_emit_comparison_instruction(struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { @@ -7132,17 +7166,22 @@ static void vkd3d_dxbc_compiler_emit_comparison_instruction(struct vkd3d_dxbc_co const struct vkd3d_shader_src_param *src = instruction->src; uint32_t src0_id, src1_id, type_id, result_id; unsigned int component_count; + DWORD src_mask; SpvOp op;
switch (instruction->handler_idx) { + case VKD3DSIH_DEQ: case VKD3DSIH_EQ: op = SpvOpFOrdEqual; break; + case VKD3DSIH_DGE: case VKD3DSIH_GE: op = SpvOpFOrdGreaterThanEqual; break; case VKD3DSIH_IEQ: op = SpvOpIEqual; break; case VKD3DSIH_IGE: op = SpvOpSGreaterThanEqual; break; case VKD3DSIH_ILT: op = SpvOpSLessThan; break; case VKD3DSIH_INE: op = SpvOpINotEqual; break; + case VKD3DSIH_DLT: case VKD3DSIH_LT: op = SpvOpFOrdLessThan; break; + case VKD3DSIH_DNE: case VKD3DSIH_NE: op = SpvOpFUnordNotEqual; break; case VKD3DSIH_UGE: op = SpvOpUGreaterThanEqual; break; case VKD3DSIH_ULT: op = SpvOpULessThan; break; @@ -7153,8 +7192,9 @@ static void vkd3d_dxbc_compiler_emit_comparison_instruction(struct vkd3d_dxbc_co
component_count = vkd3d_write_mask_component_count(dst->write_mask);
- src0_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], dst->write_mask); - src1_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[1], dst->write_mask); + src_mask = vkd3d_dxbc_compiler_cross_type_src_mask(src->reg.data_type, dst->reg.data_type, dst->write_mask); + src0_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], src_mask); + src1_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[1], src_mask);
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); result_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, @@ -9291,8 +9331,11 @@ int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, case VKD3DSIH_IMAX: case VKD3DSIH_IMIN: case VKD3DSIH_LOG: + case VKD3DSIH_DFMA: case VKD3DSIH_MAD: + case VKD3DSIH_DMAX: case VKD3DSIH_MAX: + case VKD3DSIH_DMIN: case VKD3DSIH_MIN: case VKD3DSIH_ROUND_NE: case VKD3DSIH_ROUND_NI: @@ -9325,13 +9368,17 @@ int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, case VKD3DSIH_UDIV: vkd3d_dxbc_compiler_emit_udiv(compiler, instruction); break; + case VKD3DSIH_DEQ: case VKD3DSIH_EQ: + case VKD3DSIH_DGE: case VKD3DSIH_GE: case VKD3DSIH_IEQ: case VKD3DSIH_IGE: case VKD3DSIH_ILT: case VKD3DSIH_INE: + case VKD3DSIH_DLT: case VKD3DSIH_LT: + case VKD3DSIH_DNE: case VKD3DSIH_NE: case VKD3DSIH_UGE: case VKD3DSIH_ULT: diff --git a/libs/vkd3d-shader/trace.c b/libs/vkd3d-shader/trace.c index 3812b573..c3e2d9b6 100644 --- a/libs/vkd3d-shader/trace.c +++ b/libs/vkd3d-shader/trace.c @@ -269,10 +269,17 @@ static const char * const shader_opcode_names[] = /* VKD3DSIH_UTOF */ "utof", /* VKD3DSIH_XOR */ "xor", /* VKD3DSIH_DADD */ "dadd", + /* VKD3DSIH_DMAX */ "dmax", + /* VKD3DSIH_DMIN */ "dmin", /* VKD3DSIH_DMUL */ "dmul", + /* VKD3DSIH_DEQ */ "deq", + /* VKD3DSIH_DGE */ "dge", + /* VKD3DSIH_DLT */ "dlt", + /* VKD3DSIH_DNE */ "dne", /* VKD3DSIH_DMOV */ "dmov", /* VKD3DSIH_DMOVC */ "dmovc", /* VKD3DSIH_DDIV */ "ddiv", + /* VKD3DSIH_DFMA */ "dfma", /* VKD3DSIH_DRCP */ "drcp", };
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index d0fd25ee..ec1c6847 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -355,10 +355,17 @@ enum vkd3d_shader_opcode VKD3DSIH_XOR,
VKD3DSIH_DADD, + VKD3DSIH_DMAX, + VKD3DSIH_DMIN, VKD3DSIH_DMUL, + VKD3DSIH_DEQ, + VKD3DSIH_DGE, + VKD3DSIH_DLT, + VKD3DSIH_DNE, VKD3DSIH_DMOV, VKD3DSIH_DMOVC, VKD3DSIH_DDIV, + VKD3DSIH_DFMA, VKD3DSIH_DRCP,
VKD3DSIH_INVALID,
On Mon, 14 Jun 2021 at 05:27, Conor McCarthy cmccarthy@codeweavers.com wrote:
libs/vkd3d-shader/dxbc.c | 14 +++++++ libs/vkd3d-shader/spirv.c | 51 +++++++++++++++++++++++- libs/vkd3d-shader/trace.c | 7 ++++ libs/vkd3d-shader/vkd3d_shader_private.h | 7 ++++ 4 files changed, 77 insertions(+), 2 deletions(-)
The comments for patch 6/9 apply here as well.
From: Joshua Ashton joshua@froggi.es Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- libs/vkd3d-shader/dxbc.c | 12 +++++++ libs/vkd3d-shader/spirv.c | 43 ++++++++++++++++++++++++ libs/vkd3d-shader/trace.c | 6 ++++ libs/vkd3d-shader/vkd3d_shader_private.h | 6 ++++ 4 files changed, 67 insertions(+)
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index 1a79da6d..e63493fa 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -320,12 +320,18 @@ enum vkd3d_sm4_opcode VKD3D_SM5_OP_DNE = 0xc6, VKD3D_SM5_OP_DMOV = 0xc7, VKD3D_SM5_OP_DMOVC = 0xc8, + VKD3D_SM5_OP_DTOF = 0xc9, + VKD3D_SM5_OP_FTOD = 0xca, VKD3D_SM5_OP_EVAL_SAMPLE_INDEX = 0xcc, VKD3D_SM5_OP_EVAL_CENTROID = 0xcd, VKD3D_SM5_OP_DCL_GS_INSTANCES = 0xce, VKD3D_SM5_OP_DDIV = 0xd2, VKD3D_SM5_OP_DFMA = 0xd3, VKD3D_SM5_OP_DRCP = 0xd4, + VKD3D_SM5_OP_DTOI = 0xd6, + VKD3D_SM5_OP_DTOU = 0xd7, + VKD3D_SM5_OP_ITOD = 0xd8, + VKD3D_SM5_OP_UTOD = 0xd9, };
enum vkd3d_sm4_instruction_modifier @@ -1259,9 +1265,15 @@ static const struct vkd3d_sm4_opcode_info opcode_table[] = {VKD3D_SM5_OP_DNE, VKD3DSIH_DNE, "u", "dd"}, {VKD3D_SM5_OP_DMOV, VKD3DSIH_DMOV, "d", "d"}, {VKD3D_SM5_OP_DMOVC, VKD3DSIH_DMOVC, "d", "udd"}, + {VKD3D_SM5_OP_DTOF, VKD3DSIH_DTOF, "f", "d"}, + {VKD3D_SM5_OP_FTOD, VKD3DSIH_FTOD, "d", "f"}, {VKD3D_SM5_OP_DDIV, VKD3DSIH_DDIV, "d", "dd"}, {VKD3D_SM5_OP_DFMA, VKD3DSIH_DFMA, "d", "ddd"}, {VKD3D_SM5_OP_DRCP, VKD3DSIH_DRCP, "d", "d"}, + {VKD3D_SM5_OP_DTOI, VKD3DSIH_DTOI, "i", "d"}, + {VKD3D_SM5_OP_DTOU, VKD3DSIH_DTOU, "u", "d"}, + {VKD3D_SM5_OP_ITOD, VKD3DSIH_ITOD, "d", "i"}, + {VKD3D_SM5_OP_UTOD, VKD3DSIH_UTOD, "d", "u"}, };
static const enum vkd3d_shader_register_type register_type_table[] = diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 6be1fda5..a44437ec 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -9102,6 +9102,41 @@ static void vkd3d_dxbc_compiler_emit_cut_stream(struct vkd3d_dxbc_compiler *comp vkd3d_spirv_build_op_end_primitive(builder); }
+static void vkd3d_dxbc_compiler_emit_double_conversion(struct vkd3d_dxbc_compiler *compiler, + const struct vkd3d_shader_instruction *instruction) +{ + 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, val_id, type_id; + DWORD src_mask; + SpvOp op; + + switch (instruction->handler_idx) + { + case VKD3DSIH_DTOF: + case VKD3DSIH_FTOD: op = SpvOpFConvert; break; + case VKD3DSIH_DTOI: op = SpvOpConvertFToS; break; + case VKD3DSIH_DTOU: op = SpvOpConvertFToU; break; + case VKD3DSIH_ITOD: op = SpvOpConvertSToF; break; + case VKD3DSIH_UTOD: op = SpvOpConvertUToF; break; + default: + ERR("Unexpected instruction %#x.\n", instruction->handler_idx); + return; + } + + src_mask = vkd3d_dxbc_compiler_cross_type_src_mask(src->reg.data_type, dst->reg.data_type, dst->write_mask); + src_id = vkd3d_dxbc_compiler_emit_load_src(compiler, src, src_mask); + + type_id = vkd3d_spirv_get_type_id(builder, vkd3d_component_type_from_data_type(dst->reg.data_type), + vkd3d_write_mask_component_count_typed(dst->write_mask, dst->reg.data_type)); + + val_id = vkd3d_spirv_build_op_trv(builder, &builder->function_stream, + op, type_id, &src_id, 1); + + vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, val_id); +} + static void vkd3d_dxbc_compiler_emit_hull_shader_inputs(struct vkd3d_dxbc_compiler *compiler) { const struct vkd3d_shader_signature *signature = compiler->input_signature; @@ -9510,6 +9545,14 @@ int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, case VKD3DSIH_CUT_STREAM: vkd3d_dxbc_compiler_emit_cut_stream(compiler, instruction); break; + case VKD3DSIH_DTOF: + case VKD3DSIH_FTOD: + case VKD3DSIH_DTOI: + case VKD3DSIH_DTOU: + case VKD3DSIH_ITOD: + case VKD3DSIH_UTOD: + vkd3d_dxbc_compiler_emit_double_conversion(compiler, instruction); + break; case VKD3DSIH_DCL_HS_MAX_TESSFACTOR: case VKD3DSIH_HS_DECLS: case VKD3DSIH_NOP: diff --git a/libs/vkd3d-shader/trace.c b/libs/vkd3d-shader/trace.c index c3e2d9b6..a11083ef 100644 --- a/libs/vkd3d-shader/trace.c +++ b/libs/vkd3d-shader/trace.c @@ -278,9 +278,15 @@ static const char * const shader_opcode_names[] = /* VKD3DSIH_DNE */ "dne", /* VKD3DSIH_DMOV */ "dmov", /* VKD3DSIH_DMOVC */ "dmovc", + /* VKD3DSIH_DTOF */ "dtof", + /* VKD3DSIH_FTOD */ "ftod", /* VKD3DSIH_DDIV */ "ddiv", /* VKD3DSIH_DFMA */ "dfma", /* VKD3DSIH_DRCP */ "drcp", + /* VKD3DSIH_DTOI */ "dtoi", + /* VKD3DSIH_DTOU */ "dtou", + /* VKD3DSIH_ITOD */ "itod", + /* VKD3DSIH_UTOD */ "utod", };
static const struct diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index ec1c6847..86860b9d 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -364,9 +364,15 @@ enum vkd3d_shader_opcode VKD3DSIH_DNE, VKD3DSIH_DMOV, VKD3DSIH_DMOVC, + VKD3DSIH_DTOF, + VKD3DSIH_FTOD, VKD3DSIH_DDIV, VKD3DSIH_DFMA, VKD3DSIH_DRCP, + VKD3DSIH_DTOI, + VKD3DSIH_DTOU, + VKD3DSIH_ITOD, + VKD3DSIH_UTOD,
VKD3DSIH_INVALID, };
On Mon, 14 Jun 2021 at 05:27, Conor McCarthy cmccarthy@codeweavers.com wrote:
libs/vkd3d-shader/dxbc.c | 12 +++++++ libs/vkd3d-shader/spirv.c | 43 ++++++++++++++++++++++++ libs/vkd3d-shader/trace.c | 6 ++++ libs/vkd3d-shader/vkd3d_shader_private.h | 6 ++++ 4 files changed, 67 insertions(+)
...and here.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- tests/d3d12.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/tests/d3d12.c b/tests/d3d12.c index 55c9ca4d..2c144a58 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -10142,8 +10142,7 @@ static void test_shader_instructions(void) return; command_list = context.list; queue = context.queue; - /* Float64 instructions are not supported and pipeline state creation will fail. */ - test_shader_float64 = is_shader_float64_supported(context.device) && vkd3d_test_platform_is_windows(); + test_shader_float64 = is_shader_float64_supported(context.device);
context.root_signature = create_cb_root_signature(context.device, 0, D3D12_SHADER_VISIBILITY_PIXEL, D3D12_ROOT_SIGNATURE_FLAG_NONE);
On Mon, 14 Jun 2021 at 05:27, Conor McCarthy cmccarthy@codeweavers.com wrote:
@@ -9818,6 +10142,8 @@ static void test_shader_instructions(void) return; command_list = context.list; queue = context.queue;
- /* Float64 instructions are not supported and pipeline state creation will fail. */
- test_shader_float64 = is_shader_float64_supported(context.device) && vkd3d_test_platform_is_windows();
If that's the case, we should just handle pipeline state creation failures, and add appropriate todos, instead of using vkd3d_test_platform_is_windows() here.