【问题标题】:DXGI_FORMAT_YUY2 textures return different RowPitch under Windows 8.1 and Windows 10DXGI_FORMAT_YUY2 纹理在 Windows 8.1 和 Windows 10 下返回不同的 RowPitch
【发布时间】:2016-06-11 01:40:37
【问题描述】:

我的构建环境如下: Windows 8.1,VS2012,使用 windows 8.0 SDK 和 C++ 构建的桌面应用程序。

当我在 Windows 8.1 上运行我的程序时,RowPitch 打印 2560,但在 Windows 10 下,相同的程序打印 5120。

我在这里做错了什么?

这是代码,感谢所有回复。

#include <d3d11.h>

static bool init_directx11(ID3D11Device **pDevice, ID3D11DeviceContext **pDeviceContext)
{
    D3D_FEATURE_LEVEL featureLevels[] = {D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_1};

    D3D_FEATURE_LEVEL featureLevel;

    UINT createDeviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
    HRESULT hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, pDevice,
                                   &featureLevel, pDeviceContext);

    return SUCCEEDED(hr);
}

int _tmain(int argc, _TCHAR* argv[])
{
    ID3D11Device *pDevice = nullptr;
    ID3D11DeviceContext *pDeviceContext= nullptr;
    if (!init_directx11(&pDevice, &pDeviceContext))
    {
        return FALSE;
    }

    D3D11_TEXTURE2D_DESC desc;
    ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));

    desc.ArraySize = 1;
    desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
    desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    desc.Format = DXGI_FORMAT_YUY2;
    desc.MipLevels = 1;
    desc.MiscFlags = 0;
    desc.SampleDesc.Count = 1;
    desc.SampleDesc.Quality = 0;
    desc.Usage = D3D11_USAGE_DYNAMIC;
    desc.Width = 1280;
    desc.Height = 720;

    ID3D11Texture2D* pTexture2D = nullptr;
    HRESULT hr = pDevice->CreateTexture2D(&desc, NULL, &pTexture2D);

    D3D11_MAPPED_SUBRESOURCE mappedResource;
    ZeroMemory(&mappedResource, sizeof(DXGI_MAPPED_RECT));
    hr = pDeviceContext->Map(pTexture2D, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);

    printf("RowPitch = %d\n", mappedResource.RowPitch);

    pDeviceContext->Unmap(pTexture2D, 0);


    pTexture2D->Release();
    pDeviceContext->Release();
    pDevice->Release();

    getchar();
   }

【问题讨论】:

    标签: c++ windows-8.1 windows-10 directx-11


    【解决方案1】:

    我在这里做错了什么?

    这不一定是错的。 RowPitch 取决于为纹理分配的硬件和驱动程序的布局。音高可能会有所不同。一旦资源被映射,您应该读回音调,并分别使用它来读取或写入数据。

    请参阅this thread and message 了解音高使用代码 sn-p:

    纹理资源将有自己的间距(一行中的字节数),这可能与源数据的间距不同。此音高作为 D3D11_MAPPED_SUBRESOURCE 的“RowPitch”成员提供给您。所以通常你会这样做:

    BYTE* mappedData = reinterpret_cast<BYTE*>(mappedResource.pData);
    for(UINT i = 0; i < height; ++i)
    {
      memcpy(mappedData, buffer, rowspan);
      mappedData += mappedResource.RowPitch;
      buffer += rowspan;
    }
    

    【讨论】:

    • 如前所述,这并不重要,因为您应该使用返回的映射值。我注意到这是与平台团队的操作系统差异。
    • 阅读这篇文章后,我确实使用了映射值。但是,当我将我的 YUY2 数据从网络摄像头复制到纹理(在 Win10 上返回两倍的行间距)然后尝试使用像素着色器显示该纹理时,图像的内容会完整显示但仅填充一半我显示它们的矩形区域。这在 Windows 8.1 上不会发生,图像显示正确。我知道有填充,但填充是两倍?
    • 另外,根据msdn.microsoft.com/en-us/library/windows/desktop/…,YUY2 纹理中的数据应该是连续的,因此我的图像必须像在 Win 8.1 上一样正确显示
    • 数据不必是连续的。是的,它通常是连续的,但在这种特殊情况下,视频适配器出于性能原因故意使用它选择的布局,并带有填充和扩展步幅。你必须接受它。如果图像不能很好地显示,那么您可能还有另一个(尽管可能相关)问题需要处理。
    • 当我说连续时,我的意思是我在纹理中每行 5120 字节复制 2560 字节(我的图像是 1280x720),正如您在第一篇文章中的链接所指出的那样,但是每一行数据是连续的,同一行上的像素之间没有间隙。然而,一旦我开始在像素着色器中对这些数据进行采样,我只能得到一半的屏幕,其中包含完整的图像,但颜色有些混乱。相同的像素着色器在 Windows 8.1 中完美运行。
    猜你喜欢
    • 2016-06-09
    • 2018-09-02
    • 2018-07-08
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 2015-09-15
    相关资源
    最近更新 更多