From 944088ed749f195699228598ce3955063696931b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 20 Nov 2012 14:47:03 +0000 Subject: [PATCH] d3dretrace: Dump d3d10 snapshots too. --- retrace/CMakeLists.txt | 8 +- retrace/d3d10state.cpp | 47 +++++ retrace/d3d10state_images.cpp | 311 ++++++++++++++++++++++++++++++++++ retrace/d3d11state.cpp | 2 +- retrace/d3dcommonretrace.py | 11 ++ retrace/d3dstate.hpp | 8 + 6 files changed, 384 insertions(+), 3 deletions(-) create mode 100644 retrace/d3d10state.cpp create mode 100644 retrace/d3d10state_images.cpp diff --git a/retrace/CMakeLists.txt b/retrace/CMakeLists.txt index c582338..383417d 100644 --- a/retrace/CMakeLists.txt +++ b/retrace/CMakeLists.txt @@ -153,6 +153,10 @@ if (WIN32 AND DirectX_D3DX9_INCLUDE_DIR) include_directories (SYSTEM ${DirectX_D3D10_1_INCLUDE_DIR}) set (D3D10_MODULES ${D3D10_MODULES} d3d10_1) endif () + set (D3DSTATE_SOURCES ${D3DSTATE_SOURCES} + d3d10state.cpp + d3d10state_images.cpp + ) endif () if (DirectX_D3D11_INCLUDE_DIR) @@ -162,7 +166,7 @@ if (WIN32 AND DirectX_D3DX9_INCLUDE_DIR) include_directories (SYSTEM ${DirectX_D3D11_1_INCLUDE_DIR}) set (D3D10_MODULES ${D3D10_MODULES} d3d11_1) endif () - set (D3D11STATE_SOURCES + set (D3DSTATE_SOURCES ${D3DSTATE_SOURCES} d3d11state.cpp d3d11state_images.cpp ) @@ -200,7 +204,7 @@ if (WIN32 AND DirectX_D3DX9_INCLUDE_DIR) d3dretrace_ws.cpp d3d9state.cpp d3d9state_images.cpp - ${D3D11STATE_SOURCES} + ${D3DSTATE_SOURCES} ) target_link_libraries (d3dretrace retrace_common diff --git a/retrace/d3d10state.cpp b/retrace/d3d10state.cpp new file mode 100644 index 0000000..fd0eb5b --- /dev/null +++ b/retrace/d3d10state.cpp @@ -0,0 +1,47 @@ +/************************************************************************** + * + * Copyright 2011 Jose Fonseca + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + + +#include + +#include + +#include "d3d11imports.hpp" +#include "json.hpp" + + +namespace d3dstate { + + +void +dumpDevice(std::ostream &os, ID3D10Device *pDevice) +{ + JSONWriter json(os); + + /* TODO */ +} + + +} /* namespace d3dstate */ diff --git a/retrace/d3d10state_images.cpp b/retrace/d3d10state_images.cpp new file mode 100644 index 0000000..781f937 --- /dev/null +++ b/retrace/d3d10state_images.cpp @@ -0,0 +1,311 @@ +/************************************************************************** + * + * Copyright 2011 Jose Fonseca + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + + +#include + +#include +#include + +#include "image.hpp" +#include "d3d10imports.hpp" + + +namespace d3dstate { + +static HRESULT +stageResource(ID3D10Device *pDevice, + ID3D10Resource *pResource, + ID3D10Resource **ppStagingResource, + UINT *pWidth, UINT *pHeight, UINT *pDepth) { + D3D10_USAGE Usage = D3D10_USAGE_STAGING; + UINT BindFlags = 0; + UINT CPUAccessFlags = D3D10_CPU_ACCESS_READ; + UINT MiscFlags = 0; + union { + ID3D10Resource *pStagingResource; + ID3D10Buffer *pStagingBuffer; + ID3D10Texture1D *pStagingTexture1D; + ID3D10Texture2D *pStagingTexture2D; + ID3D10Texture3D *pStagingTexture3D; + }; + HRESULT hr; + + D3D10_RESOURCE_DIMENSION Type = D3D10_RESOURCE_DIMENSION_UNKNOWN; + pResource->GetType(&Type); + switch (Type) { + case D3D10_RESOURCE_DIMENSION_BUFFER: + { + D3D10_BUFFER_DESC Desc; + static_cast(pResource)->GetDesc(&Desc); + Desc.Usage = Usage; + Desc.BindFlags = BindFlags; + Desc.CPUAccessFlags = CPUAccessFlags; + Desc.MiscFlags = MiscFlags; + + *pWidth = Desc.ByteWidth; + *pHeight = 1; + *pDepth = 1; + + hr = pDevice->CreateBuffer(&Desc, NULL, &pStagingBuffer); + } + break; + case D3D10_RESOURCE_DIMENSION_TEXTURE1D: + { + D3D10_TEXTURE1D_DESC Desc; + static_cast(pResource)->GetDesc(&Desc); + Desc.Usage = Usage; + Desc.BindFlags = BindFlags; + Desc.CPUAccessFlags = CPUAccessFlags; + Desc.MiscFlags = MiscFlags; + + *pWidth = Desc.Width; + *pHeight = 1; + *pDepth = 1; + + hr = pDevice->CreateTexture1D(&Desc, NULL, &pStagingTexture1D); + } + break; + case D3D10_RESOURCE_DIMENSION_TEXTURE2D: + { + D3D10_TEXTURE2D_DESC Desc; + static_cast(pResource)->GetDesc(&Desc); + Desc.Usage = Usage; + Desc.BindFlags = BindFlags; + Desc.CPUAccessFlags = CPUAccessFlags; + Desc.MiscFlags &= ~D3D10_RESOURCE_MISC_TEXTURECUBE; + + *pWidth = Desc.Width; + *pHeight = Desc.Height; + *pDepth = 1; + + hr = pDevice->CreateTexture2D(&Desc, NULL, &pStagingTexture2D); + } + break; + case D3D10_RESOURCE_DIMENSION_TEXTURE3D: + { + D3D10_TEXTURE3D_DESC Desc; + static_cast(pResource)->GetDesc(&Desc); + Desc.Usage = Usage; + Desc.BindFlags = BindFlags; + Desc.CPUAccessFlags = CPUAccessFlags; + Desc.MiscFlags = MiscFlags; + + *pWidth = Desc.Width; + *pHeight = Desc.Height; + *pDepth = Desc.Depth; + + hr = pDevice->CreateTexture3D(&Desc, NULL, &pStagingTexture3D); + } + break; + default: + assert(0); + hr = E_NOTIMPL; + break; + } + + if (SUCCEEDED(hr)) { + *ppStagingResource = pStagingResource; + pDevice->CopyResource(pStagingResource, pResource); + } + + return hr; +} + +static HRESULT +mapResource(ID3D10Resource *pResource, + UINT Subresource, D3D10_MAP MapType, UINT MapFlags, + D3D10_MAPPED_TEXTURE3D *pMappedSubresource) { + D3D10_RESOURCE_DIMENSION Type = D3D10_RESOURCE_DIMENSION_UNKNOWN; + pResource->GetType(&Type); + switch (Type) { + case D3D10_RESOURCE_DIMENSION_BUFFER: + assert(Subresource == 0); + return static_cast(pResource)->Map(MapType, MapFlags, &pMappedSubresource->pData); + case D3D10_RESOURCE_DIMENSION_TEXTURE1D: + return static_cast(pResource)->Map(Subresource, MapType, MapFlags, &pMappedSubresource->pData); + case D3D10_RESOURCE_DIMENSION_TEXTURE2D: + return static_cast(pResource)->Map(Subresource, MapType, MapFlags, reinterpret_cast(pMappedSubresource)); + case D3D10_RESOURCE_DIMENSION_TEXTURE3D: + return static_cast(pResource)->Map(Subresource, MapType, MapFlags, pMappedSubresource); + default: + assert(0); + return E_NOTIMPL; + } +} + +static void +unmapResource(ID3D10Resource *pResource, UINT Subresource) { + D3D10_RESOURCE_DIMENSION Type = D3D10_RESOURCE_DIMENSION_UNKNOWN; + pResource->GetType(&Type); + switch (Type) { + case D3D10_RESOURCE_DIMENSION_BUFFER: + assert(Subresource == 0); + static_cast(pResource)->Unmap(); + break; + case D3D10_RESOURCE_DIMENSION_TEXTURE1D: + static_cast(pResource)->Unmap(Subresource); + break; + case D3D10_RESOURCE_DIMENSION_TEXTURE2D: + static_cast(pResource)->Unmap(Subresource); + break; + case D3D10_RESOURCE_DIMENSION_TEXTURE3D: + static_cast(pResource)->Unmap(Subresource); + break; + default: + assert(0); + } +} + +image::Image * +getRenderTargetImage(ID3D10Device *pDevice) { + image::Image *image = NULL; + ID3D10RenderTargetView *pRenderTargetView = NULL; + D3D10_RENDER_TARGET_VIEW_DESC Desc; + ID3D10Resource *pResource = NULL; + ID3D10Resource *pStagingResource = NULL; + UINT Width, Height, Depth; + UINT MipSlice; + UINT Subresource; + D3D10_MAPPED_TEXTURE3D MappedSubresource; + HRESULT hr; + const unsigned char *src; + unsigned char *dst; + + pDevice->OMGetRenderTargets(1, &pRenderTargetView, NULL); + if (!pRenderTargetView) { + goto no_rendertarget; + } + + pRenderTargetView->GetResource(&pResource); + assert(pResource); + + pRenderTargetView->GetDesc(&Desc); + if (Desc.Format != DXGI_FORMAT_R8G8B8A8_UNORM && + Desc.Format != DXGI_FORMAT_R32G32B32A32_FLOAT && + Desc.Format != DXGI_FORMAT_B8G8R8A8_UNORM) { + std::cerr << "warning: unsupported DXGI format " << Desc.Format << "\n"; + goto no_staging; + } + + hr = stageResource(pDevice, pResource, &pStagingResource, &Width, &Height, &Depth); + if (FAILED(hr)) { + goto no_staging; + } + + // TODO: Take the slice in consideration + switch (Desc.ViewDimension) { + case D3D10_RTV_DIMENSION_BUFFER: + MipSlice = 0; + break; + case D3D10_RTV_DIMENSION_TEXTURE1D: + MipSlice = Desc.Texture1D.MipSlice; + break; + case D3D10_RTV_DIMENSION_TEXTURE1DARRAY: + MipSlice = Desc.Texture1DArray.MipSlice; + break; + case D3D10_RTV_DIMENSION_TEXTURE2D: + MipSlice = Desc.Texture2D.MipSlice; + MipSlice = 0; + break; + case D3D10_RTV_DIMENSION_TEXTURE2DARRAY: + MipSlice = Desc.Texture2DArray.MipSlice; + break; + case D3D10_RTV_DIMENSION_TEXTURE2DMS: + MipSlice = 0; + break; + case D3D10_RTV_DIMENSION_TEXTURE2DMSARRAY: + MipSlice = 0; + break; + case D3D10_RTV_DIMENSION_TEXTURE3D: + MipSlice = Desc.Texture3D.MipSlice; + break; + case D3D10_SRV_DIMENSION_UNKNOWN: + default: + assert(0); + goto no_map; + } + Subresource = MipSlice; + + Width = std::max(Width >> MipSlice, 1U); + Height = std::max(Height >> MipSlice, 1U); + Depth = std::max(Depth >> MipSlice, 1U); + + hr = mapResource(pStagingResource, Subresource, D3D10_MAP_READ, 0, &MappedSubresource); + if (FAILED(hr)) { + goto no_map; + } + + image = new image::Image(Width, Height, 4, true); + if (!image) { + goto no_image; + } + + dst = image->start(); + src = (const unsigned char *)MappedSubresource.pData; + for (unsigned y = 0; y < Height; ++y) { + if (Desc.Format == DXGI_FORMAT_R8G8B8A8_UNORM) { + memcpy(dst, src, Width * 4); + } else if (Desc.Format == DXGI_FORMAT_R32G32B32A32_FLOAT) { + float scale = 1.0f/255.0f; + for (unsigned x = 0; x < Width; ++x) { + dst[4*x + 0] = ((float *)src)[4*x + 0] * scale; + dst[4*x + 1] = ((float *)src)[4*x + 1] * scale; + dst[4*x + 2] = ((float *)src)[4*x + 2] * scale; + dst[4*x + 3] = ((float *)src)[4*x + 3] * scale; + } + } else if (Desc.Format == DXGI_FORMAT_B8G8R8A8_UNORM) { + for (unsigned x = 0; x < Width; ++x) { + dst[4*x + 0] = src[4*x + 2]; + dst[4*x + 1] = src[4*x + 1]; + dst[4*x + 2] = src[4*x + 0]; + dst[4*x + 3] = src[4*x + 3]; + } + } else { + assert(0); + } + src += MappedSubresource.RowPitch; + dst += image->stride(); + } + +no_image: + unmapResource(pStagingResource, Subresource); +no_map: + if (pStagingResource) { + pStagingResource->Release(); + } +no_staging: + if (pResource) { + pResource->Release(); + } + if (pRenderTargetView) { + pRenderTargetView->Release(); + } +no_rendertarget: + return image; +} + + +} /* namespace d3dstate */ diff --git a/retrace/d3d11state.cpp b/retrace/d3d11state.cpp index 602f05f..05885f4 100644 --- a/retrace/d3d11state.cpp +++ b/retrace/d3d11state.cpp @@ -36,7 +36,7 @@ namespace d3dstate { void -dumpDevice(std::ostream &os, ID3D11DeviceContext *pDevice) +dumpDevice(std::ostream &os, ID3D11DeviceContext *pDeviceContext) { JSONWriter json(os); diff --git a/retrace/d3dcommonretrace.py b/retrace/d3dcommonretrace.py index 4496b2c..7a64d81 100644 --- a/retrace/d3dcommonretrace.py +++ b/retrace/d3dcommonretrace.py @@ -81,6 +81,11 @@ class D3DRetracer(Retracer): def invokeInterfaceMethod(self, interface, method): # keep track of the last used device for state dumping + if interface.name in ('ID3D10Device', 'ID3D10Device1'): + if method.name == 'Release': + print r' d3d10Dumper.unbindDevice(_this);' + else: + print r' d3d10Dumper.bindDevice(_this);' if interface.name in ('ID3D11DeviceContext',): if method.name == 'Release': print r' d3d11Dumper.unbindDevice(_this);' @@ -137,8 +142,10 @@ def main(): moduleNames = sys.argv[1:] api = API() + if moduleNames: api.addModule(dxgi) + if 'd3d10' in moduleNames: if 'd3d10_1' in moduleNames: print r'#include "d3d10_1imports.hpp"' @@ -149,6 +156,10 @@ def main(): print r'#include "d3d10imports.hpp"' print r'#include "d3d10size.hpp"' api.addModule(d3d10) + print + print '''static d3dretrace::D3DDumper d3d10Dumper;''' + print + if 'd3d11' in moduleNames: print r'#include "d3d11imports.hpp"' if 'd3d11_1' in moduleNames: diff --git a/retrace/d3dstate.hpp b/retrace/d3dstate.hpp index 941d82d..c21c361 100644 --- a/retrace/d3dstate.hpp +++ b/retrace/d3dstate.hpp @@ -31,6 +31,7 @@ struct IDirect3DDevice9; +struct ID3D10Device; struct ID3D11DeviceContext; @@ -49,6 +50,13 @@ void dumpDevice(std::ostream &os, IDirect3DDevice9 *pDevice); +image::Image * +getRenderTargetImage(ID3D10Device *pDevice); + +void +dumpDevice(std::ostream &os, ID3D10Device *pDevice); + + image::Image * getRenderTargetImage(ID3D11DeviceContext *pDeviceContext); -- 2.43.0