Blit11.cpp (79423B)
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 52 void StretchedBlitNearest_RowByRow(const gl::Box &sourceArea, 53 const gl::Box &destArea, 54 const gl::Rectangle &clippedDestArea, 55 const gl::Extents &sourceSize, 56 unsigned int sourceRowPitch, 57 unsigned int destRowPitch, 58 size_t pixelSize, 59 const uint8_t *sourceData, 60 uint8_t *destData) 61 { 62 int srcHeightSubOne = (sourceArea.height - 1); 63 size_t copySize = pixelSize * clippedDestArea.width; 64 size_t srcOffset = sourceArea.x * pixelSize; 65 size_t destOffset = clippedDestArea.x * pixelSize; 66 67 for (int y = clippedDestArea.y; y < clippedDestArea.y + clippedDestArea.height; y++) 68 { 69 // TODO: Fix divide by zero when height == 1. http://anglebug.com/6099 70 float yPerc = static_cast<float>(y - destArea.y) / (destArea.height - 1); 71 72 // Interpolate using the original source rectangle to determine which row to sample from 73 // while clamping to the edges 74 unsigned int readRow = static_cast<unsigned int>( 75 gl::clamp(sourceArea.y + floor(yPerc * srcHeightSubOne + 0.5f), 0, srcHeightSubOne)); 76 unsigned int writeRow = y; 77 78 const uint8_t *sourceRow = sourceData + readRow * sourceRowPitch + srcOffset; 79 uint8_t *destRow = destData + writeRow * destRowPitch + destOffset; 80 memcpy(destRow, sourceRow, copySize); 81 } 82 } 83 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 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 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 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 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 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 197 void LoadDepth24Stencil8(const float *source, uint8_t *dest) 198 { 199 LoadDepth24(source, &dest[0]); 200 LoadStencilHelper(source, &dest[3]); 201 } 202 203 void LoadDepth32F(const float *source, uint8_t *dest) 204 { 205 memcpy(dest, source, sizeof(float)); 206 } 207 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> 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 252 void Depth32FStencil8ToDepth32F(const float *source, float *dest) 253 { 254 *dest = *source; 255 } 256 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 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 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 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 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 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 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 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 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 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 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 574 Blit11::~Blit11() {} 575 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 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 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 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 912 angle::Result Blit11::copyTexture(const gl::Context *context, 913 const d3d11::SharedSRV &source, 914 const gl::Box &sourceArea, 915 const gl::Extents &sourceSize, 916 GLenum sourceFormat, 917 const d3d11::RenderTargetView &dest, 918 const gl::Box &destArea, 919 const gl::Extents &destSize, 920 const gl::Rectangle *scissor, 921 GLenum destFormat, 922 GLenum destTypeForDownsampling, 923 GLenum filter, 924 bool maskOffAlpha, 925 bool unpackPremultiplyAlpha, 926 bool unpackUnmultiplyAlpha) 927 { 928 ANGLE_TRY(initResources(context)); 929 930 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); 931 932 // Determine if the source format is a signed integer format, the destFormat will already 933 // be GL_XXXX_INTEGER but it does not tell us if it is signed or unsigned. 934 D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc; 935 source.get()->GetDesc(&sourceSRVDesc); 936 937 GLenum componentType = d3d11::GetComponentType(sourceSRVDesc.Format); 938 939 ASSERT(componentType != GL_NONE); 940 ASSERT(componentType != GL_SIGNED_NORMALIZED); 941 bool isSrcSigned = (componentType == GL_INT); 942 943 D3D11_RENDER_TARGET_VIEW_DESC destRTVDesc; 944 dest.get()->GetDesc(&destRTVDesc); 945 946 GLenum destComponentType = d3d11::GetComponentType(destRTVDesc.Format); 947 948 ASSERT(componentType != GL_NONE); 949 bool isDestSigned = (destComponentType == GL_INT); 950 951 ShaderDimension dimension = SHADER_INVALID; 952 953 switch (sourceSRVDesc.ViewDimension) 954 { 955 case D3D11_SRV_DIMENSION_TEXTURE2D: 956 dimension = SHADER_2D; 957 break; 958 case D3D11_SRV_DIMENSION_TEXTURE3D: 959 dimension = SHADER_3D; 960 break; 961 case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: 962 dimension = SHADER_2DARRAY; 963 break; 964 default: 965 UNREACHABLE(); 966 } 967 968 const Shader *shader = nullptr; 969 970 ANGLE_TRY(getBlitShader(context, destFormat, sourceFormat, isSrcSigned, isDestSigned, 971 unpackPremultiplyAlpha, unpackUnmultiplyAlpha, destTypeForDownsampling, 972 dimension, &shader)); 973 974 ShaderSupport support; 975 ANGLE_TRY(getShaderSupport(context, *shader, &support)); 976 977 // Set vertices 978 D3D11_MAPPED_SUBRESOURCE mappedResource; 979 ANGLE_TRY(mRenderer->mapResource(context, mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, 980 &mappedResource)); 981 982 UINT stride = 0; 983 UINT drawCount = 0; 984 D3D11_PRIMITIVE_TOPOLOGY topology; 985 986 support.vertexWriteFunction(sourceArea, sourceSize, destArea, destSize, mappedResource.pData, 987 &stride, &drawCount, &topology); 988 989 deviceContext->Unmap(mVertexBuffer.get(), 0); 990 991 StateManager11 *stateManager = mRenderer->getStateManager(); 992 993 // Apply vertex buffer 994 stateManager->setSingleVertexBuffer(&mVertexBuffer, stride, 0); 995 996 // Apply state 997 if (maskOffAlpha) 998 { 999 ANGLE_TRY(mAlphaMaskBlendState.resolve(GetImplAs<Context11>(context), mRenderer)); 1000 stateManager->setSimpleBlendState(&mAlphaMaskBlendState.getObj()); 1001 } 1002 else 1003 { 1004 stateManager->setSimpleBlendState(nullptr); 1005 } 1006 stateManager->setDepthStencilState(nullptr, 0xFFFFFFFF); 1007 1008 if (scissor) 1009 { 1010 stateManager->setSimpleScissorRect(*scissor); 1011 stateManager->setRasterizerState(&mScissorEnabledRasterizerState); 1012 } 1013 else 1014 { 1015 stateManager->setRasterizerState(&mScissorDisabledRasterizerState); 1016 } 1017 1018 // Apply shaders 1019 stateManager->setInputLayout(support.inputLayout); 1020 stateManager->setPrimitiveTopology(topology); 1021 1022 stateManager->setDrawShaders(support.vertexShader, support.geometryShader, 1023 &shader->pixelShader); 1024 1025 // Apply render target 1026 stateManager->setRenderTarget(dest.get(), nullptr); 1027 1028 // Set the viewport 1029 stateManager->setSimpleViewport(destSize); 1030 1031 // Apply texture and sampler 1032 switch (filter) 1033 { 1034 case GL_NEAREST: 1035 stateManager->setSimplePixelTextureAndSampler(source, mPointSampler); 1036 break; 1037 case GL_LINEAR: 1038 stateManager->setSimplePixelTextureAndSampler(source, mLinearSampler); 1039 break; 1040 1041 default: 1042 UNREACHABLE(); 1043 ANGLE_TRY_HR(GetImplAs<Context11>(context), E_FAIL, 1044 "Internal error, unknown blit filter mode."); 1045 } 1046 1047 // Draw the quad 1048 deviceContext->Draw(drawCount, 0); 1049 1050 return angle::Result::Continue; 1051 } 1052 1053 angle::Result Blit11::copyStencil(const gl::Context *context, 1054 const TextureHelper11 &source, 1055 unsigned int sourceSubresource, 1056 const gl::Box &sourceArea, 1057 const gl::Extents &sourceSize, 1058 const TextureHelper11 &dest, 1059 unsigned int destSubresource, 1060 const gl::Box &destArea, 1061 const gl::Extents &destSize, 1062 const gl::Rectangle *scissor) 1063 { 1064 return copyDepthStencilImpl(context, source, sourceSubresource, sourceArea, sourceSize, dest, 1065 destSubresource, destArea, destSize, scissor, true); 1066 } 1067 1068 angle::Result Blit11::copyDepth(const gl::Context *context, 1069 const d3d11::SharedSRV &source, 1070 const gl::Box &sourceArea, 1071 const gl::Extents &sourceSize, 1072 const d3d11::DepthStencilView &dest, 1073 const gl::Box &destArea, 1074 const gl::Extents &destSize, 1075 const gl::Rectangle *scissor) 1076 { 1077 ANGLE_TRY(initResources(context)); 1078 1079 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); 1080 1081 // Set vertices 1082 D3D11_MAPPED_SUBRESOURCE mappedResource; 1083 ANGLE_TRY(mRenderer->mapResource(context, mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, 1084 &mappedResource)); 1085 1086 UINT stride = 0; 1087 UINT drawCount = 0; 1088 D3D11_PRIMITIVE_TOPOLOGY topology; 1089 1090 Write2DVertices(sourceArea, sourceSize, destArea, destSize, mappedResource.pData, &stride, 1091 &drawCount, &topology); 1092 1093 deviceContext->Unmap(mVertexBuffer.get(), 0); 1094 1095 StateManager11 *stateManager = mRenderer->getStateManager(); 1096 1097 // Apply vertex buffer 1098 stateManager->setSingleVertexBuffer(&mVertexBuffer, stride, 0); 1099 1100 // Apply state 1101 stateManager->setSimpleBlendState(nullptr); 1102 stateManager->setDepthStencilState(&mDepthStencilState, 0xFFFFFFFF); 1103 1104 if (scissor) 1105 { 1106 stateManager->setSimpleScissorRect(*scissor); 1107 stateManager->setRasterizerState(&mScissorEnabledRasterizerState); 1108 } 1109 else 1110 { 1111 stateManager->setRasterizerState(&mScissorDisabledRasterizerState); 1112 } 1113 1114 Context11 *context11 = GetImplAs<Context11>(context); 1115 1116 ANGLE_TRY(mQuad2DIL.resolve(context11, mRenderer)); 1117 ANGLE_TRY(mQuad2DVS.resolve(context11, mRenderer)); 1118 ANGLE_TRY(mDepthPS.resolve(context11, mRenderer)); 1119 1120 // Apply shaders 1121 stateManager->setInputLayout(&mQuad2DIL.getObj()); 1122 stateManager->setPrimitiveTopology(topology); 1123 1124 stateManager->setDrawShaders(&mQuad2DVS.getObj(), nullptr, &mDepthPS.getObj()); 1125 1126 // Apply render target 1127 stateManager->setRenderTarget(nullptr, dest.get()); 1128 1129 // Set the viewport 1130 stateManager->setSimpleViewport(destSize); 1131 1132 // Apply texture and sampler 1133 stateManager->setSimplePixelTextureAndSampler(source, mPointSampler); 1134 1135 // Draw the quad 1136 deviceContext->Draw(drawCount, 0); 1137 1138 return angle::Result::Continue; 1139 } 1140 1141 angle::Result Blit11::copyDepthStencil(const gl::Context *context, 1142 const TextureHelper11 &source, 1143 unsigned int sourceSubresource, 1144 const gl::Box &sourceArea, 1145 const gl::Extents &sourceSize, 1146 const TextureHelper11 &dest, 1147 unsigned int destSubresource, 1148 const gl::Box &destArea, 1149 const gl::Extents &destSize, 1150 const gl::Rectangle *scissor) 1151 { 1152 return copyDepthStencilImpl(context, source, sourceSubresource, sourceArea, sourceSize, dest, 1153 destSubresource, destArea, destSize, scissor, false); 1154 } 1155 1156 angle::Result Blit11::copyDepthStencilImpl(const gl::Context *context, 1157 const TextureHelper11 &source, 1158 unsigned int sourceSubresource, 1159 const gl::Box &sourceArea, 1160 const gl::Extents &sourceSize, 1161 const TextureHelper11 &dest, 1162 unsigned int destSubresource, 1163 const gl::Box &destArea, 1164 const gl::Extents &destSize, 1165 const gl::Rectangle *scissor, 1166 bool stencilOnly) 1167 { 1168 auto srcDXGIFormat = source.getFormat(); 1169 const auto &srcSizeInfo = d3d11::GetDXGIFormatSizeInfo(srcDXGIFormat); 1170 unsigned int srcPixelSize = srcSizeInfo.pixelBytes; 1171 unsigned int copyOffset = 0; 1172 unsigned int copySize = srcPixelSize; 1173 auto destDXGIFormat = dest.getFormat(); 1174 const auto &destSizeInfo = d3d11::GetDXGIFormatSizeInfo(destDXGIFormat); 1175 unsigned int destPixelSize = destSizeInfo.pixelBytes; 1176 1177 ASSERT(srcDXGIFormat == destDXGIFormat || destDXGIFormat == DXGI_FORMAT_R32_TYPELESS); 1178 1179 if (stencilOnly) 1180 { 1181 const auto &srcFormat = source.getFormatSet().format(); 1182 1183 // Stencil channel should be right after the depth channel. Some views to depth/stencil 1184 // resources have red channel for depth, in which case the depth channel bit width is in 1185 // redBits. 1186 ASSERT((srcFormat.redBits != 0) != (srcFormat.depthBits != 0)); 1187 GLuint depthBits = srcFormat.redBits + srcFormat.depthBits; 1188 // Known formats have either 24 or 32 bits of depth. 1189 ASSERT(depthBits == 24 || depthBits == 32); 1190 copyOffset = depthBits / 8; 1191 1192 // Stencil is assumed to be 8-bit - currently this is true for all possible formats. 1193 copySize = 1; 1194 } 1195 1196 if (srcDXGIFormat != destDXGIFormat) 1197 { 1198 if (srcDXGIFormat == DXGI_FORMAT_R24G8_TYPELESS) 1199 { 1200 ASSERT(sourceArea == destArea && sourceSize == destSize && scissor == nullptr); 1201 return copyAndConvert(context, source, sourceSubresource, sourceArea, sourceSize, dest, 1202 destSubresource, destArea, destSize, scissor, copyOffset, 1203 copyOffset, copySize, srcPixelSize, destPixelSize, 1204 BlitD24S8ToD32F); 1205 } 1206 ASSERT(srcDXGIFormat == DXGI_FORMAT_R32G8X24_TYPELESS); 1207 return copyAndConvert(context, source, sourceSubresource, sourceArea, sourceSize, dest, 1208 destSubresource, destArea, destSize, scissor, copyOffset, copyOffset, 1209 copySize, srcPixelSize, destPixelSize, BlitD32FS8ToD32F); 1210 } 1211 1212 return copyAndConvert(context, source, sourceSubresource, sourceArea, sourceSize, dest, 1213 destSubresource, destArea, destSize, scissor, copyOffset, copyOffset, 1214 copySize, srcPixelSize, destPixelSize, StretchedBlitNearest); 1215 } 1216 1217 angle::Result Blit11::copyAndConvertImpl(const gl::Context *context, 1218 const TextureHelper11 &source, 1219 unsigned int sourceSubresource, 1220 const gl::Box &sourceArea, 1221 const gl::Extents &sourceSize, 1222 const TextureHelper11 &destStaging, 1223 const gl::Box &destArea, 1224 const gl::Extents &destSize, 1225 const gl::Rectangle *scissor, 1226 size_t readOffset, 1227 size_t writeOffset, 1228 size_t copySize, 1229 size_t srcPixelStride, 1230 size_t destPixelStride, 1231 BlitConvertFunction *convertFunction) 1232 { 1233 ANGLE_TRY(initResources(context)); 1234 1235 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); 1236 1237 TextureHelper11 sourceStaging; 1238 ANGLE_TRY(mRenderer->createStagingTexture(context, ResourceType::Texture2D, 1239 source.getFormatSet(), sourceSize, 1240 StagingAccess::READ, &sourceStaging)); 1241 1242 deviceContext->CopySubresourceRegion(sourceStaging.get(), 0, 0, 0, 0, source.get(), 1243 sourceSubresource, nullptr); 1244 1245 D3D11_MAPPED_SUBRESOURCE sourceMapping; 1246 ANGLE_TRY( 1247 mRenderer->mapResource(context, sourceStaging.get(), 0, D3D11_MAP_READ, 0, &sourceMapping)); 1248 1249 D3D11_MAPPED_SUBRESOURCE destMapping; 1250 angle::Result error = 1251 mRenderer->mapResource(context, destStaging.get(), 0, D3D11_MAP_WRITE, 0, &destMapping); 1252 if (error == angle::Result::Stop) 1253 { 1254 deviceContext->Unmap(sourceStaging.get(), 0); 1255 return error; 1256 } 1257 1258 // Clip dest area to the destination size 1259 gl::Rectangle clipRect = gl::Rectangle(0, 0, destSize.width, destSize.height); 1260 1261 // Clip dest area to the scissor 1262 if (scissor) 1263 { 1264 if (!gl::ClipRectangle(clipRect, *scissor, &clipRect)) 1265 { 1266 return angle::Result::Continue; 1267 } 1268 } 1269 1270 convertFunction(sourceArea, destArea, clipRect, sourceSize, sourceMapping.RowPitch, 1271 destMapping.RowPitch, readOffset, writeOffset, copySize, srcPixelStride, 1272 destPixelStride, static_cast<const uint8_t *>(sourceMapping.pData), 1273 static_cast<uint8_t *>(destMapping.pData)); 1274 1275 deviceContext->Unmap(sourceStaging.get(), 0); 1276 deviceContext->Unmap(destStaging.get(), 0); 1277 1278 return angle::Result::Continue; 1279 } 1280 1281 angle::Result Blit11::copyAndConvert(const gl::Context *context, 1282 const TextureHelper11 &source, 1283 unsigned int sourceSubresource, 1284 const gl::Box &sourceArea, 1285 const gl::Extents &sourceSize, 1286 const TextureHelper11 &dest, 1287 unsigned int destSubresource, 1288 const gl::Box &destArea, 1289 const gl::Extents &destSize, 1290 const gl::Rectangle *scissor, 1291 size_t readOffset, 1292 size_t writeOffset, 1293 size_t copySize, 1294 size_t srcPixelStride, 1295 size_t destPixelStride, 1296 BlitConvertFunction *convertFunction) 1297 { 1298 ANGLE_TRY(initResources(context)); 1299 1300 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); 1301 1302 // HACK: Create the destination staging buffer as a read/write texture so 1303 // ID3D11DevicContext::UpdateSubresource can be called 1304 // using it's mapped data as a source 1305 TextureHelper11 destStaging; 1306 ANGLE_TRY(mRenderer->createStagingTexture(context, ResourceType::Texture2D, dest.getFormatSet(), 1307 destSize, StagingAccess::READ_WRITE, &destStaging)); 1308 1309 deviceContext->CopySubresourceRegion(destStaging.get(), 0, 0, 0, 0, dest.get(), destSubresource, 1310 nullptr); 1311 1312 ANGLE_TRY(copyAndConvertImpl(context, source, sourceSubresource, sourceArea, sourceSize, 1313 destStaging, destArea, destSize, scissor, readOffset, writeOffset, 1314 copySize, srcPixelStride, destPixelStride, convertFunction)); 1315 1316 // Work around timeouts/TDRs in older NVIDIA drivers. 1317 if (mRenderer->getFeatures().depthStencilBlitExtraCopy.enabled) 1318 { 1319 D3D11_MAPPED_SUBRESOURCE mapped; 1320 ANGLE_TRY( 1321 mRenderer->mapResource(context, destStaging.get(), 0, D3D11_MAP_READ, 0, &mapped)); 1322 deviceContext->UpdateSubresource(dest.get(), destSubresource, nullptr, mapped.pData, 1323 mapped.RowPitch, mapped.DepthPitch); 1324 deviceContext->Unmap(destStaging.get(), 0); 1325 } 1326 else 1327 { 1328 deviceContext->CopySubresourceRegion(dest.get(), destSubresource, 0, 0, 0, 1329 destStaging.get(), 0, nullptr); 1330 } 1331 1332 return angle::Result::Continue; 1333 } 1334 1335 angle::Result Blit11::addBlitShaderToMap(const gl::Context *context, 1336 BlitShaderType blitShaderType, 1337 ShaderDimension dimension, 1338 const ShaderData &shaderData, 1339 const char *name) 1340 { 1341 ASSERT(mBlitShaderMap.find(blitShaderType) == mBlitShaderMap.end()); 1342 1343 d3d11::PixelShader ps; 1344 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), shaderData, &ps)); 1345 ps.setInternalName(name); 1346 1347 Shader shader; 1348 shader.dimension = dimension; 1349 shader.pixelShader = std::move(ps); 1350 1351 mBlitShaderMap[blitShaderType] = std::move(shader); 1352 return angle::Result::Continue; 1353 } 1354 1355 angle::Result Blit11::addSwizzleShaderToMap(const gl::Context *context, 1356 SwizzleShaderType swizzleShaderType, 1357 ShaderDimension dimension, 1358 const ShaderData &shaderData, 1359 const char *name) 1360 { 1361 ASSERT(mSwizzleShaderMap.find(swizzleShaderType) == mSwizzleShaderMap.end()); 1362 1363 d3d11::PixelShader ps; 1364 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), shaderData, &ps)); 1365 ps.setInternalName(name); 1366 1367 Shader shader; 1368 shader.dimension = dimension; 1369 shader.pixelShader = std::move(ps); 1370 1371 mSwizzleShaderMap[swizzleShaderType] = std::move(shader); 1372 return angle::Result::Continue; 1373 } 1374 1375 void Blit11::clearShaderMap() 1376 { 1377 mBlitShaderMap.clear(); 1378 mSwizzleShaderMap.clear(); 1379 } 1380 1381 Blit11::BlitShaderOperation Blit11::getBlitShaderOperation(GLenum destinationFormat, 1382 GLenum sourceFormat, 1383 bool isSrcSigned, 1384 bool isDestSigned, 1385 bool unpackPremultiplyAlpha, 1386 bool unpackUnmultiplyAlpha, 1387 GLenum destTypeForDownsampling) 1388 { 1389 bool floatToIntBlit = 1390 !gl::IsIntegerFormat(sourceFormat) && gl::IsIntegerFormat(destinationFormat); 1391 1392 if (isSrcSigned) 1393 { 1394 ASSERT(!unpackPremultiplyAlpha && !unpackUnmultiplyAlpha); 1395 switch (destinationFormat) 1396 { 1397 case GL_RGBA_INTEGER: 1398 return RGBAI; 1399 case GL_RGB_INTEGER: 1400 return RGBI; 1401 case GL_RG_INTEGER: 1402 return RGI; 1403 case GL_RED_INTEGER: 1404 return RI; 1405 default: 1406 UNREACHABLE(); 1407 return OPERATION_INVALID; 1408 } 1409 } 1410 else if (isDestSigned) 1411 { 1412 ASSERT(floatToIntBlit); 1413 1414 switch (destinationFormat) 1415 { 1416 case GL_RGBA_INTEGER: 1417 if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha) 1418 { 1419 return RGBAF_TOI; 1420 } 1421 return unpackPremultiplyAlpha ? RGBAF_TOI_PREMULTIPLY : RGBAF_TOI_UNMULTIPLY; 1422 case GL_RGB_INTEGER: 1423 case GL_RG_INTEGER: 1424 case GL_RED_INTEGER: 1425 if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha) 1426 { 1427 return RGBF_TOI; 1428 } 1429 return unpackPremultiplyAlpha ? RGBF_TOI_PREMULTIPLY : RGBF_TOI_UNMULTIPLY; 1430 default: 1431 UNREACHABLE(); 1432 return OPERATION_INVALID; 1433 } 1434 } 1435 else 1436 { 1437 // Check for the downsample formats first 1438 switch (destTypeForDownsampling) 1439 { 1440 case GL_UNSIGNED_SHORT_4_4_4_4: 1441 ASSERT(destinationFormat == GL_RGBA && !floatToIntBlit); 1442 if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha) 1443 { 1444 return RGBAF_4444; 1445 } 1446 else if (unpackPremultiplyAlpha) 1447 { 1448 return RGBAF_4444_PREMULTIPLY; 1449 } 1450 else 1451 { 1452 return RGBAF_4444_UNMULTIPLY; 1453 } 1454 1455 case GL_UNSIGNED_SHORT_5_6_5: 1456 ASSERT(destinationFormat == GL_RGB && !floatToIntBlit); 1457 if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha) 1458 { 1459 return RGBF_565; 1460 } 1461 else 1462 { 1463 return unpackPremultiplyAlpha ? RGBF_565_PREMULTIPLY : RGBF_565_UNMULTIPLY; 1464 } 1465 case GL_UNSIGNED_SHORT_5_5_5_1: 1466 if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha) 1467 { 1468 return RGBAF_5551; 1469 } 1470 else 1471 { 1472 return unpackPremultiplyAlpha ? RGBAF_5551_PREMULTIPLY : RGBAF_5551_UNMULTIPLY; 1473 } 1474 1475 default: 1476 // By default, use the regular passthrough/multiply/unmultiply shaders. The above 1477 // shaders are only needed for some emulated texture formats. 1478 break; 1479 } 1480 1481 if (unpackPremultiplyAlpha != unpackUnmultiplyAlpha || floatToIntBlit) 1482 { 1483 switch (destinationFormat) 1484 { 1485 case GL_RGBA: 1486 case GL_BGRA_EXT: 1487 ASSERT(!floatToIntBlit); 1488 return unpackPremultiplyAlpha ? RGBAF_PREMULTIPLY : RGBAF_UNMULTIPLY; 1489 case GL_RGB: 1490 case GL_RG: 1491 case GL_RED: 1492 if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha) 1493 { 1494 return RGBF_TOUI; 1495 } 1496 else 1497 { 1498 return unpackPremultiplyAlpha ? RGBF_PREMULTIPLY : RGBF_UNMULTIPLY; 1499 } 1500 case GL_RGBA_INTEGER: 1501 if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha) 1502 { 1503 return RGBAF_TOUI; 1504 } 1505 else 1506 { 1507 return unpackPremultiplyAlpha ? RGBAF_TOUI_PREMULTIPLY 1508 : RGBAF_TOUI_UNMULTIPLY; 1509 } 1510 case GL_RGB_INTEGER: 1511 case GL_RG_INTEGER: 1512 case GL_RED_INTEGER: 1513 if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha) 1514 { 1515 return RGBF_TOUI; 1516 } 1517 else 1518 { 1519 return unpackPremultiplyAlpha ? RGBF_TOUI_PREMULTIPLY 1520 : RGBF_TOUI_UNMULTIPLY; 1521 } 1522 case GL_LUMINANCE: 1523 ASSERT(!floatToIntBlit); 1524 return unpackPremultiplyAlpha ? LUMAF_PREMULTIPLY : LUMAF_UNMULTIPLY; 1525 1526 case GL_LUMINANCE_ALPHA: 1527 ASSERT(!floatToIntBlit); 1528 return unpackPremultiplyAlpha ? LUMAALPHAF_PREMULTIPLY : LUMAALPHAF_UNMULTIPLY; 1529 case GL_ALPHA: 1530 return ALPHA; 1531 default: 1532 UNREACHABLE(); 1533 return OPERATION_INVALID; 1534 } 1535 } 1536 else 1537 { 1538 switch (destinationFormat) 1539 { 1540 case GL_RGBA: 1541 return RGBAF; 1542 case GL_RGBA_INTEGER: 1543 return RGBAUI; 1544 case GL_BGRA_EXT: 1545 return BGRAF; 1546 case GL_RGB: 1547 return RGBF; 1548 case GL_RGB_INTEGER: 1549 return RGBUI; 1550 case GL_RG: 1551 return RGF; 1552 case GL_RG_INTEGER: 1553 return RGUI; 1554 case GL_RED: 1555 return RF; 1556 case GL_RED_INTEGER: 1557 return RUI; 1558 case GL_ALPHA: 1559 return ALPHA; 1560 case GL_LUMINANCE: 1561 return LUMA; 1562 case GL_LUMINANCE_ALPHA: 1563 return LUMAALPHA; 1564 default: 1565 UNREACHABLE(); 1566 return OPERATION_INVALID; 1567 } 1568 } 1569 } 1570 } 1571 1572 angle::Result Blit11::getBlitShader(const gl::Context *context, 1573 GLenum destFormat, 1574 GLenum sourceFormat, 1575 bool isSrcSigned, 1576 bool isDestSigned, 1577 bool unpackPremultiplyAlpha, 1578 bool unpackUnmultiplyAlpha, 1579 GLenum destTypeForDownsampling, 1580 ShaderDimension dimension, 1581 const Shader **shader) 1582 { 1583 BlitShaderOperation blitShaderOperation = OPERATION_INVALID; 1584 1585 blitShaderOperation = getBlitShaderOperation(destFormat, sourceFormat, isSrcSigned, 1586 isDestSigned, unpackPremultiplyAlpha, 1587 unpackUnmultiplyAlpha, destTypeForDownsampling); 1588 1589 BlitShaderType blitShaderType = BLITSHADER_INVALID; 1590 1591 blitShaderType = getBlitShaderType(blitShaderOperation, dimension); 1592 1593 ANGLE_CHECK_HR(GetImplAs<Context11>(context), blitShaderType != BLITSHADER_INVALID, 1594 "Internal blit shader type mismatch", E_FAIL); 1595 1596 auto blitShaderIt = mBlitShaderMap.find(blitShaderType); 1597 if (blitShaderIt != mBlitShaderMap.end()) 1598 { 1599 *shader = &blitShaderIt->second; 1600 return angle::Result::Continue; 1601 } 1602 1603 ASSERT(dimension == SHADER_2D || mRenderer->isES3Capable()); 1604 1605 ANGLE_TRY(mapBlitShader(context, blitShaderType)); 1606 1607 blitShaderIt = mBlitShaderMap.find(blitShaderType); 1608 ASSERT(blitShaderIt != mBlitShaderMap.end()); 1609 *shader = &blitShaderIt->second; 1610 return angle::Result::Continue; 1611 } 1612 1613 angle::Result Blit11::getSwizzleShader(const gl::Context *context, 1614 GLenum type, 1615 D3D11_SRV_DIMENSION viewDimension, 1616 const Shader **shader) 1617 { 1618 SwizzleShaderType swizzleShaderType = GetSwizzleShaderType(type, viewDimension); 1619 1620 ANGLE_CHECK_HR(GetImplAs<Context11>(context), swizzleShaderType != SWIZZLESHADER_INVALID, 1621 "Swizzle shader type not found", E_FAIL); 1622 1623 auto swizzleShaderIt = mSwizzleShaderMap.find(swizzleShaderType); 1624 if (swizzleShaderIt != mSwizzleShaderMap.end()) 1625 { 1626 *shader = &swizzleShaderIt->second; 1627 return angle::Result::Continue; 1628 } 1629 1630 // Swizzling shaders (OpenGL ES 3+) 1631 ASSERT(mRenderer->isES3Capable()); 1632 1633 switch (swizzleShaderType) 1634 { 1635 case SWIZZLESHADER_2D_FLOAT: 1636 ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_2D, 1637 ShaderData(g_PS_SwizzleF2D), 1638 "Blit11 2D F swizzle pixel shader")); 1639 break; 1640 case SWIZZLESHADER_2D_UINT: 1641 ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_2D, 1642 ShaderData(g_PS_SwizzleUI2D), 1643 "Blit11 2D UI swizzle pixel shader")); 1644 break; 1645 case SWIZZLESHADER_2D_INT: 1646 ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_2D, 1647 ShaderData(g_PS_SwizzleI2D), 1648 "Blit11 2D I swizzle pixel shader")); 1649 break; 1650 case SWIZZLESHADER_CUBE_FLOAT: 1651 ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D, 1652 ShaderData(g_PS_SwizzleF2DArray), 1653 "Blit11 2D Cube F swizzle pixel shader")); 1654 break; 1655 case SWIZZLESHADER_CUBE_UINT: 1656 ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D, 1657 ShaderData(g_PS_SwizzleUI2DArray), 1658 "Blit11 2D Cube UI swizzle pixel shader")); 1659 break; 1660 case SWIZZLESHADER_CUBE_INT: 1661 ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D, 1662 ShaderData(g_PS_SwizzleI2DArray), 1663 "Blit11 2D Cube I swizzle pixel shader")); 1664 break; 1665 case SWIZZLESHADER_3D_FLOAT: 1666 ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D, 1667 ShaderData(g_PS_SwizzleF3D), 1668 "Blit11 3D F swizzle pixel shader")); 1669 break; 1670 case SWIZZLESHADER_3D_UINT: 1671 ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D, 1672 ShaderData(g_PS_SwizzleUI3D), 1673 "Blit11 3D UI swizzle pixel shader")); 1674 break; 1675 case SWIZZLESHADER_3D_INT: 1676 ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D, 1677 ShaderData(g_PS_SwizzleI3D), 1678 "Blit11 3D I swizzle pixel shader")); 1679 break; 1680 case SWIZZLESHADER_ARRAY_FLOAT: 1681 ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D, 1682 ShaderData(g_PS_SwizzleF2DArray), 1683 "Blit11 2D Array F swizzle pixel shader")); 1684 break; 1685 case SWIZZLESHADER_ARRAY_UINT: 1686 ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D, 1687 ShaderData(g_PS_SwizzleUI2DArray), 1688 "Blit11 2D Array UI swizzle pixel shader")); 1689 break; 1690 case SWIZZLESHADER_ARRAY_INT: 1691 ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D, 1692 ShaderData(g_PS_SwizzleI2DArray), 1693 "Blit11 2D Array I swizzle pixel shader")); 1694 break; 1695 default: 1696 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 1697 } 1698 1699 swizzleShaderIt = mSwizzleShaderMap.find(swizzleShaderType); 1700 ASSERT(swizzleShaderIt != mSwizzleShaderMap.end()); 1701 *shader = &swizzleShaderIt->second; 1702 return angle::Result::Continue; 1703 } 1704 1705 angle::Result Blit11::resolveDepth(const gl::Context *context, 1706 RenderTarget11 *depth, 1707 TextureHelper11 *textureOut) 1708 { 1709 ANGLE_TRY(initResources(context)); 1710 1711 // Multisampled depth stencil SRVs are not available in feature level 10.0 1712 ASSERT(mRenderer->getRenderer11DeviceCaps().featureLevel > D3D_FEATURE_LEVEL_10_0); 1713 1714 const auto &extents = depth->getExtents(); 1715 auto *deviceContext = mRenderer->getDeviceContext(); 1716 auto *stateManager = mRenderer->getStateManager(); 1717 1718 ANGLE_TRY(initResolveDepthOnly(context, depth->getFormatSet(), extents)); 1719 1720 Context11 *context11 = GetImplAs<Context11>(context); 1721 1722 ANGLE_TRY(mResolveDepthStencilVS.resolve(context11, mRenderer)); 1723 ANGLE_TRY(mResolveDepthPS.resolve(context11, mRenderer)); 1724 1725 // Apply the necessary state changes to the D3D11 immediate device context. 1726 stateManager->setInputLayout(nullptr); 1727 stateManager->setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); 1728 stateManager->setDrawShaders(&mResolveDepthStencilVS.getObj(), nullptr, 1729 &mResolveDepthPS.getObj()); 1730 stateManager->setRasterizerState(nullptr); 1731 stateManager->setDepthStencilState(&mDepthStencilState, 0xFFFFFFFF); 1732 stateManager->setRenderTargets(nullptr, 0, mResolvedDepthDSView.get()); 1733 stateManager->setSimpleBlendState(nullptr); 1734 stateManager->setSimpleViewport(extents); 1735 1736 // Set the viewport 1737 const d3d11::SharedSRV *srv; 1738 ANGLE_TRY(depth->getShaderResourceView(context, &srv)); 1739 1740 stateManager->setShaderResourceShared(gl::ShaderType::Fragment, 0, srv); 1741 1742 // Trigger the blit on the GPU. 1743 deviceContext->Draw(6, 0); 1744 1745 *textureOut = mResolvedDepth; 1746 return angle::Result::Continue; 1747 } 1748 1749 angle::Result Blit11::initResolveDepthOnly(const gl::Context *context, 1750 const d3d11::Format &format, 1751 const gl::Extents &extents) 1752 { 1753 if (mResolvedDepth.valid() && extents == mResolvedDepth.getExtents() && 1754 format.texFormat == mResolvedDepth.getFormat()) 1755 { 1756 return angle::Result::Continue; 1757 } 1758 1759 D3D11_TEXTURE2D_DESC textureDesc; 1760 textureDesc.Width = extents.width; 1761 textureDesc.Height = extents.height; 1762 textureDesc.MipLevels = 1; 1763 textureDesc.ArraySize = 1; 1764 textureDesc.Format = format.texFormat; 1765 textureDesc.SampleDesc.Count = 1; 1766 textureDesc.SampleDesc.Quality = 0; 1767 textureDesc.Usage = D3D11_USAGE_DEFAULT; 1768 textureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE; 1769 textureDesc.CPUAccessFlags = 0; 1770 textureDesc.MiscFlags = 0; 1771 1772 Context11 *context11 = GetImplAs<Context11>(context); 1773 1774 ANGLE_TRY(mRenderer->allocateTexture(context11, textureDesc, format, &mResolvedDepth)); 1775 mResolvedDepth.setInternalName("Blit11::mResolvedDepth"); 1776 1777 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; 1778 dsvDesc.Flags = 0; 1779 dsvDesc.Format = format.dsvFormat; 1780 dsvDesc.Texture2D.MipSlice = 0; 1781 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; 1782 1783 ANGLE_TRY(mRenderer->allocateResource(context11, dsvDesc, mResolvedDepth.get(), 1784 &mResolvedDepthDSView)); 1785 mResolvedDepthDSView.setInternalName("Blit11::mResolvedDepthDSView"); 1786 1787 // Possibly D3D11 bug or undefined behaviour: Clear the DSV so that our first render 1788 // works as expected. Otherwise the results of the first use seem to be incorrect. 1789 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); 1790 deviceContext->ClearDepthStencilView(mResolvedDepthDSView.get(), D3D11_CLEAR_DEPTH, 1.0f, 0); 1791 1792 return angle::Result::Continue; 1793 } 1794 1795 angle::Result Blit11::initResolveDepthStencil(const gl::Context *context, 1796 const gl::Extents &extents) 1797 { 1798 // Check if we need to recreate depth stencil view 1799 if (mResolvedDepthStencil.valid() && extents == mResolvedDepthStencil.getExtents()) 1800 { 1801 ASSERT(mResolvedDepthStencil.getFormat() == DXGI_FORMAT_R32G32_FLOAT); 1802 return angle::Result::Continue; 1803 } 1804 1805 if (mResolvedDepthStencil.valid()) 1806 { 1807 releaseResolveDepthStencilResources(); 1808 } 1809 1810 const auto &formatSet = d3d11::Format::Get(GL_RG32F, mRenderer->getRenderer11DeviceCaps()); 1811 1812 D3D11_TEXTURE2D_DESC textureDesc; 1813 textureDesc.Width = extents.width; 1814 textureDesc.Height = extents.height; 1815 textureDesc.MipLevels = 1; 1816 textureDesc.ArraySize = 1; 1817 textureDesc.Format = formatSet.texFormat; 1818 textureDesc.SampleDesc.Count = 1; 1819 textureDesc.SampleDesc.Quality = 0; 1820 textureDesc.Usage = D3D11_USAGE_DEFAULT; 1821 textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET; 1822 textureDesc.CPUAccessFlags = 0; 1823 textureDesc.MiscFlags = 0; 1824 1825 Context11 *context11 = GetImplAs<Context11>(context); 1826 1827 ANGLE_TRY( 1828 mRenderer->allocateTexture(context11, textureDesc, formatSet, &mResolvedDepthStencil)); 1829 mResolvedDepthStencil.setInternalName("Blit11::mResolvedDepthStencil"); 1830 1831 ANGLE_TRY(mRenderer->allocateResourceNoDesc(context11, mResolvedDepthStencil.get(), 1832 &mResolvedDepthStencilRTView)); 1833 mResolvedDepthStencilRTView.setInternalName("Blit11::mResolvedDepthStencilRTView"); 1834 1835 return angle::Result::Continue; 1836 } 1837 1838 angle::Result Blit11::resolveStencil(const gl::Context *context, 1839 RenderTarget11 *depthStencil, 1840 bool alsoDepth, 1841 TextureHelper11 *textureOut) 1842 { 1843 ANGLE_TRY(initResources(context)); 1844 1845 // Multisampled depth stencil SRVs are not available in feature level 10.0 1846 ASSERT(mRenderer->getRenderer11DeviceCaps().featureLevel > D3D_FEATURE_LEVEL_10_0); 1847 1848 const auto &extents = depthStencil->getExtents(); 1849 1850 ANGLE_TRY(initResolveDepthStencil(context, extents)); 1851 1852 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); 1853 auto *stateManager = mRenderer->getStateManager(); 1854 ID3D11Resource *stencilResource = depthStencil->getTexture().get(); 1855 1856 // Check if we need to re-create the stencil SRV. 1857 if (mStencilSRV.valid()) 1858 { 1859 ID3D11Resource *priorResource = nullptr; 1860 mStencilSRV.get()->GetResource(&priorResource); 1861 1862 if (stencilResource != priorResource) 1863 { 1864 mStencilSRV.reset(); 1865 } 1866 1867 SafeRelease(priorResource); 1868 } 1869 1870 Context11 *context11 = GetImplAs<Context11>(context); 1871 1872 if (!mStencilSRV.valid()) 1873 { 1874 D3D11_SHADER_RESOURCE_VIEW_DESC srViewDesc; 1875 srViewDesc.Format = GetStencilSRVFormat(depthStencil->getFormatSet()); 1876 srViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; 1877 1878 ANGLE_TRY( 1879 mRenderer->allocateResource(context11, srViewDesc, stencilResource, &mStencilSRV)); 1880 mStencilSRV.setInternalName("Blit11::mStencilSRV"); 1881 } 1882 1883 // Notify the Renderer that all state should be invalidated. 1884 ANGLE_TRY(mResolveDepthStencilVS.resolve(context11, mRenderer)); 1885 1886 // Resolving the depth buffer works by sampling the depth in the shader using a SRV, then 1887 // writing to the resolved depth buffer using SV_Depth. We can't use this method for stencil 1888 // because SV_StencilRef isn't supported until HLSL 5.1/D3D11.3. 1889 const d3d11::PixelShader *pixelShader = nullptr; 1890 if (alsoDepth) 1891 { 1892 ANGLE_TRY(mResolveDepthStencilPS.resolve(context11, mRenderer)); 1893 pixelShader = &mResolveDepthStencilPS.getObj(); 1894 } 1895 else 1896 { 1897 ANGLE_TRY(mResolveStencilPS.resolve(context11, mRenderer)); 1898 pixelShader = &mResolveStencilPS.getObj(); 1899 } 1900 1901 // Apply the necessary state changes to the D3D11 immediate device context. 1902 stateManager->setInputLayout(nullptr); 1903 stateManager->setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); 1904 stateManager->setDrawShaders(&mResolveDepthStencilVS.getObj(), nullptr, pixelShader); 1905 stateManager->setRasterizerState(nullptr); 1906 stateManager->setDepthStencilState(nullptr, 0xFFFFFFFF); 1907 stateManager->setRenderTarget(mResolvedDepthStencilRTView.get(), nullptr); 1908 stateManager->setSimpleBlendState(nullptr); 1909 1910 // Set the viewport 1911 stateManager->setSimpleViewport(extents); 1912 const d3d11::SharedSRV *srv; 1913 ANGLE_TRY(depthStencil->getShaderResourceView(context, &srv)); 1914 stateManager->setShaderResourceShared(gl::ShaderType::Fragment, 0, srv); 1915 stateManager->setShaderResource(gl::ShaderType::Fragment, 1, &mStencilSRV); 1916 1917 // Trigger the blit on the GPU. 1918 deviceContext->Draw(6, 0); 1919 1920 gl::Box copyBox(0, 0, 0, extents.width, extents.height, 1); 1921 1922 ANGLE_TRY(mRenderer->createStagingTexture(context, ResourceType::Texture2D, 1923 depthStencil->getFormatSet(), extents, 1924 StagingAccess::READ_WRITE, textureOut)); 1925 1926 const auto ©Function = GetCopyDepthStencilFunction(depthStencil->getInternalFormat()); 1927 const auto &dsFormatSet = depthStencil->getFormatSet(); 1928 const auto &dsDxgiInfo = d3d11::GetDXGIFormatSizeInfo(dsFormatSet.texFormat); 1929 1930 ANGLE_TRY(copyAndConvertImpl(context, mResolvedDepthStencil, 0, copyBox, extents, *textureOut, 1931 copyBox, extents, nullptr, 0, 0, 0, 8u, dsDxgiInfo.pixelBytes, 1932 copyFunction)); 1933 1934 return angle::Result::Continue; 1935 } 1936 1937 void Blit11::releaseResolveDepthStencilResources() 1938 { 1939 mStencilSRV.reset(); 1940 mResolvedDepthStencilRTView.reset(); 1941 } 1942 1943 } // namespace rx