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 getRenderTargetViewImage(ID3D10Device *pDevice,
187 ID3D10RenderTargetView *pRenderTargetView) {
188 image::Image *image = NULL;
189 D3D10_RENDER_TARGET_VIEW_DESC Desc;
190 ID3D10Resource *pResource = NULL;
191 ID3D10Resource *pStagingResource = NULL;
192 UINT Width, Height, Depth;
195 D3D10_MAPPED_TEXTURE3D MappedSubresource;
198 if (!pRenderTargetView) {
202 pRenderTargetView->GetResource(&pResource);
205 pRenderTargetView->GetDesc(&Desc);
207 hr = stageResource(pDevice, pResource, &pStagingResource, &Width, &Height, &Depth);
212 // TODO: Take the slice in consideration
213 switch (Desc.ViewDimension) {
214 case D3D10_RTV_DIMENSION_BUFFER:
217 case D3D10_RTV_DIMENSION_TEXTURE1D:
218 MipSlice = Desc.Texture1D.MipSlice;
220 case D3D10_RTV_DIMENSION_TEXTURE1DARRAY:
221 MipSlice = Desc.Texture1DArray.MipSlice;
223 case D3D10_RTV_DIMENSION_TEXTURE2D:
224 MipSlice = Desc.Texture2D.MipSlice;
227 case D3D10_RTV_DIMENSION_TEXTURE2DARRAY:
228 MipSlice = Desc.Texture2DArray.MipSlice;
230 case D3D10_RTV_DIMENSION_TEXTURE2DMS:
233 case D3D10_RTV_DIMENSION_TEXTURE2DMSARRAY:
236 case D3D10_RTV_DIMENSION_TEXTURE3D:
237 MipSlice = Desc.Texture3D.MipSlice;
239 case D3D10_SRV_DIMENSION_UNKNOWN:
244 Subresource = MipSlice;
246 Width = std::max(Width >> MipSlice, 1U);
247 Height = std::max(Height >> MipSlice, 1U);
248 Depth = std::max(Depth >> MipSlice, 1U);
250 hr = mapResource(pStagingResource, Subresource, D3D10_MAP_READ, 0, &MappedSubresource);
255 image = new image::Image(Width, Height, 4);
259 assert(image->stride() > 0);
261 hr = ConvertFormat(Desc.Format,
262 MappedSubresource.pData,
263 MappedSubresource.RowPitch,
264 DXGI_FORMAT_R8G8B8A8_UNORM,
274 unmapResource(pStagingResource, Subresource);
276 if (pStagingResource) {
277 pStagingResource->Release();
281 pResource->Release();
288 getRenderTargetImage(ID3D10Device *pDevice) {
289 ID3D10RenderTargetView *pRenderTargetView = NULL;
290 pDevice->OMGetRenderTargets(1, &pRenderTargetView, NULL);
292 image::Image *image = NULL;
293 if (pRenderTargetView) {
294 image = getRenderTargetViewImage(pDevice, pRenderTargetView);
295 pRenderTargetView->Release();
303 dumpFramebuffer(JSONWriter &json, ID3D10Device *pDevice)
305 json.beginMember("framebuffer");
308 ID3D10RenderTargetView *pRenderTargetViews[D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT];
309 pDevice->OMGetRenderTargets(D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT, pRenderTargetViews, NULL);
311 for (UINT i = 0; i < D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) {
312 if (!pRenderTargetViews[i]) {
317 image = getRenderTargetViewImage(pDevice, pRenderTargetViews[i]);
320 _snprintf(label, sizeof label, "RENDER_TARGET_%u", i);
321 json.beginMember(label);
322 json.writeImage(image, "UNKNOWN");
323 json.endMember(); // RENDER_TARGET_*
326 pRenderTargetViews[i]->Release();
330 json.endMember(); // framebuffer
334 } /* namespace d3dstate */