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