diff options
author | José Fonseca <jfonseca@vmware.com> | 2015-01-16 10:59:43 +0000 |
---|---|---|
committer | José Fonseca <jfonseca@vmware.com> | 2015-01-16 12:38:00 +0000 |
commit | e1a3c9cbe60fd0045ba1e26c2a30137fcb4b1515 (patch) | |
tree | 848250e9660e318410e8fbbdbb4857aa9f2f3c15 /retrace/d3d7state_images.cpp | |
parent | 875ee4f0eb3ddfe7856ab8ed6c49e3a86a1b0a4b (diff) |
d3d7state: Dump snapshots.
Diffstat (limited to 'retrace/d3d7state_images.cpp')
-rw-r--r-- | retrace/d3d7state_images.cpp | 127 |
1 files changed, 121 insertions, 6 deletions
diff --git a/retrace/d3d7state_images.cpp b/retrace/d3d7state_images.cpp index 0c05fab5..1c78c4ef 100644 --- a/retrace/d3d7state_images.cpp +++ b/retrace/d3d7state_images.cpp @@ -34,15 +34,114 @@ #include "d3dstate.hpp" +typedef enum _D3DFORMAT +{ + D3DFMT_UNKNOWN = 0, + + D3DFMT_R8G8B8 = 20, + D3DFMT_A8R8G8B8 = 21, + D3DFMT_X8R8G8B8 = 22, + D3DFMT_R5G6B5 = 23, + D3DFMT_X1R5G5B5 = 24, + D3DFMT_A1R5G5B5 = 25, + D3DFMT_A4R4G4B4 = 26, + D3DFMT_R3G3B2 = 27, + D3DFMT_A8 = 28, + D3DFMT_A8R3G3B2 = 29, + D3DFMT_X4R4G4B4 = 30, + D3DFMT_A2B10G10R10 = 31, + + D3DFMT_D16_LOCKABLE = 70, + D3DFMT_D32 = 71, + D3DFMT_D15S1 = 73, + D3DFMT_D24S8 = 75, + D3DFMT_D24X8 = 77, + D3DFMT_D24X4S4 = 79, + D3DFMT_D16 = 80, + + D3DFMT_D32F_LOCKABLE = 82, + D3DFMT_D24FS8 = 83, + + D3DFMT_FORCE_DWORD = 0x7fffffff +} D3DFORMAT; + + namespace d3dstate { +image::Image * +ConvertImage(D3DFORMAT SrcFormat, + void *SrcData, + INT SrcPitch, + UINT Width, UINT Height); + + +static D3DFORMAT +convertFormat(const DDPIXELFORMAT & ddpfPixelFormat) +{ + if (ddpfPixelFormat.dwSize != sizeof ddpfPixelFormat) { + return D3DFMT_UNKNOWN; + } + + switch (ddpfPixelFormat.dwFlags) { + case DDPF_RGB: + switch (ddpfPixelFormat.dwRGBBitCount) { + case 32: + if (ddpfPixelFormat.dwRBitMask == 0xff0000 && + ddpfPixelFormat.dwGBitMask == 0x00ff00 && + ddpfPixelFormat.dwBBitMask == 0x0000ff) { + return D3DFMT_X8R8G8B8; + } + break; + } + break; + case DDPF_ZBUFFER: + case DDPF_ZBUFFER | DDPF_STENCILBUFFER: + switch (ddpfPixelFormat.dwZBufferBitDepth) { + case 16: + if (ddpfPixelFormat.dwZBitMask == 0x0000ffff) { + return D3DFMT_D16; + } + break; + case 32: + if (ddpfPixelFormat.dwZBitMask == 0x00ffffff) { + return D3DFMT_D24X8; + } + break; + } + break; + } + + return D3DFMT_UNKNOWN; +} + static image::Image * -getRenderTargetImage(IDirect3DDevice7 *pDevice, - IDirectDrawSurface7 *pRenderTarget) +getSurfaceImage(IDirect3DDevice7 *pDevice, + IDirectDrawSurface7 *pSurface) { - std::cerr << "warning: D3D7 snapshots not yet implemented\n"; - return NULL; + HRESULT hr; + + DDSURFACEDESC2 Desc; + ZeroMemory(&Desc, sizeof Desc); + Desc.dwSize = sizeof Desc; + + hr = pSurface->Lock(NULL, &Desc, DDLOCK_WAIT | DDLOCK_READONLY | DDLOCK_SURFACEMEMORYPTR | DDLOCK_NOSYSLOCK, NULL); + if (FAILED(hr)) { + std::cerr << "warning: IDirectDrawSurface7::Lock failed\n"; + return NULL; + } + + image::Image *image = NULL; + D3DFORMAT Format = convertFormat(Desc.ddpfPixelFormat); + if (Format == D3DFMT_UNKNOWN) { + std::cerr << "warning: unsupported DDPIXELFORMAT\n"; + } else { + image = ConvertImage(Format, Desc.lpSurface, Desc.lPitch, Desc.dwWidth, Desc.dwHeight); + } + + pSurface->Unlock(NULL); + + return image; } @@ -57,7 +156,7 @@ getRenderTargetImage(IDirect3DDevice7 *pDevice) { } assert(pRenderTarget); - return getRenderTargetImage(pDevice, pRenderTarget); + return getSurfaceImage(pDevice, pRenderTarget); } @@ -83,12 +182,28 @@ dumpFramebuffer(JSONWriter &json, IDirect3DDevice7 *pDevice) hr = pDevice->GetRenderTarget(&pRenderTarget); if (SUCCEEDED(hr) && pRenderTarget) { image::Image *image; - image = getRenderTargetImage(pDevice, pRenderTarget); + image = getSurfaceImage(pDevice, pRenderTarget); if (image) { json.beginMember("RENDER_TARGET_0"); json.writeImage(image); json.endMember(); // RENDER_TARGET_* } + + // Search for a depth-stencil attachment + DDSCAPS2 ddsCaps; + ZeroMemory(&ddsCaps, sizeof ddsCaps); + ddsCaps.dwCaps = DDSCAPS_ZBUFFER; + com_ptr<IDirectDrawSurface7> pDepthStencil; + hr = pRenderTarget->GetAttachedSurface(&ddsCaps, &pDepthStencil); + if (SUCCEEDED(hr) && pDepthStencil) { + std::cerr << "found ZS!!\n"; + image = getSurfaceImage(pDevice, pDepthStencil); + if (image) { + json.beginMember("DEPTH_STENCIL"); + json.writeImage(image); + json.endMember(); // DEPTH_STENCIL + } + } } json.endObject(); |