什么因素决定了DXGI_FORMAT?
What factors determine DXGI_FORMAT?
我对directx不熟悉,但是我运行在一个小项目中遇到了一个问题,其中一部分涉及捕获directx数据。我希望,下面我说得有道理。
一般问题:
我想知道什么因素决定了后缓冲区中纹理的 DXGI_FORMAT(硬件?,OS?,应用程序?,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,但我不确定它是指 'give me data with this DXGI_FORMAT' 还是 'I know you work with this format, give me what you have'.
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 在您复制资源(例如复制到暂存渲染纹理)时不会进行格式转换,因此如果您想进行格式转换,您需要自己处理。请注意,可以在 DirectXTex.
中找到所有 DXGI 格式的 CPU 端转换代码
决定格式的是应用程序。最简单的是 R8G8B8A8,它只表示 RGB 和 alpha 值。但是,如果开发人员决定他将使用 HDR,则后备缓冲区可能是 R11B11G10,因为您可以在那里存储更精确的数据,而无需 alpha 通道信息。例如,如果游戏是黑白的,则无需将所有 RGB 通道都保留在后台缓冲区中,您可以使用更简单的格式。希望对您有所帮助。
我对directx不熟悉,但是我运行在一个小项目中遇到了一个问题,其中一部分涉及捕获directx数据。我希望,下面我说得有道理。
一般问题:
我想知道什么因素决定了后缓冲区中纹理的 DXGI_FORMAT(硬件?,OS?,应用程序?,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,但我不确定它是指 'give me data with this DXGI_FORMAT' 还是 'I know you work with this format, give me what you have'.
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 在您复制资源(例如复制到暂存渲染纹理)时不会进行格式转换,因此如果您想进行格式转换,您需要自己处理。请注意,可以在 DirectXTex.
中找到所有 DXGI 格式的 CPU 端转换代码决定格式的是应用程序。最简单的是 R8G8B8A8,它只表示 RGB 和 alpha 值。但是,如果开发人员决定他将使用 HDR,则后备缓冲区可能是 R11B11G10,因为您可以在那里存储更精确的数据,而无需 alpha 通道信息。例如,如果游戏是黑白的,则无需将所有 RGB 通道都保留在后台缓冲区中,您可以使用更简单的格式。希望对您有所帮助。