From 0ae84f58eee1c239d5bc2cc148a1d007b328d2e1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 20 Sep 2013 17:03:36 +0100 Subject: [PATCH] d3dretrace: Dump D3D9 depth stencil. Only works for D3DFMT_D16_LOCKABLE though. --- retrace/d3d9state_images.cpp | 109 +++++++++++++++++++++++++++-------- 1 file changed, 84 insertions(+), 25 deletions(-) diff --git a/retrace/d3d9state_images.cpp b/retrace/d3d9state_images.cpp index 570d843..87dcdc0 100644 --- a/retrace/d3d9state_images.cpp +++ b/retrace/d3d9state_images.cpp @@ -38,46 +38,47 @@ namespace d3dstate { static image::Image * -getRenderTargetImage(IDirect3DDevice9 *pDevice, - IDirect3DSurface9 *pRenderTarget) { +getSurfaceImage(IDirect3DDevice9 *pDevice, + IDirect3DSurface9 *pSurface) { image::Image *image = NULL; D3DSURFACE_DESC Desc; - IDirect3DSurface9 *pStagingSurface = NULL; D3DLOCKED_RECT LockedRect; const unsigned char *src; unsigned char *dst; HRESULT hr; - if (!pRenderTarget) { + if (!pSurface) { return NULL; } - hr = pRenderTarget->GetDesc(&Desc); + hr = pSurface->GetDesc(&Desc); assert(SUCCEEDED(hr)); - if (Desc.Format != D3DFMT_X8R8G8B8 && - Desc.Format != D3DFMT_A8R8G8B8 && - Desc.Format != D3DFMT_R5G6B5) { + unsigned numChannels; + image::ChannelType channelType; + switch (Desc.Format) { + case D3DFMT_X8R8G8B8: + case D3DFMT_A8R8G8B8: + case D3DFMT_R5G6B5: + numChannels = 3; + channelType = image::TYPE_UNORM8; + break; + case D3DFMT_D16: + case D3DFMT_D16_LOCKABLE: + numChannels = 1; + channelType = image::TYPE_FLOAT; + break; + default: std::cerr << "warning: unsupported D3DFORMAT " << Desc.Format << "\n"; - goto no_staging; + goto no_lock; } - hr = pDevice->CreateOffscreenPlainSurface(Desc.Width, Desc.Height, Desc.Format, D3DPOOL_SYSTEMMEM, &pStagingSurface, NULL); + hr = pSurface->LockRect(&LockedRect, NULL, D3DLOCK_READONLY); if (FAILED(hr)) { - goto no_staging; + goto no_lock; } - hr = pDevice->GetRenderTargetData(pRenderTarget, pStagingSurface); - if (FAILED(hr)) { - goto no_rendertargetdata; - } - - hr = pStagingSurface->LockRect(&LockedRect, NULL, D3DLOCK_READONLY); - if (FAILED(hr)) { - goto no_rendertargetdata; - } - - image = new image::Image(Desc.Width, Desc.Height, 3, true); + image = new image::Image(Desc.Width, Desc.Height, numChannels, true, channelType); if (!image) { goto no_image; } @@ -85,19 +86,32 @@ getRenderTargetImage(IDirect3DDevice9 *pDevice, dst = image->start(); src = (const unsigned char *)LockedRect.pBits; for (unsigned y = 0; y < Desc.Height; ++y) { - if (Desc.Format == D3DFMT_R5G6B5) { + switch (Desc.Format) { + case D3DFMT_R5G6B5: for (unsigned x = 0; x < Desc.Width; ++x) { uint32_t pixel = ((const uint16_t *)src)[x]; dst[3*x + 0] = (( pixel & 0x1f) * (2*0xff) + 0x1f) / (2*0x1f); dst[3*x + 1] = (((pixel >> 5) & 0x3f) * (2*0xff) + 0x3f) / (2*0x3f); dst[3*x + 2] = (( pixel >> 11 ) * (2*0xff) + 0x1f) / (2*0x1f); } - } else { + break; + case D3DFMT_X8R8G8B8: + case D3DFMT_A8R8G8B8: for (unsigned x = 0; x < Desc.Width; ++x) { dst[3*x + 0] = src[4*x + 2]; dst[3*x + 1] = src[4*x + 1]; dst[3*x + 2] = src[4*x + 0]; } + break; + case D3DFMT_D16: + case D3DFMT_D16_LOCKABLE: + for (unsigned x = 0; x < Desc.Width; ++x) { + ((float *)dst)[x] = ((const uint16_t *)src)[x] * (1.0f / 0xffff); + } + break; + default: + assert(0); + break; } src += LockedRect.Pitch; @@ -105,7 +119,39 @@ getRenderTargetImage(IDirect3DDevice9 *pDevice, } no_image: - pStagingSurface->UnlockRect(); + pSurface->UnlockRect(); +no_lock: + return image; +} + + +static image::Image * +getRenderTargetImage(IDirect3DDevice9 *pDevice, + IDirect3DSurface9 *pRenderTarget) { + image::Image *image = NULL; + D3DSURFACE_DESC Desc; + IDirect3DSurface9 *pStagingSurface = NULL; + HRESULT hr; + + if (!pRenderTarget) { + return NULL; + } + + hr = pRenderTarget->GetDesc(&Desc); + assert(SUCCEEDED(hr)); + + hr = pDevice->CreateOffscreenPlainSurface(Desc.Width, Desc.Height, Desc.Format, D3DPOOL_SYSTEMMEM, &pStagingSurface, NULL); + if (FAILED(hr)) { + goto no_staging; + } + + hr = pDevice->GetRenderTargetData(pRenderTarget, pStagingSurface); + if (FAILED(hr)) { + goto no_rendertargetdata; + } + + image = getSurfaceImage(pDevice, pStagingSurface); + no_rendertargetdata: pStagingSurface->Release(); no_staging: @@ -169,6 +215,19 @@ dumpFramebuffer(JSONWriter &json, IDirect3DDevice9 *pDevice) pRenderTarget->Release(); } + IDirect3DSurface9 *pDepthStencil = NULL; + hr = pDevice->GetDepthStencilSurface(&pDepthStencil); + if (SUCCEEDED(hr) && pDepthStencil) { + image::Image *image; + image = getSurfaceImage(pDevice, pDepthStencil); + if (image) { + json.beginMember("DEPTH_STENCIL"); + json.writeImage(image, "UNKNOWN"); + json.endMember(); // RENDER_TARGET_* + } + } + + json.endObject(); json.endMember(); // framebuffer } -- 2.43.0