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