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