1 //
2 // Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // Blit11.cpp: Texture copy utility class.
8
9 #include "libANGLE/renderer/d3d/d3d11/Blit11.h"
10
11 #include <float.h>
12
13 #include "common/utilities.h"
14 #include "libANGLE/formatutils.h"
15 #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
16 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
17 #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
18 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
19 #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
20 #include "third_party/trace_event/trace_event.h"
21
22 namespace rx
23 {
24
25 namespace
26 {
27
28 // Include inline shaders in the anonymous namespace to make sure no symbols are exported
29 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h"
30 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrougha2d11ps.h"
31 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h"
32 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h"
33 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h"
34 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h"
35 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h"
36 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h"
37 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h"
38 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h"
39 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h"
40 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h"
41 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h"
42 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h"
43 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h"
44 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h"
45 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h"
46
47 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_ps.h"
48 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_ps.h"
49 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_ps.h"
50 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_ps.h"
51 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_ps.h"
52 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_ps.h"
53 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_ps.h"
54 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_ps.h"
55 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_ps.h"
56 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_ps.h"
57 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_ps.h"
58 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_ps.h"
59 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_ps.h"
60 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_ps.h"
61
62 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h"
63 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h"
64 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h"
65 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h"
66 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h"
67 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h"
68 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h"
69 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h"
70 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h"
71 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h"
72 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h"
73 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h"
74 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h"
75 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h"
76 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h"
77 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h"
78
79 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepth11_ps.h"
80 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_ps.h"
81 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_vs.h"
82 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvestencil11_ps.h"
83
84 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h"
85 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h"
86 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h"
87 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h"
88 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h"
89 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h"
90 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h"
91 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h"
92 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h"
93
StretchedBlitNearest_RowByRow(const gl::Box & sourceArea,const gl::Box & destArea,const gl::Rectangle & clippedDestArea,const gl::Extents & sourceSize,unsigned int sourceRowPitch,unsigned int destRowPitch,size_t pixelSize,const uint8_t * sourceData,uint8_t * destData)94 void StretchedBlitNearest_RowByRow(const gl::Box &sourceArea,
95 const gl::Box &destArea,
96 const gl::Rectangle &clippedDestArea,
97 const gl::Extents &sourceSize,
98 unsigned int sourceRowPitch,
99 unsigned int destRowPitch,
100 size_t pixelSize,
101 const uint8_t *sourceData,
102 uint8_t *destData)
103 {
104 int srcHeightSubOne = (sourceArea.height - 1);
105 size_t copySize = pixelSize * destArea.width;
106 size_t srcOffset = sourceArea.x * pixelSize;
107 size_t destOffset = destArea.x * pixelSize;
108
109 for (int y = clippedDestArea.y; y < clippedDestArea.y + clippedDestArea.height; y++)
110 {
111 float yPerc = static_cast<float>(y - destArea.y) / (destArea.height - 1);
112
113 // Interpolate using the original source rectangle to determine which row to sample from
114 // while clamping to the edges
115 unsigned int readRow = static_cast<unsigned int>(
116 gl::clamp(sourceArea.y + floor(yPerc * srcHeightSubOne + 0.5f), 0, srcHeightSubOne));
117 unsigned int writeRow = y;
118
119 const uint8_t *sourceRow = sourceData + readRow * sourceRowPitch + srcOffset;
120 uint8_t *destRow = destData + writeRow * destRowPitch + destOffset;
121 memcpy(destRow, sourceRow, copySize);
122 }
123 }
124
StretchedBlitNearest_PixelByPixel(const gl::Box & sourceArea,const gl::Box & destArea,const gl::Rectangle & clippedDestArea,const gl::Extents & sourceSize,unsigned int sourceRowPitch,unsigned int destRowPitch,ptrdiff_t readOffset,ptrdiff_t writeOffset,size_t copySize,size_t srcPixelStride,size_t destPixelStride,const uint8_t * sourceData,uint8_t * destData)125 void StretchedBlitNearest_PixelByPixel(const gl::Box &sourceArea,
126 const gl::Box &destArea,
127 const gl::Rectangle &clippedDestArea,
128 const gl::Extents &sourceSize,
129 unsigned int sourceRowPitch,
130 unsigned int destRowPitch,
131 ptrdiff_t readOffset,
132 ptrdiff_t writeOffset,
133 size_t copySize,
134 size_t srcPixelStride,
135 size_t destPixelStride,
136 const uint8_t *sourceData,
137 uint8_t *destData)
138 {
139 auto xMax = clippedDestArea.x + clippedDestArea.width;
140 auto yMax = clippedDestArea.y + clippedDestArea.height;
141
142 for (int writeRow = clippedDestArea.y; writeRow < yMax; writeRow++)
143 {
144 // Interpolate using the original source rectangle to determine which row to sample from
145 // while clamping to the edges
146 float yPerc = static_cast<float>(writeRow - destArea.y) / (destArea.height - 1);
147 float yRounded = floor(yPerc * (sourceArea.height - 1) + 0.5f);
148 unsigned int readRow =
149 static_cast<unsigned int>(gl::clamp(sourceArea.y + yRounded, 0, sourceSize.height - 1));
150
151 for (int writeColumn = clippedDestArea.x; writeColumn < xMax; writeColumn++)
152 {
153 // Interpolate the original source rectangle to determine which column to sample
154 // from while clamping to the edges
155 float xPerc = static_cast<float>(writeColumn - destArea.x) / (destArea.width - 1);
156 float xRounded = floor(xPerc * (sourceArea.width - 1) + 0.5f);
157 unsigned int readColumn = static_cast<unsigned int>(
158 gl::clamp(sourceArea.x + xRounded, 0, sourceSize.height - 1));
159
160 const uint8_t *sourcePixel =
161 sourceData + readRow * sourceRowPitch + readColumn * srcPixelStride + readOffset;
162
163 uint8_t *destPixel =
164 destData + writeRow * destRowPitch + writeColumn * destPixelStride + writeOffset;
165
166 memcpy(destPixel, sourcePixel, copySize);
167 }
168 }
169 }
170
StretchedBlitNearest(const gl::Box & sourceArea,const gl::Box & destArea,const gl::Rectangle & clipRect,const gl::Extents & sourceSize,unsigned int sourceRowPitch,unsigned int destRowPitch,ptrdiff_t readOffset,ptrdiff_t writeOffset,size_t copySize,size_t srcPixelStride,size_t destPixelStride,const uint8_t * sourceData,uint8_t * destData)171 void StretchedBlitNearest(const gl::Box &sourceArea,
172 const gl::Box &destArea,
173 const gl::Rectangle &clipRect,
174 const gl::Extents &sourceSize,
175 unsigned int sourceRowPitch,
176 unsigned int destRowPitch,
177 ptrdiff_t readOffset,
178 ptrdiff_t writeOffset,
179 size_t copySize,
180 size_t srcPixelStride,
181 size_t destPixelStride,
182 const uint8_t *sourceData,
183 uint8_t *destData)
184 {
185 gl::Rectangle clippedDestArea(destArea.x, destArea.y, destArea.width, destArea.height);
186 gl::ClipRectangle(clippedDestArea, clipRect, &clippedDestArea);
187
188 // Determine if entire rows can be copied at once instead of each individual pixel. There
189 // must be no out of bounds lookups, whole rows copies, and no scale.
190 if (sourceArea.width == clippedDestArea.width && sourceArea.x >= 0 &&
191 sourceArea.x + sourceArea.width <= sourceSize.width && copySize == srcPixelStride &&
192 copySize == destPixelStride)
193 {
194 StretchedBlitNearest_RowByRow(sourceArea, destArea, clippedDestArea, sourceSize,
195 sourceRowPitch, destRowPitch, srcPixelStride, sourceData,
196 destData);
197 }
198 else
199 {
200 StretchedBlitNearest_PixelByPixel(sourceArea, destArea, clippedDestArea, sourceSize,
201 sourceRowPitch, destRowPitch, readOffset, writeOffset,
202 copySize, srcPixelStride, destPixelStride, sourceData,
203 destData);
204 }
205 }
206
207 using DepthStencilLoader = void(const float *, uint8_t *);
208
LoadDepth16(const float * source,uint8_t * dest)209 void LoadDepth16(const float *source, uint8_t *dest)
210 {
211 uint32_t convertedDepth = gl::floatToNormalized<16, uint32_t>(source[0]);
212 memcpy(dest, &convertedDepth, 2u);
213 }
214
LoadDepth24(const float * source,uint8_t * dest)215 void LoadDepth24(const float *source, uint8_t *dest)
216 {
217 uint32_t convertedDepth = gl::floatToNormalized<24, uint32_t>(source[0]);
218 memcpy(dest, &convertedDepth, 3u);
219 }
220
LoadStencilHelper(const float * source,uint8_t * dest)221 void LoadStencilHelper(const float *source, uint8_t *dest)
222 {
223 uint32_t convertedStencil = gl::getShiftedData<8, 0>(static_cast<uint32_t>(source[1]));
224 memcpy(dest, &convertedStencil, 1u);
225 }
226
LoadStencil8(const float * source,uint8_t * dest)227 void LoadStencil8(const float *source, uint8_t *dest)
228 {
229 // STENCIL_INDEX8 is implemented with D24S8, with the depth bits unused. Writes zero for safety.
230 float zero = 0.0f;
231 LoadDepth24(&zero, &dest[0]);
232 LoadStencilHelper(source, &dest[3]);
233 }
234
LoadDepth24Stencil8(const float * source,uint8_t * dest)235 void LoadDepth24Stencil8(const float *source, uint8_t *dest)
236 {
237 LoadDepth24(source, &dest[0]);
238 LoadStencilHelper(source, &dest[3]);
239 }
240
LoadDepth32F(const float * source,uint8_t * dest)241 void LoadDepth32F(const float *source, uint8_t *dest)
242 {
243 memcpy(dest, source, sizeof(float));
244 }
245
LoadDepth32FStencil8(const float * source,uint8_t * dest)246 void LoadDepth32FStencil8(const float *source, uint8_t *dest)
247 {
248 LoadDepth32F(source, &dest[0]);
249 LoadStencilHelper(source, &dest[4]);
250 }
251
252 template <DepthStencilLoader loader>
CopyDepthStencil(const gl::Box & sourceArea,const gl::Box & destArea,const gl::Rectangle & clippedDestArea,const gl::Extents & sourceSize,unsigned int sourceRowPitch,unsigned int destRowPitch,ptrdiff_t readOffset,ptrdiff_t writeOffset,size_t copySize,size_t srcPixelStride,size_t destPixelStride,const uint8_t * sourceData,uint8_t * destData)253 void CopyDepthStencil(const gl::Box &sourceArea,
254 const gl::Box &destArea,
255 const gl::Rectangle &clippedDestArea,
256 const gl::Extents &sourceSize,
257 unsigned int sourceRowPitch,
258 unsigned int destRowPitch,
259 ptrdiff_t readOffset,
260 ptrdiff_t writeOffset,
261 size_t copySize,
262 size_t srcPixelStride,
263 size_t destPixelStride,
264 const uint8_t *sourceData,
265 uint8_t *destData)
266 {
267 // No stretching or subregions are supported, only full blits.
268 ASSERT(sourceArea == destArea);
269 ASSERT(sourceSize.width == sourceArea.width && sourceSize.height == sourceArea.height &&
270 sourceSize.depth == 1);
271 ASSERT(clippedDestArea.width == sourceSize.width &&
272 clippedDestArea.height == sourceSize.height);
273 ASSERT(readOffset == 0 && writeOffset == 0);
274 ASSERT(destArea.x == 0 && destArea.y == 0);
275
276 for (int row = 0; row < destArea.height; ++row)
277 {
278 for (int column = 0; column < destArea.width; ++column)
279 {
280 ptrdiff_t offset = row * sourceRowPitch + column * srcPixelStride;
281 const float *sourcePixel = reinterpret_cast<const float *>(sourceData + offset);
282
283 uint8_t *destPixel = destData + row * destRowPitch + column * destPixelStride;
284
285 loader(sourcePixel, destPixel);
286 }
287 }
288 }
289
Depth32FStencil8ToDepth32F(const float * source,float * dest)290 void Depth32FStencil8ToDepth32F(const float *source, float *dest)
291 {
292 *dest = *source;
293 }
294
Depth24Stencil8ToDepth32F(const uint32_t * source,float * dest)295 void Depth24Stencil8ToDepth32F(const uint32_t *source, float *dest)
296 {
297 uint32_t normDepth = source[0] & 0x00FFFFFF;
298 float floatDepth = gl::normalizedToFloat<24>(normDepth);
299 *dest = floatDepth;
300 }
301
BlitD24S8ToD32F(const gl::Box & sourceArea,const gl::Box & destArea,const gl::Rectangle & clippedDestArea,const gl::Extents & sourceSize,unsigned int sourceRowPitch,unsigned int destRowPitch,ptrdiff_t readOffset,ptrdiff_t writeOffset,size_t copySize,size_t srcPixelStride,size_t destPixelStride,const uint8_t * sourceData,uint8_t * destData)302 void BlitD24S8ToD32F(const gl::Box &sourceArea,
303 const gl::Box &destArea,
304 const gl::Rectangle &clippedDestArea,
305 const gl::Extents &sourceSize,
306 unsigned int sourceRowPitch,
307 unsigned int destRowPitch,
308 ptrdiff_t readOffset,
309 ptrdiff_t writeOffset,
310 size_t copySize,
311 size_t srcPixelStride,
312 size_t destPixelStride,
313 const uint8_t *sourceData,
314 uint8_t *destData)
315 {
316 // No stretching or subregions are supported, only full blits.
317 ASSERT(sourceArea == destArea);
318 ASSERT(sourceSize.width == sourceArea.width && sourceSize.height == sourceArea.height &&
319 sourceSize.depth == 1);
320 ASSERT(clippedDestArea.width == sourceSize.width &&
321 clippedDestArea.height == sourceSize.height);
322 ASSERT(readOffset == 0 && writeOffset == 0);
323 ASSERT(destArea.x == 0 && destArea.y == 0);
324
325 for (int row = 0; row < destArea.height; ++row)
326 {
327 for (int column = 0; column < destArea.width; ++column)
328 {
329 ptrdiff_t offset = row * sourceRowPitch + column * srcPixelStride;
330 const uint32_t *sourcePixel = reinterpret_cast<const uint32_t *>(sourceData + offset);
331
332 float *destPixel =
333 reinterpret_cast<float *>(destData + row * destRowPitch + column * destPixelStride);
334
335 Depth24Stencil8ToDepth32F(sourcePixel, destPixel);
336 }
337 }
338 }
339
BlitD32FS8ToD32F(const gl::Box & sourceArea,const gl::Box & destArea,const gl::Rectangle & clippedDestArea,const gl::Extents & sourceSize,unsigned int sourceRowPitch,unsigned int destRowPitch,ptrdiff_t readOffset,ptrdiff_t writeOffset,size_t copySize,size_t srcPixelStride,size_t destPixelStride,const uint8_t * sourceData,uint8_t * destData)340 void BlitD32FS8ToD32F(const gl::Box &sourceArea,
341 const gl::Box &destArea,
342 const gl::Rectangle &clippedDestArea,
343 const gl::Extents &sourceSize,
344 unsigned int sourceRowPitch,
345 unsigned int destRowPitch,
346 ptrdiff_t readOffset,
347 ptrdiff_t writeOffset,
348 size_t copySize,
349 size_t srcPixelStride,
350 size_t destPixelStride,
351 const uint8_t *sourceData,
352 uint8_t *destData)
353 {
354 // No stretching or subregions are supported, only full blits.
355 ASSERT(sourceArea == destArea);
356 ASSERT(sourceSize.width == sourceArea.width && sourceSize.height == sourceArea.height &&
357 sourceSize.depth == 1);
358 ASSERT(clippedDestArea.width == sourceSize.width &&
359 clippedDestArea.height == sourceSize.height);
360 ASSERT(readOffset == 0 && writeOffset == 0);
361 ASSERT(destArea.x == 0 && destArea.y == 0);
362
363 for (int row = 0; row < destArea.height; ++row)
364 {
365 for (int column = 0; column < destArea.width; ++column)
366 {
367 ptrdiff_t offset = row * sourceRowPitch + column * srcPixelStride;
368 const float *sourcePixel = reinterpret_cast<const float *>(sourceData + offset);
369 float *destPixel =
370 reinterpret_cast<float *>(destData + row * destRowPitch + column * destPixelStride);
371
372 Depth32FStencil8ToDepth32F(sourcePixel, destPixel);
373 }
374 }
375 }
376
GetCopyDepthStencilFunction(GLenum internalFormat)377 Blit11::BlitConvertFunction *GetCopyDepthStencilFunction(GLenum internalFormat)
378 {
379 switch (internalFormat)
380 {
381 case GL_DEPTH_COMPONENT16:
382 return &CopyDepthStencil<LoadDepth16>;
383 case GL_DEPTH_COMPONENT24:
384 return &CopyDepthStencil<LoadDepth24>;
385 case GL_DEPTH_COMPONENT32F:
386 return &CopyDepthStencil<LoadDepth32F>;
387 case GL_STENCIL_INDEX8:
388 return &CopyDepthStencil<LoadStencil8>;
389 case GL_DEPTH24_STENCIL8:
390 return &CopyDepthStencil<LoadDepth24Stencil8>;
391 case GL_DEPTH32F_STENCIL8:
392 return &CopyDepthStencil<LoadDepth32FStencil8>;
393 default:
394 UNREACHABLE();
395 return nullptr;
396 }
397 }
398
GenerateVertexCoords(const gl::Box & sourceArea,const gl::Extents & sourceSize,const gl::Box & destArea,const gl::Extents & destSize,float * x1,float * y1,float * x2,float * y2,float * u1,float * v1,float * u2,float * v2)399 inline void GenerateVertexCoords(const gl::Box &sourceArea,
400 const gl::Extents &sourceSize,
401 const gl::Box &destArea,
402 const gl::Extents &destSize,
403 float *x1,
404 float *y1,
405 float *x2,
406 float *y2,
407 float *u1,
408 float *v1,
409 float *u2,
410 float *v2)
411 {
412 *x1 = (destArea.x / float(destSize.width)) * 2.0f - 1.0f;
413 *y1 = ((destSize.height - destArea.y - destArea.height) / float(destSize.height)) * 2.0f - 1.0f;
414 *x2 = ((destArea.x + destArea.width) / float(destSize.width)) * 2.0f - 1.0f;
415 *y2 = ((destSize.height - destArea.y) / float(destSize.height)) * 2.0f - 1.0f;
416
417 *u1 = sourceArea.x / float(sourceSize.width);
418 *v1 = sourceArea.y / float(sourceSize.height);
419 *u2 = (sourceArea.x + sourceArea.width) / float(sourceSize.width);
420 *v2 = (sourceArea.y + sourceArea.height) / float(sourceSize.height);
421 }
422
Write2DVertices(const gl::Box & sourceArea,const gl::Extents & sourceSize,const gl::Box & destArea,const gl::Extents & destSize,void * outVertices,unsigned int * outStride,unsigned int * outVertexCount,D3D11_PRIMITIVE_TOPOLOGY * outTopology)423 void Write2DVertices(const gl::Box &sourceArea,
424 const gl::Extents &sourceSize,
425 const gl::Box &destArea,
426 const gl::Extents &destSize,
427 void *outVertices,
428 unsigned int *outStride,
429 unsigned int *outVertexCount,
430 D3D11_PRIMITIVE_TOPOLOGY *outTopology)
431 {
432 float x1, y1, x2, y2, u1, v1, u2, v2;
433 GenerateVertexCoords(sourceArea, sourceSize, destArea, destSize, &x1, &y1, &x2, &y2, &u1, &v1,
434 &u2, &v2);
435
436 d3d11::PositionTexCoordVertex *vertices =
437 static_cast<d3d11::PositionTexCoordVertex *>(outVertices);
438
439 d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v2);
440 d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v1);
441 d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v2);
442 d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v1);
443
444 *outStride = sizeof(d3d11::PositionTexCoordVertex);
445 *outVertexCount = 4;
446 *outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
447 }
448
Write3DVertices(const gl::Box & sourceArea,const gl::Extents & sourceSize,const gl::Box & destArea,const gl::Extents & destSize,void * outVertices,unsigned int * outStride,unsigned int * outVertexCount,D3D11_PRIMITIVE_TOPOLOGY * outTopology)449 void Write3DVertices(const gl::Box &sourceArea,
450 const gl::Extents &sourceSize,
451 const gl::Box &destArea,
452 const gl::Extents &destSize,
453 void *outVertices,
454 unsigned int *outStride,
455 unsigned int *outVertexCount,
456 D3D11_PRIMITIVE_TOPOLOGY *outTopology)
457 {
458 ASSERT(sourceSize.depth > 0 && destSize.depth > 0);
459
460 float x1, y1, x2, y2, u1, v1, u2, v2;
461 GenerateVertexCoords(sourceArea, sourceSize, destArea, destSize, &x1, &y1, &x2, &y2, &u1, &v1,
462 &u2, &v2);
463
464 d3d11::PositionLayerTexCoord3DVertex *vertices =
465 static_cast<d3d11::PositionLayerTexCoord3DVertex *>(outVertices);
466
467 for (int i = 0; i < destSize.depth; i++)
468 {
469 float readDepth = (float)i / std::max(destSize.depth - 1, 1);
470
471 d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 0], x1, y1, i, u1, v2, readDepth);
472 d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 1], x1, y2, i, u1, v1, readDepth);
473 d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 2], x2, y1, i, u2, v2, readDepth);
474
475 d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 3], x1, y2, i, u1, v1, readDepth);
476 d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 4], x2, y2, i, u2, v1, readDepth);
477 d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 5], x2, y1, i, u2, v2, readDepth);
478 }
479
480 *outStride = sizeof(d3d11::PositionLayerTexCoord3DVertex);
481 *outVertexCount = destSize.depth * 6;
482 *outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
483 }
484
GetSwizzleIndex(GLenum swizzle)485 unsigned int GetSwizzleIndex(GLenum swizzle)
486 {
487 unsigned int colorIndex = 0;
488
489 switch (swizzle)
490 {
491 case GL_RED:
492 colorIndex = 0;
493 break;
494 case GL_GREEN:
495 colorIndex = 1;
496 break;
497 case GL_BLUE:
498 colorIndex = 2;
499 break;
500 case GL_ALPHA:
501 colorIndex = 3;
502 break;
503 case GL_ZERO:
504 colorIndex = 4;
505 break;
506 case GL_ONE:
507 colorIndex = 5;
508 break;
509 default:
510 UNREACHABLE();
511 break;
512 }
513
514 return colorIndex;
515 }
516
GetAlphaMaskBlendStateDesc()517 D3D11_BLEND_DESC GetAlphaMaskBlendStateDesc()
518 {
519 D3D11_BLEND_DESC desc;
520 memset(&desc, 0, sizeof(desc));
521 desc.RenderTarget[0].BlendEnable = TRUE;
522 desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
523 desc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO;
524 desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
525 desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO;
526 desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
527 desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
528 desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_RED |
529 D3D11_COLOR_WRITE_ENABLE_GREEN |
530 D3D11_COLOR_WRITE_ENABLE_BLUE;
531 return desc;
532 }
533
534 D3D11_INPUT_ELEMENT_DESC quad2DLayout[] = {
535 {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
536 {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0},
537 };
538
539 D3D11_INPUT_ELEMENT_DESC quad3DLayout[] = {
540 {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
541 {"LAYER", 0, DXGI_FORMAT_R32_UINT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0},
542 {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
543 };
544
GetStencilSRVFormat(const d3d11::Format & formatSet)545 DXGI_FORMAT GetStencilSRVFormat(const d3d11::Format &formatSet)
546 {
547 switch (formatSet.texFormat)
548 {
549 case DXGI_FORMAT_R32G8X24_TYPELESS:
550 return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT;
551 case DXGI_FORMAT_R24G8_TYPELESS:
552 return DXGI_FORMAT_X24_TYPELESS_G8_UINT;
553 default:
554 UNREACHABLE();
555 return DXGI_FORMAT_UNKNOWN;
556 }
557 }
558
559 } // namespace
560
561 Blit11::Shader::Shader() = default;
562
563 Blit11::Shader::Shader(Shader &&other) = default;
564
565 Blit11::Shader::~Shader() = default;
566
567 Blit11::Shader &Blit11::Shader::operator=(Blit11::Shader &&other) = default;
568
Blit11(Renderer11 * renderer)569 Blit11::Blit11(Renderer11 *renderer)
570 : mRenderer(renderer),
571 mResourcesInitialized(false),
572 mVertexBuffer(),
573 mPointSampler(),
574 mLinearSampler(),
575 mScissorEnabledRasterizerState(),
576 mScissorDisabledRasterizerState(),
577 mDepthStencilState(),
578 mQuad2DIL(quad2DLayout,
579 ArraySize(quad2DLayout),
580 g_VS_Passthrough2D,
581 ArraySize(g_VS_Passthrough2D),
582 "Blit11 2D input layout"),
583 mQuad2DVS(g_VS_Passthrough2D, ArraySize(g_VS_Passthrough2D), "Blit11 2D vertex shader"),
584 mDepthPS(g_PS_PassthroughDepth2D,
585 ArraySize(g_PS_PassthroughDepth2D),
586 "Blit11 2D depth pixel shader"),
587 mQuad3DIL(quad3DLayout,
588 ArraySize(quad3DLayout),
589 g_VS_Passthrough3D,
590 ArraySize(g_VS_Passthrough3D),
591 "Blit11 3D input layout"),
592 mQuad3DVS(g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), "Blit11 3D vertex shader"),
593 mQuad3DGS(g_GS_Passthrough3D, ArraySize(g_GS_Passthrough3D), "Blit11 3D geometry shader"),
594 mAlphaMaskBlendState(GetAlphaMaskBlendStateDesc(), "Blit11 Alpha Mask Blend"),
595 mSwizzleCB(),
596 mResolveDepthStencilVS(g_VS_ResolveDepthStencil,
597 ArraySize(g_VS_ResolveDepthStencil),
598 "Blit11::mResolveDepthStencilVS"),
599 mResolveDepthPS(g_PS_ResolveDepth, ArraySize(g_PS_ResolveDepth), "Blit11::mResolveDepthPS"),
600 mResolveDepthStencilPS(g_PS_ResolveDepthStencil,
601 ArraySize(g_PS_ResolveDepthStencil),
602 "Blit11::mResolveDepthStencilPS"),
603 mResolveStencilPS(g_PS_ResolveStencil,
604 ArraySize(g_PS_ResolveStencil),
605 "Blit11::mResolveStencilPS"),
606 mStencilSRV(),
607 mResolvedDepthStencilRTView()
608 {
609 }
610
~Blit11()611 Blit11::~Blit11()
612 {
613 }
614
initResources()615 gl::Error Blit11::initResources()
616 {
617 if (mResourcesInitialized)
618 {
619 return gl::NoError();
620 }
621
622 TRACE_EVENT0("gpu.angle", "Blit11::initResources");
623
624 D3D11_BUFFER_DESC vbDesc;
625 vbDesc.ByteWidth =
626 static_cast<unsigned int>(std::max(sizeof(d3d11::PositionLayerTexCoord3DVertex),
627 sizeof(d3d11::PositionTexCoordVertex)) *
628 6 * mRenderer->getNativeCaps().max3DTextureSize);
629 vbDesc.Usage = D3D11_USAGE_DYNAMIC;
630 vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
631 vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
632 vbDesc.MiscFlags = 0;
633 vbDesc.StructureByteStride = 0;
634
635 ANGLE_TRY(mRenderer->allocateResource(vbDesc, &mVertexBuffer));
636 mVertexBuffer.setDebugName("Blit11 vertex buffer");
637
638 D3D11_SAMPLER_DESC pointSamplerDesc;
639 pointSamplerDesc.Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
640 pointSamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
641 pointSamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
642 pointSamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
643 pointSamplerDesc.MipLODBias = 0.0f;
644 pointSamplerDesc.MaxAnisotropy = 0;
645 pointSamplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
646 pointSamplerDesc.BorderColor[0] = 0.0f;
647 pointSamplerDesc.BorderColor[1] = 0.0f;
648 pointSamplerDesc.BorderColor[2] = 0.0f;
649 pointSamplerDesc.BorderColor[3] = 0.0f;
650 pointSamplerDesc.MinLOD = 0.0f;
651 pointSamplerDesc.MaxLOD = FLT_MAX;
652
653 ANGLE_TRY(mRenderer->allocateResource(pointSamplerDesc, &mPointSampler));
654 mPointSampler.setDebugName("Blit11 point sampler");
655
656 D3D11_SAMPLER_DESC linearSamplerDesc;
657 linearSamplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
658 linearSamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
659 linearSamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
660 linearSamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
661 linearSamplerDesc.MipLODBias = 0.0f;
662 linearSamplerDesc.MaxAnisotropy = 0;
663 linearSamplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
664 linearSamplerDesc.BorderColor[0] = 0.0f;
665 linearSamplerDesc.BorderColor[1] = 0.0f;
666 linearSamplerDesc.BorderColor[2] = 0.0f;
667 linearSamplerDesc.BorderColor[3] = 0.0f;
668 linearSamplerDesc.MinLOD = 0.0f;
669 linearSamplerDesc.MaxLOD = FLT_MAX;
670
671 ANGLE_TRY(mRenderer->allocateResource(linearSamplerDesc, &mLinearSampler));
672 mLinearSampler.setDebugName("Blit11 linear sampler");
673
674 // Use a rasterizer state that will not cull so that inverted quads will not be culled
675 D3D11_RASTERIZER_DESC rasterDesc;
676 rasterDesc.FillMode = D3D11_FILL_SOLID;
677 rasterDesc.CullMode = D3D11_CULL_NONE;
678 rasterDesc.FrontCounterClockwise = FALSE;
679 rasterDesc.DepthBias = 0;
680 rasterDesc.SlopeScaledDepthBias = 0.0f;
681 rasterDesc.DepthBiasClamp = 0.0f;
682 rasterDesc.DepthClipEnable = TRUE;
683 rasterDesc.MultisampleEnable = FALSE;
684 rasterDesc.AntialiasedLineEnable = FALSE;
685
686 rasterDesc.ScissorEnable = TRUE;
687 ANGLE_TRY(mRenderer->allocateResource(rasterDesc, &mScissorEnabledRasterizerState));
688 mScissorEnabledRasterizerState.setDebugName("Blit11 scissoring rasterizer state");
689
690 rasterDesc.ScissorEnable = FALSE;
691 ANGLE_TRY(mRenderer->allocateResource(rasterDesc, &mScissorDisabledRasterizerState));
692 mScissorDisabledRasterizerState.setDebugName("Blit11 no scissoring rasterizer state");
693
694 D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
695 depthStencilDesc.DepthEnable = TRUE;
696 depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
697 depthStencilDesc.DepthFunc = D3D11_COMPARISON_ALWAYS;
698 depthStencilDesc.StencilEnable = FALSE;
699 depthStencilDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
700 depthStencilDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
701 depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
702 depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
703 depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
704 depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
705 depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
706 depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
707 depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
708 depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
709
710 ANGLE_TRY(mRenderer->allocateResource(depthStencilDesc, &mDepthStencilState));
711 mDepthStencilState.setDebugName("Blit11 depth stencil state");
712
713 D3D11_BUFFER_DESC swizzleBufferDesc;
714 swizzleBufferDesc.ByteWidth = sizeof(unsigned int) * 4;
715 swizzleBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
716 swizzleBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
717 swizzleBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
718 swizzleBufferDesc.MiscFlags = 0;
719 swizzleBufferDesc.StructureByteStride = 0;
720
721 ANGLE_TRY(mRenderer->allocateResource(swizzleBufferDesc, &mSwizzleCB));
722 mSwizzleCB.setDebugName("Blit11 swizzle constant buffer");
723
724 mResourcesInitialized = true;
725
726 return gl::NoError();
727 }
728
729 // static
GetBlitShaderType(GLenum destinationFormat,GLenum sourceFormat,bool isSigned,bool unpackPremultiplyAlpha,bool unpackUnmultiplyAlpha,ShaderDimension dimension)730 Blit11::BlitShaderType Blit11::GetBlitShaderType(GLenum destinationFormat,
731 GLenum sourceFormat,
732 bool isSigned,
733 bool unpackPremultiplyAlpha,
734 bool unpackUnmultiplyAlpha,
735 ShaderDimension dimension)
736 {
737 if (dimension == SHADER_3D)
738 {
739 ASSERT(!unpackPremultiplyAlpha && !unpackUnmultiplyAlpha);
740
741 if (isSigned)
742 {
743 switch (destinationFormat)
744 {
745 case GL_RGBA_INTEGER:
746 return BLITSHADER_3D_RGBAI;
747 case GL_RGB_INTEGER:
748 return BLITSHADER_3D_RGBI;
749 case GL_RG_INTEGER:
750 return BLITSHADER_3D_RGI;
751 case GL_RED_INTEGER:
752 return BLITSHADER_3D_RI;
753 default:
754 UNREACHABLE();
755 return BLITSHADER_INVALID;
756 }
757 }
758 else
759 {
760 switch (destinationFormat)
761 {
762 case GL_RGBA:
763 return BLITSHADER_3D_RGBAF;
764 case GL_RGBA_INTEGER:
765 return BLITSHADER_3D_RGBAUI;
766 case GL_BGRA_EXT:
767 return BLITSHADER_3D_BGRAF;
768 case GL_RGB:
769 return BLITSHADER_3D_RGBF;
770 case GL_RGB_INTEGER:
771 return BLITSHADER_3D_RGBUI;
772 case GL_RG:
773 return BLITSHADER_3D_RGF;
774 case GL_RG_INTEGER:
775 return BLITSHADER_3D_RGUI;
776 case GL_RED:
777 return BLITSHADER_3D_RF;
778 case GL_RED_INTEGER:
779 return BLITSHADER_3D_RUI;
780 case GL_ALPHA:
781 return BLITSHADER_3D_ALPHA;
782 case GL_LUMINANCE:
783 return BLITSHADER_3D_LUMA;
784 case GL_LUMINANCE_ALPHA:
785 return BLITSHADER_3D_LUMAALPHA;
786 default:
787 UNREACHABLE();
788 return BLITSHADER_INVALID;
789 }
790 }
791 }
792 else if (isSigned)
793 {
794 ASSERT(!unpackPremultiplyAlpha && !unpackUnmultiplyAlpha);
795
796 switch (destinationFormat)
797 {
798 case GL_RGBA_INTEGER:
799 return BLITSHADER_2D_RGBAI;
800 case GL_RGB_INTEGER:
801 return BLITSHADER_2D_RGBI;
802 case GL_RG_INTEGER:
803 return BLITSHADER_2D_RGI;
804 case GL_RED_INTEGER:
805 return BLITSHADER_2D_RI;
806 default:
807 UNREACHABLE();
808 return BLITSHADER_INVALID;
809 }
810 }
811 else
812 {
813 bool floatToIntBlit =
814 !gl::IsIntegerFormat(sourceFormat) && gl::IsIntegerFormat(destinationFormat);
815 if (unpackPremultiplyAlpha != unpackUnmultiplyAlpha || floatToIntBlit)
816 {
817 switch (destinationFormat)
818 {
819 case GL_RGBA:
820 case GL_BGRA_EXT:
821 ASSERT(!floatToIntBlit);
822 return unpackPremultiplyAlpha ? BLITSHADER_2D_RGBAF_PREMULTIPLY
823 : BLITSHADER_2D_RGBAF_UNMULTIPLY;
824
825 case GL_RGB:
826 case GL_RG:
827 case GL_RED:
828 ASSERT(!floatToIntBlit);
829 return unpackPremultiplyAlpha ? BLITSHADER_2D_RGBF_PREMULTIPLY
830 : BLITSHADER_2D_RGBF_UNMULTIPLY;
831
832 case GL_RGBA_INTEGER:
833 if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha)
834 {
835 return BLITSHADER_2D_RGBAF_TOUI;
836 }
837 else
838 {
839 return unpackPremultiplyAlpha ? BLITSHADER_2D_RGBAF_TOUI_PREMULTIPLY
840 : BLITSHADER_2D_RGBAF_TOUI_UNMULTIPLY;
841 }
842
843 case GL_RGB_INTEGER:
844 case GL_RG_INTEGER:
845 case GL_RED_INTEGER:
846 if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha)
847 {
848 return BLITSHADER_2D_RGBF_TOUI;
849 }
850 else
851 {
852 return unpackPremultiplyAlpha ? BLITSHADER_2D_RGBF_TOUI_PREMULTIPLY
853 : BLITSHADER_2D_RGBF_TOUI_UNMULTIPLY;
854 }
855 case GL_LUMINANCE:
856 ASSERT(!floatToIntBlit);
857 return unpackPremultiplyAlpha ? BLITSHADER_2D_LUMAF_PREMULTIPLY
858 : BLITSHADER_2D_LUMAF_UNMULTIPLY;
859 case GL_LUMINANCE_ALPHA:
860 ASSERT(!floatToIntBlit);
861 return unpackPremultiplyAlpha ? BLITSHADER_2D_LUMAALPHAF_PREMULTIPLY
862 : BLITSHADER_2D_LUMAALPHAF_UNMULTIPLY;
863 case GL_ALPHA:
864 ASSERT(!floatToIntBlit);
865 return BLITSHADER_2D_ALPHA;
866 default:
867 UNREACHABLE();
868 return BLITSHADER_INVALID;
869 }
870 }
871 else
872 {
873 switch (destinationFormat)
874 {
875 case GL_RGBA:
876 return BLITSHADER_2D_RGBAF;
877 case GL_RGBA_INTEGER:
878 return BLITSHADER_2D_RGBAUI;
879 case GL_BGRA_EXT:
880 return BLITSHADER_2D_BGRAF;
881 case GL_RGB:
882 return BLITSHADER_2D_RGBF;
883 case GL_RGB_INTEGER:
884 return BLITSHADER_2D_RGBUI;
885 case GL_RG:
886 return BLITSHADER_2D_RGF;
887 case GL_RG_INTEGER:
888 return BLITSHADER_2D_RGUI;
889 case GL_RED:
890 return BLITSHADER_2D_RF;
891 case GL_RED_INTEGER:
892 return BLITSHADER_2D_RUI;
893 case GL_ALPHA:
894 return BLITSHADER_2D_ALPHA;
895 case GL_LUMINANCE:
896 return BLITSHADER_2D_LUMA;
897 case GL_LUMINANCE_ALPHA:
898 return BLITSHADER_2D_LUMAALPHA;
899 default:
900 UNREACHABLE();
901 return BLITSHADER_INVALID;
902 }
903 }
904 }
905 }
906
907 // static
GetSwizzleShaderType(GLenum type,D3D11_SRV_DIMENSION dimensionality)908 Blit11::SwizzleShaderType Blit11::GetSwizzleShaderType(GLenum type,
909 D3D11_SRV_DIMENSION dimensionality)
910 {
911 switch (dimensionality)
912 {
913 case D3D11_SRV_DIMENSION_TEXTURE2D:
914 switch (type)
915 {
916 case GL_FLOAT:
917 return SWIZZLESHADER_2D_FLOAT;
918 case GL_UNSIGNED_INT:
919 return SWIZZLESHADER_2D_UINT;
920 case GL_INT:
921 return SWIZZLESHADER_2D_INT;
922 default:
923 UNREACHABLE();
924 return SWIZZLESHADER_INVALID;
925 }
926 case D3D11_SRV_DIMENSION_TEXTURECUBE:
927 switch (type)
928 {
929 case GL_FLOAT:
930 return SWIZZLESHADER_CUBE_FLOAT;
931 case GL_UNSIGNED_INT:
932 return SWIZZLESHADER_CUBE_UINT;
933 case GL_INT:
934 return SWIZZLESHADER_CUBE_INT;
935 default:
936 UNREACHABLE();
937 return SWIZZLESHADER_INVALID;
938 }
939 case D3D11_SRV_DIMENSION_TEXTURE3D:
940 switch (type)
941 {
942 case GL_FLOAT:
943 return SWIZZLESHADER_3D_FLOAT;
944 case GL_UNSIGNED_INT:
945 return SWIZZLESHADER_3D_UINT;
946 case GL_INT:
947 return SWIZZLESHADER_3D_INT;
948 default:
949 UNREACHABLE();
950 return SWIZZLESHADER_INVALID;
951 }
952 case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
953 switch (type)
954 {
955 case GL_FLOAT:
956 return SWIZZLESHADER_ARRAY_FLOAT;
957 case GL_UNSIGNED_INT:
958 return SWIZZLESHADER_ARRAY_UINT;
959 case GL_INT:
960 return SWIZZLESHADER_ARRAY_INT;
961 default:
962 UNREACHABLE();
963 return SWIZZLESHADER_INVALID;
964 }
965 default:
966 UNREACHABLE();
967 return SWIZZLESHADER_INVALID;
968 }
969 }
970
getShaderSupport(const Shader & shader,Blit11::ShaderSupport * supportOut)971 gl::Error Blit11::getShaderSupport(const Shader &shader, Blit11::ShaderSupport *supportOut)
972 {
973 if (shader.dimension == SHADER_2D)
974 {
975 ANGLE_TRY(mQuad2DIL.resolve(mRenderer));
976 ANGLE_TRY(mQuad2DVS.resolve(mRenderer));
977 supportOut->inputLayout = &mQuad2DIL.getObj();
978 supportOut->vertexShader = &mQuad2DVS.getObj();
979 supportOut->geometryShader = nullptr;
980 supportOut->vertexWriteFunction = Write2DVertices;
981 }
982 else
983 {
984 ASSERT(shader.dimension == SHADER_3D);
985 ANGLE_TRY(mQuad3DIL.resolve(mRenderer));
986 ANGLE_TRY(mQuad3DVS.resolve(mRenderer));
987 ANGLE_TRY(mQuad3DGS.resolve(mRenderer));
988 supportOut->inputLayout = &mQuad2DIL.getObj();
989 supportOut->vertexShader = &mQuad3DVS.getObj();
990 supportOut->geometryShader = &mQuad3DGS.getObj();
991 supportOut->vertexWriteFunction = Write3DVertices;
992 }
993
994 return gl::NoError();
995 }
996
swizzleTexture(const gl::Context * context,const d3d11::SharedSRV & source,const d3d11::RenderTargetView & dest,const gl::Extents & size,const gl::SwizzleState & swizzleTarget)997 gl::Error Blit11::swizzleTexture(const gl::Context *context,
998 const d3d11::SharedSRV &source,
999 const d3d11::RenderTargetView &dest,
1000 const gl::Extents &size,
1001 const gl::SwizzleState &swizzleTarget)
1002 {
1003 ANGLE_TRY(initResources());
1004
1005 HRESULT result;
1006 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
1007
1008 D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc;
1009 source.get()->GetDesc(&sourceSRVDesc);
1010
1011 GLenum componentType = d3d11::GetComponentType(sourceSRVDesc.Format);
1012 if (componentType == GL_NONE)
1013 {
1014 // We're swizzling the depth component of a depth-stencil texture.
1015 switch (sourceSRVDesc.Format)
1016 {
1017 case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
1018 componentType = GL_UNSIGNED_NORMALIZED;
1019 break;
1020 case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
1021 componentType = GL_FLOAT;
1022 break;
1023 default:
1024 UNREACHABLE();
1025 break;
1026 }
1027 }
1028
1029 GLenum shaderType = GL_NONE;
1030 switch (componentType)
1031 {
1032 case GL_UNSIGNED_NORMALIZED:
1033 case GL_SIGNED_NORMALIZED:
1034 case GL_FLOAT:
1035 shaderType = GL_FLOAT;
1036 break;
1037 case GL_INT:
1038 shaderType = GL_INT;
1039 break;
1040 case GL_UNSIGNED_INT:
1041 shaderType = GL_UNSIGNED_INT;
1042 break;
1043 default:
1044 UNREACHABLE();
1045 break;
1046 }
1047
1048 const Shader *shader = nullptr;
1049 ANGLE_TRY(getSwizzleShader(shaderType, sourceSRVDesc.ViewDimension, &shader));
1050
1051 // Set vertices
1052 D3D11_MAPPED_SUBRESOURCE mappedResource;
1053 result =
1054 deviceContext->Map(mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
1055 if (FAILED(result))
1056 {
1057 return gl::OutOfMemory() << "Failed to map internal vertex buffer for swizzle, "
1058 << gl::FmtHR(result);
1059 }
1060
1061 ShaderSupport support;
1062 ANGLE_TRY(getShaderSupport(*shader, &support));
1063
1064 UINT stride = 0;
1065 UINT drawCount = 0;
1066 D3D11_PRIMITIVE_TOPOLOGY topology;
1067
1068 gl::Box area(0, 0, 0, size.width, size.height, size.depth);
1069 support.vertexWriteFunction(area, size, area, size, mappedResource.pData, &stride, &drawCount,
1070 &topology);
1071
1072 deviceContext->Unmap(mVertexBuffer.get(), 0);
1073
1074 // Set constant buffer
1075 result = deviceContext->Map(mSwizzleCB.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
1076 if (FAILED(result))
1077 {
1078 return gl::OutOfMemory() << "Failed to map internal constant buffer for swizzle, "
1079 << gl::FmtHR(result);
1080 }
1081
1082 unsigned int *swizzleIndices = reinterpret_cast<unsigned int *>(mappedResource.pData);
1083 swizzleIndices[0] = GetSwizzleIndex(swizzleTarget.swizzleRed);
1084 swizzleIndices[1] = GetSwizzleIndex(swizzleTarget.swizzleGreen);
1085 swizzleIndices[2] = GetSwizzleIndex(swizzleTarget.swizzleBlue);
1086 swizzleIndices[3] = GetSwizzleIndex(swizzleTarget.swizzleAlpha);
1087
1088 deviceContext->Unmap(mSwizzleCB.get(), 0);
1089
1090 StateManager11 *stateManager = mRenderer->getStateManager();
1091
1092 // Apply vertex buffer
1093 stateManager->setSingleVertexBuffer(&mVertexBuffer, stride, 0);
1094
1095 // Apply constant buffer
1096 stateManager->setPixelConstantBuffer(0, &mSwizzleCB);
1097
1098 // Apply state
1099 stateManager->setSimpleBlendState(nullptr);
1100 stateManager->setDepthStencilState(nullptr, 0xFFFFFFFF);
1101 stateManager->setRasterizerState(&mScissorDisabledRasterizerState);
1102
1103 // Apply shaders
1104 stateManager->setInputLayout(support.inputLayout);
1105 stateManager->setPrimitiveTopology(topology);
1106
1107 stateManager->setDrawShaders(support.vertexShader, support.geometryShader,
1108 &shader->pixelShader);
1109
1110 // Apply render target
1111 stateManager->setRenderTarget(dest.get(), nullptr);
1112
1113 // Set the viewport
1114 stateManager->setSimpleViewport(size);
1115
1116 // Apply textures and sampler
1117 stateManager->setSimplePixelTextureAndSampler(source, mPointSampler);
1118
1119 // Draw the quad
1120 deviceContext->Draw(drawCount, 0);
1121
1122 return gl::NoError();
1123 }
1124
copyTexture(const gl::Context * context,const d3d11::SharedSRV & source,const gl::Box & sourceArea,const gl::Extents & sourceSize,GLenum sourceFormat,const d3d11::RenderTargetView & dest,const gl::Box & destArea,const gl::Extents & destSize,const gl::Rectangle * scissor,GLenum destFormat,GLenum filter,bool maskOffAlpha,bool unpackPremultiplyAlpha,bool unpackUnmultiplyAlpha)1125 gl::Error Blit11::copyTexture(const gl::Context *context,
1126 const d3d11::SharedSRV &source,
1127 const gl::Box &sourceArea,
1128 const gl::Extents &sourceSize,
1129 GLenum sourceFormat,
1130 const d3d11::RenderTargetView &dest,
1131 const gl::Box &destArea,
1132 const gl::Extents &destSize,
1133 const gl::Rectangle *scissor,
1134 GLenum destFormat,
1135 GLenum filter,
1136 bool maskOffAlpha,
1137 bool unpackPremultiplyAlpha,
1138 bool unpackUnmultiplyAlpha)
1139 {
1140 ANGLE_TRY(initResources());
1141
1142 HRESULT result;
1143 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
1144
1145 // Determine if the source format is a signed integer format, the destFormat will already
1146 // be GL_XXXX_INTEGER but it does not tell us if it is signed or unsigned.
1147 D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc;
1148 source.get()->GetDesc(&sourceSRVDesc);
1149
1150 GLenum componentType = d3d11::GetComponentType(sourceSRVDesc.Format);
1151
1152 ASSERT(componentType != GL_NONE);
1153 ASSERT(componentType != GL_SIGNED_NORMALIZED);
1154 bool isSigned = (componentType == GL_INT);
1155
1156 ShaderDimension dimension =
1157 (sourceSRVDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE3D) ? SHADER_3D : SHADER_2D;
1158
1159 const Shader *shader = nullptr;
1160 ANGLE_TRY(getBlitShader(destFormat, sourceFormat, isSigned, unpackPremultiplyAlpha,
1161 unpackUnmultiplyAlpha, dimension, &shader));
1162
1163 ShaderSupport support;
1164 ANGLE_TRY(getShaderSupport(*shader, &support));
1165
1166 // Set vertices
1167 D3D11_MAPPED_SUBRESOURCE mappedResource;
1168 result =
1169 deviceContext->Map(mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
1170 if (FAILED(result))
1171 {
1172 return gl::OutOfMemory() << "Failed to map internal vertex buffer for texture copy, "
1173 << gl::FmtHR(result);
1174 }
1175
1176 UINT stride = 0;
1177 UINT drawCount = 0;
1178 D3D11_PRIMITIVE_TOPOLOGY topology;
1179
1180 support.vertexWriteFunction(sourceArea, sourceSize, destArea, destSize, mappedResource.pData,
1181 &stride, &drawCount, &topology);
1182
1183 deviceContext->Unmap(mVertexBuffer.get(), 0);
1184
1185 StateManager11 *stateManager = mRenderer->getStateManager();
1186
1187 // Apply vertex buffer
1188 stateManager->setSingleVertexBuffer(&mVertexBuffer, stride, 0);
1189
1190 // Apply state
1191 if (maskOffAlpha)
1192 {
1193 ANGLE_TRY(mAlphaMaskBlendState.resolve(mRenderer));
1194 stateManager->setSimpleBlendState(&mAlphaMaskBlendState.getObj());
1195 }
1196 else
1197 {
1198 stateManager->setSimpleBlendState(nullptr);
1199 }
1200 stateManager->setDepthStencilState(nullptr, 0xFFFFFFFF);
1201
1202 if (scissor)
1203 {
1204 stateManager->setSimpleScissorRect(*scissor);
1205 stateManager->setRasterizerState(&mScissorEnabledRasterizerState);
1206 }
1207 else
1208 {
1209 stateManager->setRasterizerState(&mScissorDisabledRasterizerState);
1210 }
1211
1212 // Apply shaders
1213 stateManager->setInputLayout(support.inputLayout);
1214 stateManager->setPrimitiveTopology(topology);
1215
1216 stateManager->setDrawShaders(support.vertexShader, support.geometryShader,
1217 &shader->pixelShader);
1218
1219 // Apply render target
1220 stateManager->setRenderTarget(dest.get(), nullptr);
1221
1222 // Set the viewport
1223 stateManager->setSimpleViewport(destSize);
1224
1225 // Apply texture and sampler
1226 switch (filter)
1227 {
1228 case GL_NEAREST:
1229 stateManager->setSimplePixelTextureAndSampler(source, mPointSampler);
1230 break;
1231 case GL_LINEAR:
1232 stateManager->setSimplePixelTextureAndSampler(source, mLinearSampler);
1233 break;
1234
1235 default:
1236 UNREACHABLE();
1237 return gl::InternalError() << "Internal error, unknown blit filter mode.";
1238 }
1239
1240 // Draw the quad
1241 deviceContext->Draw(drawCount, 0);
1242
1243 return gl::NoError();
1244 }
1245
copyStencil(const gl::Context * context,const TextureHelper11 & source,unsigned int sourceSubresource,const gl::Box & sourceArea,const gl::Extents & sourceSize,const TextureHelper11 & dest,unsigned int destSubresource,const gl::Box & destArea,const gl::Extents & destSize,const gl::Rectangle * scissor)1246 gl::Error Blit11::copyStencil(const gl::Context *context,
1247 const TextureHelper11 &source,
1248 unsigned int sourceSubresource,
1249 const gl::Box &sourceArea,
1250 const gl::Extents &sourceSize,
1251 const TextureHelper11 &dest,
1252 unsigned int destSubresource,
1253 const gl::Box &destArea,
1254 const gl::Extents &destSize,
1255 const gl::Rectangle *scissor)
1256 {
1257 return copyDepthStencilImpl(source, sourceSubresource, sourceArea, sourceSize, dest,
1258 destSubresource, destArea, destSize, scissor, true);
1259 }
1260
copyDepth(const gl::Context * context,const d3d11::SharedSRV & source,const gl::Box & sourceArea,const gl::Extents & sourceSize,const d3d11::DepthStencilView & dest,const gl::Box & destArea,const gl::Extents & destSize,const gl::Rectangle * scissor)1261 gl::Error Blit11::copyDepth(const gl::Context *context,
1262 const d3d11::SharedSRV &source,
1263 const gl::Box &sourceArea,
1264 const gl::Extents &sourceSize,
1265 const d3d11::DepthStencilView &dest,
1266 const gl::Box &destArea,
1267 const gl::Extents &destSize,
1268 const gl::Rectangle *scissor)
1269 {
1270 ANGLE_TRY(initResources());
1271
1272 HRESULT result;
1273 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
1274
1275 // Set vertices
1276 D3D11_MAPPED_SUBRESOURCE mappedResource;
1277 result =
1278 deviceContext->Map(mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
1279 if (FAILED(result))
1280 {
1281 return gl::OutOfMemory() << "Failed to map internal vertex buffer for texture copy, "
1282 << gl::FmtHR(result);
1283 }
1284
1285 UINT stride = 0;
1286 UINT drawCount = 0;
1287 D3D11_PRIMITIVE_TOPOLOGY topology;
1288
1289 Write2DVertices(sourceArea, sourceSize, destArea, destSize, mappedResource.pData, &stride,
1290 &drawCount, &topology);
1291
1292 deviceContext->Unmap(mVertexBuffer.get(), 0);
1293
1294 StateManager11 *stateManager = mRenderer->getStateManager();
1295
1296 // Apply vertex buffer
1297 stateManager->setSingleVertexBuffer(&mVertexBuffer, stride, 0);
1298
1299 // Apply state
1300 stateManager->setSimpleBlendState(nullptr);
1301 stateManager->setDepthStencilState(&mDepthStencilState, 0xFFFFFFFF);
1302
1303 if (scissor)
1304 {
1305 stateManager->setSimpleScissorRect(*scissor);
1306 stateManager->setRasterizerState(&mScissorEnabledRasterizerState);
1307 }
1308 else
1309 {
1310 stateManager->setRasterizerState(&mScissorDisabledRasterizerState);
1311 }
1312
1313 ANGLE_TRY(mQuad2DIL.resolve(mRenderer));
1314 ANGLE_TRY(mQuad2DVS.resolve(mRenderer));
1315 ANGLE_TRY(mDepthPS.resolve(mRenderer));
1316
1317 // Apply shaders
1318 stateManager->setInputLayout(&mQuad2DIL.getObj());
1319 stateManager->setPrimitiveTopology(topology);
1320
1321 stateManager->setDrawShaders(&mQuad2DVS.getObj(), nullptr, &mDepthPS.getObj());
1322
1323 // Apply render target
1324 stateManager->setRenderTarget(nullptr, dest.get());
1325
1326 // Set the viewport
1327 stateManager->setSimpleViewport(destSize);
1328
1329 // Apply texture and sampler
1330 stateManager->setSimplePixelTextureAndSampler(source, mPointSampler);
1331
1332 // Draw the quad
1333 deviceContext->Draw(drawCount, 0);
1334
1335 return gl::NoError();
1336 }
1337
copyDepthStencil(const TextureHelper11 & source,unsigned int sourceSubresource,const gl::Box & sourceArea,const gl::Extents & sourceSize,const TextureHelper11 & dest,unsigned int destSubresource,const gl::Box & destArea,const gl::Extents & destSize,const gl::Rectangle * scissor)1338 gl::Error Blit11::copyDepthStencil(const TextureHelper11 &source,
1339 unsigned int sourceSubresource,
1340 const gl::Box &sourceArea,
1341 const gl::Extents &sourceSize,
1342 const TextureHelper11 &dest,
1343 unsigned int destSubresource,
1344 const gl::Box &destArea,
1345 const gl::Extents &destSize,
1346 const gl::Rectangle *scissor)
1347 {
1348 return copyDepthStencilImpl(source, sourceSubresource, sourceArea, sourceSize, dest,
1349 destSubresource, destArea, destSize, scissor, false);
1350 }
1351
copyDepthStencilImpl(const TextureHelper11 & source,unsigned int sourceSubresource,const gl::Box & sourceArea,const gl::Extents & sourceSize,const TextureHelper11 & dest,unsigned int destSubresource,const gl::Box & destArea,const gl::Extents & destSize,const gl::Rectangle * scissor,bool stencilOnly)1352 gl::Error Blit11::copyDepthStencilImpl(const TextureHelper11 &source,
1353 unsigned int sourceSubresource,
1354 const gl::Box &sourceArea,
1355 const gl::Extents &sourceSize,
1356 const TextureHelper11 &dest,
1357 unsigned int destSubresource,
1358 const gl::Box &destArea,
1359 const gl::Extents &destSize,
1360 const gl::Rectangle *scissor,
1361 bool stencilOnly)
1362 {
1363 auto srcDXGIFormat = source.getFormat();
1364 const auto &srcSizeInfo = d3d11::GetDXGIFormatSizeInfo(srcDXGIFormat);
1365 unsigned int srcPixelSize = srcSizeInfo.pixelBytes;
1366 unsigned int copyOffset = 0;
1367 unsigned int copySize = srcPixelSize;
1368 auto destDXGIFormat = dest.getFormat();
1369 const auto &destSizeInfo = d3d11::GetDXGIFormatSizeInfo(destDXGIFormat);
1370 unsigned int destPixelSize = destSizeInfo.pixelBytes;
1371
1372 ASSERT(srcDXGIFormat == destDXGIFormat || destDXGIFormat == DXGI_FORMAT_R32_TYPELESS);
1373
1374 if (stencilOnly)
1375 {
1376 const auto &srcFormat = source.getFormatSet().format();
1377
1378 // Stencil channel should be right after the depth channel. Some views to depth/stencil
1379 // resources have red channel for depth, in which case the depth channel bit width is in
1380 // redBits.
1381 ASSERT((srcFormat.redBits != 0) != (srcFormat.depthBits != 0));
1382 GLuint depthBits = srcFormat.redBits + srcFormat.depthBits;
1383 // Known formats have either 24 or 32 bits of depth.
1384 ASSERT(depthBits == 24 || depthBits == 32);
1385 copyOffset = depthBits / 8;
1386
1387 // Stencil is assumed to be 8-bit - currently this is true for all possible formats.
1388 copySize = 1;
1389 }
1390
1391 if (srcDXGIFormat != destDXGIFormat)
1392 {
1393 if (srcDXGIFormat == DXGI_FORMAT_R24G8_TYPELESS)
1394 {
1395 ASSERT(sourceArea == destArea && sourceSize == destSize && scissor == nullptr);
1396 return copyAndConvert(source, sourceSubresource, sourceArea, sourceSize, dest,
1397 destSubresource, destArea, destSize, scissor, copyOffset,
1398 copyOffset, copySize, srcPixelSize, destPixelSize,
1399 BlitD24S8ToD32F);
1400 }
1401 ASSERT(srcDXGIFormat == DXGI_FORMAT_R32G8X24_TYPELESS);
1402 return copyAndConvert(source, sourceSubresource, sourceArea, sourceSize, dest,
1403 destSubresource, destArea, destSize, scissor, copyOffset, copyOffset,
1404 copySize, srcPixelSize, destPixelSize, BlitD32FS8ToD32F);
1405 }
1406
1407 return copyAndConvert(source, sourceSubresource, sourceArea, sourceSize, dest, destSubresource,
1408 destArea, destSize, scissor, copyOffset, copyOffset, copySize,
1409 srcPixelSize, destPixelSize, StretchedBlitNearest);
1410 }
1411
copyAndConvertImpl(const TextureHelper11 & source,unsigned int sourceSubresource,const gl::Box & sourceArea,const gl::Extents & sourceSize,const TextureHelper11 & destStaging,const gl::Box & destArea,const gl::Extents & destSize,const gl::Rectangle * scissor,size_t readOffset,size_t writeOffset,size_t copySize,size_t srcPixelStride,size_t destPixelStride,BlitConvertFunction * convertFunction)1412 gl::Error Blit11::copyAndConvertImpl(const TextureHelper11 &source,
1413 unsigned int sourceSubresource,
1414 const gl::Box &sourceArea,
1415 const gl::Extents &sourceSize,
1416 const TextureHelper11 &destStaging,
1417 const gl::Box &destArea,
1418 const gl::Extents &destSize,
1419 const gl::Rectangle *scissor,
1420 size_t readOffset,
1421 size_t writeOffset,
1422 size_t copySize,
1423 size_t srcPixelStride,
1424 size_t destPixelStride,
1425 BlitConvertFunction *convertFunction)
1426 {
1427 ANGLE_TRY(initResources());
1428
1429 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
1430
1431 TextureHelper11 sourceStaging;
1432 ANGLE_TRY_RESULT(mRenderer->createStagingTexture(ResourceType::Texture2D, source.getFormatSet(),
1433 sourceSize, StagingAccess::READ),
1434 sourceStaging);
1435
1436 deviceContext->CopySubresourceRegion(sourceStaging.get(), 0, 0, 0, 0, source.get(),
1437 sourceSubresource, nullptr);
1438
1439 D3D11_MAPPED_SUBRESOURCE sourceMapping;
1440 HRESULT result = deviceContext->Map(sourceStaging.get(), 0, D3D11_MAP_READ, 0, &sourceMapping);
1441 if (FAILED(result))
1442 {
1443 return gl::OutOfMemory()
1444 << "Failed to map internal source staging texture for depth stencil blit, "
1445 << gl::FmtHR(result);
1446 }
1447
1448 D3D11_MAPPED_SUBRESOURCE destMapping;
1449 result = deviceContext->Map(destStaging.get(), 0, D3D11_MAP_WRITE, 0, &destMapping);
1450 if (FAILED(result))
1451 {
1452 deviceContext->Unmap(sourceStaging.get(), 0);
1453 return gl::OutOfMemory()
1454 << "Failed to map internal destination staging texture for depth stencil blit, "
1455 << gl::FmtHR(result);
1456 }
1457
1458 // Clip dest area to the destination size
1459 gl::Rectangle clipRect = gl::Rectangle(0, 0, destSize.width, destSize.height);
1460
1461 // Clip dest area to the scissor
1462 if (scissor)
1463 {
1464 gl::ClipRectangle(clipRect, *scissor, &clipRect);
1465 }
1466
1467 convertFunction(sourceArea, destArea, clipRect, sourceSize, sourceMapping.RowPitch,
1468 destMapping.RowPitch, readOffset, writeOffset, copySize, srcPixelStride,
1469 destPixelStride, static_cast<const uint8_t *>(sourceMapping.pData),
1470 static_cast<uint8_t *>(destMapping.pData));
1471
1472 deviceContext->Unmap(sourceStaging.get(), 0);
1473 deviceContext->Unmap(destStaging.get(), 0);
1474
1475 return gl::NoError();
1476 }
1477
copyAndConvert(const TextureHelper11 & source,unsigned int sourceSubresource,const gl::Box & sourceArea,const gl::Extents & sourceSize,const TextureHelper11 & dest,unsigned int destSubresource,const gl::Box & destArea,const gl::Extents & destSize,const gl::Rectangle * scissor,size_t readOffset,size_t writeOffset,size_t copySize,size_t srcPixelStride,size_t destPixelStride,BlitConvertFunction * convertFunction)1478 gl::Error Blit11::copyAndConvert(const TextureHelper11 &source,
1479 unsigned int sourceSubresource,
1480 const gl::Box &sourceArea,
1481 const gl::Extents &sourceSize,
1482 const TextureHelper11 &dest,
1483 unsigned int destSubresource,
1484 const gl::Box &destArea,
1485 const gl::Extents &destSize,
1486 const gl::Rectangle *scissor,
1487 size_t readOffset,
1488 size_t writeOffset,
1489 size_t copySize,
1490 size_t srcPixelStride,
1491 size_t destPixelStride,
1492 BlitConvertFunction *convertFunction)
1493 {
1494 ANGLE_TRY(initResources());
1495
1496 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
1497
1498 // HACK: Create the destination staging buffer as a read/write texture so
1499 // ID3D11DevicContext::UpdateSubresource can be called
1500 // using it's mapped data as a source
1501 TextureHelper11 destStaging;
1502 ANGLE_TRY_RESULT(mRenderer->createStagingTexture(ResourceType::Texture2D, dest.getFormatSet(),
1503 destSize, StagingAccess::READ_WRITE),
1504 destStaging);
1505
1506 deviceContext->CopySubresourceRegion(destStaging.get(), 0, 0, 0, 0, dest.get(), destSubresource,
1507 nullptr);
1508
1509 ANGLE_TRY(copyAndConvertImpl(source, sourceSubresource, sourceArea, sourceSize, destStaging,
1510 destArea, destSize, scissor, readOffset, writeOffset, copySize,
1511 srcPixelStride, destPixelStride, convertFunction));
1512
1513 // Work around timeouts/TDRs in older NVIDIA drivers.
1514 if (mRenderer->getWorkarounds().depthStencilBlitExtraCopy)
1515 {
1516 D3D11_MAPPED_SUBRESOURCE mapped;
1517 deviceContext->Map(destStaging.get(), 0, D3D11_MAP_READ, 0, &mapped);
1518 deviceContext->UpdateSubresource(dest.get(), destSubresource, nullptr, mapped.pData,
1519 mapped.RowPitch, mapped.DepthPitch);
1520 deviceContext->Unmap(destStaging.get(), 0);
1521 }
1522 else
1523 {
1524 deviceContext->CopySubresourceRegion(dest.get(), destSubresource, 0, 0, 0,
1525 destStaging.get(), 0, nullptr);
1526 }
1527
1528 return gl::NoError();
1529 }
1530
addBlitShaderToMap(BlitShaderType blitShaderType,ShaderDimension dimension,const ShaderData & shaderData,const char * name)1531 gl::Error Blit11::addBlitShaderToMap(BlitShaderType blitShaderType,
1532 ShaderDimension dimension,
1533 const ShaderData &shaderData,
1534 const char *name)
1535 {
1536 ASSERT(mBlitShaderMap.find(blitShaderType) == mBlitShaderMap.end());
1537
1538 d3d11::PixelShader ps;
1539 ANGLE_TRY(mRenderer->allocateResource(shaderData, &ps));
1540 ps.setDebugName(name);
1541
1542 Shader shader;
1543 shader.dimension = dimension;
1544 shader.pixelShader = std::move(ps);
1545
1546 mBlitShaderMap[blitShaderType] = std::move(shader);
1547 return gl::NoError();
1548 }
1549
addSwizzleShaderToMap(SwizzleShaderType swizzleShaderType,ShaderDimension dimension,const ShaderData & shaderData,const char * name)1550 gl::Error Blit11::addSwizzleShaderToMap(SwizzleShaderType swizzleShaderType,
1551 ShaderDimension dimension,
1552 const ShaderData &shaderData,
1553 const char *name)
1554 {
1555 ASSERT(mSwizzleShaderMap.find(swizzleShaderType) == mSwizzleShaderMap.end());
1556
1557 d3d11::PixelShader ps;
1558 ANGLE_TRY(mRenderer->allocateResource(shaderData, &ps));
1559 ps.setDebugName(name);
1560
1561 Shader shader;
1562 shader.dimension = dimension;
1563 shader.pixelShader = std::move(ps);
1564
1565 mSwizzleShaderMap[swizzleShaderType] = std::move(shader);
1566 return gl::NoError();
1567 }
1568
clearShaderMap()1569 void Blit11::clearShaderMap()
1570 {
1571 mBlitShaderMap.clear();
1572 mSwizzleShaderMap.clear();
1573 }
1574
getBlitShader(GLenum destFormat,GLenum sourceFormat,bool isSigned,bool unpackPremultiplyAlpha,bool unpackUnmultiplyAlpha,ShaderDimension dimension,const Shader ** shader)1575 gl::Error Blit11::getBlitShader(GLenum destFormat,
1576 GLenum sourceFormat,
1577 bool isSigned,
1578 bool unpackPremultiplyAlpha,
1579 bool unpackUnmultiplyAlpha,
1580 ShaderDimension dimension,
1581 const Shader **shader)
1582 {
1583 BlitShaderType blitShaderType =
1584 GetBlitShaderType(destFormat, sourceFormat, isSigned, unpackPremultiplyAlpha,
1585 unpackUnmultiplyAlpha, dimension);
1586
1587 if (blitShaderType == BLITSHADER_INVALID)
1588 {
1589 return gl::InternalError() << "Internal blit shader type mismatch";
1590 }
1591
1592 auto blitShaderIt = mBlitShaderMap.find(blitShaderType);
1593 if (blitShaderIt != mBlitShaderMap.end())
1594 {
1595 *shader = &blitShaderIt->second;
1596 return gl::NoError();
1597 }
1598
1599 ASSERT(dimension == SHADER_2D || mRenderer->isES3Capable());
1600
1601 switch (blitShaderType)
1602 {
1603 case BLITSHADER_2D_RGBAF:
1604 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D,
1605 ShaderData(g_PS_PassthroughRGBA2D),
1606 "Blit11 2D RGBA pixel shader"));
1607 break;
1608 case BLITSHADER_2D_BGRAF:
1609 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D,
1610 ShaderData(g_PS_PassthroughRGBA2D),
1611 "Blit11 2D BGRA pixel shader"));
1612 break;
1613 case BLITSHADER_2D_RGBF:
1614 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D,
1615 ShaderData(g_PS_PassthroughRGB2D),
1616 "Blit11 2D RGB pixel shader"));
1617 break;
1618 case BLITSHADER_2D_RGF:
1619 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D,
1620 ShaderData(g_PS_PassthroughRG2D),
1621 "Blit11 2D RG pixel shader"));
1622 break;
1623 case BLITSHADER_2D_RF:
1624 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_PassthroughR2D),
1625 "Blit11 2D R pixel shader"));
1626 break;
1627 case BLITSHADER_2D_ALPHA:
1628 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_PassthroughA2D),
1629 "Blit11 2D alpha pixel shader"));
1630 break;
1631 case BLITSHADER_2D_LUMA:
1632 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D,
1633 ShaderData(g_PS_PassthroughLum2D),
1634 "Blit11 2D lum pixel shader"));
1635 break;
1636 case BLITSHADER_2D_LUMAALPHA:
1637 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D,
1638 ShaderData(g_PS_PassthroughLumAlpha2D),
1639 "Blit11 2D luminance alpha pixel shader"));
1640 break;
1641 case BLITSHADER_2D_RGBAUI:
1642 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D,
1643 ShaderData(g_PS_PassthroughRGBA2DUI),
1644 "Blit11 2D RGBA UI pixel shader"));
1645 break;
1646 case BLITSHADER_2D_RGBAI:
1647 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D,
1648 ShaderData(g_PS_PassthroughRGBA2DI),
1649 "Blit11 2D RGBA I pixel shader"));
1650 break;
1651 case BLITSHADER_2D_RGBUI:
1652 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D,
1653 ShaderData(g_PS_PassthroughRGB2DUI),
1654 "Blit11 2D RGB UI pixel shader"));
1655 break;
1656 case BLITSHADER_2D_RGBI:
1657 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D,
1658 ShaderData(g_PS_PassthroughRGB2DI),
1659 "Blit11 2D RGB I pixel shader"));
1660 break;
1661 case BLITSHADER_2D_RGUI:
1662 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D,
1663 ShaderData(g_PS_PassthroughRG2DUI),
1664 "Blit11 2D RG UI pixel shader"));
1665 break;
1666 case BLITSHADER_2D_RGI:
1667 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D,
1668 ShaderData(g_PS_PassthroughRG2DI),
1669 "Blit11 2D RG I pixel shader"));
1670 break;
1671 case BLITSHADER_2D_RUI:
1672 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D,
1673 ShaderData(g_PS_PassthroughR2DUI),
1674 "Blit11 2D R UI pixel shader"));
1675 break;
1676 case BLITSHADER_2D_RI:
1677 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D,
1678 ShaderData(g_PS_PassthroughR2DI),
1679 "Blit11 2D R I pixel shader"));
1680 break;
1681 case BLITSHADER_3D_RGBAF:
1682 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D,
1683 ShaderData(g_PS_PassthroughRGBA3D),
1684 "Blit11 3D RGBA pixel shader"));
1685 break;
1686 case BLITSHADER_3D_RGBAUI:
1687 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D,
1688 ShaderData(g_PS_PassthroughRGBA3DUI),
1689 "Blit11 3D UI RGBA pixel shader"));
1690 break;
1691 case BLITSHADER_3D_RGBAI:
1692 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D,
1693 ShaderData(g_PS_PassthroughRGBA3DI),
1694 "Blit11 3D I RGBA pixel shader"));
1695 break;
1696 case BLITSHADER_3D_BGRAF:
1697 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D,
1698 ShaderData(g_PS_PassthroughRGBA3D),
1699 "Blit11 3D BGRA pixel shader"));
1700 break;
1701 case BLITSHADER_3D_RGBF:
1702 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D,
1703 ShaderData(g_PS_PassthroughRGB3D),
1704 "Blit11 3D RGB pixel shader"));
1705 break;
1706 case BLITSHADER_3D_RGBUI:
1707 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D,
1708 ShaderData(g_PS_PassthroughRGB3DUI),
1709 "Blit11 3D RGB UI pixel shader"));
1710 break;
1711 case BLITSHADER_3D_RGBI:
1712 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D,
1713 ShaderData(g_PS_PassthroughRGB3DI),
1714 "Blit11 3D RGB I pixel shader"));
1715 break;
1716 case BLITSHADER_3D_RGF:
1717 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D,
1718 ShaderData(g_PS_PassthroughRG3D),
1719 "Blit11 3D RG pixel shader"));
1720 break;
1721 case BLITSHADER_3D_RGUI:
1722 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D,
1723 ShaderData(g_PS_PassthroughRG3DUI),
1724 "Blit11 3D RG UI pixel shader"));
1725 break;
1726 case BLITSHADER_3D_RGI:
1727 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D,
1728 ShaderData(g_PS_PassthroughRG3DI),
1729 "Blit11 3D RG I pixel shader"));
1730 break;
1731 case BLITSHADER_3D_RF:
1732 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D, ShaderData(g_PS_PassthroughR3D),
1733 "Blit11 3D R pixel shader"));
1734 break;
1735 case BLITSHADER_3D_RUI:
1736 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D,
1737 ShaderData(g_PS_PassthroughR3DUI),
1738 "Blit11 3D R UI pixel shader"));
1739 break;
1740 case BLITSHADER_3D_RI:
1741 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D,
1742 ShaderData(g_PS_PassthroughR3DI),
1743 "Blit11 3D R I pixel shader"));
1744 break;
1745 case BLITSHADER_3D_ALPHA:
1746 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D,
1747 ShaderData(g_PS_PassthroughRGBA3D),
1748 "Blit11 3D alpha pixel shader"));
1749 break;
1750 case BLITSHADER_3D_LUMA:
1751 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D,
1752 ShaderData(g_PS_PassthroughLum3D),
1753 "Blit11 3D luminance pixel shader"));
1754 break;
1755 case BLITSHADER_3D_LUMAALPHA:
1756 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D,
1757 ShaderData(g_PS_PassthroughLumAlpha3D),
1758 "Blit11 3D luminance alpha pixel shader"));
1759 break;
1760
1761 case BLITSHADER_2D_RGBAF_PREMULTIPLY:
1762 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoF_PM_RGBA),
1763 "Blit11 2D RGBA premultiply pixel shader"));
1764 break;
1765
1766 case BLITSHADER_2D_RGBAF_UNMULTIPLY:
1767 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoF_UM_RGBA),
1768 "Blit11 2D RGBA unmultiply pixel shader"));
1769 break;
1770
1771 case BLITSHADER_2D_RGBF_PREMULTIPLY:
1772 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoF_PM_RGB),
1773 "Blit11 2D RGB premultiply pixel shader"));
1774 break;
1775
1776 case BLITSHADER_2D_RGBF_UNMULTIPLY:
1777 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoF_UM_RGB),
1778 "Blit11 2D RGB unmultiply pixel shader"));
1779 break;
1780
1781 case BLITSHADER_2D_RGBAF_TOUI:
1782 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoU_PT_RGBA),
1783 "Blit11 2D RGBA to uint pixel shader"));
1784 break;
1785
1786 case BLITSHADER_2D_RGBAF_TOUI_PREMULTIPLY:
1787 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoU_PM_RGBA),
1788 "Blit11 2D RGBA to uint premultiply pixel shader"));
1789 break;
1790
1791 case BLITSHADER_2D_RGBAF_TOUI_UNMULTIPLY:
1792 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoU_UM_RGBA),
1793 "Blit11 2D RGBA to uint unmultiply pixel shader"));
1794 break;
1795
1796 case BLITSHADER_2D_RGBF_TOUI:
1797 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoU_PT_RGB),
1798 "Blit11 2D RGB to uint pixel shader"));
1799 break;
1800
1801 case BLITSHADER_2D_RGBF_TOUI_PREMULTIPLY:
1802 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoU_PM_RGB),
1803 "Blit11 2D RGB to uint premultiply pixel shader"));
1804 break;
1805
1806 case BLITSHADER_2D_RGBF_TOUI_UNMULTIPLY:
1807 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoU_UM_RGB),
1808 "Blit11 2D RGB to uint unmultiply pixel shader"));
1809 break;
1810 case BLITSHADER_2D_LUMAF_PREMULTIPLY:
1811 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoF_PM_LUMA),
1812 "Blit11 2D LUMA premultiply pixel shader"));
1813 break;
1814 case BLITSHADER_2D_LUMAF_UNMULTIPLY:
1815 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoF_UM_LUMA),
1816 "Blit11 2D LUMA unmultiply pixel shader"));
1817 break;
1818 case BLITSHADER_2D_LUMAALPHAF_PREMULTIPLY:
1819 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D,
1820 ShaderData(g_PS_FtoF_PM_LUMAALPHA),
1821 "Blit11 2D LUMAALPHA premultiply pixel shader"));
1822 break;
1823 case BLITSHADER_2D_LUMAALPHAF_UNMULTIPLY:
1824 ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D,
1825 ShaderData(g_PS_FtoF_UM_LUMAALPHA),
1826 "Blit11 2D LUMAALPHA unmultiply pixel shader"));
1827 break;
1828
1829 default:
1830 UNREACHABLE();
1831 return gl::InternalError() << "Internal error";
1832 }
1833
1834 blitShaderIt = mBlitShaderMap.find(blitShaderType);
1835 ASSERT(blitShaderIt != mBlitShaderMap.end());
1836 *shader = &blitShaderIt->second;
1837 return gl::NoError();
1838 }
1839
getSwizzleShader(GLenum type,D3D11_SRV_DIMENSION viewDimension,const Shader ** shader)1840 gl::Error Blit11::getSwizzleShader(GLenum type,
1841 D3D11_SRV_DIMENSION viewDimension,
1842 const Shader **shader)
1843 {
1844 SwizzleShaderType swizzleShaderType = GetSwizzleShaderType(type, viewDimension);
1845
1846 if (swizzleShaderType == SWIZZLESHADER_INVALID)
1847 {
1848 return gl::InternalError() << "Swizzle shader type not found";
1849 }
1850
1851 auto swizzleShaderIt = mSwizzleShaderMap.find(swizzleShaderType);
1852 if (swizzleShaderIt != mSwizzleShaderMap.end())
1853 {
1854 *shader = &swizzleShaderIt->second;
1855 return gl::NoError();
1856 }
1857
1858 // Swizzling shaders (OpenGL ES 3+)
1859 ASSERT(mRenderer->isES3Capable());
1860
1861 switch (swizzleShaderType)
1862 {
1863 case SWIZZLESHADER_2D_FLOAT:
1864 ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_2D,
1865 ShaderData(g_PS_SwizzleF2D),
1866 "Blit11 2D F swizzle pixel shader"));
1867 break;
1868 case SWIZZLESHADER_2D_UINT:
1869 ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_2D,
1870 ShaderData(g_PS_SwizzleUI2D),
1871 "Blit11 2D UI swizzle pixel shader"));
1872 break;
1873 case SWIZZLESHADER_2D_INT:
1874 ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_2D,
1875 ShaderData(g_PS_SwizzleI2D),
1876 "Blit11 2D I swizzle pixel shader"));
1877 break;
1878 case SWIZZLESHADER_CUBE_FLOAT:
1879 ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_3D,
1880 ShaderData(g_PS_SwizzleF2DArray),
1881 "Blit11 2D Cube F swizzle pixel shader"));
1882 break;
1883 case SWIZZLESHADER_CUBE_UINT:
1884 ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_3D,
1885 ShaderData(g_PS_SwizzleUI2DArray),
1886 "Blit11 2D Cube UI swizzle pixel shader"));
1887 break;
1888 case SWIZZLESHADER_CUBE_INT:
1889 ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_3D,
1890 ShaderData(g_PS_SwizzleI2DArray),
1891 "Blit11 2D Cube I swizzle pixel shader"));
1892 break;
1893 case SWIZZLESHADER_3D_FLOAT:
1894 ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_3D,
1895 ShaderData(g_PS_SwizzleF3D),
1896 "Blit11 3D F swizzle pixel shader"));
1897 break;
1898 case SWIZZLESHADER_3D_UINT:
1899 ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_3D,
1900 ShaderData(g_PS_SwizzleUI3D),
1901 "Blit11 3D UI swizzle pixel shader"));
1902 break;
1903 case SWIZZLESHADER_3D_INT:
1904 ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_3D,
1905 ShaderData(g_PS_SwizzleI3D),
1906 "Blit11 3D I swizzle pixel shader"));
1907 break;
1908 case SWIZZLESHADER_ARRAY_FLOAT:
1909 ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_3D,
1910 ShaderData(g_PS_SwizzleF2DArray),
1911 "Blit11 2D Array F swizzle pixel shader"));
1912 break;
1913 case SWIZZLESHADER_ARRAY_UINT:
1914 ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_3D,
1915 ShaderData(g_PS_SwizzleUI2DArray),
1916 "Blit11 2D Array UI swizzle pixel shader"));
1917 break;
1918 case SWIZZLESHADER_ARRAY_INT:
1919 ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_3D,
1920 ShaderData(g_PS_SwizzleI2DArray),
1921 "Blit11 2D Array I swizzle pixel shader"));
1922 break;
1923 default:
1924 UNREACHABLE();
1925 return gl::InternalError() << "Internal error";
1926 }
1927
1928 swizzleShaderIt = mSwizzleShaderMap.find(swizzleShaderType);
1929 ASSERT(swizzleShaderIt != mSwizzleShaderMap.end());
1930 *shader = &swizzleShaderIt->second;
1931 return gl::NoError();
1932 }
1933
resolveDepth(const gl::Context * context,RenderTarget11 * depth)1934 gl::ErrorOrResult<TextureHelper11> Blit11::resolveDepth(const gl::Context *context,
1935 RenderTarget11 *depth)
1936 {
1937 ANGLE_TRY(initResources());
1938
1939 // Multisampled depth stencil SRVs are not available in feature level 10.0
1940 ASSERT(mRenderer->getRenderer11DeviceCaps().featureLevel > D3D_FEATURE_LEVEL_10_0);
1941
1942 const auto &extents = depth->getExtents();
1943 auto *deviceContext = mRenderer->getDeviceContext();
1944 auto *stateManager = mRenderer->getStateManager();
1945
1946 ANGLE_TRY(initResolveDepthOnly(depth->getFormatSet(), extents));
1947
1948 ANGLE_TRY(mResolveDepthStencilVS.resolve(mRenderer));
1949 ANGLE_TRY(mResolveDepthPS.resolve(mRenderer));
1950
1951 // Apply the necessary state changes to the D3D11 immediate device context.
1952 stateManager->setInputLayout(nullptr);
1953 stateManager->setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
1954 stateManager->setDrawShaders(&mResolveDepthStencilVS.getObj(), nullptr,
1955 &mResolveDepthPS.getObj());
1956 stateManager->setRasterizerState(nullptr);
1957 stateManager->setDepthStencilState(&mDepthStencilState, 0xFFFFFFFF);
1958 stateManager->setRenderTargets(nullptr, 0, mResolvedDepthDSView.get());
1959 stateManager->setSimpleBlendState(nullptr);
1960 stateManager->setSimpleViewport(extents);
1961
1962 // Set the viewport
1963 stateManager->setShaderResourceShared(gl::SAMPLER_PIXEL, 0, &depth->getShaderResourceView());
1964
1965 // Trigger the blit on the GPU.
1966 deviceContext->Draw(6, 0);
1967
1968 return mResolvedDepth;
1969 }
1970
initResolveDepthOnly(const d3d11::Format & format,const gl::Extents & extents)1971 gl::Error Blit11::initResolveDepthOnly(const d3d11::Format &format, const gl::Extents &extents)
1972 {
1973 if (mResolvedDepth.valid() && extents == mResolvedDepth.getExtents() &&
1974 format.texFormat == mResolvedDepth.getFormat())
1975 {
1976 return gl::NoError();
1977 }
1978
1979 D3D11_TEXTURE2D_DESC textureDesc;
1980 textureDesc.Width = extents.width;
1981 textureDesc.Height = extents.height;
1982 textureDesc.MipLevels = 1;
1983 textureDesc.ArraySize = 1;
1984 textureDesc.Format = format.texFormat;
1985 textureDesc.SampleDesc.Count = 1;
1986 textureDesc.SampleDesc.Quality = 0;
1987 textureDesc.Usage = D3D11_USAGE_DEFAULT;
1988 textureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
1989 textureDesc.CPUAccessFlags = 0;
1990 textureDesc.MiscFlags = 0;
1991
1992 ANGLE_TRY(mRenderer->allocateTexture(textureDesc, format, &mResolvedDepth));
1993 mResolvedDepth.setDebugName("Blit11::mResolvedDepth");
1994
1995 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
1996 dsvDesc.Flags = 0;
1997 dsvDesc.Format = format.dsvFormat;
1998 dsvDesc.Texture2D.MipSlice = 0;
1999 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
2000
2001 ANGLE_TRY(mRenderer->allocateResource(dsvDesc, mResolvedDepth.get(), &mResolvedDepthDSView));
2002 mResolvedDepthDSView.setDebugName("Blit11::mResolvedDepthDSView");
2003
2004 // Possibly D3D11 bug or undefined behaviour: Clear the DSV so that our first render
2005 // works as expected. Otherwise the results of the first use seem to be incorrect.
2006 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
2007 context->ClearDepthStencilView(mResolvedDepthDSView.get(), D3D11_CLEAR_DEPTH, 1.0f, 0);
2008
2009 return gl::NoError();
2010 }
2011
initResolveDepthStencil(const gl::Extents & extents)2012 gl::Error Blit11::initResolveDepthStencil(const gl::Extents &extents)
2013 {
2014 // Check if we need to recreate depth stencil view
2015 if (mResolvedDepthStencil.valid() && extents == mResolvedDepthStencil.getExtents())
2016 {
2017 ASSERT(mResolvedDepthStencil.getFormat() == DXGI_FORMAT_R32G32_FLOAT);
2018 return gl::NoError();
2019 }
2020
2021 if (mResolvedDepthStencil.valid())
2022 {
2023 releaseResolveDepthStencilResources();
2024 }
2025
2026 const auto &formatSet = d3d11::Format::Get(GL_RG32F, mRenderer->getRenderer11DeviceCaps());
2027
2028 D3D11_TEXTURE2D_DESC textureDesc;
2029 textureDesc.Width = extents.width;
2030 textureDesc.Height = extents.height;
2031 textureDesc.MipLevels = 1;
2032 textureDesc.ArraySize = 1;
2033 textureDesc.Format = formatSet.texFormat;
2034 textureDesc.SampleDesc.Count = 1;
2035 textureDesc.SampleDesc.Quality = 0;
2036 textureDesc.Usage = D3D11_USAGE_DEFAULT;
2037 textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET;
2038 textureDesc.CPUAccessFlags = 0;
2039 textureDesc.MiscFlags = 0;
2040
2041 ANGLE_TRY(mRenderer->allocateTexture(textureDesc, formatSet, &mResolvedDepthStencil));
2042 mResolvedDepthStencil.setDebugName("Blit11::mResolvedDepthStencil");
2043
2044 ANGLE_TRY(mRenderer->allocateResourceNoDesc(mResolvedDepthStencil.get(),
2045 &mResolvedDepthStencilRTView));
2046 mResolvedDepthStencilRTView.setDebugName("Blit11::mResolvedDepthStencilRTView");
2047
2048 return gl::NoError();
2049 }
2050
resolveStencil(const gl::Context * context,RenderTarget11 * depthStencil,bool alsoDepth)2051 gl::ErrorOrResult<TextureHelper11> Blit11::resolveStencil(const gl::Context *context,
2052 RenderTarget11 *depthStencil,
2053 bool alsoDepth)
2054 {
2055 ANGLE_TRY(initResources());
2056
2057 // Multisampled depth stencil SRVs are not available in feature level 10.0
2058 ASSERT(mRenderer->getRenderer11DeviceCaps().featureLevel > D3D_FEATURE_LEVEL_10_0);
2059
2060 const auto &extents = depthStencil->getExtents();
2061
2062 ANGLE_TRY(initResolveDepthStencil(extents));
2063
2064 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
2065 auto *stateManager = mRenderer->getStateManager();
2066 ID3D11Resource *stencilResource = depthStencil->getTexture().get();
2067
2068 // Check if we need to re-create the stencil SRV.
2069 if (mStencilSRV.valid())
2070 {
2071 ID3D11Resource *priorResource = nullptr;
2072 mStencilSRV.get()->GetResource(&priorResource);
2073
2074 if (stencilResource != priorResource)
2075 {
2076 mStencilSRV.reset();
2077 }
2078
2079 SafeRelease(priorResource);
2080 }
2081
2082 if (!mStencilSRV.valid())
2083 {
2084 D3D11_SHADER_RESOURCE_VIEW_DESC srViewDesc;
2085 srViewDesc.Format = GetStencilSRVFormat(depthStencil->getFormatSet());
2086 srViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
2087
2088 ANGLE_TRY(mRenderer->allocateResource(srViewDesc, stencilResource, &mStencilSRV));
2089 mStencilSRV.setDebugName("Blit11::mStencilSRV");
2090 }
2091
2092 // Notify the Renderer that all state should be invalidated.
2093 ANGLE_TRY(mResolveDepthStencilVS.resolve(mRenderer));
2094
2095 // Resolving the depth buffer works by sampling the depth in the shader using a SRV, then
2096 // writing to the resolved depth buffer using SV_Depth. We can't use this method for stencil
2097 // because SV_StencilRef isn't supported until HLSL 5.1/D3D11.3.
2098 const d3d11::PixelShader *pixelShader = nullptr;
2099 if (alsoDepth)
2100 {
2101 ANGLE_TRY(mResolveDepthStencilPS.resolve(mRenderer));
2102 pixelShader = &mResolveDepthStencilPS.getObj();
2103 }
2104 else
2105 {
2106 ANGLE_TRY(mResolveStencilPS.resolve(mRenderer));
2107 pixelShader = &mResolveStencilPS.getObj();
2108 }
2109
2110 // Apply the necessary state changes to the D3D11 immediate device context.
2111 stateManager->setInputLayout(nullptr);
2112 stateManager->setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
2113 stateManager->setDrawShaders(&mResolveDepthStencilVS.getObj(), nullptr, pixelShader);
2114 stateManager->setRasterizerState(nullptr);
2115 stateManager->setDepthStencilState(nullptr, 0xFFFFFFFF);
2116 stateManager->setRenderTarget(mResolvedDepthStencilRTView.get(), nullptr);
2117 stateManager->setSimpleBlendState(nullptr);
2118
2119 // Set the viewport
2120 stateManager->setSimpleViewport(extents);
2121 stateManager->setShaderResourceShared(gl::SAMPLER_PIXEL, 0,
2122 &depthStencil->getShaderResourceView());
2123 stateManager->setShaderResource(gl::SAMPLER_PIXEL, 1, &mStencilSRV);
2124
2125 // Trigger the blit on the GPU.
2126 deviceContext->Draw(6, 0);
2127
2128 gl::Box copyBox(0, 0, 0, extents.width, extents.height, 1);
2129
2130 TextureHelper11 dest;
2131 ANGLE_TRY_RESULT(
2132 mRenderer->createStagingTexture(ResourceType::Texture2D, depthStencil->getFormatSet(),
2133 extents, StagingAccess::READ_WRITE),
2134 dest);
2135
2136 const auto ©Function = GetCopyDepthStencilFunction(depthStencil->getInternalFormat());
2137 const auto &dsFormatSet = depthStencil->getFormatSet();
2138 const auto &dsDxgiInfo = d3d11::GetDXGIFormatSizeInfo(dsFormatSet.texFormat);
2139
2140 ANGLE_TRY(copyAndConvertImpl(mResolvedDepthStencil, 0, copyBox, extents, dest, copyBox, extents,
2141 nullptr, 0, 0, 0, 8u, dsDxgiInfo.pixelBytes, copyFunction));
2142
2143 // Return the resolved depth texture, which the caller must Release.
2144 return dest;
2145 }
2146
releaseResolveDepthStencilResources()2147 void Blit11::releaseResolveDepthStencilResources()
2148 {
2149 mStencilSRV.reset();
2150 mResolvedDepthStencilRTView.reset();
2151 }
2152
2153 } // namespace rx
2154