]> git.cworth.org Git - apitrace/blob - retrace/d3d11state_images.cpp
glstate: Dump parameters for array and multisample texture targets.
[apitrace] / retrace / d3d11state_images.cpp
1 /**************************************************************************
2  *
3  * Copyright 2011 Jose Fonseca
4  * All Rights Reserved.
5  *
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:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
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
22  * THE SOFTWARE.
23  *
24  **************************************************************************/
25
26
27 #include <assert.h>
28
29 #include <iostream>
30 #include <algorithm>
31
32 #include "os.hpp"
33 #include "json.hpp"
34 #include "d3d11imports.hpp"
35 #include "d3d10state.hpp"
36 #include "dxgistate.hpp"
37
38
39 namespace d3dstate {
40
41 static HRESULT
42 stageResource(ID3D11DeviceContext *pDeviceContext,
43               ID3D11Resource *pResource,
44               ID3D11Resource **ppStagingResource,
45               UINT *pWidth, UINT *pHeight, UINT *pDepth) {
46     D3D11_USAGE Usage = D3D11_USAGE_STAGING;
47     UINT BindFlags = 0;
48     UINT CPUAccessFlags = D3D11_CPU_ACCESS_READ;
49     UINT MiscFlags = 0;
50     union {
51          ID3D11Resource *pStagingResource;
52          ID3D11Buffer *pStagingBuffer;
53          ID3D11Texture1D *pStagingTexture1D;
54          ID3D11Texture2D *pStagingTexture2D;
55          ID3D11Texture3D *pStagingTexture3D;
56     };
57     HRESULT hr;
58
59     ID3D11Device *pDevice = NULL;
60     pDeviceContext->GetDevice(&pDevice);
61
62     D3D11_RESOURCE_DIMENSION Type = D3D11_RESOURCE_DIMENSION_UNKNOWN;
63     pResource->GetType(&Type);
64     switch (Type) {
65     case D3D11_RESOURCE_DIMENSION_BUFFER:
66         {
67             D3D11_BUFFER_DESC Desc;
68             static_cast<ID3D11Buffer *>(pResource)->GetDesc(&Desc);
69             Desc.Usage = Usage;
70             Desc.BindFlags = BindFlags;
71             Desc.CPUAccessFlags = CPUAccessFlags;
72             Desc.MiscFlags = MiscFlags;
73
74             *pWidth = Desc.ByteWidth;
75             *pHeight = 1;
76             *pDepth = 1;
77
78             hr = pDevice->CreateBuffer(&Desc, NULL, &pStagingBuffer);
79         }
80         break;
81     case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
82         {
83             D3D11_TEXTURE1D_DESC Desc;
84             static_cast<ID3D11Texture1D *>(pResource)->GetDesc(&Desc);
85             Desc.Usage = Usage;
86             Desc.BindFlags = BindFlags;
87             Desc.CPUAccessFlags = CPUAccessFlags;
88             Desc.MiscFlags = MiscFlags;
89
90             *pWidth = Desc.Width;
91             *pHeight = 1;
92             *pDepth = 1;
93
94             hr = pDevice->CreateTexture1D(&Desc, NULL, &pStagingTexture1D);
95         }
96         break;
97     case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
98         {
99             D3D11_TEXTURE2D_DESC Desc;
100             static_cast<ID3D11Texture2D *>(pResource)->GetDesc(&Desc);
101             Desc.Usage = Usage;
102             Desc.BindFlags = BindFlags;
103             Desc.CPUAccessFlags = CPUAccessFlags;
104             Desc.MiscFlags &= D3D11_RESOURCE_MISC_TEXTURECUBE;
105
106             *pWidth = Desc.Width;
107             *pHeight = Desc.Height;
108             *pDepth = 1;
109
110             hr = pDevice->CreateTexture2D(&Desc, NULL, &pStagingTexture2D);
111         }
112         break;
113     case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
114         {
115             D3D11_TEXTURE3D_DESC Desc;
116             static_cast<ID3D11Texture3D *>(pResource)->GetDesc(&Desc);
117             Desc.Usage = Usage;
118             Desc.BindFlags = BindFlags;
119             Desc.CPUAccessFlags = CPUAccessFlags;
120             Desc.MiscFlags = MiscFlags;
121
122             *pWidth = Desc.Width;
123             *pHeight = Desc.Height;
124             *pDepth = Desc.Depth;
125
126             hr = pDevice->CreateTexture3D(&Desc, NULL, &pStagingTexture3D);
127         }
128         break;
129     default:
130         assert(0);
131         hr = E_NOTIMPL;
132         break;
133     }
134
135     if (SUCCEEDED(hr)) {
136         *ppStagingResource = pStagingResource;
137         pDeviceContext->CopyResource(pStagingResource, pResource);
138     }
139     
140     pDevice->Release();
141
142     return hr;
143 }
144
145 static image::Image *
146 getRenderTargetViewImage(ID3D11DeviceContext *pDevice,
147                          ID3D11RenderTargetView *pRenderTargetView) {
148     image::Image *image = NULL;
149     D3D11_RENDER_TARGET_VIEW_DESC Desc;
150     ID3D11Resource *pResource = NULL;
151     ID3D11Resource *pStagingResource = NULL;
152     UINT Width, Height, Depth;
153     UINT MipSlice;
154     UINT Subresource;
155     D3D11_MAPPED_SUBRESOURCE MappedSubresource;
156     HRESULT hr;
157
158     if (!pRenderTargetView) {
159         return NULL;
160     }
161
162     pRenderTargetView->GetResource(&pResource);
163     assert(pResource);
164
165     pRenderTargetView->GetDesc(&Desc);
166
167     hr = stageResource(pDevice, pResource, &pStagingResource, &Width, &Height, &Depth);
168     if (FAILED(hr)) {
169         goto no_staging;
170     }
171
172     // TODO: Take the slice in consideration
173     switch (Desc.ViewDimension) {
174     case D3D11_RTV_DIMENSION_BUFFER:
175         MipSlice = 0;
176         break;
177     case D3D11_RTV_DIMENSION_TEXTURE1D:
178         MipSlice = Desc.Texture1D.MipSlice;
179         break;
180     case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
181         MipSlice = Desc.Texture1DArray.MipSlice;
182         break;
183     case D3D11_RTV_DIMENSION_TEXTURE2D:
184         MipSlice = Desc.Texture2D.MipSlice;
185         MipSlice = 0;
186         break;
187     case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
188         MipSlice = Desc.Texture2DArray.MipSlice;
189         break;
190     case D3D11_RTV_DIMENSION_TEXTURE2DMS:
191         MipSlice = 0;
192         break;
193     case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
194         MipSlice = 0;
195         break;
196     case D3D11_RTV_DIMENSION_TEXTURE3D:
197         MipSlice = Desc.Texture3D.MipSlice;
198         break;
199     case D3D11_SRV_DIMENSION_UNKNOWN:
200     default:
201         assert(0);
202         goto no_map;
203     }
204     Subresource = MipSlice;
205
206     Width  = std::max(Width  >> MipSlice, 1U);
207     Height = std::max(Height >> MipSlice, 1U);
208     Depth  = std::max(Depth  >> MipSlice, 1U);
209
210     hr = pDevice->Map(pStagingResource, Subresource, D3D11_MAP_READ, 0, &MappedSubresource);
211     if (FAILED(hr)) {
212         goto no_map;
213     }
214
215     image = ConvertImage(Desc.Format,
216                          MappedSubresource.pData,
217                          MappedSubresource.RowPitch,
218                          Width, Height);
219
220     pDevice->Unmap(pStagingResource, Subresource);
221 no_map:
222     if (pStagingResource) {
223         pStagingResource->Release();
224     }
225 no_staging:
226     if (pResource) {
227         pResource->Release();
228     }
229     return image;
230 }
231
232 static image::Image *
233 getDepthStencilViewImage(ID3D11DeviceContext *pDevice,
234                          ID3D11DepthStencilView *pDepthStencilView) {
235     image::Image *image = NULL;
236     D3D11_DEPTH_STENCIL_VIEW_DESC Desc;
237     ID3D11Resource *pResource = NULL;
238     ID3D11Resource *pStagingResource = NULL;
239     UINT Width, Height, Depth;
240     UINT MipSlice;
241     UINT Subresource;
242     D3D11_MAPPED_SUBRESOURCE MappedSubresource;
243     HRESULT hr;
244
245     if (!pDepthStencilView) {
246         return NULL;
247     }
248
249     pDepthStencilView->GetResource(&pResource);
250     assert(pResource);
251
252     pDepthStencilView->GetDesc(&Desc);
253
254     hr = stageResource(pDevice, pResource, &pStagingResource, &Width, &Height, &Depth);
255     if (FAILED(hr)) {
256         goto no_staging;
257     }
258
259     // TODO: Take the slice in consideration
260     switch (Desc.ViewDimension) {
261     case D3D11_DSV_DIMENSION_TEXTURE1D:
262         MipSlice = Desc.Texture1D.MipSlice;
263         break;
264     case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
265         MipSlice = Desc.Texture1DArray.MipSlice;
266         break;
267     case D3D11_DSV_DIMENSION_TEXTURE2D:
268         MipSlice = Desc.Texture2D.MipSlice;
269         MipSlice = 0;
270         break;
271     case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
272         MipSlice = Desc.Texture2DArray.MipSlice;
273         break;
274     case D3D11_DSV_DIMENSION_TEXTURE2DMS:
275         MipSlice = 0;
276         break;
277     case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
278         MipSlice = 0;
279         break;
280     case D3D11_SRV_DIMENSION_UNKNOWN:
281     default:
282         assert(0);
283         goto no_map;
284     }
285     Subresource = MipSlice;
286
287     Width  = std::max(Width  >> MipSlice, 1U);
288     Height = std::max(Height >> MipSlice, 1U);
289     Depth  = std::max(Depth  >> MipSlice, 1U);
290
291     hr = pDevice->Map(pStagingResource, Subresource, D3D11_MAP_READ, 0, &MappedSubresource);
292     if (FAILED(hr)) {
293         goto no_map;
294     }
295
296     image = ConvertImage(Desc.Format,
297                          MappedSubresource.pData,
298                          MappedSubresource.RowPitch,
299                          Width, Height);
300
301     pDevice->Unmap(pStagingResource, Subresource);
302 no_map:
303     if (pStagingResource) {
304         pStagingResource->Release();
305     }
306 no_staging:
307     if (pResource) {
308         pResource->Release();
309     }
310     return image;
311 }
312
313
314 image::Image *
315 getRenderTargetImage(ID3D11DeviceContext *pDevice) {
316     ID3D11RenderTargetView *pRenderTargetView = NULL;
317     pDevice->OMGetRenderTargets(1, &pRenderTargetView, NULL);
318
319     image::Image *image = NULL;
320     if (pRenderTargetView) {
321         image = getRenderTargetViewImage(pDevice, pRenderTargetView);
322         pRenderTargetView->Release();
323     }
324
325     return image;
326 }
327
328
329 void
330 dumpFramebuffer(JSONWriter &json, ID3D11DeviceContext *pDevice)
331 {
332     json.beginMember("framebuffer");
333     json.beginObject();
334
335     ID3D11RenderTargetView *pRenderTargetViews[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
336     ID3D11DepthStencilView *pDepthStencilView;
337     pDevice->OMGetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, pRenderTargetViews,
338                                 &pDepthStencilView);
339
340     for (UINT i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) {
341         if (!pRenderTargetViews[i]) {
342             continue;
343         }
344
345         image::Image *image;
346         image = getRenderTargetViewImage(pDevice, pRenderTargetViews[i]);
347         if (image) {
348             char label[64];
349             _snprintf(label, sizeof label, "RENDER_TARGET_%u", i);
350             json.beginMember(label);
351             json.writeImage(image, "UNKNOWN");
352             json.endMember(); // RENDER_TARGET_*
353         }
354
355         pRenderTargetViews[i]->Release();
356     }
357
358     if (pDepthStencilView) {
359         image::Image *image;
360         image = getDepthStencilViewImage(pDevice, pDepthStencilView);
361         if (image) {
362             json.beginMember("DEPTH_STENCIL");
363             json.writeImage(image, "UNKNOWN");
364             json.endMember();
365         }
366
367         pDepthStencilView->Release();
368
369     }
370
371     json.endObject();
372     json.endMember(); // framebuffer
373 }
374
375
376 } /* namespace d3dstate */