1 /**************************************************************************
3 * Copyright 2011 Jose Fonseca
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 **************************************************************************/
34 #include "d3d10imports.hpp"
35 #include "d3dstate.hpp"
36 #include "dxgistate.hpp"
42 stageResource(ID3D10Device *pDevice,
43 ID3D10Resource *pResource,
44 ID3D10Resource **ppStagingResource,
45 UINT *pWidth, UINT *pHeight, UINT *pDepth) {
46 D3D10_USAGE Usage = D3D10_USAGE_STAGING;
48 UINT CPUAccessFlags = D3D10_CPU_ACCESS_READ;
51 ID3D10Resource *pStagingResource;
52 ID3D10Buffer *pStagingBuffer;
53 ID3D10Texture1D *pStagingTexture1D;
54 ID3D10Texture2D *pStagingTexture2D;
55 ID3D10Texture3D *pStagingTexture3D;
59 D3D10_RESOURCE_DIMENSION Type = D3D10_RESOURCE_DIMENSION_UNKNOWN;
60 pResource->GetType(&Type);
62 case D3D10_RESOURCE_DIMENSION_BUFFER:
64 D3D10_BUFFER_DESC Desc;
65 static_cast<ID3D10Buffer *>(pResource)->GetDesc(&Desc);
67 Desc.BindFlags = BindFlags;
68 Desc.CPUAccessFlags = CPUAccessFlags;
69 Desc.MiscFlags = MiscFlags;
71 *pWidth = Desc.ByteWidth;
75 hr = pDevice->CreateBuffer(&Desc, NULL, &pStagingBuffer);
78 case D3D10_RESOURCE_DIMENSION_TEXTURE1D:
80 D3D10_TEXTURE1D_DESC Desc;
81 static_cast<ID3D10Texture1D *>(pResource)->GetDesc(&Desc);
83 Desc.BindFlags = BindFlags;
84 Desc.CPUAccessFlags = CPUAccessFlags;
85 Desc.MiscFlags = MiscFlags;
91 hr = pDevice->CreateTexture1D(&Desc, NULL, &pStagingTexture1D);
94 case D3D10_RESOURCE_DIMENSION_TEXTURE2D:
96 D3D10_TEXTURE2D_DESC Desc;
97 static_cast<ID3D10Texture2D *>(pResource)->GetDesc(&Desc);
99 Desc.BindFlags = BindFlags;
100 Desc.CPUAccessFlags = CPUAccessFlags;
101 Desc.MiscFlags &= D3D10_RESOURCE_MISC_TEXTURECUBE;
103 *pWidth = Desc.Width;
104 *pHeight = Desc.Height;
107 hr = pDevice->CreateTexture2D(&Desc, NULL, &pStagingTexture2D);
110 case D3D10_RESOURCE_DIMENSION_TEXTURE3D:
112 D3D10_TEXTURE3D_DESC Desc;
113 static_cast<ID3D10Texture3D *>(pResource)->GetDesc(&Desc);
115 Desc.BindFlags = BindFlags;
116 Desc.CPUAccessFlags = CPUAccessFlags;
117 Desc.MiscFlags = MiscFlags;
119 *pWidth = Desc.Width;
120 *pHeight = Desc.Height;
121 *pDepth = Desc.Depth;
123 hr = pDevice->CreateTexture3D(&Desc, NULL, &pStagingTexture3D);
133 *ppStagingResource = pStagingResource;
134 pDevice->CopyResource(pStagingResource, pResource);
141 mapResource(ID3D10Resource *pResource,
142 UINT SubResource, D3D10_MAP MapType, UINT MapFlags,
143 D3D10_MAPPED_TEXTURE3D *pMappedSubResource) {
144 D3D10_RESOURCE_DIMENSION Type = D3D10_RESOURCE_DIMENSION_UNKNOWN;
145 pResource->GetType(&Type);
147 case D3D10_RESOURCE_DIMENSION_BUFFER:
148 assert(SubResource == 0);
149 return static_cast<ID3D10Buffer *>(pResource)->Map(MapType, MapFlags, &pMappedSubResource->pData);
150 case D3D10_RESOURCE_DIMENSION_TEXTURE1D:
151 return static_cast<ID3D10Texture1D *>(pResource)->Map(SubResource, MapType, MapFlags, &pMappedSubResource->pData);
152 case D3D10_RESOURCE_DIMENSION_TEXTURE2D:
153 return static_cast<ID3D10Texture2D *>(pResource)->Map(SubResource, MapType, MapFlags, reinterpret_cast<D3D10_MAPPED_TEXTURE2D *>(pMappedSubResource));
154 case D3D10_RESOURCE_DIMENSION_TEXTURE3D:
155 return static_cast<ID3D10Texture3D *>(pResource)->Map(SubResource, MapType, MapFlags, pMappedSubResource);
163 unmapResource(ID3D10Resource *pResource, UINT SubResource) {
164 D3D10_RESOURCE_DIMENSION Type = D3D10_RESOURCE_DIMENSION_UNKNOWN;
165 pResource->GetType(&Type);
167 case D3D10_RESOURCE_DIMENSION_BUFFER:
168 assert(SubResource == 0);
169 static_cast<ID3D10Buffer *>(pResource)->Unmap();
171 case D3D10_RESOURCE_DIMENSION_TEXTURE1D:
172 static_cast<ID3D10Texture1D *>(pResource)->Unmap(SubResource);
174 case D3D10_RESOURCE_DIMENSION_TEXTURE2D:
175 static_cast<ID3D10Texture2D *>(pResource)->Unmap(SubResource);
177 case D3D10_RESOURCE_DIMENSION_TEXTURE3D:
178 static_cast<ID3D10Texture3D *>(pResource)->Unmap(SubResource);
186 static image::Image *
187 getSubResourceImage(ID3D10Device *pDevice,
188 ID3D10Resource *pResource,
192 image::Image *image = NULL;
193 ID3D10Resource *pStagingResource = NULL;
194 UINT Width, Height, Depth;
195 UINT SubResource = MipSlice;
196 D3D10_MAPPED_TEXTURE3D MappedSubResource;
203 hr = stageResource(pDevice, pResource, &pStagingResource, &Width, &Height, &Depth);
208 Width = std::max(Width >> MipSlice, 1U);
209 Height = std::max(Height >> MipSlice, 1U);
210 Depth = std::max(Depth >> MipSlice, 1U);
212 hr = mapResource(pStagingResource, SubResource, D3D10_MAP_READ, 0, &MappedSubResource);
217 image = ConvertImage(Format,
218 MappedSubResource.pData,
219 MappedSubResource.RowPitch,
222 unmapResource(pStagingResource, SubResource);
224 if (pStagingResource) {
225 pStagingResource->Release();
229 pResource->Release();
235 static image::Image *
236 getShaderResourceViewImage(ID3D10Device *pDevice,
237 ID3D10ShaderResourceView *pShaderResourceView) {
238 D3D10_SHADER_RESOURCE_VIEW_DESC Desc;
239 ID3D10Resource *pResource = NULL;
242 if (!pShaderResourceView) {
246 pShaderResourceView->GetResource(&pResource);
249 pShaderResourceView->GetDesc(&Desc);
251 // TODO: Take the slice in consideration
252 switch (Desc.ViewDimension) {
253 case D3D10_SRV_DIMENSION_BUFFER:
256 case D3D10_SRV_DIMENSION_TEXTURE1D:
257 MipSlice = Desc.Texture1D.MostDetailedMip;
259 case D3D10_SRV_DIMENSION_TEXTURE1DARRAY:
260 MipSlice = Desc.Texture1DArray.MostDetailedMip;
262 case D3D10_SRV_DIMENSION_TEXTURE2D:
263 MipSlice = Desc.Texture2D.MostDetailedMip;
265 case D3D10_SRV_DIMENSION_TEXTURE2DARRAY:
266 MipSlice = Desc.Texture2DArray.MostDetailedMip;
268 case D3D10_SRV_DIMENSION_TEXTURE2DMS:
271 case D3D10_SRV_DIMENSION_TEXTURE2DMSARRAY:
274 case D3D10_SRV_DIMENSION_TEXTURE3D:
275 MipSlice = Desc.Texture3D.MostDetailedMip;
277 case D3D10_SRV_DIMENSION_TEXTURECUBE:
278 MipSlice = Desc.TextureCube.MostDetailedMip;
280 case D3D10_SRV_DIMENSION_UNKNOWN:
286 return getSubResourceImage(pDevice, pResource, Desc.Format, MipSlice);
290 static image::Image *
291 getRenderTargetViewImage(ID3D10Device *pDevice,
292 ID3D10RenderTargetView *pRenderTargetView) {
293 D3D10_RENDER_TARGET_VIEW_DESC Desc;
294 ID3D10Resource *pResource = NULL;
297 if (!pRenderTargetView) {
301 pRenderTargetView->GetResource(&pResource);
304 pRenderTargetView->GetDesc(&Desc);
306 // TODO: Take the slice in consideration
307 switch (Desc.ViewDimension) {
308 case D3D10_RTV_DIMENSION_BUFFER:
311 case D3D10_RTV_DIMENSION_TEXTURE1D:
312 MipSlice = Desc.Texture1D.MipSlice;
314 case D3D10_RTV_DIMENSION_TEXTURE1DARRAY:
315 MipSlice = Desc.Texture1DArray.MipSlice;
317 case D3D10_RTV_DIMENSION_TEXTURE2D:
318 MipSlice = Desc.Texture2D.MipSlice;
321 case D3D10_RTV_DIMENSION_TEXTURE2DARRAY:
322 MipSlice = Desc.Texture2DArray.MipSlice;
324 case D3D10_RTV_DIMENSION_TEXTURE2DMS:
327 case D3D10_RTV_DIMENSION_TEXTURE2DMSARRAY:
330 case D3D10_RTV_DIMENSION_TEXTURE3D:
331 MipSlice = Desc.Texture3D.MipSlice;
333 case D3D10_RTV_DIMENSION_UNKNOWN:
339 return getSubResourceImage(pDevice, pResource, Desc.Format, MipSlice);
343 static image::Image *
344 getDepthStencilViewImage(ID3D10Device *pDevice,
345 ID3D10DepthStencilView *pDepthStencilView) {
346 D3D10_DEPTH_STENCIL_VIEW_DESC Desc;
347 ID3D10Resource *pResource = NULL;
350 if (!pDepthStencilView) {
354 pDepthStencilView->GetResource(&pResource);
357 pDepthStencilView->GetDesc(&Desc);
359 // TODO: Take the slice in consideration
360 switch (Desc.ViewDimension) {
361 case D3D10_DSV_DIMENSION_TEXTURE1D:
362 MipSlice = Desc.Texture1D.MipSlice;
364 case D3D10_DSV_DIMENSION_TEXTURE1DARRAY:
365 MipSlice = Desc.Texture1DArray.MipSlice;
367 case D3D10_DSV_DIMENSION_TEXTURE2D:
368 MipSlice = Desc.Texture2D.MipSlice;
370 case D3D10_DSV_DIMENSION_TEXTURE2DARRAY:
371 MipSlice = Desc.Texture2DArray.MipSlice;
373 case D3D10_DSV_DIMENSION_TEXTURE2DMS:
376 case D3D10_DSV_DIMENSION_TEXTURE2DMSARRAY:
379 case D3D10_DSV_DIMENSION_UNKNOWN:
385 return getSubResourceImage(pDevice, pResource, Desc.Format, MipSlice);
390 dumpStageTextures(JSONWriter &json, ID3D10Device *pDevice, const char *stageName,
392 ID3D10ShaderResourceView **ppShaderResourceViews)
394 for (UINT i = 0; i < NumViews; ++i) {
395 if (!ppShaderResourceViews[i]) {
400 image = getShaderResourceViewImage(pDevice, ppShaderResourceViews[i]);
403 _snprintf(label, sizeof label, "%s_RESOURCE_%u", stageName, i);
404 json.beginMember(label);
405 json.writeImage(image, "UNKNOWN");
406 json.endMember(); // *_RESOURCE_*
409 ppShaderResourceViews[i]->Release();
415 dumpTextures(JSONWriter &json, ID3D10Device *pDevice)
417 json.beginMember("textures");
420 ID3D10ShaderResourceView *pShaderResourceViews[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT];
422 pDevice->PSGetShaderResources(0, ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);
423 dumpStageTextures(json, pDevice, "PS", ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);
425 pDevice->VSGetShaderResources(0, ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);
426 dumpStageTextures(json, pDevice, "VS", ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);
428 pDevice->GSGetShaderResources(0, ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);
429 dumpStageTextures(json, pDevice, "GS", ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);
432 json.endMember(); // textures
437 getRenderTargetImage(ID3D10Device *pDevice) {
438 ID3D10RenderTargetView *pRenderTargetView = NULL;
439 pDevice->OMGetRenderTargets(1, &pRenderTargetView, NULL);
441 image::Image *image = NULL;
442 if (pRenderTargetView) {
443 image = getRenderTargetViewImage(pDevice, pRenderTargetView);
444 pRenderTargetView->Release();
452 dumpFramebuffer(JSONWriter &json, ID3D10Device *pDevice)
454 json.beginMember("framebuffer");
457 ID3D10RenderTargetView *pRenderTargetViews[D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT];
458 ID3D10DepthStencilView *pDepthStencilView;
459 pDevice->OMGetRenderTargets(ARRAYSIZE(pRenderTargetViews), pRenderTargetViews,
462 for (UINT i = 0; i < ARRAYSIZE(pRenderTargetViews); ++i) {
463 if (!pRenderTargetViews[i]) {
468 image = getRenderTargetViewImage(pDevice, pRenderTargetViews[i]);
471 _snprintf(label, sizeof label, "RENDER_TARGET_%u", i);
472 json.beginMember(label);
473 json.writeImage(image, "UNKNOWN");
474 json.endMember(); // RENDER_TARGET_*
477 pRenderTargetViews[i]->Release();
480 if (pDepthStencilView) {
482 image = getDepthStencilViewImage(pDevice, pDepthStencilView);
484 json.beginMember("DEPTH_STENCIL");
485 json.writeImage(image, "UNKNOWN");
489 pDepthStencilView->Release();
494 json.endMember(); // framebuffer
498 } /* namespace d3dstate */