Wine-devel
Threads by month
- ----- 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
April 2018
- 75 participants
- 538 discussions
From: Sven Hesse <shesse(a)codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/d3d10core/tests/device.c | 530 ++++++++++++++++++++++++++++++++++++++++-
dlls/d3d11/d3d11_private.h | 3 +
dlls/d3d11/tests/d3d11.c | 534 +++++++++++++++++++++++++++++++++++++++++-
dlls/d3d11/texture.c | 89 ++++++-
dlls/d3d11/utils.c | 8 +
5 files changed, 1155 insertions(+), 9 deletions(-)
diff --git a/dlls/d3d10core/tests/device.c b/dlls/d3d10core/tests/device.c
index c4349395338..5cd4e5184aa 100644
--- a/dlls/d3d10core/tests/device.c
+++ b/dlls/d3d10core/tests/device.c
@@ -1313,6 +1313,7 @@ static void test_device_interfaces(void)
static void test_create_texture1d(void)
{
ULONG refcount, expected_refcount;
+ D3D10_SUBRESOURCE_DATA data = {0};
ID3D10Device *device, *tmp;
D3D10_TEXTURE1D_DESC desc;
ID3D10Texture1D *texture;
@@ -1334,6 +1335,9 @@ static void test_create_texture1d(void)
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
+ hr = ID3D10Device_CreateTexture1D(device, &desc, &data, &texture);
+ ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
+
expected_refcount = get_refcount(device) + 1;
hr = ID3D10Device_CreateTexture1D(device, &desc, NULL, &texture);
ok(SUCCEEDED(hr), "Failed to create a 1d texture, hr %#x.\n", hr);
@@ -1381,8 +1385,7 @@ static void test_create_texture1d(void)
desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
desc.MiscFlags = 0;
hr = ID3D10Device_CreateTexture1D(device, &desc, NULL, (ID3D10Texture1D **)&texture);
- todo_wine_if(!i)
- ok(hr == (i ? S_OK : E_INVALIDARG), "Test %u: Got unexpected hr %#x.\n", i, hr);
+ ok(hr == (i ? S_OK : E_INVALIDARG), "Test %u: Got unexpected hr %#x.\n", i, hr);
if (SUCCEEDED(hr))
ID3D10Texture1D_Release(texture);
}
@@ -5550,6 +5553,528 @@ done:
release_test_context(&test_context);
}
+static void test_texture1d(void)
+{
+ struct shader
+ {
+ const DWORD *code;
+ size_t size;
+ };
+ struct texture
+ {
+ UINT width;
+ UINT miplevel_count;
+ UINT array_size;
+ DXGI_FORMAT format;
+ D3D10_SUBRESOURCE_DATA data[3];
+ };
+
+ struct d3d10core_test_context test_context;
+ D3D10_SHADER_RESOURCE_VIEW_DESC srv_desc;
+ const struct texture *current_texture;
+ D3D10_TEXTURE1D_DESC texture_desc;
+ D3D10_SAMPLER_DESC sampler_desc;
+ const struct shader *current_ps;
+ ID3D10ShaderResourceView *srv;
+ ID3D10SamplerState *sampler;
+ struct resource_readback rb;
+ ID3D10Texture1D *texture;
+ struct vec4 ps_constant;
+ ID3D10PixelShader *ps;
+ ID3D10Device *device;
+ unsigned int i, x;
+ ID3D10Buffer *cb;
+ DWORD color;
+ HRESULT hr;
+
+ static const DWORD ps_ld_code[] =
+ {
+#if 0
+ Texture1D t;
+
+ float miplevel;
+
+ float4 main(float4 position : SV_POSITION) : SV_TARGET
+ {
+ float2 p;
+ t.GetDimensions(miplevel, p.x, p.y);
+ p.y = miplevel;
+ p *= float2(position.x / 640.0f, 1.0f);
+ return t.Load(int2(p));
+ }
+#endif
+ 0x43425844, 0x7b0c6359, 0x598178f6, 0xef2ddbdb, 0x88fc794c, 0x00000001, 0x000001ac, 0x00000003,
+ 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
+ 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000010f, 0x505f5653, 0x5449534f, 0x004e4f49,
+ 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
+ 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000110, 0x00000040,
+ 0x00000044, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04001058, 0x00107000, 0x00000000,
+ 0x00005555, 0x04002064, 0x00101012, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
+ 0x02000068, 0x00000001, 0x0600001c, 0x00100012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000,
+ 0x0700003d, 0x001000f2, 0x00000000, 0x0010000a, 0x00000000, 0x00107e46, 0x00000000, 0x07000038,
+ 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010100a, 0x00000000, 0x06000036, 0x001000e2,
+ 0x00000000, 0x00208006, 0x00000000, 0x00000000, 0x0a000038, 0x001000f2, 0x00000000, 0x00100e46,
+ 0x00000000, 0x00004002, 0x3acccccd, 0x3f800000, 0x3f800000, 0x3f800000, 0x0500001b, 0x001000f2,
+ 0x00000000, 0x00100e46, 0x00000000, 0x0700002d, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000,
+ 0x00107e46, 0x00000000, 0x0100003e,
+ };
+ static const struct shader ps_ld = {ps_ld_code, sizeof(ps_ld_code)};
+ static const DWORD ps_ld_sint8_code[] =
+ {
+#if 0
+ Texture1D<int4> t;
+
+ float4 main(float4 position : SV_POSITION) : SV_TARGET
+ {
+ float2 p, s;
+ int4 c;
+
+ p = float2(position.x / 640.0f, 0.0f);
+ t.GetDimensions(0, s.x, s.y);
+ p *= s;
+
+ c = t.Load(int2(p));
+ return (max(c / (float4)127, (float4)-1) + (float4)1) / 2.0f;
+ }
+#endif
+ 0x43425844, 0x65a13d1e, 0x8a0bfc92, 0xa2f2708a, 0x0bafafb6, 0x00000001, 0x00000234, 0x00000003,
+ 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
+ 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000010f, 0x505f5653, 0x5449534f, 0x004e4f49,
+ 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
+ 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000198, 0x00000040,
+ 0x00000066, 0x04001058, 0x00107000, 0x00000000, 0x00003333, 0x04002064, 0x00101012, 0x00000000,
+ 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0700003d, 0x001000f2,
+ 0x00000000, 0x00004001, 0x00000000, 0x00107e46, 0x00000000, 0x07000038, 0x00100012, 0x00000001,
+ 0x0010100a, 0x00000000, 0x00004001, 0x3acccccd, 0x08000036, 0x001000e2, 0x00000001, 0x00004002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x07000038, 0x001000f2, 0x00000000, 0x00100fc6,
+ 0x00000000, 0x00100e46, 0x00000001, 0x0500001b, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000,
+ 0x0700002d, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00107e46, 0x00000000, 0x0500002b,
+ 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x0a000038, 0x001000f2, 0x00000000, 0x00100e46,
+ 0x00000000, 0x00004002, 0x3c010204, 0x3c010204, 0x3c010204, 0x3c010204, 0x0a000034, 0x001000f2,
+ 0x00000000, 0x00100e46, 0x00000000, 0x00004002, 0xbf800000, 0xbf800000, 0xbf800000, 0xbf800000,
+ 0x0a000000, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00004002, 0x3f800000, 0x3f800000,
+ 0x3f800000, 0x3f800000, 0x0a000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00004002,
+ 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x0100003e,
+ };
+ static const struct shader ps_ld_sint8 = {ps_ld_sint8_code, sizeof(ps_ld_sint8_code)};
+ static const DWORD ps_ld_uint8_code[] =
+ {
+#if 0
+ Texture1D<uint4> t;
+
+ float4 main(float4 position : SV_POSITION) : SV_TARGET
+ {
+ float2 p, s;
+
+ p = float2(position.x / 640.0f, 0.0f);
+ t.GetDimensions(0, s.x, s.y);
+ p *= s;
+
+ return t.Load(int2(p)) / (float4)255;
+ }
+#endif
+ 0x43425844, 0x35186c1f, 0x55bad4fd, 0xb7c97a57, 0x99c060e7, 0x00000001, 0x000001bc, 0x00000003,
+ 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
+ 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000010f, 0x505f5653, 0x5449534f, 0x004e4f49,
+ 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
+ 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000120, 0x00000040,
+ 0x00000048, 0x04001058, 0x00107000, 0x00000000, 0x00004444, 0x04002064, 0x00101012, 0x00000000,
+ 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0700003d, 0x001000f2,
+ 0x00000000, 0x00004001, 0x00000000, 0x00107e46, 0x00000000, 0x07000038, 0x00100012, 0x00000001,
+ 0x0010100a, 0x00000000, 0x00004001, 0x3acccccd, 0x08000036, 0x001000e2, 0x00000001, 0x00004002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x07000038, 0x001000f2, 0x00000000, 0x00100fc6,
+ 0x00000000, 0x00100e46, 0x00000001, 0x0500001b, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000,
+ 0x0700002d, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00107e46, 0x00000000, 0x05000056,
+ 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x0a000038, 0x001020f2, 0x00000000, 0x00100e46,
+ 0x00000000, 0x00004002, 0x3b808081, 0x3b808081, 0x3b808081, 0x3b808081, 0x0100003e,
+ };
+ static const struct shader ps_ld_uint8 = {ps_ld_uint8_code, sizeof(ps_ld_uint8_code)};
+ static DWORD ps_ld_array_code[] =
+ {
+#if 0
+ Texture1DArray t;
+
+ float miplevel;
+
+ float4 main(float4 position : SV_POSITION) : SV_TARGET
+ {
+ float3 p;
+ t.GetDimensions(miplevel, p.x, p.y, p.z);
+ p.y = 1;
+ p.z = miplevel;
+ p *= float3(position.x / 640.0f, 1.0f, 1.0f);
+ return t.Load(int3(p));
+ }
+#endif
+ 0x43425844, 0xbfccadc4, 0xc00ff13d, 0x2ba75365, 0xf747cbee, 0x00000001, 0x000001c0, 0x00000003,
+ 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
+ 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000010f, 0x505f5653, 0x5449534f, 0x004e4f49,
+ 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
+ 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000124, 0x00000040,
+ 0x00000049, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04003858, 0x00107000, 0x00000000,
+ 0x00005555, 0x04002064, 0x00101012, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
+ 0x02000068, 0x00000001, 0x0600001c, 0x00100012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000,
+ 0x0700003d, 0x001000f2, 0x00000000, 0x0010000a, 0x00000000, 0x00107e46, 0x00000000, 0x07000038,
+ 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010100a, 0x00000000, 0x06000036, 0x001000c2,
+ 0x00000000, 0x00208006, 0x00000000, 0x00000000, 0x0a000038, 0x00100072, 0x00000000, 0x00100386,
+ 0x00000000, 0x00004002, 0x3acccccd, 0x3f800000, 0x3f800000, 0x00000000, 0x0500001b, 0x001000d2,
+ 0x00000000, 0x00100906, 0x00000000, 0x05000036, 0x00100022, 0x00000000, 0x00004001, 0x00000001,
+ 0x0700002d, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00107e46, 0x00000000, 0x0100003e,
+ };
+ static const struct shader ps_ld_array = {ps_ld_array_code, sizeof(ps_ld_array_code)};
+
+ static const DWORD rgba_level_0[] =
+ {
+ 0xff0000ff, 0xff00ffff, 0xff00ff00, 0xffffff00,
+ };
+ static const DWORD rgba_level_1[] =
+ {
+ 0xffffffff, 0xff0000ff,
+ };
+ static const DWORD rgba_level_2[] =
+ {
+ 0xffff0000,
+ };
+ static const DWORD srgb_data[] =
+ {
+ 0x00000000, 0xffffffff, 0xff000000, 0x7f7f7f7f,
+ };
+ static const DWORD r32_uint[] =
+ {
+ 0, 1, 2, 3,
+ };
+ static const DWORD r9g9b9e5_data[] =
+ {
+ 0x80000100, 0x80020000, 0x84000000, 0x84000100,
+ };
+ static const DWORD array_data0[] =
+ {
+ 0xff0000ff, 0xff00ffff, 0xff00ff00, 0xffffff00,
+ };
+ static const DWORD array_data1[] =
+ {
+ 0x00ffff00, 0xff000000, 0x00ff0000, 0x000000ff,
+ };
+ static const DWORD array_data2[] =
+ {
+ 0x000000ff, 0xffff00ff, 0x0000ff00, 0xff000000,
+ };
+ static const struct texture rgba_texture =
+ {
+ 4, 3, 1, DXGI_FORMAT_R8G8B8A8_UNORM,
+ {
+ {rgba_level_0, 4 * sizeof(*rgba_level_0), 0},
+ {rgba_level_1, 2 * sizeof(*rgba_level_1), 0},
+ {rgba_level_2, sizeof(*rgba_level_2), 0},
+ }
+ };
+ static const struct texture srgb_texture = {4, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ {{srgb_data, 4 * sizeof(*srgb_data)}}};
+ static const struct texture sint8_texture = {4, 1, 1, DXGI_FORMAT_R8G8B8A8_SINT,
+ {{rgba_level_0, 4 * sizeof(*rgba_level_0)}}};
+ static const struct texture uint8_texture = {4, 1, 1, DXGI_FORMAT_R8G8B8A8_UINT,
+ {{rgba_level_0, 4 * sizeof(*rgba_level_0)}}};
+ static const struct texture r32u_typeless = {4, 1, 1, DXGI_FORMAT_R32_TYPELESS,
+ {{r32_uint, 4 * sizeof(*r32_uint)}}};
+ static const struct texture r9g9b9e5_texture = {4, 1, 1, DXGI_FORMAT_R9G9B9E5_SHAREDEXP,
+ {{r9g9b9e5_data, 4 * sizeof(*r9g9b9e5_data)}}};
+ static const struct texture array_texture = {4, 1, 3, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ {
+ {array_data0, 4 * sizeof(*array_data0)},
+ {array_data1, 4 * sizeof(*array_data1)},
+ {array_data2, 4 * sizeof(*array_data2)},
+ }
+ };
+
+ static const DWORD level_1_colors[] =
+ {
+ 0xffffffff, 0xffffffff, 0xff0000ff, 0xff0000ff,
+ };
+ static const DWORD level_2_colors[] =
+ {
+ 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000,
+ };
+ static const DWORD srgb_colors[] =
+ {
+ 0x00000001, 0xffffffff, 0xff000000, 0x7f363636,
+ };
+ static const DWORD sint8_colors[] =
+ {
+ 0x7e80807e, 0x7e807e7e, 0x7e807e80, 0x7e7e7e80,
+ };
+ static const DWORD r32u_colors[4] =
+ {
+ 0x01000000, 0x01000001, 0x01000002, 0x01000003,
+ };
+ static const DWORD r9g9b9e5_colors[4] =
+ {
+ 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffff00ff,
+ };
+ static const DWORD zero_colors[4] = {0};
+ static const float red[] = {1.0f, 0.0f, 0.0f, 0.5f};
+ static const struct texture_test
+ {
+ const struct shader *ps;
+ const struct texture *texture;
+ D3D10_FILTER filter;
+ float lod_bias;
+ float min_lod;
+ float max_lod;
+ float ps_constant;
+ const DWORD *expected_colors;
+ }
+ texture_tests[] =
+ {
+#define POINT D3D10_FILTER_MIN_MAG_MIP_POINT
+#define POINT_LINEAR D3D10_FILTER_MIN_MAG_POINT_MIP_LINEAR
+#define MIP_MAX D3D10_FLOAT32_MAX
+ {&ps_ld, &rgba_texture, POINT, 0.0f, 0.0f, 0.0f, 0.0f, rgba_level_0},
+ {&ps_ld, &rgba_texture, POINT, 0.0f, 0.0f, 0.0f, 1.0f, level_1_colors},
+ {&ps_ld, &rgba_texture, POINT, 0.0f, 0.0f, 0.0f, 2.0f, level_2_colors},
+ {&ps_ld, &rgba_texture, POINT, 0.0f, 0.0f, 0.0f, 3.0f, zero_colors},
+ {&ps_ld, &srgb_texture, POINT, 0.0f, 0.0f, 0.0f, 0.0f, srgb_colors},
+ {&ps_ld, &r9g9b9e5_texture, POINT, 0.0f, 0.0f, 0.0f, 0.0f, r9g9b9e5_colors},
+ {&ps_ld, NULL, POINT, 0.0f, 0.0f, 0.0f, 0.0f, zero_colors},
+ {&ps_ld, NULL, POINT, 0.0f, 0.0f, MIP_MAX, 0.0f, zero_colors},
+ {&ps_ld_sint8, &sint8_texture, POINT, 0.0f, 0.0f, 0.0f, 0.0f, sint8_colors},
+ {&ps_ld_uint8, &uint8_texture, POINT, 0.0f, 0.0f, 0.0f, 0.0f, rgba_level_0},
+ {&ps_ld_array, &array_texture, POINT, 0.0f, 0.0f, 0.0f, 0.0f, array_data1},
+ };
+#undef POINT
+#undef POINT_LINEAR
+#undef MIP_MAX
+ static const struct srv_test
+ {
+ const struct shader *ps;
+ const struct texture *texture;
+ struct srv_desc srv_desc;
+ float ps_constant;
+ const DWORD *expected_colors;
+ }
+ srv_tests[] =
+ {
+#define TEX_1D D3D10_SRV_DIMENSION_TEXTURE1D
+#define R32_UINT DXGI_FORMAT_R32_UINT
+ {&ps_ld_uint8, &r32u_typeless, {R32_UINT, TEX_1D, 0, 1}, 0.0f, r32u_colors},
+#undef TEX_1D
+#undef R32_UINT
+#undef FMT_UNKNOWN
+ };
+
+ if (!init_test_context(&test_context))
+ return;
+
+ device = test_context.device;
+
+ cb = create_buffer(device, D3D10_BIND_CONSTANT_BUFFER, sizeof(ps_constant), NULL);
+
+ ID3D10Device_PSSetConstantBuffers(device, 0, 1, &cb);
+
+ texture_desc.Usage = D3D10_USAGE_DEFAULT;
+ texture_desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
+ texture_desc.CPUAccessFlags = 0;
+ texture_desc.MiscFlags = 0;
+
+ sampler_desc.Filter = D3D10_FILTER_MIN_MAG_MIP_POINT;
+ sampler_desc.AddressU = D3D10_TEXTURE_ADDRESS_CLAMP;
+ sampler_desc.AddressV = D3D10_TEXTURE_ADDRESS_CLAMP;
+ sampler_desc.AddressW = D3D10_TEXTURE_ADDRESS_CLAMP;
+ sampler_desc.MipLODBias = 0.0f;
+ sampler_desc.MaxAnisotropy = 0;
+ sampler_desc.ComparisonFunc = D3D10_COMPARISON_NEVER;
+ sampler_desc.BorderColor[0] = 0.0f;
+ sampler_desc.BorderColor[1] = 0.0f;
+ sampler_desc.BorderColor[2] = 0.0f;
+ sampler_desc.BorderColor[3] = 0.0f;
+ sampler_desc.MinLOD = 0.0f;
+ sampler_desc.MaxLOD = D3D10_FLOAT32_MAX;
+
+ ps = NULL;
+ srv = NULL;
+ sampler = NULL;
+ texture = NULL;
+ current_ps = NULL;
+ current_texture = NULL;
+ for (i = 0; i < ARRAY_SIZE(texture_tests); ++i)
+ {
+ const struct texture_test *test = &texture_tests[i];
+
+ if (current_ps != test->ps)
+ {
+ if (ps)
+ ID3D10PixelShader_Release(ps);
+
+ current_ps = test->ps;
+
+ hr = ID3D10Device_CreatePixelShader(device, current_ps->code, current_ps->size, &ps);
+ ok(SUCCEEDED(hr), "Test %u: Failed to create pixel shader, hr %#x.\n", i, hr);
+
+ ID3D10Device_PSSetShader(device, ps);
+ }
+
+ if (current_texture != test->texture)
+ {
+ if (texture)
+ ID3D10Texture1D_Release(texture);
+ if (srv)
+ ID3D10ShaderResourceView_Release(srv);
+
+ current_texture = test->texture;
+
+ if (current_texture)
+ {
+ texture_desc.Width = current_texture->width;
+ texture_desc.MipLevels = current_texture->miplevel_count;
+ texture_desc.ArraySize = current_texture->array_size;
+ texture_desc.Format = current_texture->format;
+
+ hr = ID3D10Device_CreateTexture1D(device, &texture_desc, current_texture->data, &texture);
+ ok(SUCCEEDED(hr), "Test %u: Failed to create 1d texture, hr %#x.\n", i, hr);
+
+ hr = ID3D10Device_CreateShaderResourceView(device, (ID3D10Resource *)texture, NULL, &srv);
+ ok(SUCCEEDED(hr), "Test %u: Failed to create shader resource view, hr %#x.\n", i, hr);
+ }
+ else
+ {
+ texture = NULL;
+ srv = NULL;
+ }
+
+ ID3D10Device_PSSetShaderResources(device, 0, 1, &srv);
+ }
+
+ if (!sampler || (sampler_desc.Filter != test->filter
+ || sampler_desc.MipLODBias != test->lod_bias
+ || sampler_desc.MinLOD != test->min_lod
+ || sampler_desc.MaxLOD != test->max_lod))
+ {
+ if (sampler)
+ ID3D10SamplerState_Release(sampler);
+
+ sampler_desc.Filter = test->filter;
+ sampler_desc.MipLODBias = test->lod_bias;
+ sampler_desc.MinLOD = test->min_lod;
+ sampler_desc.MaxLOD = test->max_lod;
+
+ hr = ID3D10Device_CreateSamplerState(device, &sampler_desc, &sampler);
+ ok(SUCCEEDED(hr), "Test %u: Failed to create sampler state, hr %#x.\n", i, hr);
+
+ ID3D10Device_PSSetSamplers(device, 0, 1, &sampler);
+ }
+
+ ps_constant.x = test->ps_constant;
+ ID3D10Device_UpdateSubresource(device, (ID3D10Resource *)cb, 0, NULL, &ps_constant, 0, 0);
+
+ ID3D10Device_ClearRenderTargetView(device, test_context.backbuffer_rtv, red);
+
+ draw_quad(&test_context);
+
+ get_texture_readback(test_context.backbuffer, 0, &rb);
+ for (x = 0; x < 4; ++x)
+ {
+ color = get_readback_color(&rb, 80 + x * 160, 0);
+ ok(compare_color(color, test->expected_colors[x], 2),
+ "Test %u: Got unexpected color 0x%08x at (%u).\n", i, color, x);
+ }
+ release_resource_readback(&rb);
+ }
+ if (srv)
+ ID3D10ShaderResourceView_Release(srv);
+ ID3D10SamplerState_Release(sampler);
+ if (texture)
+ ID3D10Texture1D_Release(texture);
+ ID3D10PixelShader_Release(ps);
+
+ if (is_warp_device(device) && !is_d3d11_interface_available(device))
+ {
+ win_skip("SRV tests are broken on WARP.\n");
+ ID3D10Buffer_Release(cb);
+ release_test_context(&test_context);
+ return;
+ }
+
+ sampler_desc.Filter = D3D10_FILTER_MIN_MAG_MIP_POINT;
+ sampler_desc.MipLODBias = 0.0f;
+ sampler_desc.MinLOD = 0.0f;
+ sampler_desc.MaxLOD = D3D10_FLOAT32_MAX;
+
+ hr = ID3D10Device_CreateSamplerState(device, &sampler_desc, &sampler);
+ ok(SUCCEEDED(hr), "Failed to create sampler state, hr %#x.\n", hr);
+
+ ID3D10Device_PSSetSamplers(device, 0, 1, &sampler);
+
+ ps = NULL;
+ srv = NULL;
+ texture = NULL;
+ current_ps = NULL;
+ current_texture = NULL;
+ for (i = 0; i < ARRAY_SIZE(srv_tests); ++i)
+ {
+ const struct srv_test *test = &srv_tests[i];
+
+ if (current_ps != test->ps)
+ {
+ if (ps)
+ ID3D10PixelShader_Release(ps);
+
+ current_ps = test->ps;
+
+ hr = ID3D10Device_CreatePixelShader(device, current_ps->code, current_ps->size, &ps);
+ ok(SUCCEEDED(hr), "Test %u: Failed to create pixel shader, hr %#x.\n", i, hr);
+
+ ID3D10Device_PSSetShader(device, ps);
+ }
+
+ if (current_texture != test->texture)
+ {
+ if (texture)
+ ID3D10Texture1D_Release(texture);
+
+ current_texture = test->texture;
+
+ texture_desc.Width = current_texture->width;
+ texture_desc.MipLevels = current_texture->miplevel_count;
+ texture_desc.ArraySize = current_texture->array_size;
+ texture_desc.Format = current_texture->format;
+
+ hr = ID3D10Device_CreateTexture1D(device, &texture_desc, current_texture->data, &texture);
+ ok(SUCCEEDED(hr), "Test %u: Failed to create 1d texture, hr %#x.\n", i, hr);
+ }
+
+ if (srv)
+ ID3D10ShaderResourceView_Release(srv);
+
+ get_srv_desc(&srv_desc, &test->srv_desc);
+ hr = ID3D10Device_CreateShaderResourceView(device, (ID3D10Resource *)texture, &srv_desc, &srv);
+ ok(SUCCEEDED(hr), "Test %u: Failed to create shader resource view, hr %#x.\n", i, hr);
+
+ ID3D10Device_PSSetShaderResources(device, 0, 1, &srv);
+
+ ps_constant.x = test->ps_constant;
+ ID3D10Device_UpdateSubresource(device, (ID3D10Resource *)cb, 0, NULL, &ps_constant, 0, 0);
+
+ ID3D10Device_ClearRenderTargetView(device, test_context.backbuffer_rtv, red);
+
+ draw_quad(&test_context);
+
+ get_texture_readback(test_context.backbuffer, 0, &rb);
+ for (x = 0; x < 4; ++x)
+ {
+ color = get_readback_color(&rb, 80 + x * 160, 0);
+ ok(compare_color(color, test->expected_colors[x], 1),
+ "Test %u: Got unexpected color 0x%08x at (%u).\n", i, color, x);
+ }
+ release_resource_readback(&rb);
+ }
+ ID3D10PixelShader_Release(ps);
+ ID3D10Texture1D_Release(texture);
+ ID3D10ShaderResourceView_Release(srv);
+ ID3D10SamplerState_Release(sampler);
+
+ ID3D10Buffer_Release(cb);
+ release_test_context(&test_context);
+}
+
static void test_texture(void)
{
struct shader
@@ -15040,6 +15565,7 @@ START_TEST(device)
test_scissor();
test_clear_state();
test_blend();
+ test_texture1d();
test_texture();
test_cube_maps();
test_depth_stencil_sampling();
diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h
index 68e56d76092..1921299faf8 100644
--- a/dlls/d3d11/d3d11_private.h
+++ b/dlls/d3d11/d3d11_private.h
@@ -120,12 +120,15 @@ struct d3d_texture1d
LONG refcount;
struct wined3d_private_store private_store;
+ struct wined3d_texture *wined3d_texture;
D3D11_TEXTURE1D_DESC desc;
ID3D11Device *device;
};
HRESULT d3d_texture1d_create(struct d3d_device *device, const D3D11_TEXTURE1D_DESC *desc,
const D3D11_SUBRESOURCE_DATA *data, struct d3d_texture1d **texture) DECLSPEC_HIDDEN;
+struct d3d_texture1d *unsafe_impl_from_ID3D11Texture1D(ID3D11Texture1D *iface) DECLSPEC_HIDDEN;
+struct d3d_texture1d *unsafe_impl_from_ID3D10Texture1D(ID3D10Texture1D *iface) DECLSPEC_HIDDEN;
/* ID3D11Texture2D, ID3D10Texture2D */
struct d3d_texture2d
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c
index 146509dd05e..e8408c0a0a4 100644
--- a/dlls/d3d11/tests/d3d11.c
+++ b/dlls/d3d11/tests/d3d11.c
@@ -1828,6 +1828,7 @@ static void test_get_immediate_context(void)
static void test_create_texture1d(void)
{
ULONG refcount, expected_refcount;
+ D3D11_SUBRESOURCE_DATA data = {0};
ID3D11Device *device, *tmp;
D3D11_TEXTURE1D_DESC desc;
ID3D11Texture1D *texture;
@@ -1849,6 +1850,9 @@ static void test_create_texture1d(void)
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
+ hr = ID3D11Device_CreateTexture1D(device, &desc, &data, &texture);
+ ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
+
expected_refcount = get_refcount(device) + 1;
hr = ID3D11Device_CreateTexture1D(device, &desc, NULL, &texture);
ok(SUCCEEDED(hr), "Failed to create a 1d texture, hr %#x.\n", hr);
@@ -1906,8 +1910,7 @@ static void test_create_texture1d(void)
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.MiscFlags = 0;
hr = ID3D11Device_CreateTexture1D(device, &desc, NULL, (ID3D11Texture1D **)&texture);
- todo_wine_if(!i)
- ok(hr == (i ? S_OK : E_INVALIDARG), "Test %u: Got unexpected hr %#x.\n", i, hr);
+ ok(hr == (i ? S_OK : E_INVALIDARG), "Test %u: Got unexpected hr %#x.\n", i, hr);
if (SUCCEEDED(hr))
ID3D11Texture1D_Release(texture);
}
@@ -6032,6 +6035,532 @@ done:
release_test_context(&test_context);
}
+static void test_texture1d(void)
+{
+ struct shader
+ {
+ const DWORD *code;
+ size_t size;
+ };
+ struct texture
+ {
+ UINT width;
+ UINT miplevel_count;
+ UINT array_size;
+ DXGI_FORMAT format;
+ D3D11_SUBRESOURCE_DATA data[3];
+ };
+
+ D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc;
+ struct d3d11_test_context test_context;
+ const struct texture *current_texture;
+ D3D11_TEXTURE1D_DESC texture_desc;
+ D3D11_SAMPLER_DESC sampler_desc;
+ const struct shader *current_ps;
+ D3D_FEATURE_LEVEL feature_level;
+ ID3D11ShaderResourceView *srv;
+ ID3D11DeviceContext *context;
+ ID3D11SamplerState *sampler;
+ struct resource_readback rb;
+ ID3D11Texture1D *texture;
+ struct vec4 ps_constant;
+ ID3D11PixelShader *ps;
+ ID3D11Device *device;
+ unsigned int i, x;
+ ID3D11Buffer *cb;
+ DWORD color;
+ HRESULT hr;
+
+ static const DWORD ps_ld_code[] =
+ {
+#if 0
+ Texture1D t;
+
+ float miplevel;
+
+ float4 main(float4 position : SV_POSITION) : SV_TARGET
+ {
+ float2 p;
+ t.GetDimensions(miplevel, p.x, p.y);
+ p.y = miplevel;
+ p *= float2(position.x / 640.0f, 1.0f);
+ return t.Load(int2(p));
+ }
+#endif
+ 0x43425844, 0x7b0c6359, 0x598178f6, 0xef2ddbdb, 0x88fc794c, 0x00000001, 0x000001ac, 0x00000003,
+ 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
+ 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000010f, 0x505f5653, 0x5449534f, 0x004e4f49,
+ 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
+ 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000110, 0x00000040,
+ 0x00000044, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04001058, 0x00107000, 0x00000000,
+ 0x00005555, 0x04002064, 0x00101012, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
+ 0x02000068, 0x00000001, 0x0600001c, 0x00100012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000,
+ 0x0700003d, 0x001000f2, 0x00000000, 0x0010000a, 0x00000000, 0x00107e46, 0x00000000, 0x07000038,
+ 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010100a, 0x00000000, 0x06000036, 0x001000e2,
+ 0x00000000, 0x00208006, 0x00000000, 0x00000000, 0x0a000038, 0x001000f2, 0x00000000, 0x00100e46,
+ 0x00000000, 0x00004002, 0x3acccccd, 0x3f800000, 0x3f800000, 0x3f800000, 0x0500001b, 0x001000f2,
+ 0x00000000, 0x00100e46, 0x00000000, 0x0700002d, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000,
+ 0x00107e46, 0x00000000, 0x0100003e,
+ };
+ static const struct shader ps_ld = {ps_ld_code, sizeof(ps_ld_code)};
+ static const DWORD ps_ld_sint8_code[] =
+ {
+#if 0
+ Texture1D<int4> t;
+
+ float4 main(float4 position : SV_POSITION) : SV_TARGET
+ {
+ float2 p, s;
+ int4 c;
+
+ p = float2(position.x / 640.0f, 0.0f);
+ t.GetDimensions(0, s.x, s.y);
+ p *= s;
+
+ c = t.Load(int2(p));
+ return (max(c / (float4)127, (float4)-1) + (float4)1) / 2.0f;
+ }
+#endif
+ 0x43425844, 0x65a13d1e, 0x8a0bfc92, 0xa2f2708a, 0x0bafafb6, 0x00000001, 0x00000234, 0x00000003,
+ 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
+ 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000010f, 0x505f5653, 0x5449534f, 0x004e4f49,
+ 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
+ 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000198, 0x00000040,
+ 0x00000066, 0x04001058, 0x00107000, 0x00000000, 0x00003333, 0x04002064, 0x00101012, 0x00000000,
+ 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0700003d, 0x001000f2,
+ 0x00000000, 0x00004001, 0x00000000, 0x00107e46, 0x00000000, 0x07000038, 0x00100012, 0x00000001,
+ 0x0010100a, 0x00000000, 0x00004001, 0x3acccccd, 0x08000036, 0x001000e2, 0x00000001, 0x00004002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x07000038, 0x001000f2, 0x00000000, 0x00100fc6,
+ 0x00000000, 0x00100e46, 0x00000001, 0x0500001b, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000,
+ 0x0700002d, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00107e46, 0x00000000, 0x0500002b,
+ 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x0a000038, 0x001000f2, 0x00000000, 0x00100e46,
+ 0x00000000, 0x00004002, 0x3c010204, 0x3c010204, 0x3c010204, 0x3c010204, 0x0a000034, 0x001000f2,
+ 0x00000000, 0x00100e46, 0x00000000, 0x00004002, 0xbf800000, 0xbf800000, 0xbf800000, 0xbf800000,
+ 0x0a000000, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00004002, 0x3f800000, 0x3f800000,
+ 0x3f800000, 0x3f800000, 0x0a000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00004002,
+ 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x0100003e,
+ };
+ static const struct shader ps_ld_sint8 = {ps_ld_sint8_code, sizeof(ps_ld_sint8_code)};
+ static const DWORD ps_ld_uint8_code[] =
+ {
+#if 0
+ Texture1D<uint4> t;
+
+ float4 main(float4 position : SV_POSITION) : SV_TARGET
+ {
+ float2 p, s;
+
+ p = float2(position.x / 640.0f, 0.0f);
+ t.GetDimensions(0, s.x, s.y);
+ p *= s;
+
+ return t.Load(int2(p)) / (float4)255;
+ }
+#endif
+ 0x43425844, 0x35186c1f, 0x55bad4fd, 0xb7c97a57, 0x99c060e7, 0x00000001, 0x000001bc, 0x00000003,
+ 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
+ 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000010f, 0x505f5653, 0x5449534f, 0x004e4f49,
+ 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
+ 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000120, 0x00000040,
+ 0x00000048, 0x04001058, 0x00107000, 0x00000000, 0x00004444, 0x04002064, 0x00101012, 0x00000000,
+ 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0700003d, 0x001000f2,
+ 0x00000000, 0x00004001, 0x00000000, 0x00107e46, 0x00000000, 0x07000038, 0x00100012, 0x00000001,
+ 0x0010100a, 0x00000000, 0x00004001, 0x3acccccd, 0x08000036, 0x001000e2, 0x00000001, 0x00004002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x07000038, 0x001000f2, 0x00000000, 0x00100fc6,
+ 0x00000000, 0x00100e46, 0x00000001, 0x0500001b, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000,
+ 0x0700002d, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00107e46, 0x00000000, 0x05000056,
+ 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x0a000038, 0x001020f2, 0x00000000, 0x00100e46,
+ 0x00000000, 0x00004002, 0x3b808081, 0x3b808081, 0x3b808081, 0x3b808081, 0x0100003e,
+ };
+ static const struct shader ps_ld_uint8 = {ps_ld_uint8_code, sizeof(ps_ld_uint8_code)};
+ static DWORD ps_ld_array_code[] =
+ {
+#if 0
+ Texture1DArray t;
+
+ float miplevel;
+
+ float4 main(float4 position : SV_POSITION) : SV_TARGET
+ {
+ float3 p;
+ t.GetDimensions(miplevel, p.x, p.y, p.z);
+ p.y = 1;
+ p.z = miplevel;
+ p *= float3(position.x / 640.0f, 1.0f, 1.0f);
+ return t.Load(int3(p));
+ }
+#endif
+ 0x43425844, 0xbfccadc4, 0xc00ff13d, 0x2ba75365, 0xf747cbee, 0x00000001, 0x000001c0, 0x00000003,
+ 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
+ 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000010f, 0x505f5653, 0x5449534f, 0x004e4f49,
+ 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
+ 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000124, 0x00000040,
+ 0x00000049, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04003858, 0x00107000, 0x00000000,
+ 0x00005555, 0x04002064, 0x00101012, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
+ 0x02000068, 0x00000001, 0x0600001c, 0x00100012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000,
+ 0x0700003d, 0x001000f2, 0x00000000, 0x0010000a, 0x00000000, 0x00107e46, 0x00000000, 0x07000038,
+ 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010100a, 0x00000000, 0x06000036, 0x001000c2,
+ 0x00000000, 0x00208006, 0x00000000, 0x00000000, 0x0a000038, 0x00100072, 0x00000000, 0x00100386,
+ 0x00000000, 0x00004002, 0x3acccccd, 0x3f800000, 0x3f800000, 0x00000000, 0x0500001b, 0x001000d2,
+ 0x00000000, 0x00100906, 0x00000000, 0x05000036, 0x00100022, 0x00000000, 0x00004001, 0x00000001,
+ 0x0700002d, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00107e46, 0x00000000, 0x0100003e,
+ };
+ static const struct shader ps_ld_array = {ps_ld_array_code, sizeof(ps_ld_array_code)};
+
+ static const DWORD rgba_level_0[] =
+ {
+ 0xff0000ff, 0xff00ffff, 0xff00ff00, 0xffffff00,
+ };
+ static const DWORD rgba_level_1[] =
+ {
+ 0xffffffff, 0xff0000ff,
+ };
+ static const DWORD rgba_level_2[] =
+ {
+ 0xffff0000,
+ };
+ static const DWORD srgb_data[] =
+ {
+ 0x00000000, 0xffffffff, 0xff000000, 0x7f7f7f7f,
+ };
+ static const DWORD r32_uint[] =
+ {
+ 0, 1, 2, 3,
+ };
+ static const DWORD r9g9b9e5_data[] =
+ {
+ 0x80000100, 0x80020000, 0x84000000, 0x84000100,
+ };
+ static const DWORD array_data0[] =
+ {
+ 0xff0000ff, 0xff00ffff, 0xff00ff00, 0xffffff00,
+ };
+ static const DWORD array_data1[] =
+ {
+ 0x00ffff00, 0xff000000, 0x00ff0000, 0x000000ff,
+ };
+ static const DWORD array_data2[] =
+ {
+ 0x000000ff, 0xffff00ff, 0x0000ff00, 0xff000000,
+ };
+ static const struct texture rgba_texture =
+ {
+ 4, 3, 1, DXGI_FORMAT_R8G8B8A8_UNORM,
+ {
+ {rgba_level_0, 4 * sizeof(*rgba_level_0), 0},
+ {rgba_level_1, 2 * sizeof(*rgba_level_1), 0},
+ {rgba_level_2, sizeof(*rgba_level_2), 0},
+ }
+ };
+ static const struct texture srgb_texture = {4, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ {{srgb_data, 4 * sizeof(*srgb_data)}}};
+ static const struct texture sint8_texture = {4, 1, 1, DXGI_FORMAT_R8G8B8A8_SINT,
+ {{rgba_level_0, 4 * sizeof(*rgba_level_0)}}};
+ static const struct texture uint8_texture = {4, 1, 1, DXGI_FORMAT_R8G8B8A8_UINT,
+ {{rgba_level_0, 4 * sizeof(*rgba_level_0)}}};
+ static const struct texture r32u_typeless = {4, 1, 1, DXGI_FORMAT_R32_TYPELESS,
+ {{r32_uint, 4 * sizeof(*r32_uint)}}};
+ static const struct texture r9g9b9e5_texture = {4, 1, 1, DXGI_FORMAT_R9G9B9E5_SHAREDEXP,
+ {{r9g9b9e5_data, 4 * sizeof(*r9g9b9e5_data)}}};
+ static const struct texture array_texture = {4, 1, 3, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ {
+ {array_data0, 4 * sizeof(*array_data0)},
+ {array_data1, 4 * sizeof(*array_data1)},
+ {array_data2, 4 * sizeof(*array_data2)},
+ }
+ };
+
+ static const DWORD level_1_colors[] =
+ {
+ 0xffffffff, 0xffffffff, 0xff0000ff, 0xff0000ff,
+ };
+ static const DWORD level_2_colors[] =
+ {
+ 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000,
+ };
+ static const DWORD srgb_colors[] =
+ {
+ 0x00000001, 0xffffffff, 0xff000000, 0x7f363636,
+ };
+ static const DWORD sint8_colors[] =
+ {
+ 0x7e80807e, 0x7e807e7e, 0x7e807e80, 0x7e7e7e80,
+ };
+ static const DWORD r32u_colors[4] =
+ {
+ 0x01000000, 0x01000001, 0x01000002, 0x01000003,
+ };
+ static const DWORD r9g9b9e5_colors[4] =
+ {
+ 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffff00ff,
+ };
+ static const DWORD zero_colors[4] = {0};
+ static const float red[] = {1.0f, 0.0f, 0.0f, 0.5f};
+ static const struct texture_test
+ {
+ const struct shader *ps;
+ const struct texture *texture;
+ D3D11_FILTER filter;
+ float lod_bias;
+ float min_lod;
+ float max_lod;
+ float ps_constant;
+ const DWORD *expected_colors;
+ }
+ texture_tests[] =
+ {
+#define POINT D3D11_FILTER_MIN_MAG_MIP_POINT
+#define POINT_LINEAR D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR
+#define MIP_MAX D3D11_FLOAT32_MAX
+ {&ps_ld, &rgba_texture, POINT, 0.0f, 0.0f, 0.0f, 0.0f, rgba_level_0},
+ {&ps_ld, &rgba_texture, POINT, 0.0f, 0.0f, 0.0f, 1.0f, level_1_colors},
+ {&ps_ld, &rgba_texture, POINT, 0.0f, 0.0f, 0.0f, 2.0f, level_2_colors},
+ {&ps_ld, &rgba_texture, POINT, 0.0f, 0.0f, 0.0f, 3.0f, zero_colors},
+ {&ps_ld, &srgb_texture, POINT, 0.0f, 0.0f, 0.0f, 0.0f, srgb_colors},
+ {&ps_ld, &r9g9b9e5_texture, POINT, 0.0f, 0.0f, 0.0f, 0.0f, r9g9b9e5_colors},
+ {&ps_ld, NULL, POINT, 0.0f, 0.0f, 0.0f, 0.0f, zero_colors},
+ {&ps_ld, NULL, POINT, 0.0f, 0.0f, MIP_MAX, 0.0f, zero_colors},
+ {&ps_ld_sint8, &sint8_texture, POINT, 0.0f, 0.0f, 0.0f, 0.0f, sint8_colors},
+ {&ps_ld_uint8, &uint8_texture, POINT, 0.0f, 0.0f, 0.0f, 0.0f, rgba_level_0},
+ {&ps_ld_array, &array_texture, POINT, 0.0f, 0.0f, 0.0f, 0.0f, array_data1},
+ };
+#undef POINT
+#undef POINT_LINEAR
+#undef MIP_MAX
+ static const struct srv_test
+ {
+ const struct shader *ps;
+ const struct texture *texture;
+ struct srv_desc srv_desc;
+ float ps_constant;
+ const DWORD *expected_colors;
+ }
+ srv_tests[] =
+ {
+#define TEX_1D D3D11_SRV_DIMENSION_TEXTURE1D
+#define R32_UINT DXGI_FORMAT_R32_UINT
+ {&ps_ld_uint8, &r32u_typeless, {R32_UINT, TEX_1D, 0, 1}, 0.0f, r32u_colors},
+#undef TEX_1D
+#undef R32_UINT
+#undef FMT_UNKNOWN
+ };
+
+ if (!init_test_context(&test_context, NULL))
+ return;
+
+ device = test_context.device;
+ context = test_context.immediate_context;
+ feature_level = ID3D11Device_GetFeatureLevel(device);
+
+ cb = create_buffer(device, D3D11_BIND_CONSTANT_BUFFER, sizeof(ps_constant), NULL);
+
+ ID3D11DeviceContext_PSSetConstantBuffers(context, 0, 1, &cb);
+
+ texture_desc.Usage = D3D11_USAGE_DEFAULT;
+ texture_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+ texture_desc.CPUAccessFlags = 0;
+ texture_desc.MiscFlags = 0;
+
+ sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
+ sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
+ sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
+ sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
+ sampler_desc.MipLODBias = 0.0f;
+ sampler_desc.MaxAnisotropy = 0;
+ sampler_desc.ComparisonFunc = D3D11_COMPARISON_NEVER;
+ sampler_desc.BorderColor[0] = 0.0f;
+ sampler_desc.BorderColor[1] = 0.0f;
+ sampler_desc.BorderColor[2] = 0.0f;
+ sampler_desc.BorderColor[3] = 0.0f;
+ sampler_desc.MinLOD = 0.0f;
+ sampler_desc.MaxLOD = D3D11_FLOAT32_MAX;
+
+ ps = NULL;
+ srv = NULL;
+ sampler = NULL;
+ texture = NULL;
+ current_ps = NULL;
+ current_texture = NULL;
+ for (i = 0; i < ARRAY_SIZE(texture_tests); ++i)
+ {
+ const struct texture_test *test = &texture_tests[i];
+
+ if (current_ps != test->ps)
+ {
+ if (ps)
+ ID3D11PixelShader_Release(ps);
+
+ current_ps = test->ps;
+
+ hr = ID3D11Device_CreatePixelShader(device, current_ps->code, current_ps->size, NULL, &ps);
+ ok(SUCCEEDED(hr), "Test %u: Failed to create pixel shader, hr %#x.\n", i, hr);
+
+ ID3D11DeviceContext_PSSetShader(context, ps, NULL, 0);
+ }
+
+ if (current_texture != test->texture)
+ {
+ if (texture)
+ ID3D11Texture1D_Release(texture);
+ if (srv)
+ ID3D11ShaderResourceView_Release(srv);
+
+ current_texture = test->texture;
+
+ if (current_texture)
+ {
+ texture_desc.Width = current_texture->width;
+ texture_desc.MipLevels = current_texture->miplevel_count;
+ texture_desc.ArraySize = current_texture->array_size;
+ texture_desc.Format = current_texture->format;
+
+ hr = ID3D11Device_CreateTexture1D(device, &texture_desc, current_texture->data, &texture);
+ ok(SUCCEEDED(hr), "Test %u: Failed to create 1d texture, hr %#x.\n", i, hr);
+
+ hr = ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource *)texture, NULL, &srv);
+ ok(SUCCEEDED(hr), "Test %u: Failed to create shader resource view, hr %#x.\n", i, hr);
+ }
+ else
+ {
+ texture = NULL;
+ srv = NULL;
+ }
+
+ ID3D11DeviceContext_PSSetShaderResources(context, 0, 1, &srv);
+ }
+
+ if (!sampler || (sampler_desc.Filter != test->filter
+ || sampler_desc.MipLODBias != test->lod_bias
+ || sampler_desc.MinLOD != test->min_lod
+ || sampler_desc.MaxLOD != test->max_lod))
+ {
+ if (sampler)
+ ID3D11SamplerState_Release(sampler);
+
+ sampler_desc.Filter = test->filter;
+ sampler_desc.MipLODBias = test->lod_bias;
+ sampler_desc.MinLOD = test->min_lod;
+ sampler_desc.MaxLOD = test->max_lod;
+
+ hr = ID3D11Device_CreateSamplerState(device, &sampler_desc, &sampler);
+ ok(SUCCEEDED(hr), "Test %u: Failed to create sampler state, hr %#x.\n", i, hr);
+
+ ID3D11DeviceContext_PSSetSamplers(context, 0, 1, &sampler);
+ }
+
+ ps_constant.x = test->ps_constant;
+ ID3D11DeviceContext_UpdateSubresource(context, (ID3D11Resource *)cb, 0, NULL, &ps_constant, 0, 0);
+
+ ID3D11DeviceContext_ClearRenderTargetView(context, test_context.backbuffer_rtv, red);
+
+ draw_quad(&test_context);
+
+ get_texture_readback(test_context.backbuffer, 0, &rb);
+ for (x = 0; x < 4; ++x)
+ {
+ color = get_readback_color(&rb, 80 + x * 160, 0);
+ ok(compare_color(color, test->expected_colors[x], 2),
+ "Test %u: Got unexpected color 0x%08x at (%u).\n", i, color, x);
+ }
+ release_resource_readback(&rb);
+ }
+ if (srv)
+ ID3D11ShaderResourceView_Release(srv);
+ ID3D11SamplerState_Release(sampler);
+ if (texture)
+ ID3D11Texture1D_Release(texture);
+ ID3D11PixelShader_Release(ps);
+
+ if (is_warp_device(device) && feature_level < D3D_FEATURE_LEVEL_11_0)
+ {
+ win_skip("SRV tests are broken on WARP.\n");
+ ID3D11Buffer_Release(cb);
+ release_test_context(&test_context);
+ return;
+ }
+
+ sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
+ sampler_desc.MipLODBias = 0.0f;
+ sampler_desc.MinLOD = 0.0f;
+ sampler_desc.MaxLOD = D3D11_FLOAT32_MAX;
+
+ hr = ID3D11Device_CreateSamplerState(device, &sampler_desc, &sampler);
+ ok(SUCCEEDED(hr), "Failed to create sampler state, hr %#x.\n", hr);
+
+ ID3D11DeviceContext_PSSetSamplers(context, 0, 1, &sampler);
+
+ ps = NULL;
+ srv = NULL;
+ texture = NULL;
+ current_ps = NULL;
+ current_texture = NULL;
+ for (i = 0; i < ARRAY_SIZE(srv_tests); ++i)
+ {
+ const struct srv_test *test = &srv_tests[i];
+
+ if (current_ps != test->ps)
+ {
+ if (ps)
+ ID3D11PixelShader_Release(ps);
+
+ current_ps = test->ps;
+
+ hr = ID3D11Device_CreatePixelShader(device, current_ps->code, current_ps->size, NULL, &ps);
+ ok(SUCCEEDED(hr), "Test %u: Failed to create pixel shader, hr %#x.\n", i, hr);
+
+ ID3D11DeviceContext_PSSetShader(context, ps, NULL, 0);
+ }
+
+ if (current_texture != test->texture)
+ {
+ if (texture)
+ ID3D11Texture1D_Release(texture);
+
+ current_texture = test->texture;
+
+ texture_desc.Width = current_texture->width;
+ texture_desc.MipLevels = current_texture->miplevel_count;
+ texture_desc.ArraySize = current_texture->array_size;
+ texture_desc.Format = current_texture->format;
+
+ hr = ID3D11Device_CreateTexture1D(device, &texture_desc, current_texture->data, &texture);
+ ok(SUCCEEDED(hr), "Test %u: Failed to create 1d texture, hr %#x.\n", i, hr);
+ }
+
+ if (srv)
+ ID3D11ShaderResourceView_Release(srv);
+
+ get_srv_desc(&srv_desc, &test->srv_desc);
+ hr = ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource *)texture, &srv_desc, &srv);
+ ok(SUCCEEDED(hr), "Test %u: Failed to create shader resource view, hr %#x.\n", i, hr);
+
+ ID3D11DeviceContext_PSSetShaderResources(context, 0, 1, &srv);
+
+ ps_constant.x = test->ps_constant;
+ ID3D11DeviceContext_UpdateSubresource(context, (ID3D11Resource *)cb, 0, NULL, &ps_constant, 0, 0);
+
+ ID3D11DeviceContext_ClearRenderTargetView(context, test_context.backbuffer_rtv, red);
+
+ draw_quad(&test_context);
+
+ get_texture_readback(test_context.backbuffer, 0, &rb);
+ for (x = 0; x < 4; ++x)
+ {
+ color = get_readback_color(&rb, 80 + x * 160, 0);
+ ok(compare_color(color, test->expected_colors[x], 1),
+ "Test %u: Got unexpected color 0x%08x at (%u).\n", i, color, x);
+ }
+ release_resource_readback(&rb);
+ }
+ ID3D11PixelShader_Release(ps);
+ ID3D11Texture1D_Release(texture);
+ ID3D11ShaderResourceView_Release(srv);
+ ID3D11SamplerState_Release(sampler);
+
+ ID3D11Buffer_Release(cb);
+ release_test_context(&test_context);
+}
+
static void test_texture(void)
{
struct shader
@@ -25229,6 +25758,7 @@ START_TEST(d3d11)
run_for_each_feature_level(test_state_refcounting);
test_device_context_state();
test_blend();
+ test_texture1d();
test_texture();
test_cube_maps();
test_depth_stencil_sampling();
diff --git a/dlls/d3d11/texture.c b/dlls/d3d11/texture.c
index 8c7a54956a7..66328b7724c 100644
--- a/dlls/d3d11/texture.c
+++ b/dlls/d3d11/texture.c
@@ -70,6 +70,14 @@ static ULONG STDMETHODCALLTYPE d3d11_texture1d_AddRef(ID3D11Texture1D *iface)
TRACE("%p increasing refcount to %u.\n", texture, refcount);
+ if (refcount == 1)
+ {
+ ID3D11Device_AddRef(texture->device);
+ wined3d_mutex_lock();
+ wined3d_texture_incref(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+ }
+
return refcount;
}
@@ -82,9 +90,14 @@ static ULONG STDMETHODCALLTYPE d3d11_texture1d_Release(ID3D11Texture1D *iface)
if (!refcount)
{
- wined3d_private_store_cleanup(&texture->private_store);
- ID3D11Device_Release(texture->device);
- heap_free(texture);
+ ID3D11Device *device = texture->device;
+
+ wined3d_mutex_lock();
+ wined3d_texture_decref(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+ /* Release the device last, it may cause the wined3d device to be
+ * destroyed. */
+ ID3D11Device_Release(device);
}
return refcount;
@@ -178,6 +191,14 @@ static const struct ID3D11Texture1DVtbl d3d11_texture1d_vtbl =
d3d11_texture1d_GetDesc,
};
+struct d3d_texture1d *unsafe_impl_from_ID3D11Texture1D(ID3D11Texture1D *iface)
+{
+ if (!iface)
+ return NULL;
+ assert(iface->lpVtbl == &d3d11_texture1d_vtbl);
+ return CONTAINING_RECORD(iface, struct d3d_texture1d, ID3D11Texture1D_iface);
+}
+
static inline struct d3d_texture1d *impl_from_ID3D10Texture1D(ID3D10Texture1D *iface)
{
return CONTAINING_RECORD(iface, struct d3d_texture1d, ID3D10Texture1D_iface);
@@ -203,6 +224,14 @@ static ULONG STDMETHODCALLTYPE d3d10_texture1d_AddRef(ID3D10Texture1D *iface)
return d3d11_texture1d_AddRef(&texture->ID3D11Texture1D_iface);
}
+static void STDMETHODCALLTYPE d3d_texture1d_wined3d_object_released(void *parent)
+{
+ struct d3d_texture1d *texture = parent;
+
+ wined3d_private_store_cleanup(&texture->private_store);
+ heap_free(texture);
+}
+
static ULONG STDMETHODCALLTYPE d3d10_texture1d_Release(ID3D10Texture1D *iface)
{
struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface);
@@ -317,10 +346,27 @@ static const struct ID3D10Texture1DVtbl d3d10_texture1d_vtbl =
d3d10_texture1d_GetDesc,
};
+struct d3d_texture1d *unsafe_impl_from_ID3D10Texture1D(ID3D10Texture1D *iface)
+{
+ if (!iface)
+ return NULL;
+ assert(iface->lpVtbl == &d3d10_texture1d_vtbl);
+ return CONTAINING_RECORD(iface, struct d3d_texture1d, ID3D10Texture1D_iface);
+}
+
+static const struct wined3d_parent_ops d3d_texture1d_wined3d_parent_ops =
+{
+ d3d_texture1d_wined3d_object_released,
+};
+
HRESULT d3d_texture1d_create(struct d3d_device *device, const D3D11_TEXTURE1D_DESC *desc,
const D3D11_SUBRESOURCE_DATA *data, struct d3d_texture1d **out)
{
+ struct wined3d_resource_desc wined3d_desc;
struct d3d_texture1d *texture;
+ unsigned int levels;
+ DWORD flags = 0;
+ HRESULT hr;
if (!(texture = heap_alloc_zero(sizeof(*texture))))
return E_OUTOFMEMORY;
@@ -328,10 +374,43 @@ HRESULT d3d_texture1d_create(struct d3d_device *device, const D3D11_TEXTURE1D_DE
texture->ID3D11Texture1D_iface.lpVtbl = &d3d11_texture1d_vtbl;
texture->ID3D10Texture1D_iface.lpVtbl = &d3d10_texture1d_vtbl;
texture->refcount = 1;
-
wined3d_private_store_init(&texture->private_store);
texture->desc = *desc;
- texture->desc.MipLevels = desc->MipLevels ? desc->MipLevels : wined3d_log2i(desc->Width) + 1;
+ levels = desc->MipLevels ? desc->MipLevels : wined3d_log2i(desc->Width) + 1;
+ texture->desc.MipLevels = levels;
+
+ wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE_1D;
+ wined3d_desc.format = wined3dformat_from_dxgi_format(desc->Format);
+ wined3d_desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
+ wined3d_desc.multisample_quality = 0;
+ wined3d_desc.usage = wined3d_usage_from_d3d11(desc->BindFlags, desc->Usage);
+ wined3d_desc.access = wined3d_access_from_d3d11(desc->Usage,
+ desc->Usage == D3D11_USAGE_DEFAULT ? 0 : desc->CPUAccessFlags);
+ wined3d_desc.width = desc->Width;
+ wined3d_desc.height = 1;
+ wined3d_desc.depth = 1;
+ wined3d_desc.size = 0;
+
+ if (desc->MiscFlags & D3D11_RESOURCE_MISC_GDI_COMPATIBLE)
+ flags |= WINED3D_TEXTURE_CREATE_GET_DC;
+ if (desc->MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS)
+ flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS;
+
+ wined3d_mutex_lock();
+ hr = wined3d_texture_create(device->wined3d_device, &wined3d_desc,
+ desc->ArraySize, levels, flags, (struct wined3d_sub_resource_data *)data,
+ texture, &d3d_texture1d_wined3d_parent_ops, &texture->wined3d_texture);
+ wined3d_mutex_unlock();
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d texture, hr %#x.\n", hr);
+ wined3d_private_store_cleanup(&texture->private_store);
+ heap_free(texture);
+ if (hr == WINED3DERR_NOTAVAILABLE || hr == WINED3DERR_INVALIDCALL)
+ hr = E_INVALIDARG;
+ return hr;
+ }
+
texture->device = &device->ID3D11Device_iface;
ID3D11Device_AddRef(texture->device);
diff --git a/dlls/d3d11/utils.c b/dlls/d3d11/utils.c
index cd226b21fb8..8fdb00518ff 100644
--- a/dlls/d3d11/utils.c
+++ b/dlls/d3d11/utils.c
@@ -713,6 +713,10 @@ struct wined3d_resource *wined3d_resource_from_d3d11_resource(ID3D11Resource *re
return wined3d_buffer_get_resource(unsafe_impl_from_ID3D11Buffer(
(ID3D11Buffer *)resource)->wined3d_buffer);
+ case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
+ return wined3d_texture_get_resource(unsafe_impl_from_ID3D11Texture1D(
+ (ID3D11Texture1D *)resource)->wined3d_texture);
+
case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
return wined3d_texture_get_resource(unsafe_impl_from_ID3D11Texture2D(
(ID3D11Texture2D *)resource)->wined3d_texture);
@@ -739,6 +743,10 @@ struct wined3d_resource *wined3d_resource_from_d3d10_resource(ID3D10Resource *re
return wined3d_buffer_get_resource(unsafe_impl_from_ID3D10Buffer(
(ID3D10Buffer *)resource)->wined3d_buffer);
+ case D3D10_RESOURCE_DIMENSION_TEXTURE1D:
+ return wined3d_texture_get_resource(unsafe_impl_from_ID3D10Texture1D(
+ (ID3D10Texture1D *)resource)->wined3d_texture);
+
case D3D10_RESOURCE_DIMENSION_TEXTURE2D:
return wined3d_texture_get_resource(unsafe_impl_from_ID3D10Texture2D(
(ID3D10Texture2D *)resource)->wined3d_texture);
--
2.11.0
1
0
From: Sven Hesse <shesse(a)codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/context.c | 20 ++-
dlls/wined3d/device.c | 17 +++
dlls/wined3d/directx.c | 14 ++
dlls/wined3d/glsl_shader.c | 7 +
dlls/wined3d/nvidia_texture_shader.c | 3 +
dlls/wined3d/resource.c | 1 +
dlls/wined3d/shader.c | 3 +-
dlls/wined3d/texture.c | 284 ++++++++++++++++++++++++++++-------
dlls/wined3d/utils.c | 1 +
dlls/wined3d/view.c | 5 +
dlls/wined3d/wined3d_private.h | 2 +
include/wine/wined3d.h | 5 +-
12 files changed, 306 insertions(+), 56 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 47eb42e9f71..4b2f26359b7 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -144,7 +144,8 @@ static void context_attach_gl_texture_fbo(struct wined3d_context *context,
gl_info->fbo_ops.glFramebufferTexture(fbo_target, attachment,
resource->object, resource->level);
}
- else if (resource->target == GL_TEXTURE_2D_ARRAY || resource->target == GL_TEXTURE_3D)
+ else if (resource->target == GL_TEXTURE_1D_ARRAY || resource->target == GL_TEXTURE_2D_ARRAY
+ || resource->target == GL_TEXTURE_3D)
{
if (!gl_info->fbo_ops.glFramebufferTextureLayer)
{
@@ -155,6 +156,11 @@ static void context_attach_gl_texture_fbo(struct wined3d_context *context,
gl_info->fbo_ops.glFramebufferTextureLayer(fbo_target, attachment,
resource->object, resource->level, resource->layer);
}
+ else if (resource->target == GL_TEXTURE_1D)
+ {
+ gl_info->fbo_ops.glFramebufferTexture1D(fbo_target, attachment,
+ resource->target, resource->object, resource->level);
+ }
else
{
gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, attachment,
@@ -242,6 +248,8 @@ static void context_dump_fbo_attachment(const struct wined3d_gl_info *gl_info, G
}
texture_type[] =
{
+ {GL_TEXTURE_1D, GL_TEXTURE_BINDING_1D, "1d", WINED3D_GL_EXT_NONE},
+ {GL_TEXTURE_1D_ARRAY, GL_TEXTURE_BINDING_1D_ARRAY, "1d-array", EXT_TEXTURE_ARRAY},
{GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D, "2d", WINED3D_GL_EXT_NONE},
{GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_BINDING_RECTANGLE_ARB, "rectangle", ARB_TEXTURE_RECTANGLE},
{GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BINDING_2D_ARRAY, "2d-array" , EXT_TEXTURE_ARRAY},
@@ -1742,6 +1750,7 @@ void context_bind_dummy_textures(const struct wined3d_device *device, const stru
{
GL_EXTCALL(glActiveTexture(GL_TEXTURE0 + i));
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, textures->tex_1d);
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, textures->tex_2d);
if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
@@ -1757,7 +1766,10 @@ void context_bind_dummy_textures(const struct wined3d_device *device, const stru
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, textures->tex_cube_array);
if (gl_info->supported[EXT_TEXTURE_ARRAY])
+ {
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, textures->tex_1d_array);
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY, textures->tex_2d_array);
+ }
if (gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT])
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_BUFFER, textures->tex_buffer);
@@ -2491,6 +2503,12 @@ void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint
case GL_NONE:
/* nothing to do */
break;
+ case GL_TEXTURE_1D:
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, textures->tex_1d);
+ break;
+ case GL_TEXTURE_1D_ARRAY:
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, textures->tex_1d_array);
+ break;
case GL_TEXTURE_2D:
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, textures->tex_2d);
break;
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index adaa4f10000..cc42dba45df 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -630,6 +630,12 @@ static void create_dummy_textures(struct wined3d_device *device, struct wined3d_
* to each texture stage when the currently set D3D texture is NULL. */
context_active_texture(context, gl_info, 0);
+ gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_1d);
+ TRACE("Dummy 1D texture given name %u.\n", textures->tex_1d);
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, textures->tex_1d);
+ gl_info->gl_ops.gl.p_glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA8, 1, 0,
+ GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
+
gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_2d);
TRACE("Dummy 2D texture given name %u.\n", textures->tex_2d);
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, textures->tex_2d);
@@ -681,6 +687,12 @@ static void create_dummy_textures(struct wined3d_device *device, struct wined3d_
if (gl_info->supported[EXT_TEXTURE_ARRAY])
{
+ gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_1d_array);
+ TRACE("Dummy 1D array texture given name %u.\n", textures->tex_1d_array);
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, textures->tex_1d_array);
+ gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_1D_ARRAY, 0, GL_RGBA8, 1, 1, 0,
+ GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
+
gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_2d_array);
TRACE("Dummy 2D array texture given name %u.\n", textures->tex_2d_array);
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY, textures->tex_2d_array);
@@ -748,7 +760,10 @@ static void destroy_dummy_textures(struct wined3d_device *device, struct wined3d
gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_buffer);
if (gl_info->supported[EXT_TEXTURE_ARRAY])
+ {
gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_2d_array);
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_1d_array);
+ }
if (gl_info->supported[ARB_TEXTURE_CUBE_MAP_ARRAY])
gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_cube_array);
@@ -763,6 +778,7 @@ static void destroy_dummy_textures(struct wined3d_device *device, struct wined3d
gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_rect);
gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_2d);
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_1d);
checkGLcall("delete dummy textures");
@@ -5055,6 +5071,7 @@ void device_resource_released(struct wined3d_device *device, struct wined3d_reso
switch (type)
{
+ case WINED3D_RTYPE_TEXTURE_1D:
case WINED3D_RTYPE_TEXTURE_2D:
case WINED3D_RTYPE_TEXTURE_3D:
for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 3bd63c3c074..7deefaf82dc 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -5320,6 +5320,20 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad
gl_type_end = WINED3D_GL_RES_TYPE_TEX_3D;
break;
+ case WINED3D_RTYPE_TEXTURE_1D:
+ allowed_usage = WINED3DUSAGE_DYNAMIC
+ | WINED3DUSAGE_SOFTWAREPROCESSING
+ | WINED3DUSAGE_TEXTURE
+ | WINED3DUSAGE_QUERY_FILTER
+ | WINED3DUSAGE_QUERY_GENMIPMAP
+ | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
+ | WINED3DUSAGE_QUERY_SRGBREAD
+ | WINED3DUSAGE_QUERY_SRGBWRITE
+ | WINED3DUSAGE_QUERY_VERTEXTEXTURE
+ | WINED3DUSAGE_QUERY_WRAPANDMIP;
+ gl_type = gl_type_end = WINED3D_GL_RES_TYPE_TEX_1D;
+ break;
+
case WINED3D_RTYPE_TEXTURE_2D:
allowed_usage = WINED3DUSAGE_DEPTHSTENCIL
| WINED3DUSAGE_RENDERTARGET
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index e920fac3907..0bc6aa02319 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -2576,6 +2576,13 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
sampler_type = "samplerCube";
break;
+ case WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY:
+ if (shadow_sampler)
+ sampler_type = "sampler1DArrayShadow";
+ else
+ sampler_type = "sampler1DArray";
+ break;
+
case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY:
if (shadow_sampler)
sampler_type = "sampler2DArrayShadow";
diff --git a/dlls/wined3d/nvidia_texture_shader.c b/dlls/wined3d/nvidia_texture_shader.c
index 0baa414e57d..20db62739b5 100644
--- a/dlls/wined3d/nvidia_texture_shader.c
+++ b/dlls/wined3d/nvidia_texture_shader.c
@@ -69,6 +69,9 @@ static void nvts_activate_dimensions(const struct wined3d_state *state, DWORD st
gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB);
checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB)");
break;
+ default:
+ FIXME("Unhandled target %#x.\n", state->textures[stage]->target);
+ break;
}
}
else
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c
index a95d6f50b68..2a6fa6ad7ec 100644
--- a/dlls/wined3d/resource.c
+++ b/dlls/wined3d/resource.c
@@ -75,6 +75,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *
resource_types[] =
{
{WINED3D_RTYPE_BUFFER, 0, WINED3D_GL_RES_TYPE_BUFFER},
+ {WINED3D_RTYPE_TEXTURE_1D, 0, WINED3D_GL_RES_TYPE_TEX_1D},
{WINED3D_RTYPE_TEXTURE_2D, 0, WINED3D_GL_RES_TYPE_TEX_2D},
{WINED3D_RTYPE_TEXTURE_2D, 0, WINED3D_GL_RES_TYPE_TEX_RECT},
{WINED3D_RTYPE_TEXTURE_2D, 0, WINED3D_GL_RES_TYPE_RB},
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 93079e89120..c20c1da14bc 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -3871,8 +3871,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
switch (texture->target)
{
/* RECT textures are distinguished from 2D textures via np2_fixup */
- case GL_TEXTURE_RECTANGLE_ARB:
- case GL_TEXTURE_2D:
+ default:
break;
case GL_TEXTURE_3D:
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 9e6b599c8e9..b56e6e4e65e 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -445,7 +445,10 @@ static void wined3d_texture_allocate_gl_mutable_storage(struct wined3d_texture *
GLenum target;
level_count = texture->level_count;
- layer_count = texture->target == GL_TEXTURE_2D_ARRAY ? 1 : texture->layer_count;
+ if (texture->target == GL_TEXTURE_1D_ARRAY || texture->target == GL_TEXTURE_2D_ARRAY)
+ layer_count = 1;
+ else
+ layer_count = texture->layer_count;
for (layer = 0; layer < layer_count; ++layer)
{
@@ -472,10 +475,16 @@ static void wined3d_texture_allocate_gl_mutable_storage(struct wined3d_texture *
format->glFormat, format->glType, NULL));
checkGLcall("glTexImage3D");
}
+ else if (target == GL_TEXTURE_1D)
+ {
+ gl_info->gl_ops.gl.p_glTexImage1D(target, level, gl_internal_format,
+ width, 0, format->glFormat, format->glType, NULL);
+ }
else
{
- gl_info->gl_ops.gl.p_glTexImage2D(target, level, gl_internal_format,
- width, height, 0, format->glFormat, format->glType, NULL);
+ gl_info->gl_ops.gl.p_glTexImage2D(target, level, gl_internal_format, width,
+ target == GL_TEXTURE_1D_ARRAY ? texture->layer_count : height, 0,
+ format->glFormat, format->glType, NULL);
checkGLcall("glTexImage2D");
}
}
@@ -509,6 +518,13 @@ static void wined3d_texture_allocate_gl_immutable_storage(struct wined3d_texture
GL_EXTCALL(glTexStorage3DMultisample(texture->target, samples,
gl_internal_format, width, height, texture->layer_count, GL_FALSE));
break;
+ case GL_TEXTURE_1D_ARRAY:
+ GL_EXTCALL(glTexStorage2D(texture->target, texture->level_count,
+ gl_internal_format, width, texture->layer_count));
+ break;
+ case GL_TEXTURE_1D:
+ GL_EXTCALL(glTexStorage1D(texture->target, texture->level_count, gl_internal_format, width));
+ break;
default:
GL_EXTCALL(glTexStorage2D(texture->target, texture->level_count,
gl_internal_format, width, height));
@@ -1782,7 +1798,12 @@ void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int s
target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx);
level = sub_resource_idx % texture->level_count;
- if (target == GL_TEXTURE_2D_ARRAY)
+ if (target == GL_TEXTURE_1D_ARRAY)
+ {
+ dst_y = sub_resource_idx / texture->level_count;
+ update_h = 1;
+ }
+ else if (target == GL_TEXTURE_2D_ARRAY)
{
dst_z = sub_resource_idx / texture->level_count;
update_d = 1;
@@ -1860,7 +1881,12 @@ void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int s
target, level, dst_x, dst_y, dst_z, update_w, update_h,
update_d, internal, dst_slice_pitch, addr);
- if (dst_row_pitch == src_row_pitch)
+ if (target == GL_TEXTURE_1D)
+ {
+ GL_EXTCALL(glCompressedTexSubImage1D(target, level, dst_x,
+ update_w, internal, dst_row_pitch, addr));
+ }
+ else if (dst_row_pitch == src_row_pitch)
{
if (target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_3D)
{
@@ -1915,6 +1941,11 @@ void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int s
GL_EXTCALL(glTexSubImage3D(target, level, dst_x, dst_y, dst_z,
update_w, update_h, update_d, format->glFormat, format->glType, bo.addr));
}
+ else if (target == GL_TEXTURE_1D)
+ {
+ gl_info->gl_ops.gl.p_glTexSubImage1D(target, level, dst_x,
+ update_w, format->glFormat, format->glType, bo.addr);
+ }
else
{
gl_info->gl_ops.gl.p_glTexSubImage2D(target, level, dst_x, dst_y,
@@ -2247,6 +2278,142 @@ static const struct wined3d_resource_ops texture_resource_ops =
texture_resource_sub_resource_unmap,
};
+/* Context activation is done by the caller. */
+static void texture1d_download_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+ const struct wined3d_context *context, const struct wined3d_bo_address *data)
+{
+ const struct wined3d_format *format = texture->resource.format;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ if (format->conv_byte_count)
+ {
+ FIXME("Attempting to download a converted texture, format %s.\n",
+ debug_d3dformat(format->id));
+ return;
+ }
+
+ if (data->buffer_object)
+ {
+ GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object));
+ checkGLcall("glBindBuffer");
+ }
+
+ gl_info->gl_ops.gl.p_glGetTexImage(texture->target, sub_resource_idx,
+ format->glFormat, format->glType, data->addr);
+ checkGLcall("glGetTexImage");
+
+ if (data->buffer_object)
+ {
+ GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
+ checkGLcall("glBindBuffer");
+ }
+}
+
+/* Context activation is done by the caller. */
+static BOOL texture1d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+ struct wined3d_context *context, DWORD location)
+{
+ struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx];
+ unsigned int row_pitch, slice_pitch;
+
+ TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n",
+ texture, sub_resource_idx, context, wined3d_debug_location(location));
+
+ if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location))
+ return FALSE;
+
+ switch (location)
+ {
+ case WINED3D_LOCATION_TEXTURE_RGB:
+ case WINED3D_LOCATION_TEXTURE_SRGB:
+ if (sub_resource->locations & WINED3D_LOCATION_SYSMEM)
+ {
+ struct wined3d_const_bo_address data = {0, texture->resource.heap_memory};
+ struct wined3d_box src_box;
+
+ data.addr += sub_resource->offset;
+ wined3d_texture_bind_and_dirtify(texture, context,
+ location == WINED3D_LOCATION_TEXTURE_SRGB);
+ wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
+ wined3d_texture_get_level_box(texture, sub_resource_idx % texture->level_count, &src_box);
+ wined3d_texture_upload_data(texture, sub_resource_idx, context, texture->resource.format,
+ &src_box, &data, row_pitch, slice_pitch, 0, 0, 0, FALSE);
+ }
+ else if (sub_resource->locations & WINED3D_LOCATION_BUFFER)
+ {
+ struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL};
+ struct wined3d_box src_box;
+
+ wined3d_texture_bind_and_dirtify(texture, context,
+ location == WINED3D_LOCATION_TEXTURE_SRGB);
+ wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
+ wined3d_texture_get_level_box(texture, sub_resource_idx % texture->level_count, &src_box);
+ wined3d_texture_upload_data(texture, sub_resource_idx, context, texture->resource.format,
+ &src_box, &data, row_pitch, slice_pitch, 0, 0, 0, FALSE);
+ }
+ else
+ {
+ FIXME("Implement texture loading from %s.\n", wined3d_debug_location(sub_resource->locations));
+ return FALSE;
+ }
+ break;
+
+ case WINED3D_LOCATION_SYSMEM:
+ if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
+ {
+ struct wined3d_bo_address data = {0, texture->resource.heap_memory};
+
+ data.addr += sub_resource->offset;
+ if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
+ wined3d_texture_bind_and_dirtify(texture, context, FALSE);
+ else
+ wined3d_texture_bind_and_dirtify(texture, context, TRUE);
+
+ texture1d_download_data(texture, sub_resource_idx, context, &data);
+ ++texture->download_count;
+ }
+ else
+ {
+ FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n",
+ wined3d_debug_location(sub_resource->locations));
+ return FALSE;
+ }
+ break;
+
+ case WINED3D_LOCATION_BUFFER:
+ if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
+ {
+ struct wined3d_bo_address data = {sub_resource->buffer_object, NULL};
+
+ if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
+ wined3d_texture_bind_and_dirtify(texture, context, FALSE);
+ else
+ wined3d_texture_bind_and_dirtify(texture, context, TRUE);
+
+ texture1d_download_data(texture, sub_resource_idx, context, &data);
+ }
+ else
+ {
+ FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n",
+ wined3d_debug_location(sub_resource->locations));
+ return FALSE;
+ }
+ break;
+
+ default:
+ FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location),
+ wined3d_debug_location(sub_resource->locations));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static const struct wined3d_texture_ops texture1d_ops =
+{
+ texture1d_load_location,
+};
+
static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc,
unsigned int layer_count, unsigned int level_count, DWORD flags, struct wined3d_device *device,
void *parent, const struct wined3d_parent_ops *parent_ops, const struct wined3d_texture_ops *texture_ops)
@@ -2443,6 +2610,46 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
list_init(&texture->renderbuffers);
+ switch (desc->resource_type)
+ {
+ case WINED3D_RTYPE_TEXTURE_1D:
+ if (layer_count > 1)
+ texture->target = GL_TEXTURE_1D_ARRAY;
+ else
+ texture->target = GL_TEXTURE_1D;
+ break;
+
+ case WINED3D_RTYPE_TEXTURE_2D:
+ if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP)
+ {
+ texture->target = GL_TEXTURE_CUBE_MAP_ARB;
+ }
+ else if (desc->multisample_type && gl_info->supported[ARB_TEXTURE_MULTISAMPLE])
+ {
+ if (layer_count > 1)
+ texture->target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
+ else
+ texture->target = GL_TEXTURE_2D_MULTISAMPLE;
+ }
+ else
+ {
+ if (layer_count > 1)
+ texture->target = GL_TEXTURE_2D_ARRAY;
+ else
+ texture->target = GL_TEXTURE_2D;
+ }
+ break;
+
+ case WINED3D_RTYPE_TEXTURE_3D:
+ texture->target = GL_TEXTURE_3D;
+ break;
+
+ default:
+ ERR("Invalid resource type %s.\n", debug_d3dresourcetype(desc->resource_type));
+ wined3d_texture_cleanup_sync(texture);
+ return WINED3DERR_INVALIDCALL;
+ }
+
/* Precalculated scaling for 'faked' non power of two texture coords. */
if (texture->resource.gl_type == WINED3D_GL_RES_TYPE_TEX_RECT)
{
@@ -2451,41 +2658,16 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
texture->flags &= ~(WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS);
texture->target = GL_TEXTURE_RECTANGLE_ARB;
}
+ else if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED)
+ {
+ texture->pow2_matrix[0] = (((float)desc->width) / ((float)pow2_width));
+ texture->pow2_matrix[5] = (((float)desc->height) / ((float)pow2_height));
+ texture->flags &= ~WINED3D_TEXTURE_POW2_MAT_IDENT;
+ }
else
{
- if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED)
- {
- texture->pow2_matrix[0] = (((float)desc->width) / ((float)pow2_width));
- texture->pow2_matrix[5] = (((float)desc->height) / ((float)pow2_height));
- texture->flags &= ~WINED3D_TEXTURE_POW2_MAT_IDENT;
- }
- else
- {
- texture->pow2_matrix[0] = 1.0f;
- texture->pow2_matrix[5] = 1.0f;
- }
- if (desc->resource_type == WINED3D_RTYPE_TEXTURE_3D)
- {
- texture->target = GL_TEXTURE_3D;
- }
- else if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP)
- {
- texture->target = GL_TEXTURE_CUBE_MAP_ARB;
- }
- else if (desc->multisample_type && gl_info->supported[ARB_TEXTURE_MULTISAMPLE])
- {
- if (layer_count > 1)
- texture->target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
- else
- texture->target = GL_TEXTURE_2D_MULTISAMPLE;
- }
- else
- {
- if (layer_count > 1)
- texture->target = GL_TEXTURE_2D_ARRAY;
- else
- texture->target = GL_TEXTURE_2D;
- }
+ texture->pow2_matrix[0] = 1.0f;
+ texture->pow2_matrix[5] = 1.0f;
}
texture->pow2_matrix[10] = 1.0f;
texture->pow2_matrix[15] = 1.0f;
@@ -2982,6 +3164,7 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct
UINT layer_count, UINT level_count, DWORD flags, const struct wined3d_sub_resource_data *data,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture)
{
+ const struct wined3d_texture_ops *texture_ops;
struct wined3d_texture *object;
HRESULT hr;
@@ -3028,29 +3211,28 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct
}
}
- if (!(object = heap_alloc_zero(FIELD_OFFSET(struct wined3d_texture,
- sub_resources[level_count * layer_count]))))
- return E_OUTOFMEMORY;
-
switch (desc->resource_type)
{
+ case WINED3D_RTYPE_TEXTURE_1D:
+ texture_ops = &texture1d_ops;
+ break;
case WINED3D_RTYPE_TEXTURE_2D:
- hr = wined3d_texture_init(object, desc, layer_count, level_count,
- flags, device, parent, parent_ops, &texture2d_ops);
+ texture_ops = &texture2d_ops;
break;
-
case WINED3D_RTYPE_TEXTURE_3D:
- hr = wined3d_texture_init(object, desc, layer_count, level_count,
- flags, device, parent, parent_ops, &texture3d_ops);
+ texture_ops = &texture3d_ops;
break;
-
default:
ERR("Invalid resource type %s.\n", debug_d3dresourcetype(desc->resource_type));
- hr = WINED3DERR_INVALIDCALL;
- break;
+ return WINED3DERR_INVALIDCALL;
}
- if (FAILED(hr))
+ if (!(object = heap_alloc_zero(FIELD_OFFSET(struct wined3d_texture,
+ sub_resources[level_count * layer_count]))))
+ return E_OUTOFMEMORY;
+
+ if (FAILED(hr = wined3d_texture_init(object, desc, layer_count,
+ level_count, flags, device, parent, parent_ops, texture_ops)))
{
WARN("Failed to initialize texture, returning %#x.\n", hr);
heap_free(object);
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 8b2019d671d..0775f53b7a5 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -4269,6 +4269,7 @@ const char *debug_d3dresourcetype(enum wined3d_resource_type resource_type)
#define WINED3D_TO_STR(x) case x: return #x
WINED3D_TO_STR(WINED3D_RTYPE_NONE);
WINED3D_TO_STR(WINED3D_RTYPE_BUFFER);
+ WINED3D_TO_STR(WINED3D_RTYPE_TEXTURE_1D);
WINED3D_TO_STR(WINED3D_RTYPE_TEXTURE_2D);
WINED3D_TO_STR(WINED3D_RTYPE_TEXTURE_3D);
#undef WINED3D_TO_STR
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c
index 05167f4be9c..c98ebfb7ee8 100644
--- a/dlls/wined3d/view.c
+++ b/dlls/wined3d/view.c
@@ -59,6 +59,11 @@ static GLenum get_texture_view_target(const struct wined3d_gl_info *gl_info,
{GL_TEXTURE_2D_MULTISAMPLE, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_MULTISAMPLE_ARRAY},
{GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0, GL_TEXTURE_2D_MULTISAMPLE},
{GL_TEXTURE_2D_MULTISAMPLE_ARRAY, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_MULTISAMPLE_ARRAY},
+
+ {GL_TEXTURE_1D, 0, GL_TEXTURE_1D},
+ {GL_TEXTURE_1D, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_1D_ARRAY},
+ {GL_TEXTURE_1D_ARRAY, 0, GL_TEXTURE_1D},
+ {GL_TEXTURE_1D_ARRAY, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_1D_ARRAY},
};
unsigned int i;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index a25d984a4f5..cdea1125f36 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2859,11 +2859,13 @@ struct wined3d_state
struct wined3d_dummy_textures
{
+ GLuint tex_1d;
GLuint tex_2d;
GLuint tex_rect;
GLuint tex_3d;
GLuint tex_cube;
GLuint tex_cube_array;
+ GLuint tex_1d_array;
GLuint tex_2d_array;
GLuint tex_buffer;
GLuint tex_2d_ms;
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 4e390cc960a..446e98b96f1 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -690,8 +690,9 @@ enum wined3d_resource_type
{
WINED3D_RTYPE_NONE = 0,
WINED3D_RTYPE_BUFFER = 1,
- WINED3D_RTYPE_TEXTURE_2D = 2,
- WINED3D_RTYPE_TEXTURE_3D = 3,
+ WINED3D_RTYPE_TEXTURE_1D = 2,
+ WINED3D_RTYPE_TEXTURE_2D = 3,
+ WINED3D_RTYPE_TEXTURE_3D = 4,
};
enum wined3d_query_type
--
2.11.0
1
0
From: Sven Hesse <shesse(a)codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/d3d10core/tests/device.c | 82 +++++++++++++++++++++++++++++++++++++++++++
dlls/d3d11/device.c | 23 ++++++++++--
2 files changed, 103 insertions(+), 2 deletions(-)
diff --git a/dlls/d3d10core/tests/device.c b/dlls/d3d10core/tests/device.c
index 7b28e016c4b..c4349395338 100644
--- a/dlls/d3d10core/tests/device.c
+++ b/dlls/d3d10core/tests/device.c
@@ -1310,6 +1310,87 @@ static void test_device_interfaces(void)
ok(!refcount, "Device has %u references left.\n", refcount);
}
+static void test_create_texture1d(void)
+{
+ ULONG refcount, expected_refcount;
+ ID3D10Device *device, *tmp;
+ D3D10_TEXTURE1D_DESC desc;
+ ID3D10Texture1D *texture;
+ unsigned int i;
+ HRESULT hr;
+
+ if (!(device = create_device()))
+ {
+ skip("Failed to create device.\n");
+ return;
+ }
+
+ desc.Width = 512;
+ desc.MipLevels = 1;
+ desc.ArraySize = 1;
+ desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ desc.Usage = D3D10_USAGE_DEFAULT;
+ desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ expected_refcount = get_refcount(device) + 1;
+ hr = ID3D10Device_CreateTexture1D(device, &desc, NULL, &texture);
+ ok(SUCCEEDED(hr), "Failed to create a 1d texture, hr %#x.\n", hr);
+ refcount = get_refcount(device);
+ ok(refcount >= expected_refcount, "Got unexpected refcount %u, expected >= %u.\n", refcount, expected_refcount);
+ tmp = NULL;
+ expected_refcount = refcount + 1;
+ ID3D10Texture1D_GetDevice(texture, &tmp);
+ ok(tmp == device, "Got unexpected device %p, expected %p.\n", tmp, device);
+ refcount = get_refcount(device);
+ ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
+ ID3D10Device_Release(tmp);
+
+ ID3D10Texture1D_Release(texture);
+
+ desc.MipLevels = 0;
+ expected_refcount = get_refcount(device) + 1;
+ hr = ID3D10Device_CreateTexture1D(device, &desc, NULL, &texture);
+ ok(SUCCEEDED(hr), "Failed to create a 1d texture, hr %#x.\n", hr);
+ refcount = get_refcount(device);
+ ok(refcount >= expected_refcount, "Got unexpected refcount %u, expected >= %u.\n", refcount, expected_refcount);
+ tmp = NULL;
+ expected_refcount = refcount + 1;
+ ID3D10Texture1D_GetDevice(texture, &tmp);
+ ok(tmp == device, "Got unexpected device %p, expected %p.\n", tmp, device);
+ refcount = get_refcount(device);
+ ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
+ ID3D10Device_Release(tmp);
+
+ check_interface(texture, &IID_IDXGISurface, FALSE, FALSE);
+ ID3D10Texture1D_Release(texture);
+
+ desc.MipLevels = 1;
+ desc.ArraySize = 2;
+ hr = ID3D10Device_CreateTexture1D(device, &desc, NULL, &texture);
+ ok(SUCCEEDED(hr), "Failed to create a 1d texture, hr %#x.\n", hr);
+
+ check_interface(texture, &IID_IDXGISurface, FALSE, FALSE);
+ ID3D10Texture1D_Release(texture);
+
+ for (i = 0; i < 4; ++i)
+ {
+ desc.ArraySize = i;
+ desc.Format = DXGI_FORMAT_R32G32B32A32_TYPELESS;
+ desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
+ desc.MiscFlags = 0;
+ hr = ID3D10Device_CreateTexture1D(device, &desc, NULL, (ID3D10Texture1D **)&texture);
+ todo_wine_if(!i)
+ ok(hr == (i ? S_OK : E_INVALIDARG), "Test %u: Got unexpected hr %#x.\n", i, hr);
+ if (SUCCEEDED(hr))
+ ID3D10Texture1D_Release(texture);
+ }
+
+ refcount = ID3D10Device_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+}
+
static void test_create_texture2d(void)
{
ULONG refcount, expected_refcount;
@@ -14935,6 +15016,7 @@ START_TEST(device)
test_feature_level();
test_device_interfaces();
+ test_create_texture1d();
test_create_texture2d();
test_texture2d_interfaces();
test_create_texture3d();
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c
index 9799d73dbf7..8316105034e 100644
--- a/dlls/d3d11/device.c
+++ b/dlls/d3d11/device.c
@@ -4995,9 +4995,28 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreateBuffer(ID3D10Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d10_device_CreateTexture1D(ID3D10Device1 *iface,
const D3D10_TEXTURE1D_DESC *desc, const D3D10_SUBRESOURCE_DATA *data, ID3D10Texture1D **texture)
{
- FIXME("iface %p, desc %p, data %p, texture %p stub!\n", iface, desc, data, texture);
+ struct d3d_device *device = impl_from_ID3D10Device(iface);
+ D3D11_TEXTURE1D_DESC d3d11_desc;
+ struct d3d_texture1d *object;
+ HRESULT hr;
- return E_NOTIMPL;
+ TRACE("iface %p, desc %p, data %p, texture %p.\n", iface, desc, data, texture);
+
+ d3d11_desc.Width = desc->Width;
+ d3d11_desc.MipLevels = desc->MipLevels;
+ d3d11_desc.ArraySize = desc->ArraySize;
+ d3d11_desc.Format = desc->Format;
+ d3d11_desc.Usage = d3d11_usage_from_d3d10_usage(desc->Usage);
+ d3d11_desc.BindFlags = d3d11_bind_flags_from_d3d10_bind_flags(desc->BindFlags);
+ d3d11_desc.CPUAccessFlags = d3d11_cpu_access_flags_from_d3d10_cpu_access_flags(desc->CPUAccessFlags);
+ d3d11_desc.MiscFlags = d3d11_resource_misc_flags_from_d3d10_resource_misc_flags(desc->MiscFlags);
+
+ if (FAILED(hr = d3d_texture1d_create(device, &d3d11_desc, (const D3D11_SUBRESOURCE_DATA *)data, &object)))
+ return hr;
+
+ *texture = &object->ID3D10Texture1D_iface;
+
+ return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d10_device_CreateTexture2D(ID3D10Device1 *iface,
--
2.11.0
1
0
[PATCH 5/5] windowscodecs: Directly use patterns stored in component info object in IWICMetadataReaderInfo::MatchesPattern implementation.
by Jacek Caban 02 Apr '18
by Jacek Caban 02 Apr '18
02 Apr '18
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
dlls/windowscodecs/info.c | 42 +++++++++++++++++-------------------------
1 file changed, 17 insertions(+), 25 deletions(-)
2
1
[PATCH 4/5] windowscodecs: Store metadata container patterns in meatadata reader info object.
by Jacek Caban 02 Apr '18
by Jacek Caban 02 Apr '18
02 Apr '18
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
dlls/windowscodecs/info.c | 262
++++++++++++++++++++++++++++------------------
1 file changed, 162 insertions(+), 100 deletions(-)
2
1
[PATCH 1/5] windowscodecs: Store bitmap patterns in bitmap decoder info object.
by Jacek Caban 02 Apr '18
by Jacek Caban 02 Apr '18
02 Apr '18
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
dlls/windowscodecs/info.c | 211
+++++++++++++++++++++++++++-------------------
1 file changed, 126 insertions(+), 85 deletions(-)
2
1
[PATCH 2/5] windowscodecs: Directly use patterns stored in component info object in IWICBitmapDecoderInfo::MatchesPattern implementation.
by Jacek Caban 02 Apr '18
by Jacek Caban 02 Apr '18
02 Apr '18
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
dlls/windowscodecs/info.c | 43 +++++++++++++++----------------------------
1 file changed, 15 insertions(+), 28 deletions(-)
2
1
[PATCH 3/5] windowscodecs: Store container formats in metadata component info object.
by Jacek Caban 02 Apr '18
by Jacek Caban 02 Apr '18
02 Apr '18
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
dlls/windowscodecs/info.c | 50
++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 47 insertions(+), 3 deletions(-)
2
1
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/windowscodecs/bmpdecode.c | 13 +------------
dlls/windowscodecs/gifformat.c | 13 +------------
dlls/windowscodecs/icoformat.c | 13 +------------
dlls/windowscodecs/info.c | 16 ++++++++++++++++
dlls/windowscodecs/jpegformat.c | 13 +------------
dlls/windowscodecs/pngformat.c | 13 +------------
dlls/windowscodecs/tgaformat.c | 13 +------------
dlls/windowscodecs/tiffformat.c | 13 +------------
dlls/windowscodecs/wincodecs_private.h | 1 +
9 files changed, 24 insertions(+), 84 deletions(-)
diff --git a/dlls/windowscodecs/bmpdecode.c b/dlls/windowscodecs/bmpdecode.c
index 2bcb81e0d6..4109bad4b3 100644
--- a/dlls/windowscodecs/bmpdecode.c
+++ b/dlls/windowscodecs/bmpdecode.c
@@ -1068,20 +1068,9 @@ static HRESULT WINAPI BmpDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
static HRESULT WINAPI BmpDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
IWICBitmapDecoderInfo **ppIDecoderInfo)
{
- HRESULT hr;
- IWICComponentInfo *compinfo;
-
TRACE("(%p,%p)\n", iface, ppIDecoderInfo);
- hr = CreateComponentInfo(&CLSID_WICBmpDecoder, &compinfo);
- if (FAILED(hr)) return hr;
-
- hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo,
- (void**)ppIDecoderInfo);
-
- IWICComponentInfo_Release(compinfo);
-
- return hr;
+ return get_decoder_info(&CLSID_WICBmpDecoder, ppIDecoderInfo);
}
static HRESULT WINAPI BmpDecoder_CopyPalette(IWICBitmapDecoder *iface,
diff --git a/dlls/windowscodecs/gifformat.c b/dlls/windowscodecs/gifformat.c
index f63a7f37a9..0eb1d804ec 100644
--- a/dlls/windowscodecs/gifformat.c
+++ b/dlls/windowscodecs/gifformat.c
@@ -1170,20 +1170,9 @@ static HRESULT WINAPI GifDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
static HRESULT WINAPI GifDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
IWICBitmapDecoderInfo **ppIDecoderInfo)
{
- HRESULT hr;
- IWICComponentInfo *compinfo;
-
TRACE("(%p,%p)\n", iface, ppIDecoderInfo);
- hr = CreateComponentInfo(&CLSID_WICGifDecoder, &compinfo);
- if (FAILED(hr)) return hr;
-
- hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo,
- (void**)ppIDecoderInfo);
-
- IWICComponentInfo_Release(compinfo);
-
- return hr;
+ return get_decoder_info(&CLSID_WICGifDecoder, ppIDecoderInfo);
}
static HRESULT WINAPI GifDecoder_CopyPalette(IWICBitmapDecoder *iface, IWICPalette *palette)
diff --git a/dlls/windowscodecs/icoformat.c b/dlls/windowscodecs/icoformat.c
index 1b1c79291b..5e38ee0d0f 100644
--- a/dlls/windowscodecs/icoformat.c
+++ b/dlls/windowscodecs/icoformat.c
@@ -556,20 +556,9 @@ static HRESULT WINAPI IcoDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
static HRESULT WINAPI IcoDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
IWICBitmapDecoderInfo **ppIDecoderInfo)
{
- HRESULT hr;
- IWICComponentInfo *compinfo;
-
TRACE("(%p,%p)\n", iface, ppIDecoderInfo);
- hr = CreateComponentInfo(&CLSID_WICIcoDecoder, &compinfo);
- if (FAILED(hr)) return hr;
-
- hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo,
- (void**)ppIDecoderInfo);
-
- IWICComponentInfo_Release(compinfo);
-
- return hr;
+ return get_decoder_info(&CLSID_WICIcoDecoder, ppIDecoderInfo);
}
static HRESULT WINAPI IcoDecoder_CopyPalette(IWICBitmapDecoder *iface,
diff --git a/dlls/windowscodecs/info.c b/dlls/windowscodecs/info.c
index 6114eef557..fadefba50d 100644
--- a/dlls/windowscodecs/info.c
+++ b/dlls/windowscodecs/info.c
@@ -2029,6 +2029,22 @@ void ReleaseComponentInfos(void)
IWICComponentInfo_Release(&info->IWICComponentInfo_iface);
}
+HRESULT get_decoder_info(const CLSID *clsid, IWICBitmapDecoderInfo **info)
+{
+ IWICComponentInfo *compinfo;
+ HRESULT hr;
+
+ hr = CreateComponentInfo(clsid, &compinfo);
+ if (FAILED(hr)) return hr;
+
+ hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo,
+ (void **)info);
+
+ IWICComponentInfo_Release(compinfo);
+
+ return hr;
+}
+
typedef struct {
IEnumUnknown IEnumUnknown_iface;
LONG ref;
diff --git a/dlls/windowscodecs/jpegformat.c b/dlls/windowscodecs/jpegformat.c
index 27cd88036b..f05663f070 100644
--- a/dlls/windowscodecs/jpegformat.c
+++ b/dlls/windowscodecs/jpegformat.c
@@ -398,20 +398,9 @@ static HRESULT WINAPI JpegDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
static HRESULT WINAPI JpegDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
IWICBitmapDecoderInfo **ppIDecoderInfo)
{
- HRESULT hr;
- IWICComponentInfo *compinfo;
-
TRACE("(%p,%p)\n", iface, ppIDecoderInfo);
- hr = CreateComponentInfo(&CLSID_WICJpegDecoder, &compinfo);
- if (FAILED(hr)) return hr;
-
- hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo,
- (void**)ppIDecoderInfo);
-
- IWICComponentInfo_Release(compinfo);
-
- return hr;
+ return get_decoder_info(&CLSID_WICJpegDecoder, ppIDecoderInfo);
}
static HRESULT WINAPI JpegDecoder_CopyPalette(IWICBitmapDecoder *iface,
diff --git a/dlls/windowscodecs/pngformat.c b/dlls/windowscodecs/pngformat.c
index 26b5fd52bc..fd0d197bb3 100644
--- a/dlls/windowscodecs/pngformat.c
+++ b/dlls/windowscodecs/pngformat.c
@@ -829,20 +829,9 @@ static HRESULT WINAPI PngDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
static HRESULT WINAPI PngDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
IWICBitmapDecoderInfo **ppIDecoderInfo)
{
- HRESULT hr;
- IWICComponentInfo *compinfo;
-
TRACE("(%p,%p)\n", iface, ppIDecoderInfo);
- hr = CreateComponentInfo(&CLSID_WICPngDecoder, &compinfo);
- if (FAILED(hr)) return hr;
-
- hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo,
- (void**)ppIDecoderInfo);
-
- IWICComponentInfo_Release(compinfo);
-
- return hr;
+ return get_decoder_info(&CLSID_WICPngDecoder, ppIDecoderInfo);
}
static HRESULT WINAPI PngDecoder_CopyPalette(IWICBitmapDecoder *iface,
diff --git a/dlls/windowscodecs/tgaformat.c b/dlls/windowscodecs/tgaformat.c
index ec7fa23169..b3d9aeae26 100644
--- a/dlls/windowscodecs/tgaformat.c
+++ b/dlls/windowscodecs/tgaformat.c
@@ -360,20 +360,9 @@ static HRESULT WINAPI TgaDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
static HRESULT WINAPI TgaDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
IWICBitmapDecoderInfo **ppIDecoderInfo)
{
- HRESULT hr;
- IWICComponentInfo *compinfo;
-
TRACE("(%p,%p)\n", iface, ppIDecoderInfo);
- hr = CreateComponentInfo(&CLSID_WineTgaDecoder, &compinfo);
- if (FAILED(hr)) return hr;
-
- hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo,
- (void**)ppIDecoderInfo);
-
- IWICComponentInfo_Release(compinfo);
-
- return hr;
+ return get_decoder_info(&CLSID_WineTgaDecoder, ppIDecoderInfo);
}
static HRESULT WINAPI TgaDecoder_CopyPalette(IWICBitmapDecoder *iface,
diff --git a/dlls/windowscodecs/tiffformat.c b/dlls/windowscodecs/tiffformat.c
index 6fe3f19677..2b2f84f859 100644
--- a/dlls/windowscodecs/tiffformat.c
+++ b/dlls/windowscodecs/tiffformat.c
@@ -672,20 +672,9 @@ static HRESULT WINAPI TiffDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
static HRESULT WINAPI TiffDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
IWICBitmapDecoderInfo **ppIDecoderInfo)
{
- HRESULT hr;
- IWICComponentInfo *compinfo;
-
TRACE("(%p,%p)\n", iface, ppIDecoderInfo);
- hr = CreateComponentInfo(&CLSID_WICTiffDecoder, &compinfo);
- if (FAILED(hr)) return hr;
-
- hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo,
- (void**)ppIDecoderInfo);
-
- IWICComponentInfo_Release(compinfo);
-
- return hr;
+ return get_decoder_info(&CLSID_WICTiffDecoder, ppIDecoderInfo);
}
static HRESULT WINAPI TiffDecoder_CopyPalette(IWICBitmapDecoder *iface,
diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h
index 037bde2da0..b29fc1fa4d 100644
--- a/dlls/windowscodecs/wincodecs_private.h
+++ b/dlls/windowscodecs/wincodecs_private.h
@@ -126,6 +126,7 @@ extern HRESULT CreatePropertyBag2(const PROPBAG2 *options, UINT count,
extern HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo) DECLSPEC_HIDDEN;
extern void ReleaseComponentInfos(void) DECLSPEC_HIDDEN;
extern HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown) DECLSPEC_HIDDEN;
+extern HRESULT get_decoder_info(REFCLSID clsid, IWICBitmapDecoderInfo **info) DECLSPEC_HIDDEN;
typedef struct BmpDecoder BmpDecoder;
--
2.16.2
2
1
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/user32/Makefile.in | 1 +
dlls/user32/cursoricon.c | 337 ++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 334 insertions(+), 4 deletions(-)
diff --git a/dlls/user32/Makefile.in b/dlls/user32/Makefile.in
index 246c424155..931a715763 100644
--- a/dlls/user32/Makefile.in
+++ b/dlls/user32/Makefile.in
@@ -2,6 +2,7 @@ EXTRADEFS = -D_USER32_ -D_WINABLE_
MODULE = user32.dll
IMPORTLIB = user32
IMPORTS = gdi32 version advapi32
+EXTRAINCL = $(PNG_CFLAGS)
DELAYIMPORTS = imm32 usp10
C_SRCS = \
diff --git a/dlls/user32/cursoricon.c b/dlls/user32/cursoricon.c
index 8e272f09ce..1cb46050d4 100644
--- a/dlls/user32/cursoricon.c
+++ b/dlls/user32/cursoricon.c
@@ -6,6 +6,8 @@
* 1997 Alex Korobka
* 1998 Turchanov Sergey
* 2007 Henri Verbeet
+ * Copyright 2009 Vincent Povirk for CodeWeavers
+ * Copyright 2016 Dmitry Timoshkov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -29,6 +31,9 @@
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
+#ifdef HAVE_PNG_H
+#include <png.h>
+#endif
#include "windef.h"
#include "winbase.h"
@@ -43,11 +48,17 @@
#include "wine/list.h"
#include "wine/unicode.h"
#include "wine/debug.h"
+#include "wine/library.h"
WINE_DEFAULT_DEBUG_CHANNEL(cursor);
WINE_DECLARE_DEBUG_CHANNEL(icon);
WINE_DECLARE_DEBUG_CHANNEL(resource);
+#define RIFF_FOURCC( c0, c1, c2, c3 ) \
+ ( (DWORD)(BYTE)(c0) | ( (DWORD)(BYTE)(c1) << 8 ) | \
+ ( (DWORD)(BYTE)(c2) << 16 ) | ( (DWORD)(BYTE)(c3) << 24 ) )
+#define PNG_SIGN RIFF_FOURCC(0x89,'P','N','G')
+
static struct list icon_cache = LIST_INIT( icon_cache );
/**********************************************************************
@@ -108,6 +119,307 @@ static int get_display_bpp(void)
return ret;
}
+#ifdef SONAME_LIBPNG
+
+static void *libpng_handle;
+#define MAKE_FUNCPTR(f) static typeof(f) * p##f
+MAKE_FUNCPTR(png_create_read_struct);
+MAKE_FUNCPTR(png_create_info_struct);
+MAKE_FUNCPTR(png_destroy_read_struct);
+MAKE_FUNCPTR(png_error);
+MAKE_FUNCPTR(png_get_bit_depth);
+MAKE_FUNCPTR(png_get_color_type);
+MAKE_FUNCPTR(png_get_error_ptr);
+MAKE_FUNCPTR(png_get_image_height);
+MAKE_FUNCPTR(png_get_image_width);
+MAKE_FUNCPTR(png_get_io_ptr);
+MAKE_FUNCPTR(png_read_image);
+MAKE_FUNCPTR(png_read_info);
+MAKE_FUNCPTR(png_read_update_info);
+MAKE_FUNCPTR(png_set_bgr);
+MAKE_FUNCPTR(png_set_crc_action);
+MAKE_FUNCPTR(png_set_error_fn);
+MAKE_FUNCPTR(png_set_expand);
+MAKE_FUNCPTR(png_set_gray_to_rgb);
+MAKE_FUNCPTR(png_set_read_fn);
+#undef MAKE_FUNCPTR
+
+static BOOL load_libpng(void)
+{
+ USER_Lock();
+
+ if (!libpng_handle && (libpng_handle = wine_dlopen(SONAME_LIBPNG, RTLD_NOW, NULL, 0)) != NULL)
+ {
+#define LOAD_FUNCPTR(f) \
+ if ((p##f = wine_dlsym(libpng_handle, #f, NULL, 0)) == NULL) \
+ { \
+ libpng_handle = NULL; \
+ USER_Unlock(); \
+ return FALSE; \
+ }
+ LOAD_FUNCPTR(png_create_read_struct);
+ LOAD_FUNCPTR(png_create_info_struct);
+ LOAD_FUNCPTR(png_destroy_read_struct);
+ LOAD_FUNCPTR(png_error);
+ LOAD_FUNCPTR(png_get_bit_depth);
+ LOAD_FUNCPTR(png_get_color_type);
+ LOAD_FUNCPTR(png_get_error_ptr);
+ LOAD_FUNCPTR(png_get_image_height);
+ LOAD_FUNCPTR(png_get_image_width);
+ LOAD_FUNCPTR(png_get_io_ptr);
+ LOAD_FUNCPTR(png_read_image);
+ LOAD_FUNCPTR(png_read_info);
+ LOAD_FUNCPTR(png_read_update_info);
+ LOAD_FUNCPTR(png_set_bgr);
+ LOAD_FUNCPTR(png_set_crc_action);
+ LOAD_FUNCPTR(png_set_error_fn);
+ LOAD_FUNCPTR(png_set_expand);
+ LOAD_FUNCPTR(png_set_gray_to_rgb);
+ LOAD_FUNCPTR(png_set_read_fn);
+#undef LOAD_FUNCPTR
+ }
+
+ USER_Unlock();
+ return TRUE;
+}
+
+static void user_error_fn(png_structp png_ptr, png_const_charp error_message)
+{
+ jmp_buf *pjmpbuf;
+
+ /* This uses setjmp/longjmp just like the default. We can't use the
+ * default because there's no way to access the jmp buffer in the png_struct
+ * that works in 1.2 and 1.4 and allows us to dynamically load libpng. */
+ WARN("PNG error: %s\n", debugstr_a(error_message));
+ pjmpbuf = ppng_get_error_ptr(png_ptr);
+ longjmp(*pjmpbuf, 1);
+}
+
+static void user_warning_fn(png_structp png_ptr, png_const_charp warning_message)
+{
+ WARN("PNG warning: %s\n", debugstr_a(warning_message));
+}
+
+struct png_wrapper
+{
+ png_structp png_ptr;
+ png_infop info_ptr;
+ int width, height, bpp;
+ const char *buffer;
+ int size, pos;
+};
+
+static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ struct png_wrapper *png = ppng_get_io_ptr(png_ptr);
+
+ if (png->size - png->pos >= length)
+ {
+ memcpy(data, png->buffer + png->pos, length);
+ png->pos += length;
+ }
+ else
+ {
+ ppng_error(png->png_ptr, "failed to read PNG data");
+ }
+}
+
+static BOOL create_png_decoder(struct png_wrapper *png)
+{
+ jmp_buf jmpbuf;
+ int color_type, bit_depth;
+
+ if (!load_libpng()) return FALSE;
+
+ /* initialize libpng */
+ png->png_ptr = ppng_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (!png->png_ptr) return FALSE;
+
+ png->info_ptr = ppng_create_info_struct(png->png_ptr);
+ if (!png->info_ptr)
+ {
+ ppng_destroy_read_struct(&png->png_ptr, NULL, NULL);
+ return FALSE;
+ }
+
+ /* set up setjmp/longjmp error handling */
+ if (setjmp(jmpbuf))
+ {
+ ppng_destroy_read_struct(&png->png_ptr, &png->info_ptr, NULL);
+ return FALSE;
+ }
+
+ ppng_set_error_fn(png->png_ptr, jmpbuf, user_error_fn, user_warning_fn);
+ ppng_set_crc_action(png->png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE);
+
+ /* set up custom i/o handling */
+ ppng_set_read_fn(png->png_ptr, png, user_read_data);
+
+ /* read the header */
+ ppng_read_info(png->png_ptr, png->info_ptr);
+
+ color_type = ppng_get_color_type(png->png_ptr, png->info_ptr);
+ bit_depth = ppng_get_bit_depth(png->png_ptr, png->info_ptr);
+
+ /* expand grayscale image data to rgb */
+ if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ ppng_set_gray_to_rgb(png->png_ptr);
+
+ /* expand palette image data to rgb */
+ if (color_type == PNG_COLOR_TYPE_PALETTE || bit_depth < 8)
+ ppng_set_expand(png->png_ptr);
+
+ /* update color type information */
+ ppng_read_update_info(png->png_ptr, png->info_ptr);
+
+ color_type = ppng_get_color_type(png->png_ptr, png->info_ptr);
+ bit_depth = ppng_get_bit_depth(png->png_ptr, png->info_ptr);
+
+ png->bpp = 0;
+
+ switch (color_type)
+ {
+ case PNG_COLOR_TYPE_RGB:
+ if (bit_depth == 8)
+ png->bpp = 24;
+ break;
+
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ if (bit_depth == 8)
+ {
+ ppng_set_bgr(png->png_ptr);
+ png->bpp = 32;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (!png->bpp)
+ {
+ FIXME("unsupported PNG color format %d, %d bpp\n", color_type, bit_depth);
+ ppng_destroy_read_struct(&png->png_ptr, &png->info_ptr, NULL);
+ return FALSE;
+ }
+
+ png->width = ppng_get_image_width(png->png_ptr, png->info_ptr);
+ png->height = ppng_get_image_height(png->png_ptr, png->info_ptr);
+
+ return TRUE;
+}
+
+static void destroy_png_decoder(struct png_wrapper *png)
+{
+ ppng_destroy_read_struct(&png->png_ptr, &png->info_ptr, NULL);
+}
+
+static BOOL get_png_info(const void *png_data, DWORD size, int *width, int *height, int *bpp)
+{
+ static const char png_sig[8] = { 0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a };
+ struct png_wrapper png;
+
+ if (size < sizeof(png_sig) || memcmp(png_data, png_sig, sizeof(png_sig)) != 0)
+ return FALSE;
+
+ png.buffer = png_data;
+ png.size = size;
+ png.pos = 0;
+
+ if (!create_png_decoder(&png)) return FALSE;
+
+ *width = png.width;
+ *height = png.height;
+ *bpp = png.bpp;
+
+ destroy_png_decoder(&png);
+ return TRUE;
+}
+
+static BITMAPINFO *load_png(const char *png_data, DWORD *size)
+{
+ static const char png_sig[8] = { 0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a };
+ struct png_wrapper png;
+ png_bytep *row_pointers;
+ int rowbytes, image_size, mask_size = 0, i;
+ BITMAPINFO *info;
+ unsigned char *image_data;
+
+ if (*size < sizeof(png_sig) || memcmp(png_data, png_sig, sizeof(png_sig)) != 0)
+ return NULL;
+
+ png.buffer = png_data;
+ png.size = *size;
+ png.pos = 0;
+
+ if (!create_png_decoder(&png)) return NULL;
+
+ rowbytes = (png.width * png.bpp + 7) / 8;
+ image_size = png.height * rowbytes;
+ if (png.bpp != 32) /* add a mask if there is no alpha */
+ mask_size = (png.width + 7) / 8 * png.height;
+
+ info = HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER) + image_size + mask_size);
+ if (!info)
+ {
+ destroy_png_decoder(&png);
+ return NULL;
+ }
+
+ image_data = (unsigned char *)info + sizeof(BITMAPINFOHEADER);
+ memset(image_data + image_size, 0, mask_size);
+
+ row_pointers = HeapAlloc(GetProcessHeap(), 0, png.height * sizeof(png_bytep));
+ if (!row_pointers)
+ {
+ HeapFree(GetProcessHeap(), 0, info);
+ destroy_png_decoder(&png);
+ return NULL;
+ }
+
+ /* upside down */
+ for (i = 0; i < png.height; i++)
+ row_pointers[i] = image_data + (png.height - i - 1) * rowbytes;
+
+ ppng_read_image(png.png_ptr, row_pointers);
+
+ HeapFree(GetProcessHeap(), 0, row_pointers);
+
+ info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ info->bmiHeader.biWidth = png.width;
+ info->bmiHeader.biHeight = png.height * 2;
+ info->bmiHeader.biPlanes = 1;
+ info->bmiHeader.biBitCount = png.bpp;
+ info->bmiHeader.biCompression = BI_RGB;
+ info->bmiHeader.biSizeImage = image_size;
+ info->bmiHeader.biXPelsPerMeter = 0;
+ info->bmiHeader.biYPelsPerMeter = 0;
+ info->bmiHeader.biClrUsed = 0;
+ info->bmiHeader.biClrImportant = 0;
+
+ *size = sizeof(BITMAPINFOHEADER) + image_size + mask_size;
+
+ destroy_png_decoder(&png);
+
+ return info;
+}
+
+#else /* SONAME_LIBPNG */
+
+static BOOL get_png_info(const void *png_data, DWORD size, int *width, int *height, int *bpp)
+{
+ ERR("Trying to load PNG icon, but PNG support is not compiled in.\n");
+ return FALSE;
+}
+
+static BITMAPINFO *load_png( const char *png, DWORD *max_size )
+{
+ ERR("Trying to load PNG icon, but PNG support is not compiled in.\n");
+ return NULL;
+}
+
+#endif
+
static HICON alloc_icon_handle( BOOL is_ani, UINT num_steps )
{
struct cursoricon_object *obj;
@@ -523,6 +835,8 @@ static int CURSORICON_FindBestIcon( LPCVOID dir, DWORD size, fnGetCIEntry get_en
/* Find Best Colors for Best Fit */
for ( i = 0; get_entry( dir, size, i, &cx, &cy, &bits ); i++ )
{
+ TRACE("entry %d: %d x %d, %d bpp\n", i, cx, cy, bits);
+
if(abs(width - cx) == iXDiff && abs(height - cy) == iYDiff)
{
iTempColorDiff = abs(depth - bits);
@@ -680,6 +994,10 @@ static BOOL CURSORICON_GetFileEntry( LPCVOID dir, DWORD size, int n,
entry = &filedir->idEntries[n];
if (entry->dwDIBOffset > size - sizeof(info->biSize)) return FALSE;
info = (const BITMAPINFOHEADER *)((const char *)dir + entry->dwDIBOffset);
+
+ if (info->biSize == PNG_SIGN)
+ return get_png_info(info, size, width, height, bits);
+
if (info->biSize != sizeof(BITMAPCOREHEADER))
{
if ((const char *)(info + 1) - (const char *)dir > size) return FALSE;
@@ -824,6 +1142,21 @@ static HICON create_icon_from_bmi( const BITMAPINFO *bmi, DWORD maxsize, HMODULE
/* Check bitmap header */
+ if (bmi->bmiHeader.biSize == PNG_SIGN)
+ {
+ BITMAPINFO *bmi_png;
+
+ bmi_png = load_png( (const char *)bmi, &maxsize );
+ if (bmi_png)
+ {
+ hObj = create_icon_from_bmi( bmi_png, maxsize, module, resname,
+ rsrc, hotspot, bIcon, width, height, cFlag );
+ HeapFree( GetProcessHeap(), 0, bmi_png );
+ return hObj;
+ }
+ return 0;
+ }
+
if (maxsize < sizeof(BITMAPCOREHEADER))
{
WARN( "invalid size %u\n", maxsize );
@@ -1001,10 +1334,6 @@ done:
/**********************************************************************
* .ANI cursor support
*/
-#define RIFF_FOURCC( c0, c1, c2, c3 ) \
- ( (DWORD)(BYTE)(c0) | ( (DWORD)(BYTE)(c1) << 8 ) | \
- ( (DWORD)(BYTE)(c2) << 16 ) | ( (DWORD)(BYTE)(c3) << 24 ) )
-
#define ANI_RIFF_ID RIFF_FOURCC('R', 'I', 'F', 'F')
#define ANI_LIST_ID RIFF_FOURCC('L', 'I', 'S', 'T')
#define ANI_ACON_ID RIFF_FOURCC('A', 'C', 'O', 'N')
--
2.16.2
2
3