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;
266 case D3D10_SRV_DIMENSION_TEXTURE2DARRAY:
267 MipSlice = Desc.Texture2DArray.MostDetailedMip;
269 case D3D10_SRV_DIMENSION_TEXTURE2DMS:
272 case D3D10_SRV_DIMENSION_TEXTURE2DMSARRAY:
275 case D3D10_SRV_DIMENSION_TEXTURE3D:
276 MipSlice = Desc.Texture3D.MostDetailedMip;
278 case D3D10_SRV_DIMENSION_TEXTURECUBE:
279 MipSlice = Desc.TextureCube.MostDetailedMip;
281 case D3D10_SRV_DIMENSION_UNKNOWN:
287 return getSubResourceImage(pDevice, pResource, Desc.Format, MipSlice);
291 static image::Image *
292 getRenderTargetViewImage(ID3D10Device *pDevice,
293 ID3D10RenderTargetView *pRenderTargetView) {
294 D3D10_RENDER_TARGET_VIEW_DESC Desc;
295 ID3D10Resource *pResource = NULL;
298 if (!pRenderTargetView) {
302 pRenderTargetView->GetResource(&pResource);
305 pRenderTargetView->GetDesc(&Desc);
307 // TODO: Take the slice in consideration
308 switch (Desc.ViewDimension) {
309 case D3D10_RTV_DIMENSION_BUFFER:
312 case D3D10_RTV_DIMENSION_TEXTURE1D:
313 MipSlice = Desc.Texture1D.MipSlice;
315 case D3D10_RTV_DIMENSION_TEXTURE1DARRAY:
316 MipSlice = Desc.Texture1DArray.MipSlice;
318 case D3D10_RTV_DIMENSION_TEXTURE2D:
319 MipSlice = Desc.Texture2D.MipSlice;
322 case D3D10_RTV_DIMENSION_TEXTURE2DARRAY:
323 MipSlice = Desc.Texture2DArray.MipSlice;
325 case D3D10_RTV_DIMENSION_TEXTURE2DMS:
328 case D3D10_RTV_DIMENSION_TEXTURE2DMSARRAY:
331 case D3D10_RTV_DIMENSION_TEXTURE3D:
332 MipSlice = Desc.Texture3D.MipSlice;
334 case D3D10_RTV_DIMENSION_UNKNOWN:
340 return getSubResourceImage(pDevice, pResource, Desc.Format, MipSlice);
344 static image::Image *
345 getDepthStencilViewImage(ID3D10Device *pDevice,
346 ID3D10DepthStencilView *pDepthStencilView) {
347 D3D10_DEPTH_STENCIL_VIEW_DESC Desc;
348 ID3D10Resource *pResource = NULL;
351 if (!pDepthStencilView) {
355 pDepthStencilView->GetResource(&pResource);
358 pDepthStencilView->GetDesc(&Desc);
360 // TODO: Take the slice in consideration
361 switch (Desc.ViewDimension) {
362 case D3D10_DSV_DIMENSION_TEXTURE1D:
363 MipSlice = Desc.Texture1D.MipSlice;
365 case D3D10_DSV_DIMENSION_TEXTURE1DARRAY:
366 MipSlice = Desc.Texture1DArray.MipSlice;
368 case D3D10_DSV_DIMENSION_TEXTURE2D:
369 MipSlice = Desc.Texture2D.MipSlice;
372 case D3D10_DSV_DIMENSION_TEXTURE2DARRAY:
373 MipSlice = Desc.Texture2DArray.MipSlice;
375 case D3D10_DSV_DIMENSION_TEXTURE2DMS:
378 case D3D10_DSV_DIMENSION_TEXTURE2DMSARRAY:
381 case D3D10_DSV_DIMENSION_UNKNOWN:
387 return getSubResourceImage(pDevice, pResource, Desc.Format, MipSlice);
392 dumpTextures(JSONWriter &json, ID3D10Device *pDevice)
394 json.beginMember("textures");
397 ID3D10ShaderResourceView *pShaderResourceViews[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT];
398 pDevice->PSGetShaderResources(0, ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);
400 for (UINT i = 0; i < ARRAYSIZE(pShaderResourceViews); ++i) {
401 if (!pShaderResourceViews[i]) {
406 image = getShaderResourceViewImage(pDevice, pShaderResourceViews[i]);
409 _snprintf(label, sizeof label, "PS_RESOURCE_%u", i);
410 json.beginMember(label);
411 json.writeImage(image, "UNKNOWN");
412 json.endMember(); // PS_RESOURCE_*
415 pShaderResourceViews[i]->Release();
419 json.endMember(); // textures
424 getRenderTargetImage(ID3D10Device *pDevice) {
425 ID3D10RenderTargetView *pRenderTargetView = NULL;
426 pDevice->OMGetRenderTargets(1, &pRenderTargetView, NULL);
428 image::Image *image = NULL;
429 if (pRenderTargetView) {
430 image = getRenderTargetViewImage(pDevice, pRenderTargetView);
431 pRenderTargetView->Release();
439 dumpFramebuffer(JSONWriter &json, ID3D10Device *pDevice)
441 json.beginMember("framebuffer");
444 ID3D10RenderTargetView *pRenderTargetViews[D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT];
445 ID3D10DepthStencilView *pDepthStencilView;
446 pDevice->OMGetRenderTargets(ARRAYSIZE(pRenderTargetViews), pRenderTargetViews,
449 for (UINT i = 0; i < ARRAYSIZE(pRenderTargetViews); ++i) {
450 if (!pRenderTargetViews[i]) {
455 image = getRenderTargetViewImage(pDevice, pRenderTargetViews[i]);
458 _snprintf(label, sizeof label, "RENDER_TARGET_%u", i);
459 json.beginMember(label);
460 json.writeImage(image, "UNKNOWN");
461 json.endMember(); // RENDER_TARGET_*
464 pRenderTargetViews[i]->Release();
467 if (pDepthStencilView) {
469 image = getDepthStencilViewImage(pDevice, pDepthStencilView);
471 json.beginMember("DEPTH_STENCIL");
472 json.writeImage(image, "UNKNOWN");
476 pDepthStencilView->Release();
481 json.endMember(); // framebuffer
485 } /* namespace d3dstate */