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);
185 static image::Image *
186 getSubResourceImage(ID3D10Device *pDevice,
187 ID3D10Resource *pResource,
191 image::Image *image = NULL;
192 ID3D10Resource *pStagingResource = NULL;
193 UINT Width, Height, Depth;
194 UINT SubResource = MipSlice;
195 D3D10_MAPPED_TEXTURE3D MappedSubResource;
202 hr = stageResource(pDevice, pResource, &pStagingResource, &Width, &Height, &Depth);
207 Width = std::max(Width >> MipSlice, 1U);
208 Height = std::max(Height >> MipSlice, 1U);
209 Depth = std::max(Depth >> MipSlice, 1U);
211 hr = mapResource(pStagingResource, SubResource, D3D10_MAP_READ, 0, &MappedSubResource);
216 image = ConvertImage(Format,
217 MappedSubResource.pData,
218 MappedSubResource.RowPitch,
221 unmapResource(pStagingResource, SubResource);
223 if (pStagingResource) {
224 pStagingResource->Release();
228 pResource->Release();
234 static image::Image *
235 getShaderResourceViewImage(ID3D10Device *pDevice,
236 ID3D10ShaderResourceView *pShaderResourceView) {
237 D3D10_SHADER_RESOURCE_VIEW_DESC Desc;
238 ID3D10Resource *pResource = NULL;
241 if (!pShaderResourceView) {
245 pShaderResourceView->GetResource(&pResource);
248 pShaderResourceView->GetDesc(&Desc);
250 // TODO: Take the slice in consideration
251 switch (Desc.ViewDimension) {
252 case D3D10_SRV_DIMENSION_BUFFER:
255 case D3D10_SRV_DIMENSION_TEXTURE1D:
256 MipSlice = Desc.Texture1D.MostDetailedMip;
258 case D3D10_SRV_DIMENSION_TEXTURE1DARRAY:
259 MipSlice = Desc.Texture1DArray.MostDetailedMip;
261 case D3D10_SRV_DIMENSION_TEXTURE2D:
262 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;
371 case D3D10_DSV_DIMENSION_TEXTURE2DARRAY:
372 MipSlice = Desc.Texture2DArray.MipSlice;
374 case D3D10_DSV_DIMENSION_TEXTURE2DMS:
377 case D3D10_DSV_DIMENSION_TEXTURE2DMSARRAY:
380 case D3D10_DSV_DIMENSION_UNKNOWN:
386 return getSubResourceImage(pDevice, pResource, Desc.Format, MipSlice);
391 dumpTextures(JSONWriter &json, ID3D10Device *pDevice)
393 json.beginMember("textures");
396 ID3D10ShaderResourceView *pShaderResourceViews[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT];
397 pDevice->PSGetShaderResources(0, ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);
399 for (UINT i = 0; i < ARRAYSIZE(pShaderResourceViews); ++i) {
400 if (!pShaderResourceViews[i]) {
405 image = getShaderResourceViewImage(pDevice, pShaderResourceViews[i]);
408 _snprintf(label, sizeof label, "PS_RESOURCE_%u", i);
409 json.beginMember(label);
410 json.writeImage(image, "UNKNOWN");
411 json.endMember(); // PS_RESOURCE_*
414 pShaderResourceViews[i]->Release();
418 json.endMember(); // textures
423 getRenderTargetImage(ID3D10Device *pDevice) {
424 ID3D10RenderTargetView *pRenderTargetView = NULL;
425 pDevice->OMGetRenderTargets(1, &pRenderTargetView, NULL);
427 image::Image *image = NULL;
428 if (pRenderTargetView) {
429 image = getRenderTargetViewImage(pDevice, pRenderTargetView);
430 pRenderTargetView->Release();
438 dumpFramebuffer(JSONWriter &json, ID3D10Device *pDevice)
440 json.beginMember("framebuffer");
443 ID3D10RenderTargetView *pRenderTargetViews[D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT];
444 ID3D10DepthStencilView *pDepthStencilView;
445 pDevice->OMGetRenderTargets(ARRAYSIZE(pRenderTargetViews), pRenderTargetViews,
448 for (UINT i = 0; i < ARRAYSIZE(pRenderTargetViews); ++i) {
449 if (!pRenderTargetViews[i]) {
454 image = getRenderTargetViewImage(pDevice, pRenderTargetViews[i]);
457 _snprintf(label, sizeof label, "RENDER_TARGET_%u", i);
458 json.beginMember(label);
459 json.writeImage(image, "UNKNOWN");
460 json.endMember(); // RENDER_TARGET_*
463 pRenderTargetViews[i]->Release();
466 if (pDepthStencilView) {
468 image = getDepthStencilViewImage(pDevice, pDepthStencilView);
470 json.beginMember("DEPTH_STENCIL");
471 json.writeImage(image, "UNKNOWN");
475 pDepthStencilView->Release();
480 json.endMember(); // framebuffer
484 } /* namespace d3dstate */