=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: vkd3d-shader: Forbid mixing samplers with CBVs/SRVs/UAVs in root signatures.

Alexandre Julliard julliard at winehq.org
Wed Jun 12 16:27:17 CDT 2019


Module: vkd3d
Branch: master
Commit: 4a0b62084ac68bf05977553c9733339ae9a80d3f
URL:    https://source.winehq.org/git/vkd3d.git/?a=commit;h=4a0b62084ac68bf05977553c9733339ae9a80d3f

Author: Józef Kucia <jkucia at codeweavers.com>
Date:   Wed Jun 12 14:08:00 2019 +0200

vkd3d-shader: Forbid mixing samplers with CBVs/SRVs/UAVs in root signatures.

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 libs/vkd3d-shader/dxbc.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++
 tests/d3d12.c            |  34 ++++++++++++----
 2 files changed, 126 insertions(+), 8 deletions(-)

diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c
index a9cda49..98c51e4 100644
--- a/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d-shader/dxbc.c
@@ -3007,6 +3007,103 @@ static int shader_write_root_signature(struct root_signature_writer_context *con
     return shader_write_static_samplers(context, desc);
 }
 
+static int validate_descriptor_table_v_1_0(const struct vkd3d_root_descriptor_table *descriptor_table)
+{
+    bool have_srv_uav_cbv = false;
+    bool have_sampler = false;
+    unsigned int i;
+
+    for (i = 0; i < descriptor_table->descriptor_range_count; ++i)
+    {
+        const struct vkd3d_descriptor_range *r = &descriptor_table->descriptor_ranges[i];
+
+        if (r->range_type == VKD3D_DESCRIPTOR_RANGE_TYPE_SRV
+                || r->range_type == VKD3D_DESCRIPTOR_RANGE_TYPE_UAV
+                || r->range_type == VKD3D_DESCRIPTOR_RANGE_TYPE_CBV)
+        {
+            have_srv_uav_cbv = true;
+        }
+        else if (r->range_type == VKD3D_DESCRIPTOR_RANGE_TYPE_SAMPLER)
+        {
+            have_sampler = true;
+        }
+        else
+        {
+            WARN("Invalid descriptor range type %#x.\n", r->range_type);
+            return VKD3D_ERROR_INVALID_ARGUMENT;
+        }
+    }
+
+    if (have_srv_uav_cbv && have_sampler)
+    {
+        WARN("Samplers cannot be mixed with CBVs/SRVs/UAVs in descriptor tables.\n");
+        return VKD3D_ERROR_INVALID_ARGUMENT;
+    }
+
+    return VKD3D_OK;
+}
+
+static int validate_descriptor_table_v_1_1(const struct vkd3d_root_descriptor_table1 *descriptor_table)
+{
+    bool have_srv_uav_cbv = false;
+    bool have_sampler = false;
+    unsigned int i;
+
+    for (i = 0; i < descriptor_table->descriptor_range_count; ++i)
+    {
+        const struct vkd3d_descriptor_range1 *r = &descriptor_table->descriptor_ranges[i];
+
+        if (r->range_type == VKD3D_DESCRIPTOR_RANGE_TYPE_SRV
+                || r->range_type == VKD3D_DESCRIPTOR_RANGE_TYPE_UAV
+                || r->range_type == VKD3D_DESCRIPTOR_RANGE_TYPE_CBV)
+        {
+            have_srv_uav_cbv = true;
+        }
+        else if (r->range_type == VKD3D_DESCRIPTOR_RANGE_TYPE_SAMPLER)
+        {
+            have_sampler = true;
+        }
+        else
+        {
+            WARN("Invalid descriptor range type %#x.\n", r->range_type);
+            return VKD3D_ERROR_INVALID_ARGUMENT;
+        }
+    }
+
+    if (have_srv_uav_cbv && have_sampler)
+    {
+        WARN("Samplers cannot be mixed with CBVs/SRVs/UAVs in descriptor tables.\n");
+        return VKD3D_ERROR_INVALID_ARGUMENT;
+    }
+
+    return VKD3D_OK;
+}
+
+static int validate_root_signature_desc(const struct vkd3d_versioned_root_signature_desc *desc)
+{
+    int ret = VKD3D_OK;
+    unsigned int i;
+
+    for (i = 0; i < versioned_root_signature_get_parameter_count(desc); ++i)
+    {
+        enum vkd3d_root_parameter_type type;
+
+        type = versioned_root_signature_get_parameter_type(desc, i);
+        if (type == VKD3D_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE)
+        {
+            if (desc->version == VKD3D_ROOT_SIGNATURE_VERSION_1_0)
+                ret = validate_descriptor_table_v_1_0(&desc->u.v_1_0.parameters[i].u.descriptor_table);
+            else
+                ret = validate_descriptor_table_v_1_1(&desc->u.v_1_1.parameters[i].u.descriptor_table);
+        }
+
+        if (ret < 0)
+            break;
+    }
+
+    return ret;
+}
+
 int vkd3d_shader_serialize_root_signature(const struct vkd3d_versioned_root_signature_desc *root_signature,
         struct vkd3d_shader_code *dxbc)
 {
@@ -3024,6 +3121,9 @@ int vkd3d_shader_serialize_root_signature(const struct vkd3d_versioned_root_sign
         return VKD3D_ERROR_INVALID_ARGUMENT;
     }
 
+    if ((ret = validate_root_signature_desc(root_signature)) < 0)
+        return ret;
+
     memset(dxbc, 0, sizeof(*dxbc));
     memset(&context, 0, sizeof(context));
     if ((ret = shader_write_root_signature_header(&context)) < 0)
diff --git a/tests/d3d12.c b/tests/d3d12.c
index 903c423..642d625 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -2488,7 +2488,7 @@ static void test_create_unordered_access_view(void)
 static void test_create_root_signature(void)
 {
     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
-    D3D12_DESCRIPTOR_RANGE descriptor_ranges[1];
+    D3D12_DESCRIPTOR_RANGE descriptor_ranges[2];
     D3D12_ROOT_PARAMETER root_parameters[3];
     ID3D12RootSignature *root_signature;
     ID3D12Device *device, *tmp_device;
@@ -2517,12 +2517,12 @@ static void test_create_root_signature(void)
     root_signature_desc.pStaticSamplers = NULL;
     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
     hr = create_root_signature(device, &root_signature_desc, &root_signature);
-    ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
+    ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
 
     refcount = get_refcount(device);
     ok(refcount == 2, "Got unexpected refcount %u.\n", (unsigned int)refcount);
     hr = ID3D12RootSignature_GetDevice(root_signature, &IID_ID3D12Device, (void **)&tmp_device);
-    ok(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr);
+    ok(hr == S_OK, "Failed to get device, hr %#x.\n", hr);
     refcount = get_refcount(device);
     ok(refcount == 3, "Got unexpected refcount %u.\n", (unsigned int)refcount);
     refcount = ID3D12Device_Release(tmp_device);
@@ -2536,14 +2536,32 @@ static void test_create_root_signature(void)
     refcount = ID3D12RootSignature_Release(root_signature);
     ok(!refcount, "ID3D12RootSignature has %u references left.\n", (unsigned int)refcount);
 
-    /* empty */
+    /* sampler and SRV in the same descriptor table */
+    descriptor_ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
+    descriptor_ranges[1].NumDescriptors = 1;
+    descriptor_ranges[1].BaseShaderRegister = 2;
+    descriptor_ranges[1].RegisterSpace = 0;
+    descriptor_ranges[1].OffsetInDescriptorsFromTableStart = 10;
+    root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
+    root_parameters[0].DescriptorTable.NumDescriptorRanges = 2;
+    root_parameters[0].DescriptorTable.pDescriptorRanges = descriptor_ranges;
+    root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
+    root_signature_desc.NumParameters = 1;
+    root_signature_desc.pParameters = root_parameters;
+    root_signature_desc.NumStaticSamplers = 0;
+    root_signature_desc.pStaticSamplers = NULL;
+    root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
+    hr = create_root_signature(device, &root_signature_desc, &root_signature);
+    ok(hr == E_INVALIDARG, "Failed to create root signature, hr %#x.\n", hr);
+
+    /* empty root signature */
     root_signature_desc.NumParameters = 0;
     root_signature_desc.pParameters = NULL;
     root_signature_desc.NumStaticSamplers = 0;
     root_signature_desc.pStaticSamplers = NULL;
     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
     hr = create_root_signature(device, &root_signature_desc, &root_signature);
-    ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
+    ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
     refcount = ID3D12RootSignature_Release(root_signature);
     ok(!refcount, "ID3D12RootSignature has %u references left.\n", (unsigned int)refcount);
 
@@ -2569,7 +2587,7 @@ static void test_create_root_signature(void)
         ID3D12RootSignature_Release(root_signature);
     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
     hr = create_root_signature(device, &root_signature_desc, &root_signature);
-    ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
+    ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
     refcount = ID3D12RootSignature_Release(root_signature);
     ok(!refcount, "ID3D12RootSignature has %u references left.\n", (unsigned int)refcount);
 
@@ -2580,7 +2598,7 @@ static void test_create_root_signature(void)
     root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
     root_signature_desc.NumParameters = 3;
     hr = create_root_signature(device, &root_signature_desc, &root_signature);
-    ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
+    ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
     refcount = ID3D12RootSignature_Release(root_signature);
     ok(!refcount, "ID3D12RootSignature has %u references left.\n", (unsigned int)refcount);
 
@@ -2604,7 +2622,7 @@ static void test_create_root_signature(void)
         ID3D12RootSignature_Release(root_signature);
     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_GEOMETRY;
     hr = create_root_signature(device, &root_signature_desc, &root_signature);
-    ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
+    ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
     refcount = ID3D12RootSignature_Release(root_signature);
     ok(!refcount, "ID3D12RootSignature has %u references left.\n", (unsigned int)refcount);
 




More information about the wine-cvs mailing list