Wine-Devel
Threads by month
- ----- 2026 -----
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
October 2021
- 81 participants
- 772 discussions
[PATCH vkd3d 3/5] vkd3d: Reject OFFSET_APPEND after unbounded ranges in d3d12_root_signature_info_count_descriptors().
by Henri Verbeet Oct. 6, 2021
by Henri Verbeet Oct. 6, 2021
Oct. 6, 2021
From: Conor McCarthy <cmccarthy(a)codeweavers.com>
Signed-off-by: Conor McCarthy <cmccarthy(a)codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
libs/vkd3d/state.c | 17 ++++++++++++++---
tests/d3d12.c | 2 +-
2 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c
index 9e554b44..ffb3e2f5 100644
--- a/libs/vkd3d/state.c
+++ b/libs/vkd3d/state.c
@@ -325,6 +325,7 @@ struct d3d12_root_signature_info
static HRESULT d3d12_root_signature_info_count_descriptors(struct d3d12_root_signature_info *info,
const D3D12_ROOT_DESCRIPTOR_TABLE *table, bool use_array)
{
+ bool unbounded = false;
unsigned int i;
for (i = 0; i < table->NumDescriptorRanges; ++i)
@@ -332,12 +333,16 @@ static HRESULT d3d12_root_signature_info_count_descriptors(struct d3d12_root_sig
const D3D12_DESCRIPTOR_RANGE *range = &table->pDescriptorRanges[i];
unsigned int binding_count;
- if (range->NumDescriptors == 0xffffffff)
+ if (unbounded && range->OffsetInDescriptorsFromTableStart == D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND)
{
- FIXME("Unhandled unbound descriptor range.\n");
- return E_NOTIMPL;
+ WARN("An unbounded range with offset D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND occurs after "
+ "another unbounded range.\n");
+ return E_INVALIDARG;
}
+ if (range->NumDescriptors == UINT_MAX)
+ unbounded = true;
+
binding_count = use_array ? 1 : range->NumDescriptors;
switch (range->RangeType)
@@ -365,6 +370,12 @@ static HRESULT d3d12_root_signature_info_count_descriptors(struct d3d12_root_sig
info->binding_count += binding_count;
}
+ if (unbounded)
+ {
+ FIXME("Unhandled unbounded descriptor range.\n");
+ return E_NOTIMPL;
+ }
+
return S_OK;
}
diff --git a/tests/d3d12.c b/tests/d3d12.c
index 74b4877c..5dea7812 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -2814,7 +2814,7 @@ static void test_create_root_signature(void)
* D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND. */
descriptor_ranges[1].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
hr = create_root_signature(device, &root_signature_desc, &root_signature);
- todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
+ ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
/* A bounded range overlapping an unbounded one, mapped to the same
* register space and type. */
--
2.20.1
1
0
[PATCH vkd3d 2/5] tests: Add root signature tests for unbounded descriptor ranges.
by Henri Verbeet Oct. 6, 2021
by Henri Verbeet Oct. 6, 2021
Oct. 6, 2021
Signed-off-by: Conor McCarthy <cmccarthy(a)codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
tests/d3d12.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 77 insertions(+)
diff --git a/tests/d3d12.c b/tests/d3d12.c
index 0b02e107..74b4877c 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -2777,6 +2777,83 @@ static void test_create_root_signature(void)
refcount = ID3D12RootSignature_Release(root_signature);
ok(!refcount, "ID3D12RootSignature has %u references left.\n", (unsigned int)refcount);
+ /* Unbounded descriptor ranges. */
+
+ /* A bounded range overlapping an unbounded one, mapped to a different
+ * register space of the same type. */
+ descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
+ descriptor_ranges[0].NumDescriptors = UINT_MAX;
+ descriptor_ranges[0].BaseShaderRegister = 0;
+ descriptor_ranges[0].RegisterSpace = 0;
+ descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0;
+ descriptor_ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
+ descriptor_ranges[1].NumDescriptors = 1;
+ descriptor_ranges[1].BaseShaderRegister = 16;
+ descriptor_ranges[1].RegisterSpace = 1;
+ descriptor_ranges[1].OffsetInDescriptorsFromTableStart = 16;
+ 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);
+ todo ok(hr == S_OK || (binding_tier == D3D12_RESOURCE_BINDING_TIER_1 && (hr == E_FAIL || hr == E_INVALIDARG)),
+ "Got unexpected hr %#x.\n", hr);
+ if (SUCCEEDED(hr))
+ {
+ refcount = ID3D12RootSignature_Release(root_signature);
+ ok(!refcount, "Got unexpected refcount %u.\n", (unsigned int)refcount);
+ }
+
+ /* A bounded range overlapping an unbounded one, mapped to a different
+ * register space of the same type. Using
+ * D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND. */
+ descriptor_ranges[1].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
+ hr = create_root_signature(device, &root_signature_desc, &root_signature);
+ todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
+
+ /* A bounded range overlapping an unbounded one, mapped to the same
+ * register space and type. */
+ descriptor_ranges[1].RegisterSpace = 0;
+ descriptor_ranges[1].OffsetInDescriptorsFromTableStart = 16;
+ hr = create_root_signature(device, &root_signature_desc, &root_signature);
+ todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
+
+ /* A bounded range overlapping an unbounded one, mapped to the same
+ * register space, but a different type. */
+ descriptor_ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV;
+ hr = create_root_signature(device, &root_signature_desc, &root_signature);
+ todo ok(hr == S_OK || (binding_tier <= D3D12_RESOURCE_BINDING_TIER_2 && (hr == E_FAIL || hr == E_INVALIDARG)),
+ "Got unexpected hr %#x.\n", hr);
+ if (SUCCEEDED(hr))
+ {
+ refcount = ID3D12RootSignature_Release(root_signature);
+ ok(!refcount, "Got unexpected refcount %u.\n", (unsigned int)refcount);
+ }
+
+ /* An unbounded range overlapping another unbounded range, mapped to the
+ * same register space and type. */
+ descriptor_ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
+ descriptor_ranges[1].NumDescriptors = UINT_MAX;
+ hr = create_root_signature(device, &root_signature_desc, &root_signature);
+ todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
+ if (SUCCEEDED(hr))
+ ID3D12RootSignature_Release(root_signature);
+
+ /* And unbounded range overlapping a bounded one, mapped to the same
+ * register space and type. */
+ descriptor_ranges[0].NumDescriptors = 16;
+ descriptor_ranges[1].BaseShaderRegister = 0;
+ descriptor_ranges[1].OffsetInDescriptorsFromTableStart = 15;
+ hr = create_root_signature(device, &root_signature_desc, &root_signature);
+ todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
+ if (SUCCEEDED(hr))
+ ID3D12RootSignature_Release(root_signature);
+
refcount = ID3D12Device_Release(device);
ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
}
--
2.20.1
1
0
[PATCH vkd3d 1/5] tests: Add root signature tests for descriptor register range collisions.
by Henri Verbeet Oct. 6, 2021
by Henri Verbeet Oct. 6, 2021
Oct. 6, 2021
From: Conor McCarthy <cmccarthy(a)codeweavers.com>
Signed-off-by: Conor McCarthy <cmccarthy(a)codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
tests/d3d12.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/tests/d3d12.c b/tests/d3d12.c
index 009f8331..0b02e107 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -584,6 +584,21 @@ static bool is_shader_float64_supported(ID3D12Device *device)
return options.DoublePrecisionFloatShaderOps;
}
+static D3D12_RESOURCE_BINDING_TIER get_resource_binding_tier(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 D3D12_RESOURCE_BINDING_TIER_1;
+ }
+
+ return options.ResourceBindingTier;
+}
+
#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,
@@ -2590,6 +2605,7 @@ static void test_create_root_signature(void)
{
D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
D3D12_DESCRIPTOR_RANGE descriptor_ranges[2];
+ D3D12_RESOURCE_BINDING_TIER binding_tier;
D3D12_ROOT_PARAMETER root_parameters[3];
ID3D12RootSignature *root_signature;
ID3D12Device *device, *tmp_device;
@@ -2602,6 +2618,11 @@ static void test_create_root_signature(void)
return;
}
+ /* Tier 2 is required for unbounded SRVs and Tier > 2 for unbounded CBVs and UAVs
+ * due to the need for partial binding support. It is also required for overlapping
+ * ranges of different types. */
+ binding_tier = get_resource_binding_tier(device);
+
/* descriptor table */
descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
descriptor_ranges[0].NumDescriptors = 1;
@@ -2637,6 +2658,35 @@ static void test_create_root_signature(void)
refcount = ID3D12RootSignature_Release(root_signature);
ok(!refcount, "ID3D12RootSignature has %u references left.\n", (unsigned int)refcount);
+ /* Overlapping ranges but unique register indices. */
+ descriptor_ranges[0].NumDescriptors = 8;
+ descriptor_ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
+ descriptor_ranges[1].NumDescriptors = 2;
+ descriptor_ranges[1].BaseShaderRegister = 8;
+ descriptor_ranges[1].RegisterSpace = 0;
+ descriptor_ranges[1].OffsetInDescriptorsFromTableStart = 7;
+ root_parameters[0].DescriptorTable.NumDescriptorRanges = 2;
+ hr = create_root_signature(device, &root_signature_desc, &root_signature);
+ ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
+ ID3D12RootSignature_Release(root_signature);
+
+ /* Separate ranges with ambiguous register indices. */
+ descriptor_ranges[1].BaseShaderRegister = 7;
+ descriptor_ranges[1].OffsetInDescriptorsFromTableStart = 8;
+ hr = create_root_signature(device, &root_signature_desc, &root_signature);
+ todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
+ if (SUCCEEDED(hr))
+ ID3D12RootSignature_Release(root_signature);
+
+ /* Identical ranges and register indices but different type. */
+ descriptor_ranges[1] = descriptor_ranges[0];
+ descriptor_ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV;
+ hr = create_root_signature(device, &root_signature_desc, &root_signature);
+ ok(hr == S_OK || (binding_tier <= D3D12_RESOURCE_BINDING_TIER_2 && (hr == E_FAIL || hr == E_INVALIDARG)),
+ "Got unexpected hr %#x.\n", hr);
+ if (SUCCEEDED(hr))
+ ID3D12RootSignature_Release(root_signature);
+
/* sampler and SRV in the same descriptor table */
descriptor_ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
descriptor_ranges[1].NumDescriptors = 1;
--
2.20.1
1
0
[PATCH 1/5] d3dcompiler/tests: Also accept broken HRESULT with d3dcompiler_46.
by Matteo Bruni Oct. 6, 2021
by Matteo Bruni Oct. 6, 2021
Oct. 6, 2021
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
For reference, I got this "new" result with a d3dcompiler_46.dll found
in Steam's directory.
dlls/d3dcompiler_43/tests/reflection.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/d3dcompiler_43/tests/reflection.c b/dlls/d3dcompiler_43/tests/reflection.c
index 75f30e45dce..8cf6edb1c97 100644
--- a/dlls/d3dcompiler_43/tests/reflection.c
+++ b/dlls/d3dcompiler_43/tests/reflection.c
@@ -164,8 +164,8 @@ static void test_reflection_interfaces(void)
expected_hr = D3D_COMPILER_VERSION < 46 ? E_NOINTERFACE : D3D_COMPILER_VERSION == 46 ? E_INVALIDARG : S_OK;
hr = call_reflect(test_reflection_blob, test_reflection_blob[6], &IID_ID3D12ShaderReflection, (void **)&ref12);
- /* Broken with older d3dcompiler_47. */
- ok(hr == expected_hr || broken(expected_hr == S_OK && hr == E_NOINTERFACE), "Got unexpected hr %#x.\n", hr);
+ /* Broken with older d3dcompiler_46, d3dcompiler_47. */
+ ok(hr == expected_hr || broken(expected_hr != E_NOINTERFACE && hr == E_NOINTERFACE), "Got unexpected hr %#x.\n", hr);
if (hr != S_OK)
return;
--
2.26.3
5
10
[PATCH v5 1/2] wined3d: Set VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT for unordered access images.
by Jan Sikorski Oct. 6, 2021
by Jan Sikorski Oct. 6, 2021
Oct. 6, 2021
Signed-off-by: Jan Sikorski <jsikorski(a)codeweavers.com>
---
dlls/wined3d/texture.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index db32274960f..339bf4e205a 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -5092,8 +5092,13 @@ BOOL wined3d_texture_vk_prepare_texture(struct wined3d_texture_vk *texture_vk,
resource = &texture_vk->t.resource;
format_vk = wined3d_format_vk(resource->format);
- if (wined3d_format_is_typeless(&format_vk->f) || texture_vk->t.swapchain)
+ if (wined3d_format_is_typeless(&format_vk->f) || texture_vk->t.swapchain
+ || (texture_vk->t.resource.bind_flags & WINED3D_BIND_UNORDERED_ACCESS))
+ {
+ /* For UAVs, we need this in case a clear necessitates creation of a new view
+ * with a different format. */
flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
+ }
switch (resource->type)
{
--
2.30.2
2
3
Oct. 6, 2021
Signed-off-by: Jan Sikorski <jsikorski(a)codeweavers.com>
---
dlls/wined3d/cs.c | 54 ++++++++++++++++++++---------------------------
1 file changed, 23 insertions(+), 31 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 8307ce0fa96..576a3ccd50e 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -76,11 +76,6 @@ static void wined3d_command_list_destroy_object(void *object)
for (i = 0; i < list->upload_count; ++i)
heap_free(list->uploads[i].sysmem);
- heap_free(list->command_lists);
- heap_free(list->uploads);
- heap_free(list->resources);
- heap_free(list->data);
- heap_free(list->queries);
heap_free(list);
}
@@ -3734,45 +3729,54 @@ HRESULT CDECL wined3d_deferred_context_record_command_list(struct wined3d_device
{
struct wined3d_deferred_context *deferred = wined3d_deferred_context_from_context(context);
struct wined3d_command_list *object;
+ void *memory;
TRACE("context %p, list %p.\n", context, list);
- if (!(object = heap_alloc_zero(sizeof(*object))))
+ memory = heap_alloc(sizeof(*object) + deferred->resource_count * sizeof(*object->resources)
+ + deferred->upload_count * sizeof(*object->uploads)
+ + deferred->command_list_count * sizeof(*object->command_lists)
+ + deferred->query_count * sizeof(*object->queries)
+ + deferred->data_size);
+
+ if (!memory)
return E_OUTOFMEMORY;
+ object = memory;
+ memory = &object[1];
+ memset(object, 0, sizeof(*object));
object->refcount = 1;
object->device = deferred->c.device;
- if (!(object->data = heap_alloc(deferred->data_size)))
- goto out_free_list;
- object->data_size = deferred->data_size;
- memcpy(object->data, deferred->data, deferred->data_size);
-
- if (!(object->resources = heap_alloc(deferred->resource_count * sizeof(*object->resources))))
- goto out_free_data;
+ object->resources = memory;
+ memory = &object->resources[deferred->resource_count];
object->resource_count = deferred->resource_count;
memcpy(object->resources, deferred->resources, deferred->resource_count * sizeof(*object->resources));
/* Transfer our references to the resources to the command list. */
- if (!(object->uploads = heap_alloc(deferred->upload_count * sizeof(*object->uploads))))
- goto out_free_resources;
+ object->uploads = memory;
+ memory = &object->uploads[deferred->upload_count];
object->upload_count = deferred->upload_count;
memcpy(object->uploads, deferred->uploads, deferred->upload_count * sizeof(*object->uploads));
/* Transfer our references to the resources to the command list. */
- if (!(object->command_lists = heap_alloc(deferred->command_list_count * sizeof(*object->command_lists))))
- goto out_free_uploads;
+ object->command_lists = memory;
+ memory = &object->command_lists[deferred->command_list_count];
object->command_list_count = deferred->command_list_count;
memcpy(object->command_lists, deferred->command_lists,
deferred->command_list_count * sizeof(*object->command_lists));
/* Transfer our references to the command lists to the command list. */
- if (!(object->queries = heap_alloc(deferred->query_count * sizeof(*object->queries))))
- goto out_free_command_lists;
+ object->queries = memory;
+ memory = &object->queries[deferred->query_count];
object->query_count = deferred->query_count;
memcpy(object->queries, deferred->queries, deferred->query_count * sizeof(*object->queries));
/* Transfer our references to the queries to the command list. */
+ object->data = memory;
+ object->data_size = deferred->data_size;
+ memcpy(object->data, deferred->data, deferred->data_size);
+
deferred->data_size = 0;
deferred->resource_count = 0;
deferred->upload_count = 0;
@@ -3789,16 +3793,4 @@ HRESULT CDECL wined3d_deferred_context_record_command_list(struct wined3d_device
*list = object;
return S_OK;
-
-out_free_command_lists:
- heap_free(object->command_lists);
-out_free_uploads:
- heap_free(object->uploads);
-out_free_resources:
- heap_free(object->resources);
-out_free_data:
- heap_free(object->data);
-out_free_list:
- heap_free(object);
- return E_OUTOFMEMORY;
}
--
2.30.2
2
1
The following patch removes some dead code. It is not clear to me
whether the FIXME should remain as it is so it has been left out.
David Kahurani (1):
dlls/ntdll: Remove dead code
dlls/ntdll/unix/system.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
--
2.33.0
6
8
[PATCH vkd3d 5/6] vkd3d-shader/sm1: Introduce a parser for the legacy D3D byte-code format.
by Henri Verbeet Oct. 6, 2021
by Henri Verbeet Oct. 6, 2021
Oct. 6, 2021
This is largely derived from the parser in Wine/wined3d, as of wine-6.18.
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
Makefile.am | 1 +
include/private/vkd3d_debug.h | 1 +
include/vkd3d_shader.h | 5 +
libs/vkd3d-common/debug.c | 18 +-
libs/vkd3d-shader/d3dbc.c | 958 +++++++++++++++++++++++
libs/vkd3d-shader/vkd3d_shader_main.c | 50 ++
libs/vkd3d-shader/vkd3d_shader_private.h | 12 +
programs/vkd3d-compiler/main.c | 4 +
tests/vkd3d_shader_api.c | 89 +++
9 files changed, 1133 insertions(+), 5 deletions(-)
create mode 100644 libs/vkd3d-shader/d3dbc.c
diff --git a/Makefile.am b/Makefile.am
index ee3d7495..eaa4f816 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -184,6 +184,7 @@ libvkd3d_shader_la_SOURCES = \
include/private/vkd3d_memory.h \
include/vkd3d_shader.h \
libs/vkd3d-shader/checksum.c \
+ libs/vkd3d-shader/d3dbc.c \
libs/vkd3d-shader/dxbc.c \
libs/vkd3d-shader/glsl.c \
libs/vkd3d-shader/hlsl.c \
diff --git a/include/private/vkd3d_debug.h b/include/private/vkd3d_debug.h
index a206a92b..8ab653ae 100644
--- a/include/private/vkd3d_debug.h
+++ b/include/private/vkd3d_debug.h
@@ -51,6 +51,7 @@ void vkd3d_dbg_printf(enum vkd3d_dbg_level level, const char *function, const ch
const char *vkd3d_dbg_sprintf(const char *fmt, ...) VKD3D_PRINTF_FUNC(1, 2);
const char *vkd3d_dbg_vsprintf(const char *fmt, va_list args);
const char *debugstr_a(const char *str);
+const char *debugstr_an(const char *str, size_t n);
const char *debugstr_w(const WCHAR *wstr, size_t wchar_size);
#define VKD3D_DBG_LOG(level) \
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h
index 58e507b7..37b5936d 100644
--- a/include/vkd3d_shader.h
+++ b/include/vkd3d_shader.h
@@ -467,6 +467,11 @@ enum vkd3d_shader_source_type
VKD3D_SHADER_SOURCE_DXBC_TPF,
/** High-Level Shader Language source code. */
VKD3D_SHADER_SOURCE_HLSL,
+ /**
+ * Legacy Direct3D byte-code. This is the format used for Direct3D shader
+ * model 1, 2, and 3 shaders.
+ */
+ VKD3D_SHADER_SOURCE_D3D_BYTECODE,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_SOURCE_TYPE),
};
diff --git a/libs/vkd3d-common/debug.c b/libs/vkd3d-common/debug.c
index dcf53fa9..4868f3fb 100644
--- a/libs/vkd3d-common/debug.c
+++ b/libs/vkd3d-common/debug.c
@@ -132,22 +132,25 @@ static int get_escape_char(int c)
}
}
-const char *debugstr_a(const char *str)
+const char *debugstr_an(const char *str, size_t n)
{
char *buffer, *ptr;
+ int escape_char;
char c;
if (!str)
return "(null)";
+ if (n == SIZE_MAX)
+ n = strlen(str);
ptr = buffer = get_buffer();
*ptr++ = '"';
- while ((c = *str++) && ptr <= buffer + VKD3D_DEBUG_BUFFER_SIZE - 8)
+ while (n-- && ptr <= buffer + VKD3D_DEBUG_BUFFER_SIZE - 8)
{
- int escape_char = get_escape_char(c);
+ c = *str++;
- if (escape_char)
+ if ((escape_char = get_escape_char(c)))
{
*ptr++ = '\\';
*ptr++ = escape_char;
@@ -167,7 +170,7 @@ const char *debugstr_a(const char *str)
}
*ptr++ = '"';
- if (c)
+ if (++n)
{
*ptr++ = '.';
*ptr++ = '.';
@@ -178,6 +181,11 @@ const char *debugstr_a(const char *str)
return buffer;
}
+const char *debugstr_a(const char *str)
+{
+ return debugstr_an(str, SIZE_MAX);
+}
+
static const char *debugstr_w16(const uint16_t *wstr)
{
char *buffer, *ptr;
diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c
new file mode 100644
index 00000000..267f9609
--- /dev/null
+++ b/libs/vkd3d-shader/d3dbc.c
@@ -0,0 +1,958 @@
+/*
+ * Copyright 2002-2003 Jason Edmeades
+ * Copyright 2002-2003 Raphael Junqueira
+ * Copyright 2004 Christian Costa
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2006 Ivan Gyurdiev
+ * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
+ * Copyright 2009, 2021 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "vkd3d_shader_private.h"
+
+#define VKD3D_SM1_VS 0xfffeu
+#define VKD3D_SM1_PS 0xffffu
+
+#define VKD3D_SM1_DCL_USAGE_SHIFT 0u
+#define VKD3D_SM1_DCL_USAGE_MASK (0xfu << VKD3D_SM1_DCL_USAGE_SHIFT)
+#define VKD3D_SM1_DCL_USAGE_INDEX_SHIFT 16u
+#define VKD3D_SM1_DCL_USAGE_INDEX_MASK (0xfu << VKD3D_SM1_DCL_USAGE_INDEX_SHIFT)
+
+#define VKD3D_SM1_RESOURCE_TYPE_SHIFT 27u
+#define VKD3D_SM1_RESOURCE_TYPE_MASK (0xfu << VKD3D_SM1_RESOURCE_TYPE_SHIFT)
+
+#define VKD3D_SM1_OPCODE_MASK 0x0000ffffu
+
+#define VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT 16u
+#define VKD3D_SM1_INSTRUCTION_FLAGS_MASK (0xffu << VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT)
+
+#define VKD3D_SM1_INSTRUCTION_LENGTH_SHIFT 24u
+#define VKD3D_SM1_INSTRUCTION_LENGTH_MASK (0xfu << VKD3D_SM1_INSTRUCTION_LENGTH_SHIFT)
+
+#define VKD3D_SM1_COISSUE (0x1u << 30u)
+
+#define VKD3D_SM1_COMMENT_SIZE_SHIFT 16u
+#define VKD3D_SM1_COMMENT_SIZE_MASK (0x7fffu << VKD3D_SM1_COMMENT_SIZE_SHIFT)
+
+#define VKD3D_SM1_INSTRUCTION_PREDICATED (0x1u << 28u)
+
+#define VKD3D_SM1_INSTRUCTION_PARAMETER (0x1u << 31u)
+
+#define VKD3D_SM1_REGISTER_NUMBER_MASK 0x000007ffu
+
+#define VKD3D_SM1_REGISTER_TYPE_SHIFT 28u
+#define VKD3D_SM1_REGISTER_TYPE_MASK (0x7u << VKD3D_SM1_REGISTER_TYPE_SHIFT)
+#define VKD3D_SM1_REGISTER_TYPE_SHIFT2 8u
+#define VKD3D_SM1_REGISTER_TYPE_MASK2 (0x18u << VKD3D_SM1_REGISTER_TYPE_SHIFT2)
+
+#define VKD3D_SM1_ADDRESS_MODE_SHIFT 13u
+#define VKD3D_SM1_ADDRESS_MODE_MASK (0x1u << VKD3D_SM1_ADDRESS_MODE_SHIFT)
+
+#define VKD3D_SM1_DST_MODIFIER_SHIFT 20u
+#define VKD3D_SM1_DST_MODIFIER_MASK (0xfu << VKD3D_SM1_DST_MODIFIER_SHIFT)
+
+#define VKD3D_SM1_DSTSHIFT_SHIFT 24u
+#define VKD3D_SM1_DSTSHIFT_MASK (0xfu << VKD3D_SM1_DSTSHIFT_SHIFT)
+
+#define VKD3D_SM1_WRITEMASK_SHIFT 16u
+#define VKD3D_SM1_WRITEMASK_MASK (0xfu << VKD3D_SM1_WRITEMASK_SHIFT)
+
+#define VKD3D_SM1_SWIZZLE_SHIFT 16u
+#define VKD3D_SM1_SWIZZLE_MASK (0xffu << VKD3D_SM1_SWIZZLE_SHIFT)
+#define VKD3D_SM1_SWIZZLE_DEFAULT (0u | (1u << 2) | (2u << 4) | (3u << 6))
+
+#define VKD3D_SM1_SWIZZLE_COMPONENT_SHIFT(idx) (2u * (idx))
+#define VKD3D_SM1_SWIZZLE_COMPONENT_MASK(idx) (0x3u << VKD3D_SM1_SWIZZLE_COMPONENT_SHIFT(idx))
+
+#define VKD3D_SM1_SRC_MODIFIER_SHIFT 24u
+#define VKD3D_SM1_SRC_MODIFIER_MASK (0xfu << VKD3D_SM1_SRC_MODIFIER_SHIFT)
+
+#define VKD3D_SM1_END 0x0000ffffu
+
+#define VKD3D_SM1_VERSION_MAJOR(version) (((version) >> 8u) & 0xffu)
+#define VKD3D_SM1_VERSION_MINOR(version) (((version) >> 0u) & 0xffu)
+
+enum vkd3d_sm1_address_mode_type
+{
+ VKD3D_SM1_ADDRESS_MODE_ABSOLUTE = 0x0,
+ VKD3D_SM1_ADDRESS_MODE_RELATIVE = 0x1,
+};
+
+enum vkd3d_sm1_resource_type
+{
+ VKD3D_SM1_RESOURCE_UNKNOWN = 0x0,
+ VKD3D_SM1_RESOURCE_TEXTURE_1D = 0x1,
+ VKD3D_SM1_RESOURCE_TEXTURE_2D = 0x2,
+ VKD3D_SM1_RESOURCE_TEXTURE_CUBE = 0x3,
+ VKD3D_SM1_RESOURCE_TEXTURE_3D = 0x4,
+};
+
+enum vkd3d_sm1_opcode
+{
+ VKD3D_SM1_OP_NOP = 0x00,
+ VKD3D_SM1_OP_MOV = 0x01,
+ VKD3D_SM1_OP_ADD = 0x02,
+ VKD3D_SM1_OP_SUB = 0x03,
+ VKD3D_SM1_OP_MAD = 0x04,
+ VKD3D_SM1_OP_MUL = 0x05,
+ VKD3D_SM1_OP_RCP = 0x06,
+ VKD3D_SM1_OP_RSQ = 0x07,
+ VKD3D_SM1_OP_DP3 = 0x08,
+ VKD3D_SM1_OP_DP4 = 0x09,
+ VKD3D_SM1_OP_MIN = 0x0a,
+ VKD3D_SM1_OP_MAX = 0x0b,
+ VKD3D_SM1_OP_SLT = 0x0c,
+ VKD3D_SM1_OP_SGE = 0x0d,
+ VKD3D_SM1_OP_EXP = 0x0e,
+ VKD3D_SM1_OP_LOG = 0x0f,
+ VKD3D_SM1_OP_LIT = 0x10,
+ VKD3D_SM1_OP_DST = 0x11,
+ VKD3D_SM1_OP_LRP = 0x12,
+ VKD3D_SM1_OP_FRC = 0x13,
+ VKD3D_SM1_OP_M4x4 = 0x14,
+ VKD3D_SM1_OP_M4x3 = 0x15,
+ VKD3D_SM1_OP_M3x4 = 0x16,
+ VKD3D_SM1_OP_M3x3 = 0x17,
+ VKD3D_SM1_OP_M3x2 = 0x18,
+ VKD3D_SM1_OP_CALL = 0x19,
+ VKD3D_SM1_OP_CALLNZ = 0x1a,
+ VKD3D_SM1_OP_LOOP = 0x1b,
+ VKD3D_SM1_OP_RET = 0x1c,
+ VKD3D_SM1_OP_ENDLOOP = 0x1d,
+ VKD3D_SM1_OP_LABEL = 0x1e,
+ VKD3D_SM1_OP_DCL = 0x1f,
+ VKD3D_SM1_OP_POW = 0x20,
+ VKD3D_SM1_OP_CRS = 0x21,
+ VKD3D_SM1_OP_SGN = 0x22,
+ VKD3D_SM1_OP_ABS = 0x23,
+ VKD3D_SM1_OP_NRM = 0x24,
+ VKD3D_SM1_OP_SINCOS = 0x25,
+ VKD3D_SM1_OP_REP = 0x26,
+ VKD3D_SM1_OP_ENDREP = 0x27,
+ VKD3D_SM1_OP_IF = 0x28,
+ VKD3D_SM1_OP_IFC = 0x29,
+ VKD3D_SM1_OP_ELSE = 0x2a,
+ VKD3D_SM1_OP_ENDIF = 0x2b,
+ VKD3D_SM1_OP_BREAK = 0x2c,
+ VKD3D_SM1_OP_BREAKC = 0x2d,
+ VKD3D_SM1_OP_MOVA = 0x2e,
+ VKD3D_SM1_OP_DEFB = 0x2f,
+ VKD3D_SM1_OP_DEFI = 0x30,
+
+ VKD3D_SM1_OP_TEXCOORD = 0x40,
+ VKD3D_SM1_OP_TEXKILL = 0x41,
+ VKD3D_SM1_OP_TEX = 0x42,
+ VKD3D_SM1_OP_TEXBEM = 0x43,
+ VKD3D_SM1_OP_TEXBEML = 0x44,
+ VKD3D_SM1_OP_TEXREG2AR = 0x45,
+ VKD3D_SM1_OP_TEXREG2GB = 0x46,
+ VKD3D_SM1_OP_TEXM3x2PAD = 0x47,
+ VKD3D_SM1_OP_TEXM3x2TEX = 0x48,
+ VKD3D_SM1_OP_TEXM3x3PAD = 0x49,
+ VKD3D_SM1_OP_TEXM3x3TEX = 0x4a,
+ VKD3D_SM1_OP_TEXM3x3DIFF = 0x4b,
+ VKD3D_SM1_OP_TEXM3x3SPEC = 0x4c,
+ VKD3D_SM1_OP_TEXM3x3VSPEC = 0x4d,
+ VKD3D_SM1_OP_EXPP = 0x4e,
+ VKD3D_SM1_OP_LOGP = 0x4f,
+ VKD3D_SM1_OP_CND = 0x50,
+ VKD3D_SM1_OP_DEF = 0x51,
+ VKD3D_SM1_OP_TEXREG2RGB = 0x52,
+ VKD3D_SM1_OP_TEXDP3TEX = 0x53,
+ VKD3D_SM1_OP_TEXM3x2DEPTH = 0x54,
+ VKD3D_SM1_OP_TEXDP3 = 0x55,
+ VKD3D_SM1_OP_TEXM3x3 = 0x56,
+ VKD3D_SM1_OP_TEXDEPTH = 0x57,
+ VKD3D_SM1_OP_CMP = 0x58,
+ VKD3D_SM1_OP_BEM = 0x59,
+ VKD3D_SM1_OP_DP2ADD = 0x5a,
+ VKD3D_SM1_OP_DSX = 0x5b,
+ VKD3D_SM1_OP_DSY = 0x5c,
+ VKD3D_SM1_OP_TEXLDD = 0x5d,
+ VKD3D_SM1_OP_SETP = 0x5e,
+ VKD3D_SM1_OP_TEXLDL = 0x5f,
+ VKD3D_SM1_OP_BREAKP = 0x60,
+
+ VKD3D_SM1_OP_PHASE = 0xfffd,
+ VKD3D_SM1_OP_COMMENT = 0xfffe,
+ VKD3D_SM1_OP_END = 0Xffff,
+};
+
+struct vkd3d_sm1_opcode_info
+{
+ enum vkd3d_sm1_opcode sm1_opcode;
+ unsigned int dst_count;
+ unsigned int src_count;
+ enum vkd3d_shader_opcode vkd3d_opcode;
+ struct
+ {
+ unsigned int major, minor;
+ } min_version, max_version;
+};
+
+struct vkd3d_shader_sm1_parser
+{
+ const struct vkd3d_sm1_opcode_info *opcode_table;
+ const uint32_t *start, *end;
+ bool abort;
+
+ struct vkd3d_shader_src_param src_rel_addr[4];
+ struct vkd3d_shader_src_param pred_rel_addr;
+ struct vkd3d_shader_src_param dst_rel_addr;
+ struct vkd3d_shader_src_param src_param[4];
+ struct vkd3d_shader_src_param pred_param;
+ struct vkd3d_shader_dst_param dst_param;
+
+ struct vkd3d_shader_parser p;
+};
+
+/* This table is not order or position dependent. */
+static const struct vkd3d_sm1_opcode_info vs_opcode_table[] =
+{
+ /* Arithmetic */
+ {VKD3D_SM1_OP_NOP, 0, 0, VKD3DSIH_NOP},
+ {VKD3D_SM1_OP_MOV, 1, 1, VKD3DSIH_MOV},
+ {VKD3D_SM1_OP_MOVA, 1, 1, VKD3DSIH_MOVA, {2, 0}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_ADD, 1, 2, VKD3DSIH_ADD},
+ {VKD3D_SM1_OP_SUB, 1, 2, VKD3DSIH_SUB},
+ {VKD3D_SM1_OP_MAD, 1, 3, VKD3DSIH_MAD},
+ {VKD3D_SM1_OP_MUL, 1, 2, VKD3DSIH_MUL},
+ {VKD3D_SM1_OP_RCP, 1, 1, VKD3DSIH_RCP},
+ {VKD3D_SM1_OP_RSQ, 1, 1, VKD3DSIH_RSQ},
+ {VKD3D_SM1_OP_DP3, 1, 2, VKD3DSIH_DP3},
+ {VKD3D_SM1_OP_DP4, 1, 2, VKD3DSIH_DP4},
+ {VKD3D_SM1_OP_MIN, 1, 2, VKD3DSIH_MIN},
+ {VKD3D_SM1_OP_MAX, 1, 2, VKD3DSIH_MAX},
+ {VKD3D_SM1_OP_SLT, 1, 2, VKD3DSIH_SLT},
+ {VKD3D_SM1_OP_SGE, 1, 2, VKD3DSIH_SGE},
+ {VKD3D_SM1_OP_ABS, 1, 1, VKD3DSIH_ABS},
+ {VKD3D_SM1_OP_EXP, 1, 1, VKD3DSIH_EXP},
+ {VKD3D_SM1_OP_LOG, 1, 1, VKD3DSIH_LOG},
+ {VKD3D_SM1_OP_EXPP, 1, 1, VKD3DSIH_EXPP},
+ {VKD3D_SM1_OP_LOGP, 1, 1, VKD3DSIH_LOGP},
+ {VKD3D_SM1_OP_LIT, 1, 1, VKD3DSIH_LIT},
+ {VKD3D_SM1_OP_DST, 1, 2, VKD3DSIH_DST},
+ {VKD3D_SM1_OP_LRP, 1, 3, VKD3DSIH_LRP},
+ {VKD3D_SM1_OP_FRC, 1, 1, VKD3DSIH_FRC},
+ {VKD3D_SM1_OP_POW, 1, 2, VKD3DSIH_POW},
+ {VKD3D_SM1_OP_CRS, 1, 2, VKD3DSIH_CRS},
+ {VKD3D_SM1_OP_SGN, 1, 3, VKD3DSIH_SGN, {2, 0}, { 2, 1}},
+ {VKD3D_SM1_OP_SGN, 1, 1, VKD3DSIH_SGN, {3, 0}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_NRM, 1, 1, VKD3DSIH_NRM,},
+ {VKD3D_SM1_OP_SINCOS, 1, 3, VKD3DSIH_SINCOS, {2, 0}, { 2, 1}},
+ {VKD3D_SM1_OP_SINCOS, 1, 1, VKD3DSIH_SINCOS, {3, 0}, {~0u, ~0u}},
+ /* Matrix */
+ {VKD3D_SM1_OP_M4x4, 1, 2, VKD3DSIH_M4x4},
+ {VKD3D_SM1_OP_M4x3, 1, 2, VKD3DSIH_M4x3},
+ {VKD3D_SM1_OP_M3x4, 1, 2, VKD3DSIH_M3x4},
+ {VKD3D_SM1_OP_M3x3, 1, 2, VKD3DSIH_M3x3},
+ {VKD3D_SM1_OP_M3x2, 1, 2, VKD3DSIH_M3x2},
+ /* Declarations */
+ {VKD3D_SM1_OP_DCL, 0, 2, VKD3DSIH_DCL},
+ /* Constant definitions */
+ {VKD3D_SM1_OP_DEF, 1, 4, VKD3DSIH_DEF},
+ {VKD3D_SM1_OP_DEFB, 1, 1, VKD3DSIH_DEFB},
+ {VKD3D_SM1_OP_DEFI, 1, 4, VKD3DSIH_DEFI},
+ /* Control flow */
+ {VKD3D_SM1_OP_REP, 0, 1, VKD3DSIH_REP, {2, 0}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_ENDREP, 0, 0, VKD3DSIH_ENDREP, {2, 0}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_IF, 0, 1, VKD3DSIH_IF, {2, 0}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_IFC, 0, 2, VKD3DSIH_IFC, {2, 1}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_ELSE, 0, 0, VKD3DSIH_ELSE, {2, 0}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_ENDIF, 0, 0, VKD3DSIH_ENDIF, {2, 0}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_BREAK, 0, 0, VKD3DSIH_BREAK, {2, 1}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_BREAKC, 0, 2, VKD3DSIH_BREAKC, {2, 1}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_BREAKP, 0, 1, VKD3DSIH_BREAKP},
+ {VKD3D_SM1_OP_CALL, 0, 1, VKD3DSIH_CALL, {2, 0}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_CALLNZ, 0, 2, VKD3DSIH_CALLNZ, {2, 0}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_LOOP, 0, 2, VKD3DSIH_LOOP, {2, 0}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_RET, 0, 0, VKD3DSIH_RET, {2, 0}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_ENDLOOP, 0, 0, VKD3DSIH_ENDLOOP, {2, 0}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_LABEL, 0, 1, VKD3DSIH_LABEL, {2, 0}, {~0u, ~0u}},
+
+ {VKD3D_SM1_OP_SETP, 1, 2, VKD3DSIH_SETP},
+ {VKD3D_SM1_OP_TEXLDL, 1, 2, VKD3DSIH_TEXLDL, {3, 0}, {~0u, ~0u}},
+ {0, 0, 0, VKD3DSIH_INVALID},
+};
+
+static const struct vkd3d_sm1_opcode_info ps_opcode_table[] =
+{
+ /* Arithmetic */
+ {VKD3D_SM1_OP_NOP, 0, 0, VKD3DSIH_NOP},
+ {VKD3D_SM1_OP_MOV, 1, 1, VKD3DSIH_MOV},
+ {VKD3D_SM1_OP_ADD, 1, 2, VKD3DSIH_ADD},
+ {VKD3D_SM1_OP_SUB, 1, 2, VKD3DSIH_SUB},
+ {VKD3D_SM1_OP_MAD, 1, 3, VKD3DSIH_MAD},
+ {VKD3D_SM1_OP_MUL, 1, 2, VKD3DSIH_MUL},
+ {VKD3D_SM1_OP_RCP, 1, 1, VKD3DSIH_RCP},
+ {VKD3D_SM1_OP_RSQ, 1, 1, VKD3DSIH_RSQ},
+ {VKD3D_SM1_OP_DP3, 1, 2, VKD3DSIH_DP3},
+ {VKD3D_SM1_OP_DP4, 1, 2, VKD3DSIH_DP4},
+ {VKD3D_SM1_OP_MIN, 1, 2, VKD3DSIH_MIN},
+ {VKD3D_SM1_OP_MAX, 1, 2, VKD3DSIH_MAX},
+ {VKD3D_SM1_OP_SLT, 1, 2, VKD3DSIH_SLT},
+ {VKD3D_SM1_OP_SGE, 1, 2, VKD3DSIH_SGE},
+ {VKD3D_SM1_OP_ABS, 1, 1, VKD3DSIH_ABS},
+ {VKD3D_SM1_OP_EXP, 1, 1, VKD3DSIH_EXP},
+ {VKD3D_SM1_OP_LOG, 1, 1, VKD3DSIH_LOG},
+ {VKD3D_SM1_OP_EXPP, 1, 1, VKD3DSIH_EXPP},
+ {VKD3D_SM1_OP_LOGP, 1, 1, VKD3DSIH_LOGP},
+ {VKD3D_SM1_OP_DST, 1, 2, VKD3DSIH_DST},
+ {VKD3D_SM1_OP_LRP, 1, 3, VKD3DSIH_LRP},
+ {VKD3D_SM1_OP_FRC, 1, 1, VKD3DSIH_FRC},
+ {VKD3D_SM1_OP_CND, 1, 3, VKD3DSIH_CND, {1, 0}, { 1, 4}},
+ {VKD3D_SM1_OP_CMP, 1, 3, VKD3DSIH_CMP, {1, 2}, { 3, 0}},
+ {VKD3D_SM1_OP_POW, 1, 2, VKD3DSIH_POW},
+ {VKD3D_SM1_OP_CRS, 1, 2, VKD3DSIH_CRS},
+ {VKD3D_SM1_OP_NRM, 1, 1, VKD3DSIH_NRM},
+ {VKD3D_SM1_OP_SINCOS, 1, 3, VKD3DSIH_SINCOS, {2, 0}, { 2, 1}},
+ {VKD3D_SM1_OP_SINCOS, 1, 1, VKD3DSIH_SINCOS, {3, 0}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_DP2ADD, 1, 3, VKD3DSIH_DP2ADD, {2, 0}, {~0u, ~0u}},
+ /* Matrix */
+ {VKD3D_SM1_OP_M4x4, 1, 2, VKD3DSIH_M4x4},
+ {VKD3D_SM1_OP_M4x3, 1, 2, VKD3DSIH_M4x3},
+ {VKD3D_SM1_OP_M3x4, 1, 2, VKD3DSIH_M3x4},
+ {VKD3D_SM1_OP_M3x3, 1, 2, VKD3DSIH_M3x3},
+ {VKD3D_SM1_OP_M3x2, 1, 2, VKD3DSIH_M3x2},
+ /* Declarations */
+ {VKD3D_SM1_OP_DCL, 0, 2, VKD3DSIH_DCL},
+ /* Constant definitions */
+ {VKD3D_SM1_OP_DEF, 1, 4, VKD3DSIH_DEF},
+ {VKD3D_SM1_OP_DEFB, 1, 1, VKD3DSIH_DEFB},
+ {VKD3D_SM1_OP_DEFI, 1, 4, VKD3DSIH_DEFI},
+ /* Control flow */
+ {VKD3D_SM1_OP_REP, 0, 1, VKD3DSIH_REP, {2, 1}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_ENDREP, 0, 0, VKD3DSIH_ENDREP, {2, 1}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_IF, 0, 1, VKD3DSIH_IF, {2, 1}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_IFC, 0, 2, VKD3DSIH_IFC, {2, 1}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_ELSE, 0, 0, VKD3DSIH_ELSE, {2, 1}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_ENDIF, 0, 0, VKD3DSIH_ENDIF, {2, 1}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_BREAK, 0, 0, VKD3DSIH_BREAK, {2, 1}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_BREAKC, 0, 2, VKD3DSIH_BREAKC, {2, 1}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_BREAKP, 0, 1, VKD3DSIH_BREAKP},
+ {VKD3D_SM1_OP_CALL, 0, 1, VKD3DSIH_CALL, {2, 1}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_CALLNZ, 0, 2, VKD3DSIH_CALLNZ, {2, 1}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_LOOP, 0, 2, VKD3DSIH_LOOP, {3, 0}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_RET, 0, 0, VKD3DSIH_RET, {2, 1}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_ENDLOOP, 0, 0, VKD3DSIH_ENDLOOP, {3, 0}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_LABEL, 0, 1, VKD3DSIH_LABEL, {2, 1}, {~0u, ~0u}},
+ /* Texture */
+ {VKD3D_SM1_OP_TEXCOORD, 1, 0, VKD3DSIH_TEXCOORD, {0, 0}, { 1, 3}},
+ {VKD3D_SM1_OP_TEXCOORD, 1, 1, VKD3DSIH_TEXCOORD, {1 ,4}, { 1, 4}},
+ {VKD3D_SM1_OP_TEXKILL, 1, 0, VKD3DSIH_TEXKILL, {1 ,0}, { 3, 0}},
+ {VKD3D_SM1_OP_TEX, 1, 0, VKD3DSIH_TEX, {0, 0}, { 1, 3}},
+ {VKD3D_SM1_OP_TEX, 1, 1, VKD3DSIH_TEX, {1, 4}, { 1, 4}},
+ {VKD3D_SM1_OP_TEX, 1, 2, VKD3DSIH_TEX, {2, 0}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_TEXBEM, 1, 1, VKD3DSIH_TEXBEM, {0, 0}, { 1, 3}},
+ {VKD3D_SM1_OP_TEXBEML, 1, 1, VKD3DSIH_TEXBEML, {1, 0}, { 1, 3}},
+ {VKD3D_SM1_OP_TEXREG2AR, 1, 1, VKD3DSIH_TEXREG2AR, {1, 0}, { 1, 3}},
+ {VKD3D_SM1_OP_TEXREG2GB, 1, 1, VKD3DSIH_TEXREG2GB, {1, 0}, { 1, 3}},
+ {VKD3D_SM1_OP_TEXREG2RGB, 1, 1, VKD3DSIH_TEXREG2RGB, {1, 2}, { 1, 3}},
+ {VKD3D_SM1_OP_TEXM3x2PAD, 1, 1, VKD3DSIH_TEXM3x2PAD, {1, 0}, { 1, 3}},
+ {VKD3D_SM1_OP_TEXM3x2TEX, 1, 1, VKD3DSIH_TEXM3x2TEX, {1, 0}, { 1, 3}},
+ {VKD3D_SM1_OP_TEXM3x3PAD, 1, 1, VKD3DSIH_TEXM3x3PAD, {1, 0}, { 1, 3}},
+ {VKD3D_SM1_OP_TEXM3x3DIFF, 1, 1, VKD3DSIH_TEXM3x3DIFF, {0, 0}, { 0, 0}},
+ {VKD3D_SM1_OP_TEXM3x3SPEC, 1, 2, VKD3DSIH_TEXM3x3SPEC, {1, 0}, { 1, 3}},
+ {VKD3D_SM1_OP_TEXM3x3VSPEC, 1, 1, VKD3DSIH_TEXM3x3VSPEC, {1, 0}, { 1, 3}},
+ {VKD3D_SM1_OP_TEXM3x3TEX, 1, 1, VKD3DSIH_TEXM3x3TEX, {1, 0}, { 1, 3}},
+ {VKD3D_SM1_OP_TEXDP3TEX, 1, 1, VKD3DSIH_TEXDP3TEX, {1, 2}, { 1, 3}},
+ {VKD3D_SM1_OP_TEXM3x2DEPTH, 1, 1, VKD3DSIH_TEXM3x2DEPTH, {1, 3}, { 1, 3}},
+ {VKD3D_SM1_OP_TEXDP3, 1, 1, VKD3DSIH_TEXDP3, {1, 2}, { 1, 3}},
+ {VKD3D_SM1_OP_TEXM3x3, 1, 1, VKD3DSIH_TEXM3x3, {1, 2}, { 1, 3}},
+ {VKD3D_SM1_OP_TEXDEPTH, 1, 0, VKD3DSIH_TEXDEPTH, {1, 4}, { 1, 4}},
+ {VKD3D_SM1_OP_BEM, 1, 2, VKD3DSIH_BEM, {1, 4}, { 1, 4}},
+ {VKD3D_SM1_OP_DSX, 1, 1, VKD3DSIH_DSX, {2, 1}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_DSY, 1, 1, VKD3DSIH_DSY, {2, 1}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_TEXLDD, 1, 4, VKD3DSIH_TEXLDD, {2, 1}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_SETP, 1, 2, VKD3DSIH_SETP},
+ {VKD3D_SM1_OP_TEXLDL, 1, 2, VKD3DSIH_TEXLDL, {3, 0}, {~0u, ~0u}},
+ {VKD3D_SM1_OP_PHASE, 0, 0, VKD3DSIH_PHASE},
+ {0, 0, 0, VKD3DSIH_INVALID},
+};
+
+static const enum vkd3d_shader_resource_type resource_type_table[] =
+{
+ /* VKD3D_SM1_RESOURCE_UNKNOWN */ VKD3D_SHADER_RESOURCE_NONE,
+ /* VKD3D_SM1_RESOURCE_TEXTURE_1D */ VKD3D_SHADER_RESOURCE_TEXTURE_1D,
+ /* VKD3D_SM1_RESOURCE_TEXTURE_2D */ VKD3D_SHADER_RESOURCE_TEXTURE_2D,
+ /* VKD3D_SM1_RESOURCE_TEXTURE_CUBE */ VKD3D_SHADER_RESOURCE_TEXTURE_CUBE,
+ /* VKD3D_SM1_RESOURCE_TEXTURE_3D */ VKD3D_SHADER_RESOURCE_TEXTURE_3D,
+};
+
+static struct vkd3d_shader_sm1_parser *vkd3d_shader_sm1_parser(struct vkd3d_shader_parser *parser)
+{
+ return CONTAINING_RECORD(parser, struct vkd3d_shader_sm1_parser, p);
+}
+
+static uint32_t read_u32(const uint32_t **ptr)
+{
+ return *(*ptr)++;
+}
+
+static bool shader_ver_ge(const struct vkd3d_shader_version *v, unsigned int major, unsigned int minor)
+{
+ return v->major > major || (v->major == major && v->minor >= minor);
+}
+
+static bool shader_ver_le(const struct vkd3d_shader_version *v, unsigned int major, unsigned int minor)
+{
+ return v->major < major || (v->major == major && v->minor <= minor);
+}
+
+static bool has_relative_address(uint32_t param)
+{
+ enum vkd3d_sm1_address_mode_type address_mode;
+
+ address_mode = (param & VKD3D_SM1_ADDRESS_MODE_MASK) >> VKD3D_SM1_ADDRESS_MODE_SHIFT;
+
+ return address_mode == VKD3D_SM1_ADDRESS_MODE_RELATIVE;
+}
+
+static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info(
+ const struct vkd3d_shader_sm1_parser *sm1, enum vkd3d_sm1_opcode opcode)
+{
+ const struct vkd3d_sm1_opcode_info *info;
+ unsigned int i = 0;
+
+ for (;;)
+ {
+ info = &sm1->opcode_table[i++];
+ if (info->vkd3d_opcode == VKD3DSIH_INVALID)
+ return NULL;
+
+ if (opcode == info->sm1_opcode
+ && shader_ver_ge(&sm1->p.shader_version, info->min_version.major, info->min_version.minor)
+ && (shader_ver_le(&sm1->p.shader_version, info->max_version.major, info->max_version.minor)
+ || !info->max_version.major))
+ return info;
+ }
+}
+
+static unsigned int shader_sm1_get_swizzle_component(uint32_t swizzle, unsigned int idx)
+{
+ return (swizzle & VKD3D_SM1_SWIZZLE_COMPONENT_MASK(idx)) >> VKD3D_SM1_SWIZZLE_COMPONENT_SHIFT(idx);
+}
+
+static uint32_t swizzle_from_sm1(uint32_t swizzle)
+{
+ return vkd3d_shader_create_swizzle(shader_sm1_get_swizzle_component(swizzle, 0),
+ shader_sm1_get_swizzle_component(swizzle, 1),
+ shader_sm1_get_swizzle_component(swizzle, 2),
+ shader_sm1_get_swizzle_component(swizzle, 3));
+}
+
+static void shader_sm1_parse_src_param(uint32_t param, const struct vkd3d_shader_src_param *rel_addr,
+ struct vkd3d_shader_src_param *src)
+{
+ src->reg.type = ((param & VKD3D_SM1_REGISTER_TYPE_MASK) >> VKD3D_SM1_REGISTER_TYPE_SHIFT)
+ | ((param & VKD3D_SM1_REGISTER_TYPE_MASK2) >> VKD3D_SM1_REGISTER_TYPE_SHIFT2);
+ src->reg.precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT;
+ src->reg.non_uniform = false;
+ src->reg.data_type = VKD3D_DATA_FLOAT;
+ src->reg.idx[0].offset = param & VKD3D_SM1_REGISTER_NUMBER_MASK;
+ src->reg.idx[0].rel_addr = rel_addr;
+ src->reg.idx[1].offset = ~0u;
+ src->reg.idx[1].rel_addr = NULL;
+ src->reg.idx[2].offset = ~0u;
+ src->reg.idx[2].rel_addr = NULL;
+ src->swizzle = swizzle_from_sm1((param & VKD3D_SM1_SWIZZLE_MASK) >> VKD3D_SM1_SWIZZLE_SHIFT);
+ src->modifiers = (param & VKD3D_SM1_SRC_MODIFIER_MASK) >> VKD3D_SM1_SRC_MODIFIER_SHIFT;
+}
+
+static void shader_sm1_parse_dst_param(uint32_t param, const struct vkd3d_shader_src_param *rel_addr,
+ struct vkd3d_shader_dst_param *dst)
+{
+ dst->reg.type = ((param & VKD3D_SM1_REGISTER_TYPE_MASK) >> VKD3D_SM1_REGISTER_TYPE_SHIFT)
+ | ((param & VKD3D_SM1_REGISTER_TYPE_MASK2) >> VKD3D_SM1_REGISTER_TYPE_SHIFT2);
+ dst->reg.precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT;
+ dst->reg.non_uniform = false;
+ dst->reg.data_type = VKD3D_DATA_FLOAT;
+ dst->reg.idx[0].offset = param & VKD3D_SM1_REGISTER_NUMBER_MASK;
+ dst->reg.idx[0].rel_addr = rel_addr;
+ dst->reg.idx[1].offset = ~0u;
+ dst->reg.idx[1].rel_addr = NULL;
+ dst->reg.idx[2].offset = ~0u;
+ dst->reg.idx[2].rel_addr = NULL;
+ dst->write_mask = (param & VKD3D_SM1_WRITEMASK_MASK) >> VKD3D_SM1_WRITEMASK_SHIFT;
+ dst->modifiers = (param & VKD3D_SM1_DST_MODIFIER_MASK) >> VKD3D_SM1_DST_MODIFIER_SHIFT;
+ dst->shift = (param & VKD3D_SM1_DSTSHIFT_MASK) >> VKD3D_SM1_DSTSHIFT_SHIFT;
+}
+
+/* Read a parameter token from the input stream, and possibly a relative
+ * addressing token. */
+static void shader_sm1_read_param(struct vkd3d_shader_sm1_parser *sm1,
+ const uint32_t **ptr, uint32_t *token, uint32_t *addr_token)
+{
+ if (*ptr >= sm1->end)
+ {
+ vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_UNEXPECTED_EOF,
+ "Attempted to read a parameter token, but no more tokens are remaining.");
+ sm1->abort = true;
+ *token = 0;
+ return;
+ }
+ *token = read_u32(ptr);
+ if (!has_relative_address(*token))
+ return;
+
+ /* PS >= 3.0 have relative addressing (with token)
+ * VS >= 2.0 have relative addressing (with token)
+ * VS >= 1.0 < 2.0 have relative addressing (without token)
+ * The version check below should work in general. */
+ if (sm1->p.shader_version.major < 2)
+ {
+ *addr_token = (1u << 31)
+ | ((VKD3DSPR_ADDR << VKD3D_SM1_REGISTER_TYPE_SHIFT2) & VKD3D_SM1_REGISTER_TYPE_MASK2)
+ | ((VKD3DSPR_ADDR << VKD3D_SM1_REGISTER_TYPE_SHIFT) & VKD3D_SM1_REGISTER_TYPE_MASK)
+ | (VKD3D_SM1_SWIZZLE_DEFAULT << VKD3D_SM1_SWIZZLE_SHIFT);
+ return;
+ }
+
+ if (*ptr >= sm1->end)
+ {
+ vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_UNEXPECTED_EOF,
+ "Attempted to read an indirect addressing token, but no more tokens are remaining.");
+ sm1->abort = true;
+ *addr_token = 0;
+ return;
+ }
+ *addr_token = read_u32(ptr);
+}
+
+/* Skip the parameter tokens for an opcode. */
+static void shader_sm1_skip_opcode(const struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr,
+ const struct vkd3d_sm1_opcode_info *opcode_info, uint32_t opcode_token)
+{
+ unsigned int length;
+
+ /* Version 2.0+ shaders may contain address tokens, but fortunately they
+ * have a useful length mask - use it here. Version 1.x shaders contain no
+ * such tokens. */
+ if (sm1->p.shader_version.major >= 2)
+ {
+ length = (opcode_token & VKD3D_SM1_INSTRUCTION_LENGTH_MASK) >> VKD3D_SM1_INSTRUCTION_LENGTH_SHIFT;
+ *ptr += length;
+ return;
+ }
+
+ *ptr += (opcode_info->dst_count + opcode_info->src_count);
+}
+
+static void shader_sm1_destroy(struct vkd3d_shader_parser *parser)
+{
+ struct vkd3d_shader_sm1_parser *sm1 = vkd3d_shader_sm1_parser(parser);
+
+ free_shader_desc(&sm1->p.shader_desc);
+ vkd3d_free(sm1);
+}
+
+static void shader_sm1_read_src_param(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr,
+ struct vkd3d_shader_src_param *src_param, struct vkd3d_shader_src_param *src_rel_addr)
+{
+ uint32_t token, addr_token;
+
+ shader_sm1_read_param(sm1, ptr, &token, &addr_token);
+ if (has_relative_address(token))
+ shader_sm1_parse_src_param(addr_token, NULL, src_rel_addr);
+ else
+ src_rel_addr = NULL;
+ shader_sm1_parse_src_param(token, src_rel_addr, src_param);
+}
+
+static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr,
+ struct vkd3d_shader_dst_param *dst_param, struct vkd3d_shader_src_param *dst_rel_addr)
+{
+ uint32_t token, addr_token;
+
+ shader_sm1_read_param(sm1, ptr, &token, &addr_token);
+ if (has_relative_address(token))
+ shader_sm1_parse_src_param(addr_token, NULL, dst_rel_addr);
+ else
+ dst_rel_addr = NULL;
+ shader_sm1_parse_dst_param(token, dst_rel_addr, dst_param);
+}
+
+static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1,
+ const uint32_t **ptr, struct vkd3d_shader_semantic *semantic)
+{
+ enum vkd3d_sm1_resource_type resource_type;
+ struct vkd3d_shader_register_range *range;
+ uint32_t usage_token, dst_token;
+
+ if (*ptr >= sm1->end || sm1->end - *ptr < 2)
+ {
+ vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_UNEXPECTED_EOF,
+ "Attempted to read a declaration instruction, but not enough tokens are remaining.");
+ sm1->abort = true;
+ return;
+ }
+
+ usage_token = read_u32(ptr);
+ dst_token = read_u32(ptr);
+
+ semantic->usage = (usage_token & VKD3D_SM1_DCL_USAGE_MASK) >> VKD3D_SM1_DCL_USAGE_SHIFT;
+ semantic->usage_idx = (usage_token & VKD3D_SM1_DCL_USAGE_INDEX_MASK) >> VKD3D_SM1_DCL_USAGE_INDEX_SHIFT;
+ resource_type = (usage_token & VKD3D_SM1_RESOURCE_TYPE_MASK) >> VKD3D_SM1_RESOURCE_TYPE_SHIFT;
+ if (resource_type >= ARRAY_SIZE(resource_type_table))
+ {
+ vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_INVALID_RESOURCE_TYPE,
+ "Invalid resource type %#x.", resource_type);
+ semantic->resource_type = VKD3D_SHADER_RESOURCE_NONE;
+ }
+ else
+ {
+ semantic->resource_type = resource_type_table[resource_type];
+ }
+ semantic->resource_data_type[0] = VKD3D_DATA_FLOAT;
+ semantic->resource_data_type[1] = VKD3D_DATA_FLOAT;
+ semantic->resource_data_type[2] = VKD3D_DATA_FLOAT;
+ semantic->resource_data_type[3] = VKD3D_DATA_FLOAT;
+ shader_sm1_parse_dst_param(dst_token, NULL, &semantic->resource.reg);
+ range = &semantic->resource.range;
+ range->space = 0;
+ range->first = range->last = semantic->resource.reg.reg.idx[0].offset;
+}
+
+static void shader_sm1_read_immconst(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr,
+ struct vkd3d_shader_src_param *src_param, enum vkd3d_immconst_type type, enum vkd3d_data_type data_type)
+{
+ unsigned int count = type == VKD3D_IMMCONST_VEC4 ? 4 : 1;
+
+ if (*ptr >= sm1->end || sm1->end - *ptr < count)
+ {
+ vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_UNEXPECTED_EOF,
+ "Attempted to read a constant definition, but not enough tokens are remaining. "
+ "%zu token(s) available, %u required.", sm1->end - *ptr, count);
+ sm1->abort = true;
+ return;
+ }
+
+ src_param->reg.type = VKD3DSPR_IMMCONST;
+ src_param->reg.precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT;
+ src_param->reg.non_uniform = false;
+ src_param->reg.data_type = data_type;
+ src_param->reg.idx[0].offset = ~0u;
+ src_param->reg.idx[0].rel_addr = NULL;
+ src_param->reg.idx[1].offset = ~0u;
+ src_param->reg.idx[1].rel_addr = NULL;
+ src_param->reg.idx[2].offset = ~0u;
+ src_param->reg.idx[2].rel_addr = NULL;
+ src_param->reg.immconst_type = type;
+ memcpy(src_param->reg.u.immconst_uint, *ptr, count * sizeof(uint32_t));
+ src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE;
+ src_param->modifiers = 0;
+
+ *ptr += count;
+}
+
+static void shader_sm1_read_comment(struct vkd3d_shader_sm1_parser *sm1)
+{
+ const uint32_t **ptr = &sm1->p.ptr;
+ const char *comment;
+ unsigned int size;
+ size_t remaining;
+ uint32_t token;
+
+ if (*ptr >= sm1->end)
+ return;
+
+ remaining = sm1->end - *ptr;
+
+ token = **ptr;
+ while ((token & VKD3D_SM1_OPCODE_MASK) == VKD3D_SM1_OP_COMMENT)
+ {
+ size = (token & VKD3D_SM1_COMMENT_SIZE_MASK) >> VKD3D_SM1_COMMENT_SIZE_SHIFT;
+
+ if (size > --remaining)
+ {
+ vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_UNEXPECTED_EOF,
+ "Encountered a %u token comment, but only %zu token(s) is/are remaining.",
+ size, remaining);
+ return;
+ }
+
+ comment = (const char *)++(*ptr);
+ remaining -= size;
+ *ptr += size;
+
+ if (size > 1 && *(const uint32_t *)comment == TAG_TEXT)
+ {
+ const char *end = comment + size * sizeof(token);
+ const char *p = comment + sizeof(token);
+ const char *line;
+
+ TRACE("// TEXT\n");
+ for (line = p; line < end; line = p)
+ {
+ if (!(p = memchr(line, '\n', end - line)))
+ p = end;
+ else
+ ++p;
+ TRACE("// %s\n", debugstr_an(line, p - line));
+ }
+ }
+ else if (size)
+ {
+ TRACE("// %s\n", debugstr_an(comment, size * sizeof(token)));
+ }
+ else
+ break;
+
+ if (!remaining)
+ break;
+ token = **ptr;
+ }
+}
+
+static void shader_sm1_validate_instruction(struct vkd3d_shader_sm1_parser *sm1, struct vkd3d_shader_instruction *ins)
+{
+ if ((ins->handler_idx == VKD3DSIH_BREAKP || ins->handler_idx == VKD3DSIH_IF) && ins->flags)
+ {
+ vkd3d_shader_parser_warning(&sm1->p, VKD3D_SHADER_WARNING_D3DBC_IGNORED_INSTRUCTION_FLAGS,
+ "Ignoring unexpected instruction flags %#x.", ins->flags);
+ ins->flags = 0;
+ }
+}
+
+static void shader_sm1_read_instruction(struct vkd3d_shader_parser *parser, struct vkd3d_shader_instruction *ins)
+{
+ struct vkd3d_shader_sm1_parser *sm1 = vkd3d_shader_sm1_parser(parser);
+ const struct vkd3d_sm1_opcode_info *opcode_info;
+ const uint32_t **ptr = &parser->ptr;
+ uint32_t opcode_token;
+ const uint32_t *p;
+ unsigned int i;
+
+ shader_sm1_read_comment(sm1);
+
+ if (*ptr >= sm1->end)
+ {
+ WARN("End of byte-code, failed to read opcode.\n");
+ goto fail;
+ }
+
+ ++parser->location.line;
+ opcode_token = read_u32(ptr);
+ if (!(opcode_info = shader_sm1_get_opcode_info(sm1, opcode_token & VKD3D_SM1_OPCODE_MASK)))
+ {
+ vkd3d_shader_parser_error(parser, VKD3D_SHADER_ERROR_D3DBC_INVALID_OPCODE,
+ "Invalid opcode %#x (token 0x%08x, shader version %u.%u).",
+ opcode_token & VKD3D_SM1_OPCODE_MASK, opcode_token,
+ sm1->p.shader_version.major, sm1->p.shader_version.minor);
+ goto fail;
+ }
+
+ ins->handler_idx = opcode_info->vkd3d_opcode;
+ ins->flags = (opcode_token & VKD3D_SM1_INSTRUCTION_FLAGS_MASK) >> VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT;
+ ins->coissue = opcode_token & VKD3D_SM1_COISSUE;
+ ins->raw = false;
+ ins->structured = false;
+ ins->predicate = opcode_token & VKD3D_SM1_INSTRUCTION_PREDICATED ? &sm1->pred_param : NULL;
+ ins->dst_count = opcode_info->dst_count;
+ ins->dst = &sm1->dst_param;
+ ins->src_count = opcode_info->src_count;
+ ins->src = sm1->src_param;
+ ins->resource_type = VKD3D_SHADER_RESOURCE_NONE;
+ ins->resource_stride = 0;
+ ins->resource_data_type[0] = VKD3D_DATA_FLOAT;
+ ins->resource_data_type[1] = VKD3D_DATA_FLOAT;
+ ins->resource_data_type[2] = VKD3D_DATA_FLOAT;
+ ins->resource_data_type[3] = VKD3D_DATA_FLOAT;
+ memset(&ins->texel_offset, 0, sizeof(ins->texel_offset));
+
+ p = *ptr;
+ shader_sm1_skip_opcode(sm1, ptr, opcode_info, opcode_token);
+ if (*ptr > sm1->end)
+ {
+ vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_UNEXPECTED_EOF,
+ "The current instruction ends %zu token(s) past the end of the shader.",
+ *ptr - sm1->end);
+ goto fail;
+ }
+
+ if (ins->handler_idx == VKD3DSIH_DCL)
+ {
+ shader_sm1_read_semantic(sm1, &p, &ins->declaration.semantic);
+ }
+ else if (ins->handler_idx == VKD3DSIH_DEF)
+ {
+ shader_sm1_read_dst_param(sm1, &p, &sm1->dst_param, &sm1->dst_rel_addr);
+ shader_sm1_read_immconst(sm1, &p, &sm1->src_param[0], VKD3D_IMMCONST_VEC4, VKD3D_DATA_FLOAT);
+ }
+ else if (ins->handler_idx == VKD3DSIH_DEFB)
+ {
+ shader_sm1_read_dst_param(sm1, &p, &sm1->dst_param, &sm1->dst_rel_addr);
+ shader_sm1_read_immconst(sm1, &p, &sm1->src_param[0], VKD3D_IMMCONST_SCALAR, VKD3D_DATA_UINT);
+ }
+ else if (ins->handler_idx == VKD3DSIH_DEFI)
+ {
+ shader_sm1_read_dst_param(sm1, &p, &sm1->dst_param, &sm1->dst_rel_addr);
+ shader_sm1_read_immconst(sm1, &p, &sm1->src_param[0], VKD3D_IMMCONST_VEC4, VKD3D_DATA_INT);
+ }
+ else
+ {
+ /* Destination token */
+ if (ins->dst_count)
+ shader_sm1_read_dst_param(sm1, &p, &sm1->dst_param, &sm1->dst_rel_addr);
+
+ /* Predication token */
+ if (ins->predicate)
+ shader_sm1_read_src_param(sm1, &p, &sm1->pred_param, &sm1->pred_rel_addr);
+
+ /* Other source tokens */
+ for (i = 0; i < ins->src_count; ++i)
+ shader_sm1_read_src_param(sm1, &p, &sm1->src_param[i], &sm1->src_rel_addr[i]);
+ }
+
+ if (sm1->abort)
+ {
+ sm1->abort = false;
+ goto fail;
+ }
+
+ shader_sm1_validate_instruction(sm1, ins);
+ return;
+
+fail:
+ ins->handler_idx = VKD3DSIH_INVALID;
+ *ptr = sm1->end;
+}
+
+static bool shader_sm1_is_end(struct vkd3d_shader_parser *parser)
+{
+ struct vkd3d_shader_sm1_parser *sm1 = vkd3d_shader_sm1_parser(parser);
+ const uint32_t **ptr = &parser->ptr;
+
+ shader_sm1_read_comment(sm1);
+
+ if (*ptr >= sm1->end)
+ return true;
+
+ if (**ptr == VKD3D_SM1_END)
+ {
+ ++(*ptr);
+ return true;
+ }
+
+ return false;
+}
+
+static void shader_sm1_reset(struct vkd3d_shader_parser *parser)
+{
+ struct vkd3d_shader_sm1_parser *sm1 = vkd3d_shader_sm1_parser(parser);
+
+ parser->ptr = sm1->start;
+ parser->failed = false;
+}
+
+const struct vkd3d_shader_parser_ops shader_sm1_parser_ops =
+{
+ .parser_reset = shader_sm1_reset,
+ .parser_destroy = shader_sm1_destroy,
+ .parser_read_instruction = shader_sm1_read_instruction,
+ .parser_is_end = shader_sm1_is_end,
+};
+
+static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1,
+ const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context)
+{
+ const struct vkd3d_shader_location location = {.source_name = compile_info->source_name};
+ const uint32_t *code = compile_info->source.code;
+ size_t code_size = compile_info->source.size;
+ struct vkd3d_shader_desc *shader_desc;
+ struct vkd3d_shader_version version;
+ uint16_t shader_type;
+ size_t token_count;
+
+ code = compile_info->source.code;
+ code_size = compile_info->source.size;
+ token_count = code_size / sizeof(*sm1->start);
+
+ if (token_count < 2)
+ {
+ vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_D3DBC_UNEXPECTED_EOF,
+ "Invalid shader size %zu (token count %zu). At least 2 tokens are required.",
+ code_size, token_count);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ TRACE("Version: 0x%08x.\n", code[0]);
+
+ shader_type = code[0] >> 16;
+ version.major = VKD3D_SM1_VERSION_MAJOR(code[0]);
+ version.minor = VKD3D_SM1_VERSION_MINOR(code[0]);
+
+ switch (shader_type)
+ {
+ case VKD3D_SM1_VS:
+ version.type = VKD3D_SHADER_TYPE_VERTEX;
+ sm1->opcode_table = vs_opcode_table;
+ break;
+
+ case VKD3D_SM1_PS:
+ version.type = VKD3D_SHADER_TYPE_PIXEL;
+ sm1->opcode_table = ps_opcode_table;
+ break;
+
+ default:
+ vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_D3DBC_INVALID_VERSION_TOKEN,
+ "Invalid shader type %#x (token 0x%08x).", shader_type, code[0]);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ if (!shader_ver_le(&version, 3, 0))
+ {
+ vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_D3DBC_INVALID_VERSION_TOKEN,
+ "Invalid shader version %u.%u (token 0x%08x).", version.major, version.minor, code[0]);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ sm1->start = &code[1];
+ sm1->end = &code[token_count];
+
+ vkd3d_shader_parser_init(&sm1->p, message_context, compile_info->source_name, &version, &shader_sm1_parser_ops);
+ shader_desc = &sm1->p.shader_desc;
+ shader_desc->byte_code = code;
+ shader_desc->byte_code_size = code_size;
+ sm1->p.ptr = sm1->start;
+
+ return VKD3D_OK;
+}
+
+int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compile_info,
+ struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser)
+{
+ struct vkd3d_shader_sm1_parser *sm1;
+ int ret;
+
+ if (!(sm1 = vkd3d_calloc(1, sizeof(*sm1))))
+ {
+ ERR("Failed to allocate parser.\n");
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ }
+
+ if ((ret = shader_sm1_init(sm1, compile_info, message_context)) < 0)
+ {
+ WARN("Failed to initialise shader parser, ret %d.\n", ret);
+ vkd3d_free(sm1);
+ return ret;
+ }
+
+ *parser = &sm1->p;
+
+ return VKD3D_OK;
+}
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index 98607154..6c9301c2 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -337,6 +337,8 @@ static const char *shader_get_source_type_suffix(enum vkd3d_shader_source_type t
return "dxbc";
case VKD3D_SHADER_SOURCE_HLSL:
return "hlsl";
+ case VKD3D_SHADER_SOURCE_D3D_BYTECODE:
+ return "d3dbc";
default:
FIXME("Unhandled source type %#x.\n", type);
return "bin";
@@ -386,6 +388,16 @@ void VKD3D_PRINTF_FUNC(3, 4) vkd3d_shader_parser_error(struct vkd3d_shader_parse
parser->failed = true;
}
+void VKD3D_PRINTF_FUNC(3, 4) vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser,
+ enum vkd3d_shader_error error, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ vkd3d_shader_vwarning(parser->message_context, &parser->location, error, format, args);
+ va_end(args);
+}
+
static int vkd3d_shader_validate_compile_info(const struct vkd3d_shader_compile_info *compile_info,
bool validate_target_type)
{
@@ -1119,6 +1131,30 @@ static int compile_hlsl(const struct vkd3d_shader_compile_info *compile_info,
return ret;
}
+static int compile_d3d_bytecode(const struct vkd3d_shader_compile_info *compile_info,
+ struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context)
+{
+ struct vkd3d_shader_parser *parser;
+ int ret;
+
+ if ((ret = vkd3d_shader_sm1_parser_create(compile_info, message_context, &parser)) < 0)
+ {
+ WARN("Failed to initialise shader parser.\n");
+ return ret;
+ }
+
+ vkd3d_shader_dump_shader(compile_info->source_type, parser->shader_version.type, &compile_info->source);
+
+ if (compile_info->target_type == VKD3D_SHADER_TARGET_D3D_ASM)
+ {
+ ret = vkd3d_dxbc_binary_to_text(parser, compile_info, out);
+ vkd3d_shader_parser_destroy(parser);
+ return ret;
+ }
+
+ return VKD3D_ERROR;
+}
+
int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_code *out, char **messages)
{
@@ -1145,6 +1181,10 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
ret = compile_hlsl(compile_info, out, &message_context);
break;
+ case VKD3D_SHADER_SOURCE_D3D_BYTECODE:
+ ret = compile_d3d_bytecode(compile_info, out, &message_context);
+ break;
+
default:
assert(0);
}
@@ -1301,6 +1341,7 @@ const enum vkd3d_shader_source_type *vkd3d_shader_get_supported_source_types(uns
{
VKD3D_SHADER_SOURCE_DXBC_TPF,
VKD3D_SHADER_SOURCE_HLSL,
+ VKD3D_SHADER_SOURCE_D3D_BYTECODE,
};
TRACE("count %p.\n", count);
@@ -1327,6 +1368,11 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types(
VKD3D_SHADER_TARGET_DXBC_TPF,
};
+ static const enum vkd3d_shader_target_type d3dbc_types[] =
+ {
+ VKD3D_SHADER_TARGET_D3D_ASM,
+ };
+
TRACE("source_type %#x, count %p.\n", source_type, count);
switch (source_type)
@@ -1339,6 +1385,10 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types(
*count = ARRAY_SIZE(hlsl_types);
return hlsl_types;
+ case VKD3D_SHADER_SOURCE_D3D_BYTECODE:
+ *count = ARRAY_SIZE(d3dbc_types);
+ return d3dbc_types;
+
default:
*count = 0;
return NULL;
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index da12247a..cacba300 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -117,6 +117,13 @@ enum vkd3d_shader_error
VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300,
VKD3D_SHADER_ERROR_GLSL_INTERNAL = 6000,
+
+ VKD3D_SHADER_ERROR_D3DBC_UNEXPECTED_EOF = 7000,
+ VKD3D_SHADER_ERROR_D3DBC_INVALID_VERSION_TOKEN = 7001,
+ VKD3D_SHADER_ERROR_D3DBC_INVALID_OPCODE = 7002,
+ VKD3D_SHADER_ERROR_D3DBC_INVALID_RESOURCE_TYPE = 7003,
+
+ VKD3D_SHADER_WARNING_D3DBC_IGNORED_INSTRUCTION_FLAGS= 7300,
};
enum vkd3d_shader_opcode
@@ -918,6 +925,8 @@ void vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser,
void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
struct vkd3d_shader_message_context *message_context, const char *source_name,
const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops);
+void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser,
+ enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4);
static inline void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parser)
{
@@ -1029,6 +1038,8 @@ void vkd3d_shader_trace_text_(const char *text, size_t size, const char *functio
#define vkd3d_shader_trace_text(text, size) \
vkd3d_shader_trace_text_(text, size, __FUNCTION__)
+int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compile_info,
+ struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser);
int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser);
@@ -1217,6 +1228,7 @@ static inline void *vkd3d_find_struct_(const struct vkd3d_struct *chain,
#define TAG_RTS0 MAKE_TAG('R', 'T', 'S', '0')
#define TAG_SHDR MAKE_TAG('S', 'H', 'D', 'R')
#define TAG_SHEX MAKE_TAG('S', 'H', 'E', 'X')
+#define TAG_TEXT MAKE_TAG('T', 'E', 'X', 'T')
struct dxbc_writer_section
{
diff --git a/programs/vkd3d-compiler/main.c b/programs/vkd3d-compiler/main.c
index ac01d59a..4d7d628c 100644
--- a/programs/vkd3d-compiler/main.c
+++ b/programs/vkd3d-compiler/main.c
@@ -65,6 +65,10 @@ source_type_info[] =
{VKD3D_SHADER_SOURCE_HLSL,
"hlsl", "High Level Shader Language source code.\n",
false},
+ {VKD3D_SHADER_SOURCE_D3D_BYTECODE,
+ "d3dbc", "Legacy Direct3D byte-code.\n"
+ " This is the format used for Direct3D shader model 1, 2, and 3 shaders.\n",
+ true},
};
static const struct target_type_info
diff --git a/tests/vkd3d_shader_api.c b/tests/vkd3d_shader_api.c
index d0f3f5d2..c9045b81 100644
--- a/tests/vkd3d_shader_api.c
+++ b/tests/vkd3d_shader_api.c
@@ -227,6 +227,94 @@ static void test_version(void)
ok(minor == expected_minor, "Got unexpected minor version %u.\n", minor);
}
+static void test_d3dbc(void)
+{
+ struct vkd3d_shader_compile_info info;
+ struct vkd3d_shader_code d3d_asm;
+ int rc;
+
+ static const uint32_t vs_minimal[] =
+ {
+ 0xfffe0100, /* vs_1_0 */
+ 0x0000ffff, /* end */
+ };
+ static const uint32_t invalid_type[] =
+ {
+ 0x00010100, /* <invalid>_1_0 */
+ 0x0000ffff, /* end */
+ };
+ static const uint32_t invalid_version[] =
+ {
+ 0xfffe0400, /* vs_4_0 */
+ 0x0000ffff, /* end */
+ };
+ static const uint32_t ps[] =
+ {
+ 0xffff0101, /* ps_1_1 */
+ 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
+ 0x0000ffff, /* end */
+ };
+ static const char expected[] = "vs_1_0\n";
+
+ info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO;
+ info.next = NULL;
+ info.source.code = vs_minimal;
+ info.source.size = sizeof(vs_minimal);
+ info.source_type = VKD3D_SHADER_SOURCE_D3D_BYTECODE;
+ info.target_type = VKD3D_SHADER_TARGET_D3D_ASM;
+ info.options = NULL;
+ info.option_count = 0;
+ info.log_level = VKD3D_SHADER_LOG_NONE;
+ info.source_name = NULL;
+
+ rc = vkd3d_shader_compile(&info, &d3d_asm, NULL);
+ ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
+ ok(d3d_asm.size == strlen(expected), "Got unexpected size %zu.\n", d3d_asm.size);
+ ok(!memcmp(d3d_asm.code, expected, d3d_asm.size), "Got unexpected code \"%.*s\"\n",
+ (int)d3d_asm.size, (char *)d3d_asm.code);
+ vkd3d_shader_free_shader_code(&d3d_asm);
+
+ info.source.size = sizeof(vs_minimal) + 1;
+ rc = vkd3d_shader_compile(&info, &d3d_asm, NULL);
+ ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
+ vkd3d_shader_free_shader_code(&d3d_asm);
+
+ info.source.size = ~(size_t)0;
+ rc = vkd3d_shader_compile(&info, &d3d_asm, NULL);
+ ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
+ vkd3d_shader_free_shader_code(&d3d_asm);
+
+ info.source.size = sizeof(vs_minimal) - 1;
+ rc = vkd3d_shader_compile(&info, &d3d_asm, NULL);
+ ok(rc == VKD3D_ERROR_INVALID_SHADER, "Got unexpected error code %d.\n", rc);
+
+ info.source.code = invalid_type;
+ info.source.size = sizeof(invalid_type);
+ rc = vkd3d_shader_compile(&info, &d3d_asm, NULL);
+ ok(rc == VKD3D_ERROR_INVALID_SHADER, "Got unexpected error code %d.\n", rc);
+
+ info.source.code = invalid_version;
+ info.source.size = sizeof(invalid_version);
+ rc = vkd3d_shader_compile(&info, &d3d_asm, NULL);
+ ok(rc == VKD3D_ERROR_INVALID_SHADER, "Got unexpected error code %d.\n", rc);
+
+ info.source.code = ps;
+ info.source.size = sizeof(ps);
+ rc = vkd3d_shader_compile(&info, &d3d_asm, NULL);
+ ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
+ vkd3d_shader_free_shader_code(&d3d_asm);
+
+ /* Truncated before the destination parameter. */
+ info.source.size = sizeof(ps) - 3 * sizeof(*ps);
+ rc = vkd3d_shader_compile(&info, &d3d_asm, NULL);
+ ok(rc == VKD3D_ERROR_INVALID_SHADER, "Got unexpected error code %d.\n", rc);
+
+ /* Truncated before the source parameter. */
+ info.source.size = sizeof(ps) - 2 * sizeof(*ps);
+ rc = vkd3d_shader_compile(&info, &d3d_asm, NULL);
+ ok(rc == VKD3D_ERROR_INVALID_SHADER, "Got unexpected error code %d.\n", rc);
+}
+
START_TEST(vkd3d_shader_api)
{
setlocale(LC_ALL, "");
@@ -234,4 +322,5 @@ START_TEST(vkd3d_shader_api)
run_test(test_invalid_shaders);
run_test(test_vkd3d_shader_pfns);
run_test(test_version);
+ run_test(test_d3dbc);
}
--
2.20.1
2
1
[PATCH 1/3] user32/tests: Add optional focus winevents to correspond with focus hooks.
by Connor McAdams Oct. 6, 2021
by Connor McAdams Oct. 6, 2021
Oct. 6, 2021
Add optional EVENT_OBJECT_FOCUS winevents to correspond with optional
HCBT_SETFOCUS hooks.
Signed-off-by: Connor McAdams <cmcadams(a)codeweavers.com>
---
dlls/user32/tests/msg.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 43253953a9e..3776bd17cd8 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -1312,6 +1312,7 @@ static const struct message WmFirstDrawSetWindowPosSeq3[] = {
{ WM_NCACTIVATE, sent|optional },
{ WM_ACTIVATE, sent|optional },
{ HCBT_SETFOCUS, hook|optional },
+ { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 },
{ WM_SETFOCUS, sent|defwinproc|optional },
{ 0 }
};
@@ -13500,6 +13501,7 @@ static const struct message WmShow[] = {
{ HCBT_ACTIVATE, hook|optional }, /* win2000 doesn't send it */
{ WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, /* win2000 doesn't send it */
{ HCBT_SETFOCUS, hook|optional }, /* win2000 doesn't send it */
+ { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 },
{ WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE },
{ 0 }
};
@@ -13530,10 +13532,12 @@ static const struct message WmShowNoActivate_2[] = {
{ WM_MOVE, sent|defwinproc },
{ WM_SIZE, sent|wparam|defwinproc, SIZE_RESTORED },
{ HCBT_SETFOCUS, hook|optional },
+ { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 },
{ HCBT_ACTIVATE, hook|optional }, /* win2003 doesn't send it */
{ WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, /* win2003 doesn't send it */
{ WM_WINDOWPOSCHANGED, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE },
{ HCBT_SETFOCUS, hook|optional }, /* win2003 doesn't send it */
+ { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 },
{ EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|winevent_hook_todo, 0, 0 },
{ EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* Win7 seems to send this twice. */
{ EVENT_SYSTEM_MINIMIZEEND, winevent_hook|wparam|lparam|winevent_hook_todo, 0, 0 },
@@ -13560,6 +13564,7 @@ static const struct message WmRestore_1[] = {
{ HCBT_ACTIVATE, hook|optional }, /* win2000 doesn't send it */
{ WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, /* win2000 doesn't send it */
{ HCBT_SETFOCUS, hook|optional }, /* win2000 doesn't send it */
+ { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 },
{ WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED },
{ WM_MOVE, sent|defwinproc },
{ WM_SIZE, sent|wparam|defwinproc, SIZE_RESTORED },
@@ -13577,6 +13582,7 @@ static const struct message WmRestore_2[] = {
{ HCBT_ACTIVATE, hook|optional }, /* win2000 doesn't send it */
{ WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, /* win2000 doesn't send it */
{ HCBT_SETFOCUS, hook|optional }, /* win2000 doesn't send it */
+ { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 },
{ WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE },
{ 0 }
};
@@ -13595,6 +13601,7 @@ static const struct message WmRestore_3[] = {
{ WM_MOVE, sent|defwinproc },
{ WM_SIZE, sent|wparam|defwinproc, SIZE_MAXIMIZED },
{ HCBT_SETFOCUS, hook|optional }, /* win2003 sends it */
+ { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 },
{ EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|winevent_hook_todo, 0, 0 },
{ EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* Win7 seems to send this twice. */
{ EVENT_SYSTEM_MINIMIZEEND, winevent_hook|wparam|lparam|winevent_hook_todo, 0, 0 },
@@ -13681,6 +13688,7 @@ static const struct message WmMinimize_1[] = {
static const struct message WmMinimize_2[] = {
{ HCBT_MINMAX, hook|lparam, 0, SW_MINIMIZE },
{ HCBT_SETFOCUS, hook|optional },
+ { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 },
{ WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED, 0, SWP_NOACTIVATE },
{ EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam|winevent_hook_todo, 0, 0 },
{ WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED, 0, SWP_NOACTIVATE },
@@ -13757,6 +13765,7 @@ static const struct message WmShowMaximized_1[] = {
{ HCBT_ACTIVATE, hook|optional }, /* win2000 doesn't send it */
{ WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, /* win2000 doesn't send it */
{ HCBT_SETFOCUS, hook|optional }, /* win2000 doesn't send it */
+ { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 },
{ WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED },
{ WM_MOVE, sent|defwinproc },
{ WM_SIZE, sent|wparam|defwinproc, SIZE_MAXIMIZED },
@@ -14661,6 +14670,7 @@ static const struct message SetActiveWindowSeq0[] =
{ WM_GETTEXT, sent|defwinproc|optional },
{ WM_ACTIVATE, sent|wparam|optional, 1 },
{ HCBT_SETFOCUS, hook|optional },
+ { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 },
{ WM_KILLFOCUS, sent|defwinproc|optional },
{ WM_IME_SETCONTEXT, sent|defwinproc|optional },
{ WM_IME_SETCONTEXT, sent|defwinproc|optional },
--
2.25.1
2
3
[PATCH vkd3d 6/6] vkd3d-shader/sm1: Add support for vkd3d_shader_scan().
by Henri Verbeet Oct. 6, 2021
by Henri Verbeet Oct. 6, 2021
Oct. 6, 2021
Nominally, at least. Not all of the early shader models explicitly
declare resources and samplers, so those may currently get missed for
those.
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
libs/vkd3d-shader/vkd3d_shader_main.c | 51 ++++++++++++++++++++++-----
tests/vkd3d_shader_api.c | 3 ++
2 files changed, 45 insertions(+), 9 deletions(-)
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index 6c9301c2..d2045332 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -928,13 +928,12 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
return VKD3D_OK;
}
-static int scan_dxbc(const struct vkd3d_shader_compile_info *compile_info,
- struct vkd3d_shader_message_context *message_context)
+static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info,
+ struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser *parser)
{
struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info;
struct vkd3d_shader_instruction instruction;
struct vkd3d_shader_scan_context context;
- struct vkd3d_shader_parser *parser;
int ret;
if ((scan_descriptor_info = vkd3d_find_struct(compile_info->next, SCAN_DESCRIPTOR_INFO)))
@@ -945,12 +944,6 @@ static int scan_dxbc(const struct vkd3d_shader_compile_info *compile_info,
vkd3d_shader_scan_context_init(&context, compile_info, scan_descriptor_info, message_context);
- if ((ret = vkd3d_shader_sm4_parser_create(compile_info, message_context, &parser)) < 0)
- {
- vkd3d_shader_scan_context_cleanup(&context);
- return ret;
- }
-
if (TRACE_ON())
{
vkd3d_shader_trace(parser);
@@ -982,7 +975,42 @@ static int scan_dxbc(const struct vkd3d_shader_compile_info *compile_info,
done:
vkd3d_shader_scan_context_cleanup(&context);
+ return ret;
+}
+
+static int scan_dxbc(const struct vkd3d_shader_compile_info *compile_info,
+ struct vkd3d_shader_message_context *message_context)
+{
+ struct vkd3d_shader_parser *parser;
+ int ret;
+
+ if ((ret = vkd3d_shader_sm4_parser_create(compile_info, message_context, &parser)) < 0)
+ {
+ WARN("Failed to initialise shader parser.\n");
+ return ret;
+ }
+
+ ret = scan_with_parser(compile_info, message_context, parser);
+ vkd3d_shader_parser_destroy(parser);
+
+ return ret;
+}
+
+static int scan_d3dbc(const struct vkd3d_shader_compile_info *compile_info,
+ struct vkd3d_shader_message_context *message_context)
+{
+ struct vkd3d_shader_parser *parser;
+ int ret;
+
+ if ((ret = vkd3d_shader_sm1_parser_create(compile_info, message_context, &parser)) < 0)
+ {
+ WARN("Failed to initialise shader parser.\n");
+ return ret;
+ }
+
+ ret = scan_with_parser(compile_info, message_context, parser);
vkd3d_shader_parser_destroy(parser);
+
return ret;
}
@@ -1012,6 +1040,10 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
ret = VKD3D_ERROR_NOT_IMPLEMENTED;
break;
+ case VKD3D_SHADER_SOURCE_D3D_BYTECODE:
+ ret = scan_d3dbc(compile_info, &message_context);
+ break;
+
default:
ERR("Unsupported source type %#x.\n", compile_info->source_type);
ret = VKD3D_ERROR_INVALID_ARGUMENT;
@@ -1045,6 +1077,7 @@ static int compile_dxbc_tpf(const struct vkd3d_shader_compile_info *compile_info
if ((ret = vkd3d_shader_sm4_parser_create(compile_info, message_context, &parser)) < 0)
{
+ WARN("Failed to initialise shader parser.\n");
vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info);
return ret;
}
diff --git a/tests/vkd3d_shader_api.c b/tests/vkd3d_shader_api.c
index c9045b81..6fb855c2 100644
--- a/tests/vkd3d_shader_api.c
+++ b/tests/vkd3d_shader_api.c
@@ -274,6 +274,9 @@ static void test_d3dbc(void)
(int)d3d_asm.size, (char *)d3d_asm.code);
vkd3d_shader_free_shader_code(&d3d_asm);
+ rc = vkd3d_shader_scan(&info, NULL);
+ ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
+
info.source.size = sizeof(vs_minimal) + 1;
rc = vkd3d_shader_compile(&info, &d3d_asm, NULL);
ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
--
2.20.1
1
0