directx - 哪些因素决定了 DXGI_FORMAT?

标签 directx directx-11

我对directx不熟悉,但是在一个小项目中遇到了一个问题,其中一部分涉及抓取directx数据。我希望,下面我说得有道理。

一般问题:

我想知道哪些因素决定了后缓冲区中纹理的 DXGI_FORMAT(硬件?、操作系统?、应用程序?、directx 版本?)。更重要的是,当从后台缓冲区捕获纹理时,是否可以通过提供格式作为参数来接收所需格式的纹理,并在必要时自动转换格式。

关于我的问题的细节:

我使用 Open Broadcaster Software (OBS) 从游戏中捕获屏幕,并在流式传输之前使用特定库 (OpenCV) 处理它们。我注意到,在对 Windows 和 OBS 进行更新后,我将“DXGI_FORMAT_R10G10B10A2_UNORM”作为 DXGI_FORMAT。这对我来说是个问题,因为据我所知,当颜色为 10 位时,OpenCV 不提供构建 OpenCV 对象的便捷方法。以下是修改后的 OBS 源文件中的一些相关行。

d3d11_copy_texture(data.texture, backbuffer);
...
hlog(toStr(data.format));  // prints 24 = DXGI_FORMAT_R10G10B10A2_UNORM
...
ID3D11Texture2D* tex;
bool success = create_d3d11_stage_surface(&tex);
if (success) {
    ...
    HRESULT hr = data.context->Map(tex, subresource, D3D11_MAP_READ, 0, &mappedTex);
    ...
    Mat frame(data.cy, data.cx, CV_8UC4, mappedTex.pData, (int)mappedTex.RowPitch); //This creates an OpenCV Mat object.
                                               //No support for 10-bit coors. Expects 8-bit colors (CV_8UC4 argument).
                                               //When the resulting Mat is viewed, colours are jumbled (Probably because 10-bits did not fit into 8-bits).

在更新之前(一年前我在做这个),我可能收到 DXGI_FORMAT = DXGI_FORMAT_B8G8R8A8_UNORM,因为上面的代码曾经有效。

现在我想知道发生了什么变化,以及我是否可以修改 OBS 的源代码以接收具有所需 DXGI_FORMAT 的数据。

上面调用的“create_d3d11_stage_surface”方法设置了 DXGI_FORMAT,但我不确定它的意思是“用这个 DXGI_FORMAT 给我数据”还是“我知道你使用这种格式,请给我你拥有的”。

static bool create_d3d11_stage_surface(ID3D11Texture2D **tex)
{
    HRESULT hr;

    D3D11_TEXTURE2D_DESC desc      = {};
    desc.Width                     = data.cx;
    desc.Height                    = data.cy;
    desc.Format = data.format;
    ...

我希望,用 DXGI_FORMAT_B8G8R8A8_UNORM 覆盖 desc.Format 会导致该格式作为参数传递到上面的 ID3D11DeviceContext::Map 调用中,并且我会获得指定格式的数据。但这没有用。

最佳答案

渲染目标的选择取决于应用程序,但他们需要根据 Direct3D 硬件功能级别选择一个。交换链中渲染目标的格式通常是显示扫描输出格式:

DXGI_FORMAT_R8G8B8A8_UNORM
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
DXGI_FORMAT_B8G8R8A8_UNORM
DXGI_FORMAT_B8G8R8A8_UNORM
DXGI_FORMAT_R10G10B10A2_UNORM
DXGI_FORMAT_R16G16B16A16_FLOAT
DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM (rare)

参见 DXGI documentation按功能级别查看支持的格式和用法的完整列表。

Direct3D 11 在您复制资源(例如复制到暂存渲染纹理)时不会进行格式转换,因此如果您想进行格式转换,您需要自己处理。请注意,所有 DXGI 格式的 CPU 端转换代码都可以在 DirectXTex 中找到。 .

关于directx - 哪些因素决定了 DXGI_FORMAT?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45636299/

相关文章:

c++ - ID3D11Device::CreateBuffer 在幕后做了什么?

java - 如何在Java上检索显卡信息?

c++ - 如何将 XMMATRIX 和 XMVECTOR (DirectX11) 相乘?

c++ - Windows 8.1 上的 DirectX 11 缺少 SDK 组件

c++ - 将顶点缓冲区绑定(bind)到计算着色器以修改数据?

c++ - 等同于DirectX 9的DirectX 11错误

具有自定义渲染/绘图的 Python GUI

c++ - 使用 Direct2D 和 DirectWrite(C++、DirectX)制作按钮

opengl - DirectX 与 OpenGL 游戏开发

c++ - 获取着色器字节码以传递给 CreateVertexShader()