From f3840daf258b2aa668209c3633f032000edc331a Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Tue, 3 Apr 2018 01:28:21 +0430 Subject: [PATCH] d3d11: Implement d3d11_device_CreateTexture1D(). Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/d3d11/d3d11_private.h | 15 ++ dlls/d3d11/device.c | 13 +- dlls/d3d11/tests/d3d11.c | 92 +++++++++++ dlls/d3d11/texture.c | 316 +++++++++++++++++++++++++++++++++++++ 4 files changed, 434 insertions(+), 2 deletions(-) diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h index f9cfd6cecd4..68e56d76092 100644 --- a/dlls/d3d11/d3d11_private.h +++ b/dlls/d3d11/d3d11_private.h @@ -112,6 +112,21 @@ void skip_dword_unknown(const char **ptr, unsigned int count) DECLSPEC_HIDDEN; HRESULT parse_dxbc(const char *data, SIZE_T data_size, HRESULT (*chunk_handler)(const char *data, DWORD data_size, DWORD tag, void *ctx), void *ctx) DECLSPEC_HIDDEN; +/* ID3D11Texture1D, ID3D10Texture1D */ +struct d3d_texture1d +{ + ID3D11Texture1D ID3D11Texture1D_iface; + ID3D10Texture1D ID3D10Texture1D_iface; + LONG refcount; + + struct wined3d_private_store private_store; + 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; + /* ID3D11Texture2D, ID3D10Texture2D */ struct d3d_texture2d { diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index d93f4ebe734..9799d73dbf7 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -2764,9 +2764,18 @@ static HRESULT STDMETHODCALLTYPE d3d11_device_CreateBuffer(ID3D11Device *iface, static HRESULT STDMETHODCALLTYPE d3d11_device_CreateTexture1D(ID3D11Device *iface, const D3D11_TEXTURE1D_DESC *desc, const D3D11_SUBRESOURCE_DATA *data, ID3D11Texture1D **texture) { - FIXME("iface %p, desc %p, data %p, texture %p stub!\n", iface, desc, data, texture); + struct d3d_device *device = impl_from_ID3D11Device(iface); + struct d3d_texture1d *object; + HRESULT hr; - return E_NOTIMPL; + TRACE("iface %p, desc %p, data %p, texture %p.\n", iface, desc, data, texture); + + if (FAILED(hr = d3d_texture1d_create(device, desc, data, &object))) + return hr; + + *texture = &object->ID3D11Texture1D_iface; + + return S_OK; } static HRESULT STDMETHODCALLTYPE d3d11_device_CreateTexture2D(ID3D11Device *iface, diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 6d7fccdcfb6..146509dd05e 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -1825,6 +1825,97 @@ static void test_get_immediate_context(void) ok(!refcount, "Device has %u references left.\n", refcount); } +static void test_create_texture1d(void) +{ + ULONG refcount, expected_refcount; + ID3D11Device *device, *tmp; + D3D11_TEXTURE1D_DESC desc; + ID3D11Texture1D *texture; + unsigned int i; + HRESULT hr; + + if (!(device = create_device(NULL))) + { + skip("Failed to create device.\n"); + return; + } + + desc.Width = 512; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + 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); + refcount = get_refcount(device); + ok(refcount >= expected_refcount, "Got unexpected refcount %u, expected >= %u.\n", refcount, expected_refcount); + tmp = NULL; + expected_refcount = refcount + 1; + ID3D11Texture1D_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); + ID3D11Device_Release(tmp); + + ID3D11Texture1D_Release(texture); + + desc.MipLevels = 0; + 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); + refcount = get_refcount(device); + ok(refcount >= expected_refcount, "Got unexpected refcount %u, expected >= %u.\n", refcount, expected_refcount); + tmp = NULL; + expected_refcount = refcount + 1; + ID3D11Texture1D_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); + ID3D11Device_Release(tmp); + + ID3D11Texture1D_GetDesc(texture, &desc); + ok(desc.Width == 512, "Got unexpected Width %u.\n", desc.Width); + ok(desc.MipLevels == 10, "Got unexpected MipLevels %u.\n", desc.MipLevels); + ok(desc.ArraySize == 1, "Got unexpected ArraySize %u.\n", desc.ArraySize); + ok(desc.Format == DXGI_FORMAT_R8G8B8A8_UNORM, "Got unexpected Format %#x.\n", desc.Format); + ok(desc.Usage == D3D11_USAGE_DEFAULT, "Got unexpected Usage %u.\n", desc.Usage); + ok(desc.BindFlags == D3D11_BIND_SHADER_RESOURCE, "Got unexpected BindFlags %#x.\n", desc.BindFlags); + ok(desc.CPUAccessFlags == 0, "Got unexpected CPUAccessFlags %#x.\n", desc.CPUAccessFlags); + ok(desc.MiscFlags == 0, "Got unexpected MiscFlags %#x.\n", desc.MiscFlags); + + check_interface(texture, &IID_IDXGISurface, FALSE, FALSE); + ID3D11Texture1D_Release(texture); + + desc.MipLevels = 1; + desc.ArraySize = 2; + hr = ID3D11Device_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); + ID3D11Texture1D_Release(texture); + + for (i = 0; i < 4; ++i) + { + desc.ArraySize = i; + desc.Format = DXGI_FORMAT_R32G32B32A32_TYPELESS; + 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); + if (SUCCEEDED(hr)) + ID3D11Texture1D_Release(texture); + } + + refcount = ID3D11Device_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); +} + static void test_create_texture2d(void) { ULONG refcount, expected_refcount; @@ -25114,6 +25205,7 @@ START_TEST(d3d11) test_create_device(); run_for_each_feature_level(test_device_interfaces); test_get_immediate_context(); + test_create_texture1d(); test_create_texture2d(); test_texture2d_interfaces(); test_create_texture3d(); diff --git a/dlls/d3d11/texture.c b/dlls/d3d11/texture.c index 2bcbe964b9b..8c7a54956a7 100644 --- a/dlls/d3d11/texture.c +++ b/dlls/d3d11/texture.c @@ -25,6 +25,322 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d11); +/* ID3D11Texture1D methods */ + +static inline struct d3d_texture1d *impl_from_ID3D11Texture1D(ID3D11Texture1D *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_texture1d, ID3D11Texture1D_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d11_texture1d_QueryInterface(ID3D11Texture1D *iface, REFIID iid, void **out) +{ + struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface); + + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_ID3D11Texture1D) + || IsEqualGUID(iid, &IID_ID3D11Resource) + || IsEqualGUID(iid, &IID_ID3D11DeviceChild) + || IsEqualGUID(iid, &IID_IUnknown)) + { + *out = iface; + IUnknown_AddRef(iface); + return S_OK; + } + + if (IsEqualGUID(iid, &IID_ID3D10Texture1D) + || IsEqualGUID(iid, &IID_ID3D10Resource) + || IsEqualGUID(iid, &IID_ID3D10DeviceChild)) + { + *out = &texture->ID3D10Texture1D_iface; + IUnknown_AddRef((IUnknown *)*out); + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_texture1d_AddRef(ID3D11Texture1D *iface) +{ + struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface); + ULONG refcount = InterlockedIncrement(&texture->refcount); + + TRACE("%p increasing refcount to %u.\n", texture, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_texture1d_Release(ID3D11Texture1D *iface) +{ + struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface); + ULONG refcount = InterlockedDecrement(&texture->refcount); + + TRACE("%p decreasing refcount to %u.\n", texture, refcount); + + if (!refcount) + { + wined3d_private_store_cleanup(&texture->private_store); + ID3D11Device_Release(texture->device); + heap_free(texture); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_texture1d_GetDevice(ID3D11Texture1D *iface, ID3D11Device **device) +{ + struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = texture->device; + ID3D11Device_AddRef(*device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_texture1d_GetPrivateData(ID3D11Texture1D *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&texture->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_texture1d_SetPrivateData(ID3D11Texture1D *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&texture->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_texture1d_SetPrivateDataInterface(ID3D11Texture1D *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&texture->private_store, guid, data); +} + +static void STDMETHODCALLTYPE d3d11_texture1d_GetType(ID3D11Texture1D *iface, + D3D11_RESOURCE_DIMENSION *resource_dimension) +{ + TRACE("iface %p, resource_dimension %p.\n", iface, resource_dimension); + + *resource_dimension = D3D11_RESOURCE_DIMENSION_TEXTURE1D; +} + +static void STDMETHODCALLTYPE d3d11_texture1d_SetEvictionPriority(ID3D11Texture1D *iface, UINT eviction_priority) +{ + FIXME("iface %p, eviction_priority %#x stub!\n", iface, eviction_priority); +} + +static UINT STDMETHODCALLTYPE d3d11_texture1d_GetEvictionPriority(ID3D11Texture1D *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static void STDMETHODCALLTYPE d3d11_texture1d_GetDesc(ID3D11Texture1D *iface, D3D11_TEXTURE1D_DESC *desc) +{ + struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + *desc = texture->desc; +} + +static const struct ID3D11Texture1DVtbl d3d11_texture1d_vtbl = +{ + /* IUnknown methods */ + d3d11_texture1d_QueryInterface, + d3d11_texture1d_AddRef, + d3d11_texture1d_Release, + /* ID3D11DeviceChild methods */ + d3d11_texture1d_GetDevice, + d3d11_texture1d_GetPrivateData, + d3d11_texture1d_SetPrivateData, + d3d11_texture1d_SetPrivateDataInterface, + /* ID3D11Resource methods */ + d3d11_texture1d_GetType, + d3d11_texture1d_SetEvictionPriority, + d3d11_texture1d_GetEvictionPriority, + /* ID3D11Texture1D methods */ + d3d11_texture1d_GetDesc, +}; + +static inline struct d3d_texture1d *impl_from_ID3D10Texture1D(ID3D10Texture1D *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_texture1d, ID3D10Texture1D_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_texture1d_QueryInterface(ID3D10Texture1D *iface, REFIID iid, void **out) +{ + struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface); + + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + return d3d11_texture1d_QueryInterface(&texture->ID3D11Texture1D_iface, iid, out); +} + +static ULONG STDMETHODCALLTYPE d3d10_texture1d_AddRef(ID3D10Texture1D *iface) +{ + struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_texture1d_AddRef(&texture->ID3D11Texture1D_iface); +} + +static ULONG STDMETHODCALLTYPE d3d10_texture1d_Release(ID3D10Texture1D *iface) +{ + struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface); + + TRACE("iface %p.\n", iface); + + return d3d11_texture1d_Release(&texture->ID3D11Texture1D_iface); +} + +/* ID3D10DeviceChild methods */ + +static void STDMETHODCALLTYPE d3d10_texture1d_GetDevice(ID3D10Texture1D *iface, ID3D10Device **device) +{ + struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + ID3D11Device_QueryInterface(texture->device, &IID_ID3D10Device, (void **)device); +} + +static HRESULT STDMETHODCALLTYPE d3d10_texture1d_GetPrivateData(ID3D10Texture1D *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d11_texture1d_GetPrivateData(&texture->ID3D11Texture1D_iface, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_texture1d_SetPrivateData(ID3D10Texture1D *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d11_texture1d_SetPrivateData(&texture->ID3D11Texture1D_iface, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d10_texture1d_SetPrivateDataInterface(ID3D10Texture1D *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d11_texture1d_SetPrivateDataInterface(&texture->ID3D11Texture1D_iface, guid, data); +} + +/* ID3D10Resource methods */ + +static void STDMETHODCALLTYPE d3d10_texture1d_GetType(ID3D10Texture1D *iface, + D3D10_RESOURCE_DIMENSION *resource_dimension) +{ + TRACE("iface %p, resource_dimension %p\n", iface, resource_dimension); + + *resource_dimension = D3D10_RESOURCE_DIMENSION_TEXTURE1D; +} + +static void STDMETHODCALLTYPE d3d10_texture1d_SetEvictionPriority(ID3D10Texture1D *iface, UINT eviction_priority) +{ + FIXME("iface %p, eviction_priority %u stub!\n", iface, eviction_priority); +} + +static UINT STDMETHODCALLTYPE d3d10_texture1d_GetEvictionPriority(ID3D10Texture1D *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +/* ID3D10Texture1D methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_texture1d_Map(ID3D10Texture1D *iface, UINT sub_resource_idx, + D3D10_MAP map_type, UINT map_flags, void **data) +{ + FIXME("iface %p, sub_resource_idx %u, map_type %u, map_flags %#x, data %p stub!\n", + iface, sub_resource_idx, map_type, map_flags, data); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE d3d10_texture1d_Unmap(ID3D10Texture1D *iface, UINT sub_resource_idx) +{ + FIXME("iface %p, sub_resource_idx %u stub!\n", iface, sub_resource_idx); +} + +static void STDMETHODCALLTYPE d3d10_texture1d_GetDesc(ID3D10Texture1D *iface, D3D10_TEXTURE1D_DESC *desc) +{ + FIXME("iface %p, desc %p stub!\n", iface, desc); +} + +static const struct ID3D10Texture1DVtbl d3d10_texture1d_vtbl = +{ + /* IUnknown methods */ + d3d10_texture1d_QueryInterface, + d3d10_texture1d_AddRef, + d3d10_texture1d_Release, + /* ID3D10DeviceChild methods */ + d3d10_texture1d_GetDevice, + d3d10_texture1d_GetPrivateData, + d3d10_texture1d_SetPrivateData, + d3d10_texture1d_SetPrivateDataInterface, + /* ID3D10Resource methods */ + d3d10_texture1d_GetType, + d3d10_texture1d_SetEvictionPriority, + d3d10_texture1d_GetEvictionPriority, + /* ID3D10Texture1D methods */ + d3d10_texture1d_Map, + d3d10_texture1d_Unmap, + d3d10_texture1d_GetDesc, +}; + +HRESULT d3d_texture1d_create(struct d3d_device *device, const D3D11_TEXTURE1D_DESC *desc, + const D3D11_SUBRESOURCE_DATA *data, struct d3d_texture1d **out) +{ + struct d3d_texture1d *texture; + + if (!(texture = heap_alloc_zero(sizeof(*texture)))) + return E_OUTOFMEMORY; + + 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; + texture->device = &device->ID3D11Device_iface; + ID3D11Device_AddRef(texture->device); + + TRACE("Created texture %p.\n", texture); + *out = texture; + + return S_OK; +} + /* ID3D11Texture2D methods */ static HRESULT STDMETHODCALLTYPE d3d11_texture2d_QueryInterface(ID3D11Texture2D *iface, REFIID riid, void **object)