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