summaryrefslogtreecommitdiff
path: root/retrace/d3d7state_images.cpp
diff options
context:
space:
mode:
authorJosé Fonseca <jfonseca@vmware.com>2015-01-16 10:59:43 +0000
committerJosé Fonseca <jfonseca@vmware.com>2015-01-16 12:38:00 +0000
commite1a3c9cbe60fd0045ba1e26c2a30137fcb4b1515 (patch)
tree848250e9660e318410e8fbbdbb4857aa9f2f3c15 /retrace/d3d7state_images.cpp
parent875ee4f0eb3ddfe7856ab8ed6c49e3a86a1b0a4b (diff)
d3d7state: Dump snapshots.
Diffstat (limited to 'retrace/d3d7state_images.cpp')
-rw-r--r--retrace/d3d7state_images.cpp127
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();