Nikolay Sivov : mfplat/allocator: Handle bind flags and usage attributes.
Alexandre Julliard
julliard at winehq.org
Mon Feb 15 16:09:51 CST 2021
Module: wine
Branch: master
Commit: 31202993a044ee4e0ca4cd8764a22b98a8d179c8
URL: https://source.winehq.org/git/wine.git/?a=commit;h=31202993a044ee4e0ca4cd8764a22b98a8d179c8
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Mon Feb 15 14:33:30 2021 +0300
mfplat/allocator: Handle bind flags and usage attributes.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/mfplat/sample.c | 33 ++++++++++++++++---
dlls/mfplat/tests/mfplat.c | 82 +++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 109 insertions(+), 6 deletions(-)
diff --git a/dlls/mfplat/sample.c b/dlls/mfplat/sample.c
index 82e7c8680dd..cdd3d897169 100644
--- a/dlls/mfplat/sample.c
+++ b/dlls/mfplat/sample.c
@@ -72,6 +72,8 @@ struct sample_allocator
unsigned int height;
D3DFORMAT d3d9_format;
DXGI_FORMAT dxgi_format;
+ unsigned int usage;
+ unsigned int bindflags;
unsigned int buffer_count;
} frame_desc;
@@ -1346,8 +1348,12 @@ static HRESULT sample_allocator_allocate_sample(struct sample_allocator *allocat
desc.Format = allocator->frame_desc.dxgi_format;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
- desc.Usage = 0;
- desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
+ desc.Usage = allocator->frame_desc.usage;
+ desc.BindFlags = allocator->frame_desc.bindflags;
+ if (desc.Usage == D3D11_USAGE_DYNAMIC)
+ desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ else if (desc.Usage == D3D11_USAGE_STAGING)
+ desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
if (SUCCEEDED(hr = ID3D11Device_CreateTexture2D(service->d3d11_device, &desc, NULL, &texture)))
{
@@ -1396,15 +1402,32 @@ static HRESULT sample_allocator_initialize(struct sample_allocator *allocator, u
if (sample_count > max_sample_count)
return E_INVALIDARG;
+ allocator->frame_desc.usage = D3D11_USAGE_DEFAULT;
+ if (attributes)
+ {
+ IMFAttributes_GetUINT32(attributes, &MF_SA_BUFFERS_PER_SAMPLE, &allocator->frame_desc.buffer_count);
+ IMFAttributes_GetUINT32(attributes, &MF_SA_D3D11_USAGE, &allocator->frame_desc.usage);
+ }
+
+ if (allocator->frame_desc.usage == D3D11_USAGE_IMMUTABLE || allocator->frame_desc.usage > D3D11_USAGE_STAGING)
+ return E_INVALIDARG;
+
+ if (allocator->frame_desc.usage == D3D11_USAGE_DEFAULT)
+ allocator->frame_desc.bindflags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
+ else if (allocator->frame_desc.usage == D3D11_USAGE_DYNAMIC)
+ allocator->frame_desc.bindflags = D3D11_BIND_SHADER_RESOURCE;
+ else
+ allocator->frame_desc.bindflags = 0;
+
+ if (attributes)
+ IMFAttributes_GetUINT32(attributes, &MF_SA_D3D11_BINDFLAGS, &allocator->frame_desc.bindflags);
+
sample_allocator_set_media_type(allocator, media_type);
sample_allocator_set_attributes(allocator, attributes);
sample_count = max(1, sample_count);
max_sample_count = max(1, max_sample_count);
- if (attributes)
- IMFAttributes_GetUINT32(attributes, &MF_SA_BUFFERS_PER_SAMPLE, &allocator->frame_desc.buffer_count);
-
allocator->frame_desc.d3d9_format = subtype.Data1;
allocator->frame_desc.dxgi_format = MFMapDX9FormatToDXGIFormat(allocator->frame_desc.d3d9_format);
allocator->frame_desc.width = frame_size >> 32;
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index 9e3a3da08ea..fdfcf8a5d4b 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -6295,7 +6295,7 @@ static void test_sample_allocator(void)
IMFVideoSampleAllocatorEx *allocatorex;
IDirect3DDeviceManager9 *d3d9_manager;
IMFVideoSampleAllocator *allocator;
- unsigned int buffer_count, token;
+ unsigned int i, buffer_count, token;
IDirect3DDevice9 *d3d9_device;
IMFDXGIDeviceManager *manager;
IMFSample *sample, *sample2;
@@ -6311,6 +6311,14 @@ static void test_sample_allocator(void)
HRESULT hr;
BYTE *data;
HWND window;
+ static const unsigned int usage[] =
+ {
+ D3D11_USAGE_DEFAULT,
+ D3D11_USAGE_IMMUTABLE,
+ D3D11_USAGE_DYNAMIC,
+ D3D11_USAGE_STAGING,
+ D3D11_USAGE_STAGING + 1,
+ };
if (!pMFCreateVideoSampleAllocatorEx)
{
@@ -6600,6 +6608,78 @@ todo_wine
IMFSample_Release(sample);
IMFVideoSampleAllocator_Release(allocator);
+
+ /* MF_SA_D3D11_USAGE */
+ hr = MFCreateAttributes(&attributes, 1);
+ ok(hr == S_OK, "Failed to create attributes, hr %#x.\n", hr);
+
+ for (i = 0; i < ARRAY_SIZE(usage); ++i)
+ {
+ hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = IMFVideoSampleAllocatorEx_SetDirectXManager(allocatorex, (IUnknown *)manager);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, usage[i]);
+ ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
+
+ hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
+ if (usage[i] == D3D11_USAGE_IMMUTABLE || usage[i] > D3D11_USAGE_STAGING)
+ {
+ ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+ IMFVideoSampleAllocatorEx_Release(allocatorex);
+ continue;
+ }
+ ok(hr == S_OK, "%u: Unexpected hr %#x.\n", usage[i], hr);
+
+ hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, D3D11_USAGE_DEFAULT);
+ ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
+
+ hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
+ ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
+
+ hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
+ ok(hr == S_OK, "Failed to get resource, hr %#x.\n", hr);
+
+ ID3D11Texture2D_GetDesc(texture, &desc);
+ ok(desc.Usage == usage[i], "Unexpected usage %u.\n", desc.Usage);
+ if (usage[i] == D3D11_USAGE_DEFAULT)
+ {
+ ok(desc.BindFlags == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET), "Unexpected bind flags %#x.\n",
+ desc.BindFlags);
+ ok(desc.CPUAccessFlags == 0, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
+ }
+ else if (usage[i] == D3D11_USAGE_DYNAMIC)
+ {
+ ok(desc.BindFlags == D3D11_BIND_SHADER_RESOURCE, "Unexpected bind flags %#x.\n", desc.BindFlags);
+ ok(desc.CPUAccessFlags == D3D11_CPU_ACCESS_WRITE, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
+ }
+ else if (usage[i] == D3D11_USAGE_STAGING)
+ {
+ ok(desc.BindFlags == 0, "Unexpected bind flags %#x.\n", desc.BindFlags);
+ ok(desc.CPUAccessFlags == (D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ), "Unexpected CPU access flags %#x.\n",
+ desc.CPUAccessFlags);
+ }
+ ok(desc.MiscFlags == 0, "Unexpected misc flags %#x.\n", desc.MiscFlags);
+
+ ID3D11Texture2D_Release(texture);
+ IMFDXGIBuffer_Release(dxgi_buffer);
+ IMFMediaBuffer_Release(buffer);
+
+ IMFSample_Release(sample);
+
+ IMFVideoSampleAllocatorEx_Release(allocatorex);
+ }
+
+ IMFAttributes_Release(attributes);
+
IMFDXGIDeviceManager_Release(manager);
ID3D11Device_Release(device);
More information about the wine-cvs
mailing list