尝试复制渲染目标的后备缓冲区时返回错误

发布于 2024-11-30 07:16:56 字数 1670 浏览 0 评论 0原文

我有一个适用于 DX9 的 WDDM 用户模式显示驱动程序。现在我想转储 将目标的后台缓冲区渲染为 bmp 文件。由于渲染目标资源是 不可锁定,我必须从系统缓冲区创建资源并从 将目标渲染到系统缓冲区,然后将系统缓冲区保存到bmp 文件。但是,调用 bitblt 始终返回错误代码 E_FAIL。我也 尝试调用 pfnCaptureToSysMem,它也返回相同的错误代码。 这里有什么问题吗?

    D3DDDI_SURFACEINFO nfo;
    nfo.Depth = 0;
    nfo.Width = GetRenderSize().cx;
    nfo.Height = GetRenderSize().cy;
    nfo.pSysMem = NULL;
    nfo.SysMemPitch = 0;
    nfo.SysMemSlicePitch = 0;

    D3DDDIARG_CREATERESOURCE resource;
    resource.Format = D3DDDIFMT_A8R8G8B8;
    resource.Pool = D3DDDIPOOL_SYSTEMMEM;
    resource.MultisampleType = D3DDDIMULTISAMPLE_NONE;
    resource.MultisampleQuality = 0;
    resource.pSurfList = &nfo;
    resource.SurfCount = 1;
    resource.MipLevels = 1;
    resource.Fvf = 0;
    resource.VidPnSourceId = 0;
    resource.RefreshRate.Numerator = 0;
    resource.RefreshRate.Denominator = 0;
    resource.hResource = NULL;
    resource.Flags.Value = 0;
    resource.Flags.Texture = 1;
    resource.Flags.Dynamic = 1;
    resource.Rotation = D3DDDI_ROTATION_IDENTITY;

    HRESULT hr = m_pDevice->m_deviceFuncs.pfnCreateResource(m_pDevice->GetDrv(), &resource);
    HANDLE hSysSpace = resource.hResource;

    D3DDDIARG_BLT blt;
    blt.hSrcResource = m_pDevice->m_hRenderTarget;
    blt.hDstResource = hSysSpace;
    blt.SrcRect.left = 0;
    blt.SrcRect.top = 0;
    blt.SrcRect.right = GetRenderSize().cx;
    blt.SrcRect.bottom = GetRenderSize().cy;
    blt.DstRect = blt.SrcRect;
    blt.DstSubResourceIndex = 0;
    blt.SrcSubResourceIndex = 0;
    blt.Flags.Value = 0;        
    blt.ColorKey = 0;

    hr = m_pDevice->m_deviceFuncs.pfnBlt(m_pDevice, &blt);

I have one WDDM user mode display driver for DX9. Now I would like to dump the
render target's back buffer to a bmp file. Since the render target resource is
not lockable, I have to create a resource from system buffer and bitblt from the
render target to the system buffer and then save the system buffer to the bmp
file. However, calling the bitblt always return the error code E_FAIL. I also
tried to call the pfnCaptureToSysMem which also returned the same error code.
Anything wrong here?

    D3DDDI_SURFACEINFO nfo;
    nfo.Depth = 0;
    nfo.Width = GetRenderSize().cx;
    nfo.Height = GetRenderSize().cy;
    nfo.pSysMem = NULL;
    nfo.SysMemPitch = 0;
    nfo.SysMemSlicePitch = 0;

    D3DDDIARG_CREATERESOURCE resource;
    resource.Format = D3DDDIFMT_A8R8G8B8;
    resource.Pool = D3DDDIPOOL_SYSTEMMEM;
    resource.MultisampleType = D3DDDIMULTISAMPLE_NONE;
    resource.MultisampleQuality = 0;
    resource.pSurfList = &nfo;
    resource.SurfCount = 1;
    resource.MipLevels = 1;
    resource.Fvf = 0;
    resource.VidPnSourceId = 0;
    resource.RefreshRate.Numerator = 0;
    resource.RefreshRate.Denominator = 0;
    resource.hResource = NULL;
    resource.Flags.Value = 0;
    resource.Flags.Texture = 1;
    resource.Flags.Dynamic = 1;
    resource.Rotation = D3DDDI_ROTATION_IDENTITY;

    HRESULT hr = m_pDevice->m_deviceFuncs.pfnCreateResource(m_pDevice->GetDrv(), &resource);
    HANDLE hSysSpace = resource.hResource;

    D3DDDIARG_BLT blt;
    blt.hSrcResource = m_pDevice->m_hRenderTarget;
    blt.hDstResource = hSysSpace;
    blt.SrcRect.left = 0;
    blt.SrcRect.top = 0;
    blt.SrcRect.right = GetRenderSize().cx;
    blt.SrcRect.bottom = GetRenderSize().cy;
    blt.DstRect = blt.SrcRect;
    blt.DstSubResourceIndex = 0;
    blt.SrcSubResourceIndex = 0;
    blt.Flags.Value = 0;        
    blt.ColorKey = 0;

    hr = m_pDevice->m_deviceFuncs.pfnBlt(m_pDevice, &blt);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

雪化雨蝶 2024-12-07 07:16:56

您的思路是正确的,但我认为您可以使用 DirectX 函数来实现此目的。

为了将渲染目标从视频内存复制到系统内存,您应该使用 IDirect3DDevice9::GetRenderTargetData() 函数。

此函数要求目标曲面是使用池 D3DPOOL_SYSTEMMEM 创建的屏幕外平面。该表面还必须具有与渲染目标相同的尺寸(不允许拉伸)。使用 IDirect3DDevice9::CreateOffscreenPlain() 创建这个表面。

然后这个表面可以被锁定并且颜色数据可以被CPU访问。

You are on the right track, but I think you can use the DirectX functions for this.

In order to copy the render target from video memory to system memory you should use the IDirect3DDevice9::GetRenderTargetData() function.

This function requires that the destination surface is an offscreen plain surface created with pool D3DPOOL_SYSTEMMEM. This surface also must have the same dimensions as the render target (no stretching allowed). Use IDirect3DDevice9::CreateOffscreenPlain() to create this surface.

Then this surface can be locked and the color data can be accessed by the CPU.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文