X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=retrace%2Fd3d10state_images.cpp;h=0341690c87d9f296277d339c8f8909263e474ece;hb=e4f7b243df9bb17abd4a20076bf74387bb1ac601;hp=a9d95c966cb8d9ed00868c6f055a12e701b6ebaa;hpb=65ba497caca56134f9b4f18658d104ce89092c11;p=apitrace diff --git a/retrace/d3d10state_images.cpp b/retrace/d3d10state_images.cpp index a9d95c9..0341690 100644 --- a/retrace/d3d10state_images.cpp +++ b/retrace/d3d10state_images.cpp @@ -29,10 +29,11 @@ #include #include -#include "image.hpp" +#include "os.hpp" #include "json.hpp" #include "d3d10imports.hpp" #include "d3dstate.hpp" +#include "dxgistate.hpp" namespace d3dstate { @@ -138,20 +139,20 @@ stageResource(ID3D10Device *pDevice, static HRESULT mapResource(ID3D10Resource *pResource, - UINT Subresource, D3D10_MAP MapType, UINT MapFlags, - D3D10_MAPPED_TEXTURE3D *pMappedSubresource) { + 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); + 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); + 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)); + 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); + return static_cast(pResource)->Map(SubResource, MapType, MapFlags, pMappedSubResource); default: assert(0); return E_NOTIMPL; @@ -159,42 +160,139 @@ mapResource(ID3D10Resource *pResource, } static void -unmapResource(ID3D10Resource *pResource, UINT Subresource) { +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); + assert(SubResource == 0); static_cast(pResource)->Unmap(); break; case D3D10_RESOURCE_DIMENSION_TEXTURE1D: - static_cast(pResource)->Unmap(Subresource); + static_cast(pResource)->Unmap(SubResource); break; case D3D10_RESOURCE_DIMENSION_TEXTURE2D: - static_cast(pResource)->Unmap(Subresource); + static_cast(pResource)->Unmap(SubResource); break; case D3D10_RESOURCE_DIMENSION_TEXTURE3D: - static_cast(pResource)->Unmap(Subresource); + static_cast(pResource)->Unmap(SubResource); break; default: assert(0); } } + +static image::Image * +getSubResourceImage(ID3D10Device *pDevice, + ID3D10Resource *pResource, + DXGI_FORMAT Format, + UINT MipSlice) +{ + image::Image *image = NULL; + ID3D10Resource *pStagingResource = NULL; + UINT Width, Height, Depth; + UINT SubResource = MipSlice; + D3D10_MAPPED_TEXTURE3D MappedSubResource; + HRESULT hr; + + if (!pResource) { + return NULL; + } + + hr = stageResource(pDevice, pResource, &pStagingResource, &Width, &Height, &Depth); + if (FAILED(hr)) { + goto no_staging; + } + + 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 = ConvertImage(Format, + MappedSubResource.pData, + MappedSubResource.RowPitch, + Width, Height); + + unmapResource(pStagingResource, SubResource); +no_map: + if (pStagingResource) { + pStagingResource->Release(); + } +no_staging: + if (pResource) { + pResource->Release(); + } + return image; +} + + +static image::Image * +getShaderResourceViewImage(ID3D10Device *pDevice, + ID3D10ShaderResourceView *pShaderResourceView) { + D3D10_SHADER_RESOURCE_VIEW_DESC Desc; + ID3D10Resource *pResource = NULL; + UINT MipSlice; + + if (!pShaderResourceView) { + return NULL; + } + + pShaderResourceView->GetResource(&pResource); + assert(pResource); + + pShaderResourceView->GetDesc(&Desc); + + // TODO: Take the slice in consideration + switch (Desc.ViewDimension) { + case D3D10_SRV_DIMENSION_BUFFER: + MipSlice = 0; + break; + case D3D10_SRV_DIMENSION_TEXTURE1D: + MipSlice = Desc.Texture1D.MostDetailedMip; + break; + case D3D10_SRV_DIMENSION_TEXTURE1DARRAY: + MipSlice = Desc.Texture1DArray.MostDetailedMip; + break; + case D3D10_SRV_DIMENSION_TEXTURE2D: + MipSlice = Desc.Texture2D.MostDetailedMip; + break; + case D3D10_SRV_DIMENSION_TEXTURE2DARRAY: + MipSlice = Desc.Texture2DArray.MostDetailedMip; + break; + case D3D10_SRV_DIMENSION_TEXTURE2DMS: + MipSlice = 0; + break; + case D3D10_SRV_DIMENSION_TEXTURE2DMSARRAY: + MipSlice = 0; + break; + case D3D10_SRV_DIMENSION_TEXTURE3D: + MipSlice = Desc.Texture3D.MostDetailedMip; + break; + case D3D10_SRV_DIMENSION_TEXTURECUBE: + MipSlice = Desc.TextureCube.MostDetailedMip; + break; + case D3D10_SRV_DIMENSION_UNKNOWN: + default: + assert(0); + return NULL; + } + + return getSubResourceImage(pDevice, pResource, Desc.Format, MipSlice); +} + + static image::Image * getRenderTargetViewImage(ID3D10Device *pDevice, ID3D10RenderTargetView *pRenderTargetView) { - image::Image *image = 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; if (!pRenderTargetView) { return NULL; @@ -204,17 +302,6 @@ getRenderTargetViewImage(ID3D10Device *pDevice, 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) { @@ -243,65 +330,105 @@ getRenderTargetViewImage(ID3D10Device *pDevice, case D3D10_RTV_DIMENSION_TEXTURE3D: MipSlice = Desc.Texture3D.MipSlice; break; - case D3D10_SRV_DIMENSION_UNKNOWN: + case D3D10_RTV_DIMENSION_UNKNOWN: default: assert(0); - goto no_map; + return NULL; } - Subresource = MipSlice; - Width = std::max(Width >> MipSlice, 1U); - Height = std::max(Height >> MipSlice, 1U); - Depth = std::max(Depth >> MipSlice, 1U); + return getSubResourceImage(pDevice, pResource, Desc.Format, MipSlice); +} - hr = mapResource(pStagingResource, Subresource, D3D10_MAP_READ, 0, &MappedSubresource); - if (FAILED(hr)) { - goto no_map; + +static image::Image * +getDepthStencilViewImage(ID3D10Device *pDevice, + ID3D10DepthStencilView *pDepthStencilView) { + D3D10_DEPTH_STENCIL_VIEW_DESC Desc; + ID3D10Resource *pResource = NULL; + UINT MipSlice; + + if (!pDepthStencilView) { + return NULL; } - image = new image::Image(Width, Height, 4, true); - if (!image) { - goto no_image; + pDepthStencilView->GetResource(&pResource); + assert(pResource); + + pDepthStencilView->GetDesc(&Desc); + + // TODO: Take the slice in consideration + switch (Desc.ViewDimension) { + case D3D10_DSV_DIMENSION_TEXTURE1D: + MipSlice = Desc.Texture1D.MipSlice; + break; + case D3D10_DSV_DIMENSION_TEXTURE1DARRAY: + MipSlice = Desc.Texture1DArray.MipSlice; + break; + case D3D10_DSV_DIMENSION_TEXTURE2D: + MipSlice = Desc.Texture2D.MipSlice; + break; + case D3D10_DSV_DIMENSION_TEXTURE2DARRAY: + MipSlice = Desc.Texture2DArray.MipSlice; + break; + case D3D10_DSV_DIMENSION_TEXTURE2DMS: + MipSlice = 0; + break; + case D3D10_DSV_DIMENSION_TEXTURE2DMSARRAY: + MipSlice = 0; + break; + case D3D10_DSV_DIMENSION_UNKNOWN: + default: + assert(0); + return NULL; } - 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); + return getSubResourceImage(pDevice, pResource, Desc.Format, MipSlice); +} + + +static void +dumpStageTextures(JSONWriter &json, ID3D10Device *pDevice, const char *stageName, + ID3D10ShaderResourceView *pShaderResourceViews[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT]) +{ + for (UINT i = 0; i < ARRAYSIZE(pShaderResourceViews); ++i) { + if (!pShaderResourceViews[i]) { + continue; } - src += MappedSubresource.RowPitch; - dst += image->stride(); - } -no_image: - unmapResource(pStagingResource, Subresource); -no_map: - if (pStagingResource) { - pStagingResource->Release(); - } -no_staging: - if (pResource) { - pResource->Release(); + image::Image *image; + image = getShaderResourceViewImage(pDevice, pShaderResourceViews[i]); + if (image) { + char label[64]; + _snprintf(label, sizeof label, "%s_RESOURCE_%u", stageName, i); + json.beginMember(label); + json.writeImage(image, "UNKNOWN"); + json.endMember(); // *_RESOURCE_* + } + + pShaderResourceViews[i]->Release(); } - return image; +} + + +void +dumpTextures(JSONWriter &json, ID3D10Device *pDevice) +{ + json.beginMember("textures"); + json.beginObject(); + + ID3D10ShaderResourceView *pShaderResourceViews[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT]; + + pDevice->PSGetShaderResources(0, ARRAYSIZE(pShaderResourceViews), pShaderResourceViews); + dumpStageTextures(json, pDevice, "PS", pShaderResourceViews); + + pDevice->VSGetShaderResources(0, ARRAYSIZE(pShaderResourceViews), pShaderResourceViews); + dumpStageTextures(json, pDevice, "VS", pShaderResourceViews); + + pDevice->GSGetShaderResources(0, ARRAYSIZE(pShaderResourceViews), pShaderResourceViews); + dumpStageTextures(json, pDevice, "GS", pShaderResourceViews); + + json.endObject(); + json.endMember(); // textures } @@ -327,9 +454,11 @@ dumpFramebuffer(JSONWriter &json, ID3D10Device *pDevice) json.beginObject(); ID3D10RenderTargetView *pRenderTargetViews[D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT]; - pDevice->OMGetRenderTargets(D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT, pRenderTargetViews, NULL); + ID3D10DepthStencilView *pDepthStencilView; + pDevice->OMGetRenderTargets(ARRAYSIZE(pRenderTargetViews), pRenderTargetViews, + &pDepthStencilView); - for (UINT i = 0; i < D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) { + for (UINT i = 0; i < ARRAYSIZE(pRenderTargetViews); ++i) { if (!pRenderTargetViews[i]) { continue; } @@ -338,7 +467,7 @@ dumpFramebuffer(JSONWriter &json, ID3D10Device *pDevice) image = getRenderTargetViewImage(pDevice, pRenderTargetViews[i]); if (image) { char label[64]; - snprintf(label, sizeof label, "RENDER_TARGET_%u", i); + _snprintf(label, sizeof label, "RENDER_TARGET_%u", i); json.beginMember(label); json.writeImage(image, "UNKNOWN"); json.endMember(); // RENDER_TARGET_* @@ -347,6 +476,19 @@ dumpFramebuffer(JSONWriter &json, ID3D10Device *pDevice) pRenderTargetViews[i]->Release(); } + if (pDepthStencilView) { + image::Image *image; + image = getDepthStencilViewImage(pDevice, pDepthStencilView); + if (image) { + json.beginMember("DEPTH_STENCIL"); + json.writeImage(image, "UNKNOWN"); + json.endMember(); + } + + pDepthStencilView->Release(); + + } + json.endObject(); json.endMember(); // framebuffer }