Direct3D11:翻转 ID3D11Texture2D
Direct3D11: Flipping ID3D11Texture2D
我执行了 Direct3D 后台缓冲区的捕获。当我下载像素时,图像框架沿其垂直方向翻转 axis.Is 是否可以 "tell" D3D 在复制资源或创建目标时翻转框架 ID3D11Texture2D
?
这是我的做法:
我将帧缓冲区复制到其中的纹理是这样创建的:
D3D11_TEXTURE2D_DESC description =
{
desc.BufferDesc.Width, desc.BufferDesc.Height, 1, 1,
DXGI_FORMAT_R8G8B8A8_UNORM,
{ 1, 0 }, // DXGI_SAMPLE_DESC
D3D11_USAGE_STAGING,//transder from GPU to CPU
0, D3D11_CPU_ACCESS_READ, 0
};
D3D11_SUBRESOURCE_DATA data = { buffer, desc.BufferDesc.Width * PIXEL_SIZE, 0 };
device->CreateTexture2D(&description, &data, &pNewTexture);
然后在每一帧我做:
pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast< void** >(&pSurface));
pContext->CopyResource(pNewTexture, pSurface);
D3D11_MAPPED_SUBRESOURCE resource;
pContext->Map(pNewTexture, 0, D3D11_MAP_READ , 0, &resource);
//reading from resource.pData
//...
PS:我无法控制渲染管线。我用这段代码连接了一个外部应用程序。
另外,我不想弄乱 CPU 上的像素缓冲区,例如循环中的反向复制等。复制的低延迟是高优先级。
更新:
我也试过这个:
D3D11_BOX box;
box.left = 0;
box.right = desc.BufferDesc.Width;
box.top = desc.BufferDesc.Height;
box.bottom = 0;
box.front = 0;
box.back = 1;
pContext->CopySubresourceRegion(pNewTexture, 0, 0, 0, 0, pSurface, 0, &box);
这会导致框架的内容为空。
所有 Direct3D 映射资源都应该逐条扫描处理,所以只需反向复制即可:
auto ptr = reinterpret_cast<const uint8_t>(resource.pData)
+ (desc.BufferDesc.Height - 1) * resource.RowPitch;
for(unsigned int y = 0; y < desc.BufferDesc.Height; ++y )
{
// do something with the data in ptr
// which is desc.BufferDesc.Width * BytesPerPixel(desc.Format) bytes
// i.e. DXGI_FORMAT_R8G8B8A8_UNORM would be desc.BufferDesc.Width * 4
ptr -= resource.RowPitch;
}
For lots of examples of working with Direct3D resources, see DirectXTex.
使用 D3D11_USAGE_DEAFULT 创建纹理,使用 CPUAccessFlags=0 和 BindFlags=D3D11_BIND_SHADER_RESOURCE。 CopyResource 交换链的后备缓冲区给它。使用 D3D11_BIND_RENDER_TARGET 创建另一个纹理。将其设置为渲染目标,设置像素着色器并使用第一个纹理绘制翻转的四边形。现在您应该能够将第二个纹理 CopyResource 到您现在使用的暂存纹理。这应该比使用 CPU 复制翻转图像数据更快。但是,此解决方案会占用 GPU 上的更多资源,并且可能难以在挂钩中进行设置。
我执行了 Direct3D 后台缓冲区的捕获。当我下载像素时,图像框架沿其垂直方向翻转 axis.Is 是否可以 "tell" D3D 在复制资源或创建目标时翻转框架 ID3D11Texture2D
?
这是我的做法:
我将帧缓冲区复制到其中的纹理是这样创建的:
D3D11_TEXTURE2D_DESC description =
{
desc.BufferDesc.Width, desc.BufferDesc.Height, 1, 1,
DXGI_FORMAT_R8G8B8A8_UNORM,
{ 1, 0 }, // DXGI_SAMPLE_DESC
D3D11_USAGE_STAGING,//transder from GPU to CPU
0, D3D11_CPU_ACCESS_READ, 0
};
D3D11_SUBRESOURCE_DATA data = { buffer, desc.BufferDesc.Width * PIXEL_SIZE, 0 };
device->CreateTexture2D(&description, &data, &pNewTexture);
然后在每一帧我做:
pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast< void** >(&pSurface));
pContext->CopyResource(pNewTexture, pSurface);
D3D11_MAPPED_SUBRESOURCE resource;
pContext->Map(pNewTexture, 0, D3D11_MAP_READ , 0, &resource);
//reading from resource.pData
//...
PS:我无法控制渲染管线。我用这段代码连接了一个外部应用程序。 另外,我不想弄乱 CPU 上的像素缓冲区,例如循环中的反向复制等。复制的低延迟是高优先级。
更新:
我也试过这个:
D3D11_BOX box;
box.left = 0;
box.right = desc.BufferDesc.Width;
box.top = desc.BufferDesc.Height;
box.bottom = 0;
box.front = 0;
box.back = 1;
pContext->CopySubresourceRegion(pNewTexture, 0, 0, 0, 0, pSurface, 0, &box);
这会导致框架的内容为空。
所有 Direct3D 映射资源都应该逐条扫描处理,所以只需反向复制即可:
auto ptr = reinterpret_cast<const uint8_t>(resource.pData)
+ (desc.BufferDesc.Height - 1) * resource.RowPitch;
for(unsigned int y = 0; y < desc.BufferDesc.Height; ++y )
{
// do something with the data in ptr
// which is desc.BufferDesc.Width * BytesPerPixel(desc.Format) bytes
// i.e. DXGI_FORMAT_R8G8B8A8_UNORM would be desc.BufferDesc.Width * 4
ptr -= resource.RowPitch;
}
For lots of examples of working with Direct3D resources, see DirectXTex.
使用 D3D11_USAGE_DEAFULT 创建纹理,使用 CPUAccessFlags=0 和 BindFlags=D3D11_BIND_SHADER_RESOURCE。 CopyResource 交换链的后备缓冲区给它。使用 D3D11_BIND_RENDER_TARGET 创建另一个纹理。将其设置为渲染目标,设置像素着色器并使用第一个纹理绘制翻转的四边形。现在您应该能够将第二个纹理 CopyResource 到您现在使用的暂存纹理。这应该比使用 CPU 复制翻转图像数据更快。但是,此解决方案会占用 GPU 上的更多资源,并且可能难以在挂钩中进行设置。