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 &copyFunction = 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