summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11
diff options
context:
space:
mode:
authorOliver Wolff <oliver.wolff@theqtcompany.com>2016-03-24 12:38:18 +0100
committerOliver Wolff <oliver.wolff@qt.io>2016-04-25 05:57:38 +0000
commite12ba07322cd61c5cf50c25ed8d1f08f6b1ff879 (patch)
treed31a44c9f123ed764a00eff7b4fff656a07d54ab /src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11
parentd3dcc6f610b97be7cbfbb0a65988e5940568c825 (diff)
Update ANGLE to chromium/2651
Change-Id: I1cd32b780b1a0b913fab870e155ae1f4f9ac40d7 Reviewed-by: Maurice Kalinowski <maurice.kalinowski@qt.io>
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11')
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp926
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.h145
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp875
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h52
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp229
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.h39
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp83
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h4
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp22
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.h18
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp294
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h15
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.cpp336
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.h17
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp17
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h2
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp693
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h104
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h17
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp31
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp164
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.h13
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp116
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h5
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp14
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h5
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp3096
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h285
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp14
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h4
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp1040
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.h181
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp446
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h35
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp724
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h74
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.h2
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h15
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp69
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h11
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/copyvertex.inl6
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_data.json1164
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.cpp1846
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.h44
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp1501
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.h44
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/gen_load_functions_table.cpp0
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.cpp170
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.h31
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_data.json1116
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table.h31
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp2098
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp744
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h276
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_data.json77
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_info.h51
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_info_autogen.cpp203
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_data.json692
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h64
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp1791
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp156
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp75
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h64
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp160
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h71
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp232
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h21
67 files changed, 18595 insertions, 4365 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp
index e38b61709f..e951e13408 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp
@@ -10,10 +10,11 @@
#include <float.h>
+#include "libANGLE/formatutils.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
-#include "libANGLE/formatutils.h"
+#include "third_party/trace_event/trace_event.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h"
@@ -62,7 +63,10 @@
namespace rx
{
-static DXGI_FORMAT GetTextureFormat(ID3D11Resource *resource)
+namespace
+{
+
+DXGI_FORMAT GetTextureFormat(ID3D11Resource *resource)
{
ID3D11Texture2D *texture = d3d11::DynamicCastComObject<ID3D11Texture2D>(resource);
if (!texture)
@@ -78,9 +82,9 @@ static DXGI_FORMAT GetTextureFormat(ID3D11Resource *resource)
return desc.Format;
}
-static ID3D11Resource *CreateStagingTexture(ID3D11Device *device, ID3D11DeviceContext *context,
- ID3D11Resource *source, unsigned int subresource,
- const gl::Extents &size, unsigned int cpuAccessFlags)
+ID3D11Resource *CreateStagingTexture(ID3D11Device *device, ID3D11DeviceContext *context,
+ ID3D11Resource *source, unsigned int subresource,
+ const gl::Extents &size, unsigned int cpuAccessFlags)
{
D3D11_TEXTURE2D_DESC stagingDesc;
stagingDesc.Width = size.width;
@@ -95,23 +99,23 @@ static ID3D11Resource *CreateStagingTexture(ID3D11Device *device, ID3D11DeviceCo
stagingDesc.MiscFlags = 0;
stagingDesc.BindFlags = 0;
- ID3D11Texture2D *stagingTexture = NULL;
- HRESULT result = device->CreateTexture2D(&stagingDesc, NULL, &stagingTexture);
+ ID3D11Texture2D *stagingTexture = nullptr;
+ HRESULT result = device->CreateTexture2D(&stagingDesc, nullptr, &stagingTexture);
if (FAILED(result))
{
ERR("Failed to create staging texture for depth stencil blit. HRESULT: 0x%X.", result);
- return NULL;
+ return nullptr;
}
- context->CopySubresourceRegion(stagingTexture, 0, 0, 0, 0, source, subresource, NULL);
+ context->CopySubresourceRegion(stagingTexture, 0, 0, 0, 0, source, subresource, nullptr);
return stagingTexture;
}
-inline static void 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)
+inline void 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)
{
*x1 = (destArea.x / float(destSize.width)) * 2.0f - 1.0f;
*y1 = ((destSize.height - destArea.y - destArea.height) / float(destSize.height)) * 2.0f - 1.0f;
@@ -124,10 +128,10 @@ inline static void GenerateVertexCoords(const gl::Box &sourceArea, const gl::Ext
*v2 = (sourceArea.y + sourceArea.height) / float(sourceSize.height);
}
-static void 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)
+void 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)
{
float x1, y1, x2, y2, u1, v1, u2, v2;
GenerateVertexCoords(sourceArea, sourceSize, destArea, destSize, &x1, &y1, &x2, &y2, &u1, &v1, &u2, &v2);
@@ -144,10 +148,10 @@ static void Write2DVertices(const gl::Box &sourceArea, const gl::Extents &source
*outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
}
-static void 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)
+void 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)
{
ASSERT(sourceSize.depth > 0 && destSize.depth > 0);
@@ -174,28 +178,132 @@ static void Write3DVertices(const gl::Box &sourceArea, const gl::Extents &source
*outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
}
+inline unsigned int GetSwizzleIndex(GLenum swizzle)
+{
+ unsigned int colorIndex = 0;
+
+ switch (swizzle)
+ {
+ case GL_RED: colorIndex = 0; break;
+ case GL_GREEN: colorIndex = 1; break;
+ case GL_BLUE: colorIndex = 2; break;
+ case GL_ALPHA: colorIndex = 3; break;
+ case GL_ZERO: colorIndex = 4; break;
+ case GL_ONE: colorIndex = 5; break;
+ default: UNREACHABLE(); break;
+ }
+
+ return colorIndex;
+}
+
+D3D11_BLEND_DESC GetAlphaMaskBlendStateDesc()
+{
+ D3D11_BLEND_DESC desc;
+ memset(&desc, 0, sizeof(desc));
+ desc.RenderTarget[0].BlendEnable = TRUE;
+ desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
+ desc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO;
+ desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
+ desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO;
+ desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
+ desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
+ desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_RED |
+ D3D11_COLOR_WRITE_ENABLE_GREEN |
+ D3D11_COLOR_WRITE_ENABLE_BLUE;
+ return desc;
+}
+
+D3D11_INPUT_ELEMENT_DESC quad2DLayout[] =
+{
+ { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+};
+
+D3D11_INPUT_ELEMENT_DESC quad3DLayout[] =
+{
+ { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ { "LAYER", 0, DXGI_FORMAT_R32_UINT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ { "TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+};
+
+} // namespace
+
Blit11::Blit11(Renderer11 *renderer)
- : mRenderer(renderer), mBlitShaderMap(compareBlitParameters), mSwizzleShaderMap(compareSwizzleParameters),
- mVertexBuffer(NULL), mPointSampler(NULL), mLinearSampler(NULL), mScissorEnabledRasterizerState(NULL),
- mScissorDisabledRasterizerState(NULL), mDepthStencilState(NULL),
- mQuad2DIL(NULL), mQuad2DVS(NULL), mDepthPS(NULL),
- mQuad3DIL(NULL), mQuad3DVS(NULL), mQuad3DGS(NULL),
- mSwizzleCB(NULL)
+ : mRenderer(renderer),
+ mResourcesInitialized(false),
+ mVertexBuffer(nullptr),
+ mPointSampler(nullptr),
+ mLinearSampler(nullptr),
+ mScissorEnabledRasterizerState(nullptr),
+ mScissorDisabledRasterizerState(nullptr),
+ mDepthStencilState(nullptr),
+ mQuad2DIL(quad2DLayout,
+ ArraySize(quad2DLayout),
+ g_VS_Passthrough2D,
+ ArraySize(g_VS_Passthrough2D),
+ "Blit11 2D input layout"),
+ mQuad2DVS(g_VS_Passthrough2D, ArraySize(g_VS_Passthrough2D), "Blit11 2D vertex shader"),
+ mDepthPS(g_PS_PassthroughDepth2D,
+ ArraySize(g_PS_PassthroughDepth2D),
+ "Blit11 2D depth pixel shader"),
+ mQuad3DIL(quad3DLayout,
+ ArraySize(quad3DLayout),
+ g_VS_Passthrough3D,
+ ArraySize(g_VS_Passthrough3D),
+ "Blit11 3D input layout"),
+ mQuad3DVS(g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), "Blit11 3D vertex shader"),
+ mQuad3DGS(g_GS_Passthrough3D, ArraySize(g_GS_Passthrough3D), "Blit11 3D geometry shader"),
+ mAlphaMaskBlendState(GetAlphaMaskBlendStateDesc(), "Blit11 Alpha Mask Blend"),
+ mSwizzleCB(nullptr)
+{
+}
+
+Blit11::~Blit11()
+{
+ freeResources();
+
+ mQuad2DIL.release();
+ mQuad2DVS.release();
+ mDepthPS.release();
+
+ mQuad3DIL.release();
+ mQuad3DVS.release();
+ mQuad3DGS.release();
+
+ clearShaderMap();
+}
+
+gl::Error Blit11::initResources()
{
+ if (mResourcesInitialized)
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ TRACE_EVENT0("gpu.angle", "Blit11::initResources");
+
HRESULT result;
ID3D11Device *device = mRenderer->getDevice();
D3D11_BUFFER_DESC vbDesc;
- vbDesc.ByteWidth = std::max(sizeof(d3d11::PositionLayerTexCoord3DVertex), sizeof(d3d11::PositionTexCoordVertex)) *
- 6 * renderer->getRendererCaps().max3DTextureSize;
+ vbDesc.ByteWidth =
+ static_cast<unsigned int>(std::max(sizeof(d3d11::PositionLayerTexCoord3DVertex),
+ sizeof(d3d11::PositionTexCoordVertex)) *
+ 6 * mRenderer->getRendererCaps().max3DTextureSize);
vbDesc.Usage = D3D11_USAGE_DYNAMIC;
vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
vbDesc.MiscFlags = 0;
vbDesc.StructureByteStride = 0;
- result = device->CreateBuffer(&vbDesc, NULL, &mVertexBuffer);
+ result = device->CreateBuffer(&vbDesc, nullptr, &mVertexBuffer);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ freeResources();
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create blit vertex buffer, HRESULT: 0x%X",
+ result);
+ }
d3d11::SetDebugName(mVertexBuffer, "Blit11 vertex buffer");
D3D11_SAMPLER_DESC pointSamplerDesc;
@@ -215,6 +323,12 @@ Blit11::Blit11(Renderer11 *renderer)
result = device->CreateSamplerState(&pointSamplerDesc, &mPointSampler);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ freeResources();
+ return gl::Error(GL_OUT_OF_MEMORY,
+ "Failed to create blit point sampler state, HRESULT: 0x%X", result);
+ }
d3d11::SetDebugName(mPointSampler, "Blit11 point sampler");
D3D11_SAMPLER_DESC linearSamplerDesc;
@@ -234,6 +348,12 @@ Blit11::Blit11(Renderer11 *renderer)
result = device->CreateSamplerState(&linearSamplerDesc, &mLinearSampler);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ freeResources();
+ return gl::Error(GL_OUT_OF_MEMORY,
+ "Failed to create blit linear sampler state, HRESULT: 0x%X", result);
+ }
d3d11::SetDebugName(mLinearSampler, "Blit11 linear sampler");
// Use a rasterizer state that will not cull so that inverted quads will not be culled
@@ -251,11 +371,25 @@ Blit11::Blit11(Renderer11 *renderer)
rasterDesc.ScissorEnable = TRUE;
result = device->CreateRasterizerState(&rasterDesc, &mScissorEnabledRasterizerState);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ freeResources();
+ return gl::Error(GL_OUT_OF_MEMORY,
+ "Failed to create blit scissoring rasterizer state, HRESULT: 0x%X",
+ result);
+ }
d3d11::SetDebugName(mScissorEnabledRasterizerState, "Blit11 scissoring rasterizer state");
rasterDesc.ScissorEnable = FALSE;
result = device->CreateRasterizerState(&rasterDesc, &mScissorDisabledRasterizerState);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ freeResources();
+ return gl::Error(GL_OUT_OF_MEMORY,
+ "Failed to create blit no scissoring rasterizer state, HRESULT: 0x%X",
+ result);
+ }
d3d11::SetDebugName(mScissorDisabledRasterizerState, "Blit11 no scissoring rasterizer state");
D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
@@ -276,49 +410,13 @@ Blit11::Blit11(Renderer11 *renderer)
result = device->CreateDepthStencilState(&depthStencilDesc, &mDepthStencilState);
ASSERT(SUCCEEDED(result));
- d3d11::SetDebugName(mDepthStencilState, "Blit11 depth stencil state");
-
- D3D11_INPUT_ELEMENT_DESC quad2DLayout[] =
- {
- { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
- { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
- };
-
- result = device->CreateInputLayout(quad2DLayout, ArraySize(quad2DLayout), g_VS_Passthrough2D, ArraySize(g_VS_Passthrough2D), &mQuad2DIL);
- ASSERT(SUCCEEDED(result));
- d3d11::SetDebugName(mQuad2DIL, "Blit11 2D input layout");
-
- result = device->CreateVertexShader(g_VS_Passthrough2D, ArraySize(g_VS_Passthrough2D), NULL, &mQuad2DVS);
- ASSERT(SUCCEEDED(result));
- d3d11::SetDebugName(mQuad2DVS, "Blit11 2D vertex shader");
-
- if (renderer->isES3Capable())
+ if (FAILED(result))
{
- result = device->CreatePixelShader(g_PS_PassthroughDepth2D, ArraySize(g_PS_PassthroughDepth2D), NULL, &mDepthPS);
- ASSERT(SUCCEEDED(result));
- d3d11::SetDebugName(mDepthPS, "Blit11 2D depth pixel shader");
-
- D3D11_INPUT_ELEMENT_DESC quad3DLayout[] =
- {
- { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
- { "LAYER", 0, DXGI_FORMAT_R32_UINT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
- { "TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
- };
-
- result = device->CreateInputLayout(quad3DLayout, ArraySize(quad3DLayout), g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), &mQuad3DIL);
- ASSERT(SUCCEEDED(result));
- d3d11::SetDebugName(mQuad3DIL, "Blit11 3D input layout");
-
- result = device->CreateVertexShader(g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), NULL, &mQuad3DVS);
- ASSERT(SUCCEEDED(result));
- d3d11::SetDebugName(mQuad3DVS, "Blit11 3D vertex shader");
-
- result = device->CreateGeometryShader(g_GS_Passthrough3D, ArraySize(g_GS_Passthrough3D), NULL, &mQuad3DGS);
- ASSERT(SUCCEEDED(result));
- d3d11::SetDebugName(mQuad3DGS, "Renderer11 copy 3D texture geometry shader");
+ freeResources();
+ return gl::Error(GL_OUT_OF_MEMORY,
+ "Failed to create blit depth stencil state, HRESULT: 0x%X", result);
}
-
- buildShaderMap();
+ d3d11::SetDebugName(mDepthStencilState, "Blit11 depth stencil state");
D3D11_BUFFER_DESC swizzleBufferDesc;
swizzleBufferDesc.ByteWidth = sizeof(unsigned int) * 4;
@@ -328,12 +426,22 @@ Blit11::Blit11(Renderer11 *renderer)
swizzleBufferDesc.MiscFlags = 0;
swizzleBufferDesc.StructureByteStride = 0;
- result = device->CreateBuffer(&swizzleBufferDesc, NULL, &mSwizzleCB);
+ result = device->CreateBuffer(&swizzleBufferDesc, nullptr, &mSwizzleCB);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ freeResources();
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create blit swizzle buffer, HRESULT: 0x%X",
+ result);
+ }
d3d11::SetDebugName(mSwizzleCB, "Blit11 swizzle constant buffer");
+
+ mResourcesInitialized = true;
+
+ return gl::Error(GL_NO_ERROR);
}
-Blit11::~Blit11()
+void Blit11::freeResources()
{
SafeRelease(mVertexBuffer);
SafeRelease(mPointSampler);
@@ -341,41 +449,176 @@ Blit11::~Blit11()
SafeRelease(mScissorEnabledRasterizerState);
SafeRelease(mScissorDisabledRasterizerState);
SafeRelease(mDepthStencilState);
+ SafeRelease(mSwizzleCB);
- SafeRelease(mQuad2DIL);
- SafeRelease(mQuad2DVS);
- SafeRelease(mDepthPS);
-
- SafeRelease(mQuad3DIL);
- SafeRelease(mQuad3DVS);
- SafeRelease(mQuad3DGS);
+ mResourcesInitialized = false;
+}
- SafeRelease(mSwizzleCB);
+// static
+Blit11::BlitShaderType Blit11::GetBlitShaderType(GLenum destinationFormat, bool isSigned, ShaderDimension dimension)
+{
+ if (dimension == SHADER_3D)
+ {
+ if (isSigned)
+ {
+ switch (destinationFormat)
+ {
+ case GL_RGBA_INTEGER: return BLITSHADER_3D_RGBAI;
+ case GL_RGB_INTEGER: return BLITSHADER_3D_RGBI;
+ case GL_RG_INTEGER: return BLITSHADER_3D_RGI;
+ case GL_RED_INTEGER: return BLITSHADER_3D_RI;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ }
+ else
+ {
+ switch (destinationFormat)
+ {
+ case GL_RGBA: return BLITSHADER_3D_RGBAF;
+ case GL_RGBA_INTEGER: return BLITSHADER_3D_RGBAUI;
+ case GL_BGRA_EXT: return BLITSHADER_3D_BGRAF;
+ case GL_RGB: return BLITSHADER_3D_RGBF;
+ case GL_RGB_INTEGER: return BLITSHADER_3D_RGBUI;
+ case GL_RG: return BLITSHADER_3D_RGF;
+ case GL_RG_INTEGER: return BLITSHADER_3D_RGUI;
+ case GL_RED: return BLITSHADER_3D_RF;
+ case GL_RED_INTEGER: return BLITSHADER_3D_RUI;
+ case GL_ALPHA: return BLITSHADER_3D_ALPHA;
+ case GL_LUMINANCE: return BLITSHADER_3D_LUMA;
+ case GL_LUMINANCE_ALPHA: return BLITSHADER_3D_LUMAALPHA;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ }
+ }
+ else if (isSigned)
+ {
+ switch (destinationFormat)
+ {
+ case GL_RGBA_INTEGER: return BLITSHADER_2D_RGBAI;
+ case GL_RGB_INTEGER: return BLITSHADER_2D_RGBI;
+ case GL_RG_INTEGER: return BLITSHADER_2D_RGI;
+ case GL_RED_INTEGER: return BLITSHADER_2D_RI;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ }
+ else
+ {
+ switch (destinationFormat)
+ {
+ case GL_RGBA: return BLITSHADER_2D_RGBAF;
+ case GL_RGBA_INTEGER: return BLITSHADER_2D_RGBAUI;
+ case GL_BGRA_EXT: return BLITSHADER_2D_BGRAF;
+ case GL_RGB: return BLITSHADER_2D_RGBF;
+ case GL_RGB_INTEGER: return BLITSHADER_2D_RGBUI;
+ case GL_RG: return BLITSHADER_2D_RGF;
+ case GL_RG_INTEGER: return BLITSHADER_2D_RGUI;
+ case GL_RED: return BLITSHADER_2D_RF;
+ case GL_RED_INTEGER: return BLITSHADER_2D_RUI;
+ case GL_ALPHA: return BLITSHADER_2D_ALPHA;
+ case GL_LUMINANCE: return BLITSHADER_2D_LUMA;
+ case GL_LUMINANCE_ALPHA: return BLITSHADER_2D_LUMAALPHA;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ }
+}
- clearShaderMap();
+// static
+Blit11::SwizzleShaderType Blit11::GetSwizzleShaderType(GLenum type, D3D11_SRV_DIMENSION dimensionality)
+{
+ switch (dimensionality)
+ {
+ case D3D11_SRV_DIMENSION_TEXTURE2D:
+ switch (type)
+ {
+ case GL_FLOAT: return SWIZZLESHADER_2D_FLOAT;
+ case GL_UNSIGNED_INT: return SWIZZLESHADER_2D_UINT;
+ case GL_INT: return SWIZZLESHADER_2D_INT;
+ default:
+ UNREACHABLE();
+ return SWIZZLESHADER_INVALID;
+ }
+ case D3D11_SRV_DIMENSION_TEXTURECUBE:
+ switch (type)
+ {
+ case GL_FLOAT: return SWIZZLESHADER_CUBE_FLOAT;
+ case GL_UNSIGNED_INT: return SWIZZLESHADER_CUBE_UINT;
+ case GL_INT: return SWIZZLESHADER_CUBE_INT;
+ default:
+ UNREACHABLE();
+ return SWIZZLESHADER_INVALID;
+ }
+ case D3D11_SRV_DIMENSION_TEXTURE3D:
+ switch (type)
+ {
+ case GL_FLOAT: return SWIZZLESHADER_3D_FLOAT;
+ case GL_UNSIGNED_INT: return SWIZZLESHADER_3D_UINT;
+ case GL_INT: return SWIZZLESHADER_3D_INT;
+ default:
+ UNREACHABLE();
+ return SWIZZLESHADER_INVALID;
+ }
+ case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
+ switch (type)
+ {
+ case GL_FLOAT: return SWIZZLESHADER_ARRAY_FLOAT;
+ case GL_UNSIGNED_INT: return SWIZZLESHADER_ARRAY_UINT;
+ case GL_INT: return SWIZZLESHADER_ARRAY_INT;
+ default:
+ UNREACHABLE();
+ return SWIZZLESHADER_INVALID;
+ }
+ default:
+ UNREACHABLE();
+ return SWIZZLESHADER_INVALID;
+ }
}
-static inline unsigned int GetSwizzleIndex(GLenum swizzle)
+Blit11::ShaderSupport Blit11::getShaderSupport(const Shader &shader)
{
- unsigned int colorIndex = 0;
+ ID3D11Device *device = mRenderer->getDevice();
+ ShaderSupport support;
- switch (swizzle)
+ if (shader.dimension == SHADER_2D)
{
- case GL_RED: colorIndex = 0; break;
- case GL_GREEN: colorIndex = 1; break;
- case GL_BLUE: colorIndex = 2; break;
- case GL_ALPHA: colorIndex = 3; break;
- case GL_ZERO: colorIndex = 4; break;
- case GL_ONE: colorIndex = 5; break;
- default: UNREACHABLE(); break;
+ support.inputLayout = mQuad2DIL.resolve(device);
+ support.vertexShader = mQuad2DVS.resolve(device);
+ support.geometryShader = nullptr;
+ support.vertexWriteFunction = Write2DVertices;
+ }
+ else
+ {
+ ASSERT(shader.dimension == SHADER_3D);
+ support.inputLayout = mQuad3DIL.resolve(device);
+ support.vertexShader = mQuad3DVS.resolve(device);
+ support.geometryShader = mQuad3DGS.resolve(device);
+ support.vertexWriteFunction = Write3DVertices;
}
- return colorIndex;
+ return support;
}
-gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderTargetView *dest, const gl::Extents &size,
- GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha)
+gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source,
+ ID3D11RenderTargetView *dest,
+ const gl::Extents &size,
+ GLenum swizzleRed,
+ GLenum swizzleGreen,
+ GLenum swizzleBlue,
+ GLenum swizzleAlpha)
{
+ gl::Error error = initResources();
+ if (error.isError())
+ {
+ return error;
+ }
+
HRESULT result;
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
@@ -404,19 +647,13 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT
break;
}
- SwizzleParameters parameters = { 0 };
- parameters.mDestinationType = shaderType;
- parameters.mViewDimension = sourceSRVDesc.ViewDimension;
-
- SwizzleShaderMap::const_iterator i = mSwizzleShaderMap.find(parameters);
- if (i == mSwizzleShaderMap.end())
+ const Shader *shader = nullptr;
+ error = getSwizzleShader(shaderType, sourceSRVDesc.ViewDimension, &shader);
+ if (error.isError())
{
- UNREACHABLE();
- return gl::Error(GL_INVALID_OPERATION, "Internal error, missing swizzle shader.");
+ return error;
}
- const Shader &shader = i->second;
-
// Set vertices
D3D11_MAPPED_SUBRESOURCE mappedResource;
result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
@@ -425,13 +662,15 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT
return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer for swizzle, HRESULT: 0x%X.", result);
}
+ const ShaderSupport &support = getShaderSupport(*shader);
+
UINT stride = 0;
UINT startIdx = 0;
UINT drawCount = 0;
D3D11_PRIMITIVE_TOPOLOGY topology;
gl::Box area(0, 0, 0, size.width, size.height, size.depth);
- shader.mVertexWriteFunction(area, size, area, size, mappedResource.pData, &stride, &drawCount, &topology);
+ support.vertexWriteFunction(area, size, area, size, mappedResource.pData, &stride, &drawCount, &topology);
deviceContext->Unmap(mVertexBuffer, 0);
@@ -457,20 +696,21 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT
deviceContext->PSSetConstantBuffers(0, 1, &mSwizzleCB);
// Apply state
- deviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF);
- deviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF);
+ deviceContext->OMSetBlendState(nullptr, nullptr, 0xFFFFFFF);
+ deviceContext->OMSetDepthStencilState(nullptr, 0xFFFFFFFF);
deviceContext->RSSetState(mScissorDisabledRasterizerState);
// Apply shaders
- deviceContext->IASetInputLayout(shader.mInputLayout);
+ deviceContext->IASetInputLayout(support.inputLayout);
deviceContext->IASetPrimitiveTopology(topology);
- deviceContext->VSSetShader(shader.mVertexShader, NULL, 0);
+ deviceContext->VSSetShader(support.vertexShader, nullptr, 0);
- deviceContext->PSSetShader(shader.mPixelShader, NULL, 0);
- deviceContext->GSSetShader(shader.mGeometryShader, NULL, 0);
+ deviceContext->PSSetShader(shader->pixelShader, nullptr, 0);
+ deviceContext->GSSetShader(support.geometryShader, nullptr, 0);
// Unset the currently bound shader resource to avoid conflicts
- mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
+ auto stateManager = mRenderer->getStateManager();
+ stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr);
// Apply render target
mRenderer->setOneTimeRenderTarget(dest);
@@ -479,14 +719,14 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT
D3D11_VIEWPORT viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
- viewport.Width = size.width;
- viewport.Height = size.height;
+ viewport.Width = static_cast<FLOAT>(size.width);
+ viewport.Height = static_cast<FLOAT>(size.height);
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
deviceContext->RSSetViewports(1, &viewport);
// Apply textures
- mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source);
+ stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, source);
// Apply samplers
deviceContext->PSSetSamplers(0, 1, &mPointSampler);
@@ -495,12 +735,12 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT
deviceContext->Draw(drawCount, 0);
// Unbind textures and render targets and vertex buffer
- mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
+ stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr);
mRenderer->unapplyRenderTargets();
UINT zero = 0;
- ID3D11Buffer *const nullBuffer = NULL;
+ ID3D11Buffer *const nullBuffer = nullptr;
deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero);
mRenderer->markAllStateDirty();
@@ -508,10 +748,23 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT
return gl::Error(GL_NO_ERROR);
}
-gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
- ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize,
- const gl::Rectangle *scissor, GLenum destFormat, GLenum filter)
+gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source,
+ const gl::Box &sourceArea,
+ const gl::Extents &sourceSize,
+ ID3D11RenderTargetView *dest,
+ const gl::Box &destArea,
+ const gl::Extents &destSize,
+ const gl::Rectangle *scissor,
+ GLenum destFormat,
+ GLenum filter,
+ bool maskOffAlpha)
{
+ gl::Error error = initResources();
+ if (error.isError())
+ {
+ return error;
+ }
+
HRESULT result;
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
@@ -523,19 +776,17 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &s
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(sourceSRVDesc.Format);
const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(dxgiFormatInfo.internalFormat);
- BlitParameters parameters = { 0 };
- parameters.mDestinationFormat = destFormat;
- parameters.mSignedInteger = (internalFormatInfo.componentType == GL_INT);
- parameters.m3DBlit = sourceSRVDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE3D;
+ bool isSigned = (internalFormatInfo.componentType == GL_INT);
+ ShaderDimension dimension = (sourceSRVDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE3D) ? SHADER_3D : SHADER_2D;
- BlitShaderMap::const_iterator i = mBlitShaderMap.find(parameters);
- if (i == mBlitShaderMap.end())
+ const Shader *shader = nullptr;
+ error = getBlitShader(destFormat, isSigned, dimension, &shader);
+ if (error.isError())
{
- UNREACHABLE();
- return gl::Error(GL_OUT_OF_MEMORY, "Could not find appropriate shader for internal texture blit.");
+ return error;
}
- const Shader& shader = i->second;
+ const ShaderSupport &support = getShaderSupport(*shader);
// Set vertices
D3D11_MAPPED_SUBRESOURCE mappedResource;
@@ -550,7 +801,7 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &s
UINT drawCount = 0;
D3D11_PRIMITIVE_TOPOLOGY topology;
- shader.mVertexWriteFunction(sourceArea, sourceSize, destArea, destSize, mappedResource.pData,
+ support.vertexWriteFunction(sourceArea, sourceSize, destArea, destSize, mappedResource.pData,
&stride, &drawCount, &topology);
deviceContext->Unmap(mVertexBuffer, 0);
@@ -559,8 +810,17 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &s
deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &stride, &startIdx);
// Apply state
- deviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF);
- deviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF);
+ if (maskOffAlpha)
+ {
+ ID3D11BlendState *blendState = mAlphaMaskBlendState.resolve(mRenderer->getDevice());
+ ASSERT(blendState);
+ deviceContext->OMSetBlendState(blendState, nullptr, 0xFFFFFFF);
+ }
+ else
+ {
+ deviceContext->OMSetBlendState(nullptr, nullptr, 0xFFFFFFF);
+ }
+ deviceContext->OMSetDepthStencilState(nullptr, 0xFFFFFFFF);
if (scissor)
{
@@ -579,15 +839,16 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &s
}
// Apply shaders
- deviceContext->IASetInputLayout(shader.mInputLayout);
+ deviceContext->IASetInputLayout(support.inputLayout);
deviceContext->IASetPrimitiveTopology(topology);
- deviceContext->VSSetShader(shader.mVertexShader, NULL, 0);
+ deviceContext->VSSetShader(support.vertexShader, nullptr, 0);
- deviceContext->PSSetShader(shader.mPixelShader, NULL, 0);
- deviceContext->GSSetShader(shader.mGeometryShader, NULL, 0);
+ deviceContext->PSSetShader(shader->pixelShader, nullptr, 0);
+ deviceContext->GSSetShader(support.geometryShader, nullptr, 0);
// Unset the currently bound shader resource to avoid conflicts
- mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
+ auto stateManager = mRenderer->getStateManager();
+ stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr);
// Apply render target
mRenderer->setOneTimeRenderTarget(dest);
@@ -596,17 +857,17 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &s
D3D11_VIEWPORT viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
- viewport.Width = destSize.width;
- viewport.Height = destSize.height;
+ viewport.Width = static_cast<FLOAT>(destSize.width);
+ viewport.Height = static_cast<FLOAT>(destSize.height);
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
deviceContext->RSSetViewports(1, &viewport);
// Apply textures
- mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source);
+ stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, source);
// Apply samplers
- ID3D11SamplerState *sampler = NULL;
+ ID3D11SamplerState *sampler = nullptr;
switch (filter)
{
case GL_NEAREST: sampler = mPointSampler; break;
@@ -622,12 +883,12 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &s
deviceContext->Draw(drawCount, 0);
// Unbind textures and render targets and vertex buffer
- mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
+ stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr);
mRenderer->unapplyRenderTargets();
UINT zero = 0;
- ID3D11Buffer *const nullBuffer = NULL;
+ ID3D11Buffer *const nullBuffer = nullptr;
deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero);
mRenderer->markAllStateDirty();
@@ -648,6 +909,12 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou
ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize,
const gl::Rectangle *scissor)
{
+ gl::Error error = initResources();
+ if (error.isError())
+ {
+ return error;
+ }
+
HRESULT result;
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
@@ -673,7 +940,7 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou
deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &stride, &startIdx);
// Apply state
- deviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF);
+ deviceContext->OMSetBlendState(nullptr, nullptr, 0xFFFFFFF);
deviceContext->OMSetDepthStencilState(mDepthStencilState, 0xFFFFFFFF);
if (scissor)
@@ -692,32 +959,40 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou
deviceContext->RSSetState(mScissorDisabledRasterizerState);
}
+ ID3D11Device *device = mRenderer->getDevice();
+ ID3D11VertexShader *quad2DVS = mQuad2DVS.resolve(device);
+ if (quad2DVS == nullptr)
+ {
+ return gl::Error(GL_INVALID_OPERATION, "Error compiling internal 2D blit vertex shader");
+ }
+
// Apply shaders
- deviceContext->IASetInputLayout(mQuad2DIL);
+ deviceContext->IASetInputLayout(mQuad2DIL.resolve(device));
deviceContext->IASetPrimitiveTopology(topology);
- deviceContext->VSSetShader(mQuad2DVS, NULL, 0);
+ deviceContext->VSSetShader(quad2DVS, nullptr, 0);
- deviceContext->PSSetShader(mDepthPS, NULL, 0);
- deviceContext->GSSetShader(NULL, NULL, 0);
+ deviceContext->PSSetShader(mDepthPS.resolve(device), nullptr, 0);
+ deviceContext->GSSetShader(nullptr, nullptr, 0);
// Unset the currently bound shader resource to avoid conflicts
- mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
+ auto stateManager = mRenderer->getStateManager();
+ stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr);
// Apply render target
- deviceContext->OMSetRenderTargets(0, NULL, dest);
+ deviceContext->OMSetRenderTargets(0, nullptr, dest);
// Set the viewport
D3D11_VIEWPORT viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
- viewport.Width = destSize.width;
- viewport.Height = destSize.height;
+ viewport.Width = static_cast<FLOAT>(destSize.width);
+ viewport.Height = static_cast<FLOAT>(destSize.height);
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
deviceContext->RSSetViewports(1, &viewport);
// Apply textures
- mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source);
+ stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, source);
// Apply samplers
deviceContext->PSSetSamplers(0, 1, &mPointSampler);
@@ -726,12 +1001,12 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou
deviceContext->Draw(drawCount, 0);
// Unbind textures and render targets and vertex buffer
- mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
+ stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr);
mRenderer->unapplyRenderTargets();
UINT zero = 0;
- ID3D11Buffer *const nullBuffer = NULL;
+ ID3D11Buffer *const nullBuffer = nullptr;
deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero);
mRenderer->markAllStateDirty();
@@ -752,6 +1027,12 @@ gl::Error Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSu
ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
const gl::Rectangle *scissor, bool stencilOnly)
{
+ gl::Error error = initResources();
+ if (error.isError())
+ {
+ return error;
+ }
+
ID3D11Device *device = mRenderer->getDevice();
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
@@ -826,7 +1107,7 @@ gl::Error Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSu
float yPerc = static_cast<float>(y - destArea.y) / (destArea.height - 1);
// Interpolate using the original source rectangle to determine which row to sample from while clamping to the edges
- unsigned int readRow = gl::clamp(sourceArea.y + floor(yPerc * (sourceArea.height - 1) + 0.5f), 0, sourceSize.height - 1);
+ unsigned int readRow = static_cast<unsigned int>(gl::clamp(sourceArea.y + floor(yPerc * (sourceArea.height - 1) + 0.5f), 0, sourceSize.height - 1));
unsigned int writeRow = y;
if (wholeRowCopy)
@@ -848,7 +1129,7 @@ gl::Error Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSu
float xPerc = static_cast<float>(x - destArea.x) / (destArea.width - 1);
// Interpolate the original source rectangle to determine which column to sample from while clamping to the edges
- unsigned int readColumn = gl::clamp(sourceArea.x + floor(xPerc * (sourceArea.width - 1) + 0.5f), 0, sourceSize.width - 1);
+ unsigned int readColumn = static_cast<unsigned int>(gl::clamp(sourceArea.x + floor(xPerc * (sourceArea.width - 1) + 0.5f), 0, sourceSize.width - 1));
unsigned int writeColumn = x;
void *sourcePixel = reinterpret_cast<char*>(sourceMapping.pData) +
@@ -868,14 +1149,14 @@ gl::Error Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSu
// HACK: Use ID3D11DevicContext::UpdateSubresource which causes an extra copy compared to ID3D11DevicContext::CopySubresourceRegion
// according to MSDN.
- deviceContext->UpdateSubresource(dest, destSubresource, NULL, destMapping.pData, destMapping.RowPitch, destMapping.DepthPitch);
+ deviceContext->UpdateSubresource(dest, destSubresource, nullptr, destMapping.pData, destMapping.RowPitch, destMapping.DepthPitch);
deviceContext->Unmap(sourceStaging, 0);
deviceContext->Unmap(destStaging, 0);
// TODO: Determine why this call to ID3D11DevicContext::CopySubresourceRegion causes a TDR timeout on some
// systems when called repeatedly.
- // deviceContext->CopySubresourceRegion(dest, destSubresource, 0, 0, 0, destStaging, 0, NULL);
+ // deviceContext->CopySubresourceRegion(dest, destSubresource, 0, 0, 0, destStaging, 0, nullptr);
SafeRelease(sourceStaging);
SafeRelease(destStaging);
@@ -883,177 +1164,242 @@ gl::Error Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSu
return gl::Error(GL_NO_ERROR);
}
-bool Blit11::compareBlitParameters(const Blit11::BlitParameters &a, const Blit11::BlitParameters &b)
+void Blit11::addBlitShaderToMap(BlitShaderType blitShaderType, ShaderDimension dimension, ID3D11PixelShader *ps)
{
- return memcmp(&a, &b, sizeof(Blit11::BlitParameters)) < 0;
-}
+ ASSERT(mBlitShaderMap.find(blitShaderType) == mBlitShaderMap.end());
+ ASSERT(ps);
-bool Blit11::compareSwizzleParameters(const SwizzleParameters &a, const SwizzleParameters &b)
-{
- return memcmp(&a, &b, sizeof(Blit11::SwizzleParameters)) < 0;
+ Shader shader;
+ shader.dimension = dimension;
+ shader.pixelShader = ps;
+
+ mBlitShaderMap[blitShaderType] = shader;
}
-void Blit11::add2DBlitShaderToMap(GLenum destFormat, bool signedInteger, ID3D11PixelShader *ps)
+void Blit11::addSwizzleShaderToMap(SwizzleShaderType swizzleShaderType, ShaderDimension dimension, ID3D11PixelShader *ps)
{
- BlitParameters params = { 0 };
- params.mDestinationFormat = destFormat;
- params.mSignedInteger = signedInteger;
- params.m3DBlit = false;
-
- ASSERT(mBlitShaderMap.find(params) == mBlitShaderMap.end());
+ ASSERT(mSwizzleShaderMap.find(swizzleShaderType) == mSwizzleShaderMap.end());
ASSERT(ps);
Shader shader;
- shader.mVertexWriteFunction = Write2DVertices;
- shader.mInputLayout = mQuad2DIL;
- shader.mVertexShader = mQuad2DVS;
- shader.mGeometryShader = NULL;
- shader.mPixelShader = ps;
+ shader.dimension = dimension;
+ shader.pixelShader = ps;
- mBlitShaderMap[params] = shader;
+ mSwizzleShaderMap[swizzleShaderType] = shader;
}
-void Blit11::add3DBlitShaderToMap(GLenum destFormat, bool signedInteger, ID3D11PixelShader *ps)
+void Blit11::clearShaderMap()
{
- BlitParameters params = { 0 };
- params.mDestinationFormat = destFormat;
- params.mSignedInteger = signedInteger;
- params.m3DBlit = true;
-
- ASSERT(mBlitShaderMap.find(params) == mBlitShaderMap.end());
- ASSERT(ps);
-
- Shader shader;
- shader.mVertexWriteFunction = Write3DVertices;
- shader.mInputLayout = mQuad3DIL;
- shader.mVertexShader = mQuad3DVS;
- shader.mGeometryShader = mQuad3DGS;
- shader.mPixelShader = ps;
+ for (auto &blitShader : mBlitShaderMap)
+ {
+ SafeRelease(blitShader.second.pixelShader);
+ }
+ mBlitShaderMap.clear();
- mBlitShaderMap[params] = shader;
+ for (auto &swizzleShader : mSwizzleShaderMap)
+ {
+ SafeRelease(swizzleShader.second.pixelShader);
+ }
+ mSwizzleShaderMap.clear();
}
-void Blit11::addSwizzleShaderToMap(GLenum destType, D3D11_SRV_DIMENSION viewDimension, ID3D11PixelShader *ps)
+gl::Error Blit11::getBlitShader(GLenum destFormat, bool isSigned, ShaderDimension dimension, const Shader **shader)
{
- SwizzleParameters params = { 0 };
- params.mDestinationType = destType;
- params.mViewDimension = viewDimension;
+ BlitShaderType blitShaderType = GetBlitShaderType(destFormat, isSigned, dimension);
- ASSERT(mSwizzleShaderMap.find(params) == mSwizzleShaderMap.end());
- ASSERT(ps);
+ if (blitShaderType == BLITSHADER_INVALID)
+ {
+ return gl::Error(GL_INVALID_OPERATION, "Internal blit shader type mismatch");
+ }
- Shader shader;
- switch (viewDimension)
+ auto blitShaderIt = mBlitShaderMap.find(blitShaderType);
+ if (blitShaderIt != mBlitShaderMap.end())
{
- case D3D_SRV_DIMENSION_TEXTURE2D:
- shader.mVertexWriteFunction = Write2DVertices;
- shader.mInputLayout = mQuad2DIL;
- shader.mVertexShader = mQuad2DVS;
- shader.mGeometryShader = NULL;
- break;
+ *shader = &blitShaderIt->second;
+ return gl::Error(GL_NO_ERROR);
+ }
- case D3D_SRV_DIMENSION_TEXTURE3D:
- case D3D_SRV_DIMENSION_TEXTURE2DARRAY:
- case D3D_SRV_DIMENSION_TEXTURECUBE:
- shader.mVertexWriteFunction = Write3DVertices;
- shader.mInputLayout = mQuad3DIL;
- shader.mVertexShader = mQuad3DVS;
- shader.mGeometryShader = mQuad3DGS;
- break;
+ ASSERT(dimension == SHADER_2D || mRenderer->isES3Capable());
+ ID3D11Device *device = mRenderer->getDevice();
+
+ switch (blitShaderType)
+ {
+ case BLITSHADER_2D_RGBAF:
+ addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D RGBA pixel shader"));
+ break;
+ case BLITSHADER_2D_BGRAF:
+ addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D BGRA pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBF:
+ addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGB2D, "Blit11 2D RGB pixel shader"));
+ break;
+ case BLITSHADER_2D_RGF:
+ addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRG2D, "Blit11 2D RG pixel shader"));
+ break;
+ case BLITSHADER_2D_RF:
+ addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughR2D, "Blit11 2D R pixel shader"));
+ break;
+ case BLITSHADER_2D_ALPHA:
+ addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D alpha pixel shader"));
+ break;
+ case BLITSHADER_2D_LUMA:
+ addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughLum2D, "Blit11 2D lum pixel shader"));
+ break;
+ case BLITSHADER_2D_LUMAALPHA:
+ addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughLumAlpha2D, "Blit11 2D luminance alpha pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBAUI:
+ addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGBA2DUI, "Blit11 2D RGBA UI pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBAI:
+ addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGBA2DI, "Blit11 2D RGBA I pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBUI:
+ addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGB2DUI, "Blit11 2D RGB UI pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBI:
+ addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGB2DI, "Blit11 2D RGB I pixel shader"));
+ break;
+ case BLITSHADER_2D_RGUI:
+ addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRG2DUI, "Blit11 2D RG UI pixel shader"));
+ break;
+ case BLITSHADER_2D_RGI:
+ addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRG2DI, "Blit11 2D RG I pixel shader"));
+ break;
+ case BLITSHADER_2D_RUI:
+ addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughR2DUI, "Blit11 2D R UI pixel shader"));
+ break;
+ case BLITSHADER_2D_RI:
+ addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughR2DI, "Blit11 2D R I pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBAF:
+ addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D RGBA pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBAUI:
+ addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DUI, "Blit11 3D UI RGBA pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBAI:
+ addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DI, "Blit11 3D I RGBA pixel shader"));
+ break;
+ case BLITSHADER_3D_BGRAF:
+ addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D BGRA pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBF:
+ addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGB3D, "Blit11 3D RGB pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBUI:
+ addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGB3DUI, "Blit11 3D RGB UI pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBI:
+ addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGB3DI, "Blit11 3D RGB I pixel shader"));
+ break;
+ case BLITSHADER_3D_RGF:
+ addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRG3D, "Blit11 3D RG pixel shader"));
+ break;
+ case BLITSHADER_3D_RGUI:
+ addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRG3DUI, "Blit11 3D RG UI pixel shader"));
+ break;
+ case BLITSHADER_3D_RGI:
+ addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRG3DI, "Blit11 3D RG I pixel shader"));
+ break;
+ case BLITSHADER_3D_RF:
+ addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R pixel shader"));
+ break;
+ case BLITSHADER_3D_RUI:
+ addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughR3DUI, "Blit11 3D R UI pixel shader"));
+ break;
+ case BLITSHADER_3D_RI:
+ addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughR3DI, "Blit11 3D R I pixel shader"));
+ break;
+ case BLITSHADER_3D_ALPHA:
+ addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D alpha pixel shader"));
+ break;
+ case BLITSHADER_3D_LUMA:
+ addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughLum3D, "Blit11 3D luminance pixel shader"));
+ break;
+ case BLITSHADER_3D_LUMAALPHA:
+ addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughLumAlpha3D, "Blit11 3D luminance alpha pixel shader"));
+ break;
default:
UNREACHABLE();
- break;
+ return gl::Error(GL_INVALID_OPERATION, "Internal error");
}
- shader.mPixelShader = ps;
- mSwizzleShaderMap[params] = shader;
+ blitShaderIt = mBlitShaderMap.find(blitShaderType);
+ ASSERT(blitShaderIt != mBlitShaderMap.end());
+ *shader = &blitShaderIt->second;
+ return gl::Error(GL_NO_ERROR);
}
-void Blit11::buildShaderMap()
+gl::Error Blit11::getSwizzleShader(GLenum type, D3D11_SRV_DIMENSION viewDimension, const Shader **shader)
{
- ID3D11Device *device = mRenderer->getDevice();
+ SwizzleShaderType swizzleShaderType = GetSwizzleShaderType(type, viewDimension);
- // 2D shaders (OpenGL ES 2+)
- add2DBlitShaderToMap(GL_RGBA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D RGBA pixel shader" ));
- add2DBlitShaderToMap(GL_BGRA_EXT, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D BGRA pixel shader" ));
- add2DBlitShaderToMap(GL_RGB, false, d3d11::CompilePS(device, g_PS_PassthroughRGB2D, "Blit11 2D RGB pixel shader" ));
- add2DBlitShaderToMap(GL_RG, false, d3d11::CompilePS(device, g_PS_PassthroughRG2D, "Blit11 2D RG pixel shader" ));
- add2DBlitShaderToMap(GL_RED, false, d3d11::CompilePS(device, g_PS_PassthroughR2D, "Blit11 2D R pixel shader" ));
- add2DBlitShaderToMap(GL_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D alpha pixel shader" ));
- add2DBlitShaderToMap(GL_LUMINANCE, false, d3d11::CompilePS(device, g_PS_PassthroughLum2D, "Blit11 2D lum pixel shader" ));
- add2DBlitShaderToMap(GL_LUMINANCE_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughLumAlpha2D, "Blit11 2D luminance alpha pixel shader"));
-
- // 2D shaders (OpenGL ES 3+)
- if (mRenderer->isES3Capable())
+ if (swizzleShaderType == SWIZZLESHADER_INVALID)
{
- add2DBlitShaderToMap(GL_RGBA_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA2DUI, "Blit11 2D RGBA UI pixel shader" ));
- add2DBlitShaderToMap(GL_RGBA_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGBA2DI, "Blit11 2D RGBA I pixel shader" ));
- add2DBlitShaderToMap(GL_RGB_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGB2DUI, "Blit11 2D RGB UI pixel shader" ));
- add2DBlitShaderToMap(GL_RGB_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGB2DI, "Blit11 2D RGB I pixel shader" ));
- add2DBlitShaderToMap(GL_RG_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRG2DUI, "Blit11 2D RG UI pixel shader" ));
- add2DBlitShaderToMap(GL_RG_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRG2DI, "Blit11 2D RG I pixel shader" ));
- add2DBlitShaderToMap(GL_RED_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughR2DUI, "Blit11 2D R UI pixel shader" ));
- add2DBlitShaderToMap(GL_RED_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughR2DI, "Blit11 2D R I pixel shader" ));
+ return gl::Error(GL_INVALID_OPERATION, "Swizzle shader type not found");
}
- // 3D shaders (OpenGL ES 3+)
- if (mRenderer->isES3Capable())
+ auto swizzleShaderIt = mSwizzleShaderMap.find(swizzleShaderType);
+ if (swizzleShaderIt != mSwizzleShaderMap.end())
{
- add3DBlitShaderToMap(GL_RGBA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D RGBA pixel shader" ));
- add3DBlitShaderToMap(GL_RGBA_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DUI, "Blit11 3D UI RGBA pixel shader" ));
- add3DBlitShaderToMap(GL_RGBA_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DI, "Blit11 3D I RGBA pixel shader" ));
- add3DBlitShaderToMap(GL_BGRA_EXT, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D BGRA pixel shader" ));
- add3DBlitShaderToMap(GL_RGB, false, d3d11::CompilePS(device, g_PS_PassthroughRGB3D, "Blit11 3D RGB pixel shader" ));
- add3DBlitShaderToMap(GL_RGB_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGB3DUI, "Blit11 3D RGB UI pixel shader" ));
- add3DBlitShaderToMap(GL_RGB_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGB3DI, "Blit11 3D RGB I pixel shader" ));
- add3DBlitShaderToMap(GL_RG, false, d3d11::CompilePS(device, g_PS_PassthroughRG3D, "Blit11 3D RG pixel shader" ));
- add3DBlitShaderToMap(GL_RG_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRG3DUI, "Blit11 3D RG UI pixel shader" ));
- add3DBlitShaderToMap(GL_RG_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRG3DI, "Blit11 3D RG I pixel shader" ));
- add3DBlitShaderToMap(GL_RED, false, d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R pixel shader" ));
- add3DBlitShaderToMap(GL_RED_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughR3DUI, "Blit11 3D R UI pixel shader" ));
- add3DBlitShaderToMap(GL_RED_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughR3DI, "Blit11 3D R I pixel shader" ));
- add3DBlitShaderToMap(GL_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D alpha pixel shader" ));
- add3DBlitShaderToMap(GL_LUMINANCE, false, d3d11::CompilePS(device, g_PS_PassthroughLum3D, "Blit11 3D luminance pixel shader" ));
- add3DBlitShaderToMap(GL_LUMINANCE_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughLumAlpha3D, "Blit11 3D luminance alpha pixel shader"));
+ *shader = &swizzleShaderIt->second;
+ return gl::Error(GL_NO_ERROR);
}
// Swizzling shaders (OpenGL ES 3+)
- if (mRenderer->isES3Capable())
- {
- addSwizzleShaderToMap(GL_FLOAT, D3D_SRV_DIMENSION_TEXTURE2D, d3d11::CompilePS(device, g_PS_SwizzleF2D, "Blit11 2D F swizzle pixel shader" ));
- addSwizzleShaderToMap(GL_UNSIGNED_INT, D3D_SRV_DIMENSION_TEXTURE2D, d3d11::CompilePS(device, g_PS_SwizzleUI2D, "Blit11 2D UI swizzle pixel shader"));
- addSwizzleShaderToMap(GL_INT, D3D_SRV_DIMENSION_TEXTURE2D, d3d11::CompilePS(device, g_PS_SwizzleI2D, "Blit11 2D I swizzle pixel shader" ));
-
- addSwizzleShaderToMap(GL_FLOAT, D3D_SRV_DIMENSION_TEXTURECUBE, d3d11::CompilePS(device, g_PS_SwizzleF2DArray, "Blit11 2D Cube F swizzle pixel shader" ));
- addSwizzleShaderToMap(GL_UNSIGNED_INT, D3D_SRV_DIMENSION_TEXTURECUBE, d3d11::CompilePS(device, g_PS_SwizzleUI2DArray, "Blit11 2D Cube UI swizzle pixel shader"));
- addSwizzleShaderToMap(GL_INT, D3D_SRV_DIMENSION_TEXTURECUBE, d3d11::CompilePS(device, g_PS_SwizzleI2DArray, "Blit11 2D Cube I swizzle pixel shader" ));
+ ASSERT(mRenderer->isES3Capable());
- addSwizzleShaderToMap(GL_FLOAT, D3D_SRV_DIMENSION_TEXTURE3D, d3d11::CompilePS(device, g_PS_SwizzleF3D, "Blit11 3D F swizzle pixel shader" ));
- addSwizzleShaderToMap(GL_UNSIGNED_INT, D3D_SRV_DIMENSION_TEXTURE3D, d3d11::CompilePS(device, g_PS_SwizzleUI3D, "Blit11 3D UI swizzle pixel shader"));
- addSwizzleShaderToMap(GL_INT, D3D_SRV_DIMENSION_TEXTURE3D, d3d11::CompilePS(device, g_PS_SwizzleI3D, "Blit11 3D I swizzle pixel shader" ));
-
- addSwizzleShaderToMap(GL_FLOAT, D3D_SRV_DIMENSION_TEXTURE2DARRAY, d3d11::CompilePS(device, g_PS_SwizzleF2DArray, "Blit11 2D Array F swizzle pixel shader" ));
- addSwizzleShaderToMap(GL_UNSIGNED_INT, D3D_SRV_DIMENSION_TEXTURE2DARRAY, d3d11::CompilePS(device, g_PS_SwizzleUI2DArray, "Blit11 2D Array UI swizzle pixel shader"));
- addSwizzleShaderToMap(GL_INT, D3D_SRV_DIMENSION_TEXTURE2DARRAY, d3d11::CompilePS(device, g_PS_SwizzleI2DArray, "Blit11 2D Array I swizzle pixel shader" ));
- }
-}
+ ID3D11Device *device = mRenderer->getDevice();
-void Blit11::clearShaderMap()
-{
- for (BlitShaderMap::iterator i = mBlitShaderMap.begin(); i != mBlitShaderMap.end(); ++i)
+ switch (swizzleShaderType)
{
- Shader &shader = i->second;
- SafeRelease(shader.mPixelShader);
+ case SWIZZLESHADER_2D_FLOAT:
+ addSwizzleShaderToMap(swizzleShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_SwizzleF2D, "Blit11 2D F swizzle pixel shader"));
+ break;
+ case SWIZZLESHADER_2D_UINT:
+ addSwizzleShaderToMap(swizzleShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_SwizzleUI2D, "Blit11 2D UI swizzle pixel shader"));
+ break;
+ case SWIZZLESHADER_2D_INT:
+ addSwizzleShaderToMap(swizzleShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_SwizzleI2D, "Blit11 2D I swizzle pixel shader"));
+ break;
+ case SWIZZLESHADER_CUBE_FLOAT:
+ addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleF2DArray, "Blit11 2D Cube F swizzle pixel shader"));
+ break;
+ case SWIZZLESHADER_CUBE_UINT:
+ addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleUI2DArray, "Blit11 2D Cube UI swizzle pixel shader"));
+ break;
+ case SWIZZLESHADER_CUBE_INT:
+ addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleI2DArray, "Blit11 2D Cube I swizzle pixel shader"));
+ break;
+ case SWIZZLESHADER_3D_FLOAT:
+ addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleF3D, "Blit11 3D F swizzle pixel shader"));
+ break;
+ case SWIZZLESHADER_3D_UINT:
+ addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleUI3D, "Blit11 3D UI swizzle pixel shader"));
+ break;
+ case SWIZZLESHADER_3D_INT:
+ addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleI3D, "Blit11 3D I swizzle pixel shader"));
+ break;
+ case SWIZZLESHADER_ARRAY_FLOAT:
+ addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleF2DArray, "Blit11 2D Array F swizzle pixel shader"));
+ break;
+ case SWIZZLESHADER_ARRAY_UINT:
+ addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleUI2DArray, "Blit11 2D Array UI swizzle pixel shader"));
+ break;
+ case SWIZZLESHADER_ARRAY_INT:
+ addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleI2DArray, "Blit11 2D Array I swizzle pixel shader"));
+ break;
+ default:
+ UNREACHABLE();
+ return gl::Error(GL_INVALID_OPERATION, "Internal error");
}
- mBlitShaderMap.clear();
- for (SwizzleShaderMap::iterator i = mSwizzleShaderMap.begin(); i != mSwizzleShaderMap.end(); ++i)
- {
- Shader &shader = i->second;
- SafeRelease(shader.mPixelShader);
- }
- mSwizzleShaderMap.clear();
+ swizzleShaderIt = mSwizzleShaderMap.find(swizzleShaderType);
+ ASSERT(swizzleShaderIt != mSwizzleShaderMap.end());
+ *shader = &swizzleShaderIt->second;
+ return gl::Error(GL_NO_ERROR);
}
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.h
index d3a8c2c8a3..906616131e 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.h
@@ -12,6 +12,7 @@
#include "common/angleutils.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/Error.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include <map>
@@ -28,9 +29,16 @@ class Blit11 : angle::NonCopyable
gl::Error swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderTargetView *dest, const gl::Extents &size,
GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha);
- gl::Error copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
- ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize,
- const gl::Rectangle *scissor, GLenum destFormat, GLenum filter);
+ gl::Error copyTexture(ID3D11ShaderResourceView *source,
+ const gl::Box &sourceArea,
+ const gl::Extents &sourceSize,
+ ID3D11RenderTargetView *dest,
+ const gl::Box &destArea,
+ const gl::Extents &destSize,
+ const gl::Rectangle *scissor,
+ GLenum destFormat,
+ GLenum filter,
+ bool maskOffAlpha);
gl::Error copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
@@ -45,59 +53,112 @@ class Blit11 : angle::NonCopyable
const gl::Rectangle *scissor);
private:
- Renderer11 *mRenderer;
-
- struct BlitParameters
+ enum BlitShaderType
{
- GLenum mDestinationFormat;
- bool mSignedInteger;
- bool m3DBlit;
+ BLITSHADER_INVALID,
+ BLITSHADER_2D_RGBAF,
+ BLITSHADER_2D_BGRAF,
+ BLITSHADER_2D_RGBF,
+ BLITSHADER_2D_RGF,
+ BLITSHADER_2D_RF,
+ BLITSHADER_2D_ALPHA,
+ BLITSHADER_2D_LUMA,
+ BLITSHADER_2D_LUMAALPHA,
+ BLITSHADER_2D_RGBAUI,
+ BLITSHADER_2D_RGBAI,
+ BLITSHADER_2D_RGBUI,
+ BLITSHADER_2D_RGBI,
+ BLITSHADER_2D_RGUI,
+ BLITSHADER_2D_RGI,
+ BLITSHADER_2D_RUI,
+ BLITSHADER_2D_RI,
+ BLITSHADER_3D_RGBAF,
+ BLITSHADER_3D_RGBAUI,
+ BLITSHADER_3D_RGBAI,
+ BLITSHADER_3D_BGRAF,
+ BLITSHADER_3D_RGBF,
+ BLITSHADER_3D_RGBUI,
+ BLITSHADER_3D_RGBI,
+ BLITSHADER_3D_RGF,
+ BLITSHADER_3D_RGUI,
+ BLITSHADER_3D_RGI,
+ BLITSHADER_3D_RF,
+ BLITSHADER_3D_RUI,
+ BLITSHADER_3D_RI,
+ BLITSHADER_3D_ALPHA,
+ BLITSHADER_3D_LUMA,
+ BLITSHADER_3D_LUMAALPHA,
};
- gl::Error copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
- ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
- const gl::Rectangle *scissor, bool stencilOnly);
-
- static bool compareBlitParameters(const BlitParameters &a, const BlitParameters &b);
+ enum SwizzleShaderType
+ {
+ SWIZZLESHADER_INVALID,
+ SWIZZLESHADER_2D_FLOAT,
+ SWIZZLESHADER_2D_UINT,
+ SWIZZLESHADER_2D_INT,
+ SWIZZLESHADER_CUBE_FLOAT,
+ SWIZZLESHADER_CUBE_UINT,
+ SWIZZLESHADER_CUBE_INT,
+ SWIZZLESHADER_3D_FLOAT,
+ SWIZZLESHADER_3D_UINT,
+ SWIZZLESHADER_3D_INT,
+ SWIZZLESHADER_ARRAY_FLOAT,
+ SWIZZLESHADER_ARRAY_UINT,
+ SWIZZLESHADER_ARRAY_INT,
+ };
typedef void (*WriteVertexFunction)(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);
- struct Shader
+ enum ShaderDimension
{
- WriteVertexFunction mVertexWriteFunction;
- ID3D11InputLayout *mInputLayout;
- ID3D11VertexShader *mVertexShader;
- ID3D11GeometryShader *mGeometryShader;
- ID3D11PixelShader *mPixelShader;
+ SHADER_2D,
+ SHADER_3D,
};
- typedef bool (*BlitParametersComparisonFunction)(const BlitParameters&, const BlitParameters &);
- typedef std::map<BlitParameters, Shader, BlitParametersComparisonFunction> BlitShaderMap;
- BlitShaderMap mBlitShaderMap;
-
- void add2DBlitShaderToMap(GLenum destFormat, bool signedInteger, ID3D11PixelShader *ps);
- void add3DBlitShaderToMap(GLenum destFormat, bool signedInteger, ID3D11PixelShader *ps);
+ struct Shader
+ {
+ ShaderDimension dimension;
+ ID3D11PixelShader *pixelShader;
+ };
- struct SwizzleParameters
+ struct ShaderSupport
{
- GLenum mDestinationType;
- D3D11_SRV_DIMENSION mViewDimension;
+ ID3D11InputLayout *inputLayout;
+ ID3D11VertexShader *vertexShader;
+ ID3D11GeometryShader *geometryShader;
+ WriteVertexFunction vertexWriteFunction;
};
- static bool compareSwizzleParameters(const SwizzleParameters &a, const SwizzleParameters &b);
+ gl::Error initResources();
+ void freeResources();
+
+ ShaderSupport getShaderSupport(const Shader &shader);
+
+ static BlitShaderType GetBlitShaderType(GLenum destinationFormat, bool isSigned, ShaderDimension dimension);
+ static SwizzleShaderType GetSwizzleShaderType(GLenum type, D3D11_SRV_DIMENSION dimensionality);
+
+ gl::Error copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
+ ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
+ const gl::Rectangle *scissor, bool stencilOnly);
+
+ void addBlitShaderToMap(BlitShaderType blitShaderType, ShaderDimension dimension, ID3D11PixelShader *ps);
- typedef bool (*SwizzleParametersComparisonFunction)(const SwizzleParameters&, const SwizzleParameters &);
- typedef std::map<SwizzleParameters, Shader, SwizzleParametersComparisonFunction> SwizzleShaderMap;
- SwizzleShaderMap mSwizzleShaderMap;
+ gl::Error getBlitShader(GLenum destFormat, bool isSigned, ShaderDimension dimension, const Shader **shaderOut);
+ gl::Error getSwizzleShader(GLenum type, D3D11_SRV_DIMENSION viewDimension, const Shader **shaderOut);
- void addSwizzleShaderToMap(GLenum destType, D3D11_SRV_DIMENSION viewDimension, ID3D11PixelShader *ps);
+ void addSwizzleShaderToMap(SwizzleShaderType swizzleShaderType, ShaderDimension dimension, ID3D11PixelShader *ps);
- void buildShaderMap();
void clearShaderMap();
+ Renderer11 *mRenderer;
+
+ std::map<BlitShaderType, Shader> mBlitShaderMap;
+ std::map<SwizzleShaderType, Shader> mSwizzleShaderMap;
+
+ bool mResourcesInitialized;
ID3D11Buffer *mVertexBuffer;
ID3D11SamplerState *mPointSampler;
ID3D11SamplerState *mLinearSampler;
@@ -105,13 +166,15 @@ class Blit11 : angle::NonCopyable
ID3D11RasterizerState *mScissorDisabledRasterizerState;
ID3D11DepthStencilState *mDepthStencilState;
- ID3D11InputLayout *mQuad2DIL;
- ID3D11VertexShader *mQuad2DVS;
- ID3D11PixelShader *mDepthPS;
+ d3d11::LazyInputLayout mQuad2DIL;
+ d3d11::LazyShader<ID3D11VertexShader> mQuad2DVS;
+ d3d11::LazyShader<ID3D11PixelShader> mDepthPS;
+
+ d3d11::LazyInputLayout mQuad3DIL;
+ d3d11::LazyShader<ID3D11VertexShader> mQuad3DVS;
+ d3d11::LazyShader<ID3D11GeometryShader> mQuad3DGS;
- ID3D11InputLayout *mQuad3DIL;
- ID3D11VertexShader *mQuad3DVS;
- ID3D11GeometryShader *mQuad3DGS;
+ d3d11::LazyBlendState mAlphaMaskBlendState;
ID3D11Buffer *mSwizzleCB;
};
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
index d56b0ea7ad..0d5dc08b03 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
@@ -8,10 +8,27 @@
#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
+#include <memory>
+
#include "common/MemoryBuffer.h"
+#include "libANGLE/renderer/d3d/IndexDataManager.h"
+#include "libANGLE/renderer/d3d/VertexDataManager.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+namespace
+{
+
+template <typename T>
+GLuint ReadIndexValueFromIndices(const uint8_t *data, size_t index)
+{
+ return reinterpret_cast<const T *>(data)[index];
+}
+typedef GLuint (*ReadIndexValueFunction)(const uint8_t *data, size_t index);
+}
+
#if defined(ANGLE_MINGW32_COMPAT)
typedef enum D3D11_MAP_FLAG {
D3D11_MAP_FLAG_DO_NOT_WAIT = 0x100000
@@ -20,32 +37,33 @@ typedef enum D3D11_MAP_FLAG {
namespace rx
{
-
PackPixelsParams::PackPixelsParams()
- : format(GL_NONE),
- type(GL_NONE),
- outputPitch(0),
- packBuffer(NULL),
- offset(0)
-{}
-
-PackPixelsParams::PackPixelsParams(const gl::Rectangle &areaIn, GLenum formatIn, GLenum typeIn, GLuint outputPitchIn,
- const gl::PixelPackState &packIn, ptrdiff_t offsetIn)
- : area(areaIn),
- format(formatIn),
- type(typeIn),
- outputPitch(outputPitchIn),
- packBuffer(packIn.pixelBuffer.get()),
- pack(packIn.alignment, packIn.reverseRowOrder),
- offset(offsetIn)
-{}
+ : format(GL_NONE), type(GL_NONE), outputPitch(0), packBuffer(nullptr), offset(0)
+{
+}
+
+PackPixelsParams::PackPixelsParams(const gl::Rectangle &areaIn,
+ GLenum formatIn,
+ GLenum typeIn,
+ GLuint outputPitchIn,
+ const gl::PixelPackState &packIn,
+ ptrdiff_t offsetIn)
+ : area(areaIn),
+ format(formatIn),
+ type(typeIn),
+ outputPitch(outputPitchIn),
+ packBuffer(packIn.pixelBuffer.get()),
+ pack(packIn.alignment, packIn.reverseRowOrder),
+ offset(offsetIn)
+{
+}
namespace gl_d3d11
{
D3D11_MAP GetD3DMapTypeFromBits(GLbitfield access)
{
- bool readBit = ((access & GL_MAP_READ_BIT) != 0);
+ bool readBit = ((access & GL_MAP_READ_BIT) != 0);
bool writeBit = ((access & GL_MAP_WRITE_BIT) != 0);
ASSERT(readBit || writeBit);
@@ -71,7 +89,6 @@ D3D11_MAP GetD3DMapTypeFromBits(GLbitfield access)
return D3D11_MAP_READ;
}
}
-
}
// Each instance of Buffer11::BufferStorage is specialized for a class of D3D binding points
@@ -91,8 +108,10 @@ class Buffer11::BufferStorage : angle::NonCopyable
virtual bool isMappable() const = 0;
- virtual bool copyFromStorage(BufferStorage *source, size_t sourceOffset,
- size_t size, size_t destOffset) = 0;
+ virtual bool copyFromStorage(BufferStorage *source,
+ size_t sourceOffset,
+ size_t size,
+ size_t destOffset) = 0;
virtual gl::Error resize(size_t size, bool preserveData) = 0;
virtual uint8_t *map(size_t offset, size_t length, GLbitfield access) = 0;
@@ -120,20 +139,57 @@ class Buffer11::NativeStorage : public Buffer11::BufferStorage
bool isMappable() const override { return mUsage == BUFFER_USAGE_STAGING; }
ID3D11Buffer *getNativeStorage() const { return mNativeStorage; }
-
- bool copyFromStorage(BufferStorage *source, size_t sourceOffset,
- size_t size, size_t destOffset) override;
+ bool copyFromStorage(BufferStorage *source,
+ size_t sourceOffset,
+ size_t size,
+ size_t destOffset) override;
gl::Error resize(size_t size, bool preserveData) override;
uint8_t *map(size_t offset, size_t length, GLbitfield access) override;
void unmap() override;
private:
- static void fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer11 *renderer, BufferUsage usage, unsigned int bufferSize);
+ static void fillBufferDesc(D3D11_BUFFER_DESC *bufferDesc,
+ Renderer11 *renderer,
+ BufferUsage usage,
+ unsigned int bufferSize);
ID3D11Buffer *mNativeStorage;
};
+// A emulated indexed buffer storage represents an underlying D3D11 buffer for data
+// that has been expanded to match the indices list used. This storage is only
+// used for FL9_3 pointsprite rendering emulation.
+class Buffer11::EmulatedIndexedStorage : public Buffer11::BufferStorage
+{
+ public:
+ EmulatedIndexedStorage(Renderer11 *renderer);
+ ~EmulatedIndexedStorage() override;
+
+ bool isMappable() const override { return true; }
+
+ ID3D11Buffer *getNativeStorage();
+
+ bool copyFromStorage(BufferStorage *source,
+ size_t sourceOffset,
+ size_t size,
+ size_t destOffset) override;
+
+ gl::Error resize(size_t size, bool preserveData) override;
+
+ uint8_t *map(size_t offset, size_t length, GLbitfield access) override;
+ void unmap() override;
+ bool update(SourceIndexData *indexInfo, const TranslatedAttribute *attribute);
+
+ private:
+ ID3D11Buffer *mNativeStorage; // contains expanded data for use by D3D
+ MemoryBuffer mMemoryBuffer; // original data (not expanded)
+ MemoryBuffer mIndicesMemoryBuffer; // indices data
+ SourceIndexData mIndexInfo; // indices information
+ size_t mAttributeStride; // per element stride in bytes
+ size_t mAttributeOffset; // starting offset
+};
+
// Pack storage represents internal storage for pack buffers. We implement pack buffers
// as CPU memory, tied to a staging texture, for asynchronous texture readback.
class Buffer11::PackStorage : public Buffer11::BufferStorage
@@ -143,24 +199,24 @@ class Buffer11::PackStorage : public Buffer11::BufferStorage
~PackStorage() override;
bool isMappable() const override { return true; }
-
- bool copyFromStorage(BufferStorage *source, size_t sourceOffset,
- size_t size, size_t destOffset) override;
+ bool copyFromStorage(BufferStorage *source,
+ size_t sourceOffset,
+ size_t size,
+ size_t destOffset) override;
gl::Error resize(size_t size, bool preserveData) override;
uint8_t *map(size_t offset, size_t length, GLbitfield access) override;
void unmap() override;
- gl::Error packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params);
+ gl::Error packPixels(const gl::FramebufferAttachment &readAttachment,
+ const PackPixelsParams &params);
private:
gl::Error flushQueuedPackCommand();
- ID3D11Texture2D *mStagingTexture;
- DXGI_FORMAT mTextureFormat;
- gl::Extents mTextureSize;
+ TextureHelper11 mStagingTexture;
MemoryBuffer mMemoryBuffer;
- PackPixelsParams *mQueuedPackCommand;
+ std::unique_ptr<PackPixelsParams> mQueuedPackCommand;
PackPixelsParams mPackParams;
bool mDataModified;
};
@@ -175,9 +231,10 @@ class Buffer11::SystemMemoryStorage : public Buffer11::BufferStorage
~SystemMemoryStorage() override {}
bool isMappable() const override { return true; }
-
- bool copyFromStorage(BufferStorage *source, size_t sourceOffset,
- size_t size, size_t destOffset) override;
+ bool copyFromStorage(BufferStorage *source,
+ size_t sourceOffset,
+ size_t size,
+ size_t destOffset) override;
gl::Error resize(size_t size, bool preserveData) override;
uint8_t *map(size_t offset, size_t length, GLbitfield access) override;
@@ -193,23 +250,27 @@ Buffer11::Buffer11(Renderer11 *renderer)
: BufferD3D(renderer),
mRenderer(renderer),
mSize(0),
- mMappedStorage(NULL),
- mReadUsageCount(0),
- mHasSystemMemoryStorage(false)
-{}
+ mMappedStorage(nullptr),
+ mBufferStorages(BUFFER_USAGE_COUNT, nullptr),
+ mConstantBufferStorageAdditionalSize(0),
+ mMaxConstantBufferLruCount(0),
+ mReadUsageCount(0)
+{
+}
Buffer11::~Buffer11()
{
- for (auto it = mBufferStorages.begin(); it != mBufferStorages.end(); it++)
+ for (auto &storage : mBufferStorages)
{
- SafeDelete(it->second);
+ SafeDelete(storage);
}
-}
-Buffer11 *Buffer11::makeBuffer11(BufferImpl *buffer)
-{
- ASSERT(HAS_DYNAMIC_TYPE(Buffer11*, buffer));
- return static_cast<Buffer11*>(buffer);
+ for (auto &p : mConstantBufferRangeStoragesCache)
+ {
+ SafeDelete(p.second.storage);
+ }
+
+ mRenderer->onBufferDelete(this);
}
gl::Error Buffer11::setData(const void *data, size_t size, GLenum usage)
@@ -220,18 +281,14 @@ gl::Error Buffer11::setData(const void *data, size_t size, GLenum usage)
return error;
}
- if (usage == GL_STATIC_DRAW)
- {
- initializeStaticData();
- }
-
+ updateD3DBufferUsage(usage);
return error;
}
gl::Error Buffer11::getData(const uint8_t **outData)
{
SystemMemoryStorage *systemMemoryStorage = nullptr;
- gl::Error error = getSystemMemoryStorage(&systemMemoryStorage);
+ gl::Error error = getSystemMemoryStorage(&systemMemoryStorage);
if (error.isError())
{
@@ -310,15 +367,18 @@ gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset)
}
mSize = std::max(mSize, requiredSize);
- invalidateStaticData();
+ invalidateStaticData(D3D_BUFFER_INVALIDATE_WHOLE_CACHE);
return gl::Error(GL_NO_ERROR);
}
-gl::Error Buffer11::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
+gl::Error Buffer11::copySubData(BufferImpl *source,
+ GLintptr sourceOffset,
+ GLintptr destOffset,
+ GLsizeiptr size)
{
- Buffer11 *sourceBuffer = makeBuffer11(source);
- ASSERT(sourceBuffer != NULL);
+ Buffer11 *sourceBuffer = GetAs<Buffer11>(source);
+ ASSERT(sourceBuffer != nullptr);
BufferStorage *copyDest = getLatestBufferStorage();
if (!copyDest)
@@ -363,19 +423,26 @@ gl::Error Buffer11::copySubData(BufferImpl* source, GLintptr sourceOffset, GLint
copyDest->setDataRevision(copyDest->getDataRevision() + 1);
mSize = std::max<size_t>(mSize, destOffset + size);
- invalidateStaticData();
+ invalidateStaticData(D3D_BUFFER_INVALIDATE_WHOLE_CACHE);
return gl::Error(GL_NO_ERROR);
}
-gl::Error Buffer11::map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr)
+gl::Error Buffer11::map(GLenum access, GLvoid **mapPtr)
+{
+ // GL_OES_mapbuffer uses an enum instead of a bitfield for it's access, convert to a bitfield
+ // and call mapRange.
+ ASSERT(access == GL_WRITE_ONLY_OES);
+ return mapRange(0, mSize, GL_MAP_WRITE_BIT, mapPtr);
+}
+
+gl::Error Buffer11::mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr)
{
ASSERT(!mMappedStorage);
BufferStorage *latestStorage = getLatestBufferStorage();
- if (latestStorage &&
- (latestStorage->getUsage() == BUFFER_USAGE_PIXEL_PACK ||
- latestStorage->getUsage() == BUFFER_USAGE_STAGING))
+ if (latestStorage && (latestStorage->getUsage() == BUFFER_USAGE_PIXEL_PACK ||
+ latestStorage->getUsage() == BUFFER_USAGE_STAGING))
{
// Latest storage is mappable.
mMappedStorage = latestStorage;
@@ -396,6 +463,7 @@ gl::Error Buffer11::map(size_t offset, size_t length, GLbitfield access, GLvoid
{
// Update the data revision immediately, since the data might be changed at any time
mMappedStorage->setDataRevision(mMappedStorage->getDataRevision() + 1);
+ invalidateStaticData(D3D_BUFFER_INVALIDATE_WHOLE_CACHE);
}
uint8_t *mappedBuffer = mMappedStorage->map(offset, length, access);
@@ -408,24 +476,29 @@ gl::Error Buffer11::map(size_t offset, size_t length, GLbitfield access, GLvoid
return gl::Error(GL_NO_ERROR);
}
-gl::Error Buffer11::unmap()
+gl::Error Buffer11::unmap(GLboolean *result)
{
ASSERT(mMappedStorage);
mMappedStorage->unmap();
- mMappedStorage = NULL;
+ mMappedStorage = nullptr;
+
+ // TODO: detect if we had corruption. if so, return false.
+ *result = GL_TRUE;
+
return gl::Error(GL_NO_ERROR);
}
void Buffer11::markTransformFeedbackUsage()
{
- BufferStorage *transformFeedbackStorage = getBufferStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
+ BufferStorage *transformFeedbackStorage =
+ getBufferStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
if (transformFeedbackStorage)
{
transformFeedbackStorage->setDataRevision(transformFeedbackStorage->getDataRevision() + 1);
}
- invalidateStaticData();
+ invalidateStaticData(D3D_BUFFER_INVALIDATE_WHOLE_CACHE);
}
void Buffer11::markBufferUsage()
@@ -435,14 +508,13 @@ void Buffer11::markBufferUsage()
// Free the system memory storage if we decide it isn't being used very often.
const unsigned int usageLimit = 5;
- if (mReadUsageCount > usageLimit && mHasSystemMemoryStorage)
+ BufferStorage *&sysMemUsage = mBufferStorages[BUFFER_USAGE_SYSTEM_MEMORY];
+ if (mReadUsageCount > usageLimit && sysMemUsage != nullptr)
{
- auto systemMemoryStorageIt = mBufferStorages.find(BUFFER_USAGE_SYSTEM_MEMORY);
- ASSERT(systemMemoryStorageIt != mBufferStorages.end());
-
- SafeDelete(systemMemoryStorageIt->second);
- mBufferStorages.erase(systemMemoryStorageIt);
- mHasSystemMemoryStorage = false;
+ if (getLatestBufferStorage() != sysMemUsage)
+ {
+ SafeDelete(sysMemUsage);
+ }
}
}
@@ -455,12 +527,59 @@ ID3D11Buffer *Buffer11::getBuffer(BufferUsage usage)
if (!bufferStorage)
{
// Storage out-of-memory
- return NULL;
+ return nullptr;
}
- ASSERT(HAS_DYNAMIC_TYPE(NativeStorage*, bufferStorage));
+ return GetAs<NativeStorage>(bufferStorage)->getNativeStorage();
+}
+
+ID3D11Buffer *Buffer11::getEmulatedIndexedBuffer(SourceIndexData *indexInfo,
+ const TranslatedAttribute *attribute)
+{
+ markBufferUsage();
+
+ assert(indexInfo != nullptr);
+ assert(attribute != nullptr);
- return static_cast<NativeStorage*>(bufferStorage)->getNativeStorage();
+ BufferStorage *bufferStorage = getBufferStorage(BUFFER_USAGE_EMULATED_INDEXED_VERTEX);
+ if (!bufferStorage)
+ {
+ // Storage out-of-memory
+ return nullptr;
+ }
+
+ EmulatedIndexedStorage *emulatedStorage = GetAs<EmulatedIndexedStorage>(bufferStorage);
+ if (!emulatedStorage->update(indexInfo, attribute))
+ {
+ // Storage out-of-memory
+ return nullptr;
+ }
+
+ return emulatedStorage->getNativeStorage();
+}
+
+ID3D11Buffer *Buffer11::getConstantBufferRange(GLintptr offset, GLsizeiptr size)
+{
+ markBufferUsage();
+
+ BufferStorage *bufferStorage;
+
+ if (offset == 0)
+ {
+ bufferStorage = getBufferStorage(BUFFER_USAGE_UNIFORM);
+ }
+ else
+ {
+ bufferStorage = getConstantBufferRangeStorage(offset, size);
+ }
+
+ if (!bufferStorage)
+ {
+ // Storage out-of-memory
+ return nullptr;
+ }
+
+ return GetAs<NativeStorage>(bufferStorage)->getNativeStorage();
}
ID3D11ShaderResourceView *Buffer11::getSRV(DXGI_FORMAT srvFormat)
@@ -470,11 +589,10 @@ ID3D11ShaderResourceView *Buffer11::getSRV(DXGI_FORMAT srvFormat)
if (!storage)
{
// Storage out-of-memory
- return NULL;
+ return nullptr;
}
- ASSERT(HAS_DYNAMIC_TYPE(NativeStorage*, storage));
- ID3D11Buffer *buffer = static_cast<NativeStorage*>(storage)->getNativeStorage();
+ ID3D11Buffer *buffer = GetAs<NativeStorage>(storage)->getNativeStorage();
auto bufferSRVIt = mBufferResourceViews.find(srvFormat);
@@ -491,16 +609,17 @@ ID3D11ShaderResourceView *Buffer11::getSRV(DXGI_FORMAT srvFormat)
}
}
- ID3D11Device *device = mRenderer->getDevice();
- ID3D11ShaderResourceView *bufferSRV = NULL;
+ ID3D11Device *device = mRenderer->getDevice();
+ ID3D11ShaderResourceView *bufferSRV = nullptr;
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(srvFormat);
D3D11_SHADER_RESOURCE_VIEW_DESC bufferSRVDesc;
bufferSRVDesc.Buffer.ElementOffset = 0;
- bufferSRVDesc.Buffer.ElementWidth = mSize / dxgiFormatInfo.pixelBytes;
- bufferSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
- bufferSRVDesc.Format = srvFormat;
+ bufferSRVDesc.Buffer.ElementWidth =
+ static_cast<unsigned int>(mSize) / dxgiFormatInfo.pixelBytes;
+ bufferSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
+ bufferSRVDesc.Format = srvFormat;
HRESULT result = device->CreateShaderResourceView(buffer, &bufferSRVDesc, &bufferSRV);
UNUSED_ASSERTION_VARIABLE(result);
@@ -511,14 +630,15 @@ ID3D11ShaderResourceView *Buffer11::getSRV(DXGI_FORMAT srvFormat)
return bufferSRV;
}
-gl::Error Buffer11::packPixels(ID3D11Texture2D *srcTexture, UINT srcSubresource, const PackPixelsParams &params)
+gl::Error Buffer11::packPixels(const gl::FramebufferAttachment &readAttachment,
+ const PackPixelsParams &params)
{
- PackStorage *packStorage = getPackStorage();
+ PackStorage *packStorage = getPackStorage();
BufferStorage *latestStorage = getLatestBufferStorage();
if (packStorage)
{
- gl::Error error = packStorage->packPixels(srcTexture, srcSubresource, params);
+ gl::Error error = packStorage->packPixels(readAttachment, params);
if (error.isError())
{
return error;
@@ -529,14 +649,23 @@ gl::Error Buffer11::packPixels(ID3D11Texture2D *srcTexture, UINT srcSubresource,
return gl::Error(GL_NO_ERROR);
}
+size_t Buffer11::getTotalCPUBufferMemoryBytes() const
+{
+ size_t allocationSize = 0;
+
+ BufferStorage *staging = mBufferStorages[BUFFER_USAGE_STAGING];
+ allocationSize += staging ? staging->getSize() : 0;
+
+ BufferStorage *sysMem = mBufferStorages[BUFFER_USAGE_SYSTEM_MEMORY];
+ allocationSize += sysMem ? sysMem->getSize() : 0;
+
+ return allocationSize;
+}
+
Buffer11::BufferStorage *Buffer11::getBufferStorage(BufferUsage usage)
{
- BufferStorage *newStorage = NULL;
- auto directBufferIt = mBufferStorages.find(usage);
- if (directBufferIt != mBufferStorages.end())
- {
- newStorage = directBufferIt->second;
- }
+ ASSERT(0 <= usage && usage < BUFFER_USAGE_COUNT);
+ BufferStorage *&newStorage = mBufferStorages[usage];
if (!newStorage)
{
@@ -547,15 +676,16 @@ Buffer11::BufferStorage *Buffer11::getBufferStorage(BufferUsage usage)
else if (usage == BUFFER_USAGE_SYSTEM_MEMORY)
{
newStorage = new SystemMemoryStorage(mRenderer);
- mHasSystemMemoryStorage = true;
+ }
+ else if (usage == BUFFER_USAGE_EMULATED_INDEXED_VERTEX)
+ {
+ newStorage = new EmulatedIndexedStorage(mRenderer);
}
else
{
// buffer is not allocated, create it
newStorage = new NativeStorage(mRenderer, usage);
}
-
- mBufferStorages.insert(std::make_pair(usage, newStorage));
}
// resize buffer
@@ -564,19 +694,88 @@ Buffer11::BufferStorage *Buffer11::getBufferStorage(BufferUsage usage)
if (newStorage->resize(mSize, true).isError())
{
// Out of memory error
- return NULL;
+ return nullptr;
+ }
+ }
+
+ updateBufferStorage(newStorage, 0, mSize);
+
+ return newStorage;
+}
+
+Buffer11::BufferStorage *Buffer11::getConstantBufferRangeStorage(GLintptr offset, GLsizeiptr size)
+{
+ BufferStorage *newStorage;
+
+ {
+ // Keep the cacheEntry in a limited scope because it may be invalidated later in the code if
+ // we need to reclaim some space.
+ ConstantBufferCacheEntry *cacheEntry = &mConstantBufferRangeStoragesCache[offset];
+
+ if (!cacheEntry->storage)
+ {
+ cacheEntry->storage = new NativeStorage(mRenderer, BUFFER_USAGE_UNIFORM);
+ cacheEntry->lruCount = ++mMaxConstantBufferLruCount;
}
+
+ cacheEntry->lruCount = ++mMaxConstantBufferLruCount;
+ newStorage = cacheEntry->storage;
}
+ if (newStorage->getSize() < static_cast<size_t>(size))
+ {
+ size_t maximumAllowedAdditionalSize = 2 * getSize();
+
+ size_t sizeDelta = size - newStorage->getSize();
+
+ while (mConstantBufferStorageAdditionalSize + sizeDelta > maximumAllowedAdditionalSize)
+ {
+ auto iter = std::min_element(std::begin(mConstantBufferRangeStoragesCache),
+ std::end(mConstantBufferRangeStoragesCache),
+ [](const ConstantBufferCache::value_type &a,
+ const ConstantBufferCache::value_type &b)
+ {
+ return a.second.lruCount < b.second.lruCount;
+ });
+
+ ASSERT(iter->second.storage != newStorage);
+ ASSERT(mConstantBufferStorageAdditionalSize >= iter->second.storage->getSize());
+
+ mConstantBufferStorageAdditionalSize -= iter->second.storage->getSize();
+ SafeDelete(iter->second.storage);
+ mConstantBufferRangeStoragesCache.erase(iter);
+ }
+
+ if (newStorage->resize(size, false).isError())
+ {
+ // Out of memory error
+ return nullptr;
+ }
+
+ mConstantBufferStorageAdditionalSize += sizeDelta;
+
+ // We don't copy the old data when resizing the constant buffer because the data may be
+ // out-of-date therefore we reset the data revision and let updateBufferStorage() handle the
+ // copy.
+ newStorage->setDataRevision(0);
+ }
+
+ updateBufferStorage(newStorage, offset, size);
+
+ return newStorage;
+}
+
+void Buffer11::updateBufferStorage(BufferStorage *storage, size_t sourceOffset, size_t storageSize)
+{
BufferStorage *latestBuffer = getLatestBufferStorage();
- if (latestBuffer && latestBuffer->getDataRevision() > newStorage->getDataRevision())
+ if (latestBuffer && latestBuffer->getDataRevision() > storage->getDataRevision())
{
// Copy through a staging buffer if we're copying from or to a non-staging, mappable
// buffer storage. This is because we can't map a GPU buffer, and copy CPU
// data directly. If we're already using a staging buffer we're fine.
if (latestBuffer->getUsage() != BUFFER_USAGE_STAGING &&
- newStorage->getUsage() != BUFFER_USAGE_STAGING &&
- (!latestBuffer->isMappable() || !newStorage->isMappable()))
+ storage->getUsage() != BUFFER_USAGE_STAGING &&
+ (!latestBuffer->isMappable() || !storage->isMappable()))
{
NativeStorage *stagingBuffer = getStagingStorage();
@@ -588,28 +787,25 @@ Buffer11::BufferStorage *Buffer11::getBufferStorage(BufferUsage usage)
// if copyFromStorage returns true, the D3D buffer has been recreated
// and we should update our serial
- if (newStorage->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0))
+ if (storage->copyFromStorage(latestBuffer, sourceOffset, storageSize, 0))
{
updateSerial();
}
- newStorage->setDataRevision(latestBuffer->getDataRevision());
+ storage->setDataRevision(latestBuffer->getDataRevision());
}
-
- return newStorage;
}
Buffer11::BufferStorage *Buffer11::getLatestBufferStorage() const
{
// Even though we iterate over all the direct buffers, it is expected that only
// 1 or 2 will be present.
- BufferStorage *latestStorage = NULL;
+ BufferStorage *latestStorage = nullptr;
DataRevision latestRevision = 0;
- for (auto it = mBufferStorages.begin(); it != mBufferStorages.end(); it++)
+ for (auto &storage : mBufferStorages)
{
- BufferStorage *storage = it->second;
- if (!latestStorage || storage->getDataRevision() > latestRevision)
+ if (storage && (!latestStorage || storage->getDataRevision() > latestRevision))
{
- latestStorage = storage;
+ latestStorage = storage;
latestRevision = storage->getDataRevision();
}
}
@@ -620,7 +816,7 @@ Buffer11::BufferStorage *Buffer11::getLatestBufferStorage() const
if (latestStorage->resize(mSize, true).isError())
{
// Out of memory error
- return NULL;
+ return nullptr;
}
}
@@ -634,11 +830,10 @@ Buffer11::NativeStorage *Buffer11::getStagingStorage()
if (!stagingStorage)
{
// Out-of-memory
- return NULL;
+ return nullptr;
}
- ASSERT(HAS_DYNAMIC_TYPE(NativeStorage*, stagingStorage));
- return static_cast<NativeStorage*>(stagingStorage);
+ return GetAs<NativeStorage>(stagingStorage);
}
Buffer11::PackStorage *Buffer11::getPackStorage()
@@ -648,11 +843,10 @@ Buffer11::PackStorage *Buffer11::getPackStorage()
if (!packStorage)
{
// Out-of-memory
- return NULL;
+ return nullptr;
}
- ASSERT(HAS_DYNAMIC_TYPE(PackStorage*, packStorage));
- return static_cast<PackStorage*>(packStorage);
+ return GetAs<PackStorage>(packStorage);
}
bool Buffer11::supportsDirectBinding() const
@@ -664,10 +858,7 @@ bool Buffer11::supportsDirectBinding() const
}
Buffer11::BufferStorage::BufferStorage(Renderer11 *renderer, BufferUsage usage)
- : mRenderer(renderer),
- mUsage(usage),
- mRevision(0),
- mBufferSize(0)
+ : mRenderer(renderer), mRevision(0), mUsage(usage), mBufferSize(0)
{
}
@@ -689,8 +880,7 @@ gl::Error Buffer11::BufferStorage::setData(const uint8_t *data, size_t offset, s
}
Buffer11::NativeStorage::NativeStorage(Renderer11 *renderer, BufferUsage usage)
- : BufferStorage(renderer, usage),
- mNativeStorage(NULL)
+ : BufferStorage(renderer, usage), mNativeStorage(nullptr)
{
}
@@ -700,19 +890,21 @@ Buffer11::NativeStorage::~NativeStorage()
}
// Returns true if it recreates the direct buffer
-bool Buffer11::NativeStorage::copyFromStorage(BufferStorage *source, size_t sourceOffset,
- size_t size, size_t destOffset)
+bool Buffer11::NativeStorage::copyFromStorage(BufferStorage *source,
+ size_t sourceOffset,
+ size_t size,
+ size_t destOffset)
{
ID3D11DeviceContext *context = mRenderer->getDeviceContext();
- size_t requiredSize = sourceOffset + size;
- bool createBuffer = !mNativeStorage || mBufferSize < requiredSize;
+ size_t requiredSize = destOffset + size;
+ bool createBuffer = !mNativeStorage || mBufferSize < requiredSize;
// (Re)initialize D3D buffer if needed
if (createBuffer)
{
bool preserveData = (destOffset > 0);
- resize(source->getSize(), preserveData);
+ resize(requiredSize, preserveData);
}
if (source->getUsage() == BUFFER_USAGE_PIXEL_PACK ||
@@ -724,8 +916,12 @@ bool Buffer11::NativeStorage::copyFromStorage(BufferStorage *source, size_t sour
D3D11_MAPPED_SUBRESOURCE mappedResource;
HRESULT hr = context->Map(mNativeStorage, 0, D3D11_MAP_WRITE, 0, &mappedResource);
- UNUSED_ASSERTION_VARIABLE(hr);
ASSERT(SUCCEEDED(hr));
+ if (FAILED(hr))
+ {
+ source->unmap();
+ return false;
+ }
uint8_t *destPointer = static_cast<uint8_t *>(mappedResource.pData) + destOffset;
@@ -738,20 +934,18 @@ bool Buffer11::NativeStorage::copyFromStorage(BufferStorage *source, size_t sour
}
else
{
- ASSERT(HAS_DYNAMIC_TYPE(NativeStorage*, source));
-
D3D11_BOX srcBox;
- srcBox.left = sourceOffset;
- srcBox.right = sourceOffset + size;
- srcBox.top = 0;
+ srcBox.left = static_cast<unsigned int>(sourceOffset);
+ srcBox.right = static_cast<unsigned int>(sourceOffset + size);
+ srcBox.top = 0;
srcBox.bottom = 1;
- srcBox.front = 0;
- srcBox.back = 1;
+ srcBox.front = 0;
+ srcBox.back = 1;
- ASSERT(HAS_DYNAMIC_TYPE(NativeStorage*, source));
- ID3D11Buffer *sourceBuffer = static_cast<NativeStorage*>(source)->getNativeStorage();
+ ID3D11Buffer *sourceBuffer = GetAs<NativeStorage>(source)->getNativeStorage();
- context->CopySubresourceRegion(mNativeStorage, 0, destOffset, 0, 0, sourceBuffer, 0, &srcBox);
+ context->CopySubresourceRegion(mNativeStorage, 0, static_cast<unsigned int>(destOffset), 0,
+ 0, sourceBuffer, 0, &srcBox);
}
return createBuffer;
@@ -759,32 +953,35 @@ bool Buffer11::NativeStorage::copyFromStorage(BufferStorage *source, size_t sour
gl::Error Buffer11::NativeStorage::resize(size_t size, bool preserveData)
{
- ID3D11Device *device = mRenderer->getDevice();
+ ID3D11Device *device = mRenderer->getDevice();
ID3D11DeviceContext *context = mRenderer->getDeviceContext();
D3D11_BUFFER_DESC bufferDesc;
- fillBufferDesc(&bufferDesc, mRenderer, mUsage, size);
+ fillBufferDesc(&bufferDesc, mRenderer, mUsage, static_cast<unsigned int>(size));
ID3D11Buffer *newBuffer;
- HRESULT result = device->CreateBuffer(&bufferDesc, NULL, &newBuffer);
+ HRESULT result = device->CreateBuffer(&bufferDesc, nullptr, &newBuffer);
if (FAILED(result))
{
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer, result: 0x%X.", result);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer, result: 0x%X.",
+ result);
}
+ d3d11::SetDebugName(newBuffer, "Buffer11::NativeStorage");
+
if (mNativeStorage && preserveData)
{
// We don't call resize if the buffer is big enough already.
ASSERT(mBufferSize <= size);
D3D11_BOX srcBox;
- srcBox.left = 0;
- srcBox.right = mBufferSize;
- srcBox.top = 0;
+ srcBox.left = 0;
+ srcBox.right = static_cast<unsigned int>(mBufferSize);
+ srcBox.top = 0;
srcBox.bottom = 1;
- srcBox.front = 0;
- srcBox.back = 1;
+ srcBox.front = 0;
+ srcBox.back = 1;
context->CopySubresourceRegion(newBuffer, 0, 0, 0, 0, mNativeStorage, 0, &srcBox);
}
@@ -798,58 +995,62 @@ gl::Error Buffer11::NativeStorage::resize(size_t size, bool preserveData)
return gl::Error(GL_NO_ERROR);
}
-void Buffer11::NativeStorage::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer11 *renderer,
- BufferUsage usage, unsigned int bufferSize)
+void Buffer11::NativeStorage::fillBufferDesc(D3D11_BUFFER_DESC *bufferDesc,
+ Renderer11 *renderer,
+ BufferUsage usage,
+ unsigned int bufferSize)
{
- bufferDesc->ByteWidth = bufferSize;
- bufferDesc->MiscFlags = 0;
+ bufferDesc->ByteWidth = bufferSize;
+ bufferDesc->MiscFlags = 0;
bufferDesc->StructureByteStride = 0;
switch (usage)
{
- case BUFFER_USAGE_STAGING:
- bufferDesc->Usage = D3D11_USAGE_STAGING;
- bufferDesc->BindFlags = 0;
- bufferDesc->CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
- break;
+ case BUFFER_USAGE_STAGING:
+ bufferDesc->Usage = D3D11_USAGE_STAGING;
+ bufferDesc->BindFlags = 0;
+ bufferDesc->CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
+ break;
- case BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK:
- bufferDesc->Usage = D3D11_USAGE_DEFAULT;
- bufferDesc->BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ case BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK:
+ bufferDesc->Usage = D3D11_USAGE_DEFAULT;
+ bufferDesc->BindFlags = D3D11_BIND_VERTEX_BUFFER;
- if (renderer->isES3Capable())
- {
- bufferDesc->BindFlags |= D3D11_BIND_STREAM_OUTPUT;
- }
+ if (renderer->isES3Capable())
+ {
+ bufferDesc->BindFlags |= D3D11_BIND_STREAM_OUTPUT;
+ }
- bufferDesc->CPUAccessFlags = 0;
- break;
-
- case BUFFER_USAGE_INDEX:
- bufferDesc->Usage = D3D11_USAGE_DEFAULT;
- bufferDesc->BindFlags = D3D11_BIND_INDEX_BUFFER;
- bufferDesc->CPUAccessFlags = 0;
- break;
-
- case BUFFER_USAGE_PIXEL_UNPACK:
- bufferDesc->Usage = D3D11_USAGE_DEFAULT;
- bufferDesc->BindFlags = D3D11_BIND_SHADER_RESOURCE;
- bufferDesc->CPUAccessFlags = 0;
- break;
-
- case BUFFER_USAGE_UNIFORM:
- bufferDesc->Usage = D3D11_USAGE_DYNAMIC;
- bufferDesc->BindFlags = D3D11_BIND_CONSTANT_BUFFER;
- bufferDesc->CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
-
- // Constant buffers must be of a limited size, and aligned to 16 byte boundaries
- // For our purposes we ignore any buffer data past the maximum constant buffer size
- bufferDesc->ByteWidth = roundUp(bufferDesc->ByteWidth, 16u);
- bufferDesc->ByteWidth = std::min<UINT>(bufferDesc->ByteWidth, renderer->getRendererCaps().maxUniformBlockSize);
- break;
-
- default:
- UNREACHABLE();
+ bufferDesc->CPUAccessFlags = 0;
+ break;
+
+ case BUFFER_USAGE_INDEX:
+ bufferDesc->Usage = D3D11_USAGE_DEFAULT;
+ bufferDesc->BindFlags = D3D11_BIND_INDEX_BUFFER;
+ bufferDesc->CPUAccessFlags = 0;
+ break;
+
+ case BUFFER_USAGE_PIXEL_UNPACK:
+ bufferDesc->Usage = D3D11_USAGE_DEFAULT;
+ bufferDesc->BindFlags = D3D11_BIND_SHADER_RESOURCE;
+ bufferDesc->CPUAccessFlags = 0;
+ break;
+
+ case BUFFER_USAGE_UNIFORM:
+ bufferDesc->Usage = D3D11_USAGE_DYNAMIC;
+ bufferDesc->BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+ bufferDesc->CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+
+ // Constant buffers must be of a limited size, and aligned to 16 byte boundaries
+ // For our purposes we ignore any buffer data past the maximum constant buffer size
+ bufferDesc->ByteWidth = roundUp(bufferDesc->ByteWidth, 16u);
+ bufferDesc->ByteWidth =
+ std::min<UINT>(bufferDesc->ByteWidth,
+ static_cast<UINT>(renderer->getRendererCaps().maxUniformBlockSize));
+ break;
+
+ default:
+ UNREACHABLE();
}
}
@@ -859,14 +1060,16 @@ uint8_t *Buffer11::NativeStorage::map(size_t offset, size_t length, GLbitfield a
D3D11_MAPPED_SUBRESOURCE mappedResource;
ID3D11DeviceContext *context = mRenderer->getDeviceContext();
- D3D11_MAP d3dMapType = gl_d3d11::GetD3DMapTypeFromBits(access);
- UINT d3dMapFlag = ((access & GL_MAP_UNSYNCHRONIZED_BIT) != 0 ? D3D11_MAP_FLAG_DO_NOT_WAIT : 0);
+ D3D11_MAP d3dMapType = gl_d3d11::GetD3DMapTypeFromBits(access);
+ UINT d3dMapFlag = ((access & GL_MAP_UNSYNCHRONIZED_BIT) != 0 ? D3D11_MAP_FLAG_DO_NOT_WAIT : 0);
HRESULT result = context->Map(mNativeStorage, 0, d3dMapType, d3dMapFlag, &mappedResource);
- UNUSED_ASSERTION_VARIABLE(result);
ASSERT(SUCCEEDED(result));
-
- return static_cast<uint8_t*>(mappedResource.pData) + offset;
+ if (FAILED(result))
+ {
+ return nullptr;
+ }
+ return static_cast<uint8_t *>(mappedResource.pData) + offset;
}
void Buffer11::NativeStorage::unmap()
@@ -876,23 +1079,189 @@ void Buffer11::NativeStorage::unmap()
context->Unmap(mNativeStorage, 0);
}
+Buffer11::EmulatedIndexedStorage::EmulatedIndexedStorage(Renderer11 *renderer)
+ : BufferStorage(renderer, BUFFER_USAGE_EMULATED_INDEXED_VERTEX), mNativeStorage(nullptr)
+{
+}
+
+Buffer11::EmulatedIndexedStorage::~EmulatedIndexedStorage()
+{
+ SafeRelease(mNativeStorage);
+}
+
+ID3D11Buffer *Buffer11::EmulatedIndexedStorage::getNativeStorage()
+{
+ if (!mNativeStorage)
+ {
+ // Expand the memory storage upon request and cache the results.
+ unsigned int expandedDataSize =
+ static_cast<unsigned int>((mIndexInfo.srcCount * mAttributeStride) + mAttributeOffset);
+ MemoryBuffer expandedData;
+ if (!expandedData.resize(expandedDataSize))
+ {
+ return nullptr;
+ }
+
+ // Clear the contents of the allocated buffer
+ ZeroMemory(expandedData.data(), expandedDataSize);
+
+ uint8_t *curr = expandedData.data();
+ const uint8_t *ptr = static_cast<const uint8_t *>(mIndexInfo.srcIndices);
+
+ // Ensure that we start in the correct place for the emulated data copy operation to
+ // maintain offset behaviors.
+ curr += mAttributeOffset;
+
+ ReadIndexValueFunction readIndexValue = ReadIndexValueFromIndices<GLushort>;
+
+ switch (mIndexInfo.srcIndexType)
+ {
+ case GL_UNSIGNED_INT:
+ readIndexValue = ReadIndexValueFromIndices<GLuint>;
+ break;
+ case GL_UNSIGNED_SHORT:
+ readIndexValue = ReadIndexValueFromIndices<GLushort>;
+ break;
+ case GL_UNSIGNED_BYTE:
+ readIndexValue = ReadIndexValueFromIndices<GLubyte>;
+ break;
+ }
+
+ // Iterate over the cached index data and copy entries indicated into the emulated buffer.
+ for (GLuint i = 0; i < mIndexInfo.srcCount; i++)
+ {
+ GLuint idx = readIndexValue(ptr, i);
+ memcpy(curr, mMemoryBuffer.data() + (mAttributeStride * idx), mAttributeStride);
+ curr += mAttributeStride;
+ }
+
+ // Finally, initialize the emulated indexed native storage object with the newly copied data
+ // and free the temporary buffers used.
+ ID3D11Device *device = mRenderer->getDevice();
+
+ D3D11_BUFFER_DESC bufferDesc;
+ bufferDesc.ByteWidth = expandedDataSize;
+ bufferDesc.MiscFlags = 0;
+ bufferDesc.StructureByteStride = 0;
+ bufferDesc.Usage = D3D11_USAGE_DEFAULT;
+ bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ bufferDesc.CPUAccessFlags = 0;
+
+ D3D11_SUBRESOURCE_DATA subResourceData = {expandedData.data(), 0, 0};
+
+ HRESULT result = device->CreateBuffer(&bufferDesc, &subResourceData, &mNativeStorage);
+ if (FAILED(result))
+ {
+ ERR("Could not create emulated index data buffer: %08lX", result);
+ return nullptr;
+ }
+ d3d11::SetDebugName(mNativeStorage, "Buffer11::EmulatedIndexedStorage");
+ }
+
+ return mNativeStorage;
+}
+
+bool Buffer11::EmulatedIndexedStorage::update(SourceIndexData *indexInfo,
+ const TranslatedAttribute *attribute)
+{
+ // If a change in the indices applied from the last draw call is detected, then the emulated
+ // indexed buffer needs to be invalidated. After invalidation, the change detected flag should
+ // be cleared to avoid unnecessary recreation of the buffer.
+ if (mNativeStorage == nullptr || indexInfo->srcIndicesChanged)
+ {
+ SafeRelease(mNativeStorage);
+
+ // Copy attribute offset and stride information
+ mAttributeStride = attribute->stride;
+ mAttributeOffset = attribute->offset;
+
+ // Copy the source index data. This ensures that the lifetime of the indices pointer
+ // stays with this storage until the next time we invalidate.
+ size_t indicesDataSize = 0;
+ switch (indexInfo->srcIndexType)
+ {
+ case GL_UNSIGNED_INT:
+ indicesDataSize = sizeof(GLuint) * indexInfo->srcCount;
+ break;
+ case GL_UNSIGNED_SHORT:
+ indicesDataSize = sizeof(GLushort) * indexInfo->srcCount;
+ break;
+ case GL_UNSIGNED_BYTE:
+ indicesDataSize = sizeof(GLubyte) * indexInfo->srcCount;
+ break;
+ default:
+ indicesDataSize = sizeof(GLushort) * indexInfo->srcCount;
+ break;
+ }
+
+ if (!mIndicesMemoryBuffer.resize(indicesDataSize))
+ {
+ return false;
+ }
+
+ memcpy(mIndicesMemoryBuffer.data(), indexInfo->srcIndices, indicesDataSize);
+
+ // Copy the source index data description and update the srcIndices pointer to point
+ // to our cached index data.
+ mIndexInfo = *indexInfo;
+ mIndexInfo.srcIndices = mIndicesMemoryBuffer.data();
+
+ indexInfo->srcIndicesChanged = false;
+ }
+ return true;
+}
+
+bool Buffer11::EmulatedIndexedStorage::copyFromStorage(BufferStorage *source,
+ size_t sourceOffset,
+ size_t size,
+ size_t destOffset)
+{
+ ASSERT(source->isMappable());
+ const uint8_t *sourceData = source->map(sourceOffset, size, GL_MAP_READ_BIT);
+ ASSERT(destOffset + size <= mMemoryBuffer.size());
+ memcpy(mMemoryBuffer.data() + destOffset, sourceData, size);
+ source->unmap();
+ return true;
+}
+
+gl::Error Buffer11::EmulatedIndexedStorage::resize(size_t size, bool preserveData)
+{
+ if (mMemoryBuffer.size() < size)
+ {
+ if (!mMemoryBuffer.resize(size))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize EmulatedIndexedStorage");
+ }
+ mBufferSize = size;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+uint8_t *Buffer11::EmulatedIndexedStorage::map(size_t offset, size_t length, GLbitfield access)
+{
+ ASSERT(!mMemoryBuffer.empty() && offset + length <= mMemoryBuffer.size());
+ return mMemoryBuffer.data() + offset;
+}
+
+void Buffer11::EmulatedIndexedStorage::unmap()
+{
+ // No-op
+}
+
Buffer11::PackStorage::PackStorage(Renderer11 *renderer)
- : BufferStorage(renderer, BUFFER_USAGE_PIXEL_PACK),
- mStagingTexture(NULL),
- mTextureFormat(DXGI_FORMAT_UNKNOWN),
- mQueuedPackCommand(NULL),
- mDataModified(false)
+ : BufferStorage(renderer, BUFFER_USAGE_PIXEL_PACK), mStagingTexture(), mDataModified(false)
{
}
Buffer11::PackStorage::~PackStorage()
{
- SafeRelease(mStagingTexture);
- SafeDelete(mQueuedPackCommand);
}
-bool Buffer11::PackStorage::copyFromStorage(BufferStorage *source, size_t sourceOffset,
- size_t size, size_t destOffset)
+bool Buffer11::PackStorage::copyFromStorage(BufferStorage *source,
+ size_t sourceOffset,
+ size_t size,
+ size_t destOffset)
{
// We copy through a staging buffer when drawing with a pack buffer,
// or for other cases where we access the pack buffer
@@ -925,7 +1294,7 @@ uint8_t *Buffer11::PackStorage::map(size_t offset, size_t length, GLbitfield acc
gl::Error error = flushQueuedPackCommand();
if (error.isError())
{
- return NULL;
+ return nullptr;
}
mDataModified = (mDataModified || (access & GL_MAP_WRITE_BIT) != 0);
@@ -938,7 +1307,8 @@ void Buffer11::PackStorage::unmap()
// No-op
}
-gl::Error Buffer11::PackStorage::packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params)
+gl::Error Buffer11::PackStorage::packPixels(const gl::FramebufferAttachment &readAttachment,
+ const PackPixelsParams &params)
{
gl::Error error = flushQueuedPackCommand();
if (error.isError())
@@ -946,54 +1316,37 @@ gl::Error Buffer11::PackStorage::packPixels(ID3D11Texture2D *srcTexure, UINT src
return error;
}
- mQueuedPackCommand = new PackPixelsParams(params);
-
- D3D11_TEXTURE2D_DESC textureDesc;
- srcTexure->GetDesc(&textureDesc);
-
- if (mStagingTexture != NULL &&
- (mTextureFormat != textureDesc.Format ||
- mTextureSize.width != params.area.width ||
- mTextureSize.height != params.area.height))
+ RenderTarget11 *renderTarget = nullptr;
+ error = readAttachment.getRenderTarget(&renderTarget);
+ if (error.isError())
{
- SafeRelease(mStagingTexture);
- mTextureSize.width = 0;
- mTextureSize.height = 0;
- mTextureFormat = DXGI_FORMAT_UNKNOWN;
+ return error;
}
- if (mStagingTexture == NULL)
+ ID3D11Resource *renderTargetResource = renderTarget->getTexture();
+ ASSERT(renderTargetResource);
+
+ unsigned int srcSubresource = renderTarget->getSubresourceIndex();
+ TextureHelper11 srcTexture = TextureHelper11::MakeAndReference(renderTargetResource);
+
+ mQueuedPackCommand.reset(new PackPixelsParams(params));
+
+ gl::Extents srcTextureSize(params.area.width, params.area.height, 1);
+ if (!mStagingTexture.getResource() || mStagingTexture.getFormat() != srcTexture.getFormat() ||
+ mStagingTexture.getExtents() != srcTextureSize)
{
- ID3D11Device *device = mRenderer->getDevice();
- HRESULT hr;
-
- mTextureSize.width = params.area.width;
- mTextureSize.height = params.area.height;
- mTextureFormat = textureDesc.Format;
-
- D3D11_TEXTURE2D_DESC stagingDesc;
- stagingDesc.Width = params.area.width;
- stagingDesc.Height = params.area.height;
- stagingDesc.MipLevels = 1;
- stagingDesc.ArraySize = 1;
- stagingDesc.Format = mTextureFormat;
- stagingDesc.SampleDesc.Count = 1;
- stagingDesc.SampleDesc.Quality = 0;
- stagingDesc.Usage = D3D11_USAGE_STAGING;
- stagingDesc.BindFlags = 0;
- stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
- stagingDesc.MiscFlags = 0;
-
- hr = device->CreateTexture2D(&stagingDesc, NULL, &mStagingTexture);
- if (FAILED(hr))
+ auto textureOrError =
+ CreateStagingTexture(srcTexture.getTextureType(), srcTexture.getFormat(),
+ srcTextureSize, mRenderer->getDevice());
+ if (textureOrError.isError())
{
- ASSERT(hr == E_OUTOFMEMORY);
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal staging texture.");
+ return textureOrError.getError();
}
+ mStagingTexture = std::move(textureOrError.getResult());
}
// ReadPixels from multisampled FBOs isn't supported in current GL
- ASSERT(textureDesc.SampleDesc.Count <= 1);
+ ASSERT(srcTexture.getSampleCount() <= 1);
ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
D3D11_BOX srcBox;
@@ -1001,11 +1354,18 @@ gl::Error Buffer11::PackStorage::packPixels(ID3D11Texture2D *srcTexure, UINT src
srcBox.right = params.area.x + params.area.width;
srcBox.top = params.area.y;
srcBox.bottom = params.area.y + params.area.height;
- srcBox.front = 0;
- srcBox.back = 1;
+
+ // Select the correct layer from a 3D attachment
+ srcBox.front = 0;
+ if (mStagingTexture.getTextureType() == GL_TEXTURE_3D)
+ {
+ srcBox.front = static_cast<UINT>(readAttachment.layer());
+ }
+ srcBox.back = srcBox.front + 1;
// Asynchronous copy
- immediateContext->CopySubresourceRegion(mStagingTexture, 0, 0, 0, 0, srcTexure, srcSubresource, &srcBox);
+ immediateContext->CopySubresourceRegion(mStagingTexture.getResource(), 0, 0, 0, 0,
+ srcTexture.getResource(), srcSubresource, &srcBox);
return gl::Error(GL_NO_ERROR);
}
@@ -1016,8 +1376,9 @@ gl::Error Buffer11::PackStorage::flushQueuedPackCommand()
if (mQueuedPackCommand)
{
- gl::Error error = mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, mMemoryBuffer.data());
- SafeDelete(mQueuedPackCommand);
+ gl::Error error =
+ mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, mMemoryBuffer.data());
+ mQueuedPackCommand.reset(nullptr);
if (error.isError())
{
return error;
@@ -1029,10 +1390,13 @@ gl::Error Buffer11::PackStorage::flushQueuedPackCommand()
Buffer11::SystemMemoryStorage::SystemMemoryStorage(Renderer11 *renderer)
: Buffer11::BufferStorage(renderer, BUFFER_USAGE_SYSTEM_MEMORY)
-{}
+{
+}
-bool Buffer11::SystemMemoryStorage::copyFromStorage(BufferStorage *source, size_t sourceOffset,
- size_t size, size_t destOffset)
+bool Buffer11::SystemMemoryStorage::copyFromStorage(BufferStorage *source,
+ size_t sourceOffset,
+ size_t size,
+ size_t destOffset)
{
ASSERT(source->isMappable());
const uint8_t *sourceData = source->map(sourceOffset, size, GL_MAP_READ_BIT);
@@ -1066,5 +1430,4 @@ void Buffer11::SystemMemoryStorage::unmap()
{
// No-op
}
-
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
index 39bafe880e..a748db57ae 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
@@ -9,12 +9,21 @@
#ifndef LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_
#define LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_
+#include <map>
+
#include "libANGLE/angletypes.h"
#include "libANGLE/renderer/d3d/BufferD3D.h"
+namespace gl
+{
+class FramebufferAttachment;
+}
+
namespace rx
{
class Renderer11;
+struct SourceIndexData;
+struct TranslatedAttribute;
enum BufferUsage
{
@@ -25,6 +34,9 @@ enum BufferUsage
BUFFER_USAGE_PIXEL_PACK,
BUFFER_USAGE_UNIFORM,
BUFFER_USAGE_SYSTEM_MEMORY,
+ BUFFER_USAGE_EMULATED_INDEXED_VERTEX,
+
+ BUFFER_USAGE_COUNT,
};
struct PackPixelsParams
@@ -50,28 +62,32 @@ class Buffer11 : public BufferD3D
Buffer11(Renderer11 *renderer);
virtual ~Buffer11();
- static Buffer11 *makeBuffer11(BufferImpl *buffer);
-
ID3D11Buffer *getBuffer(BufferUsage usage);
+ ID3D11Buffer *getEmulatedIndexedBuffer(SourceIndexData *indexInfo, const TranslatedAttribute *attribute);
+ ID3D11Buffer *getConstantBufferRange(GLintptr offset, GLsizeiptr size);
ID3D11ShaderResourceView *getSRV(DXGI_FORMAT srvFormat);
bool isMapped() const { return mMappedStorage != NULL; }
- gl::Error packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params);
+ gl::Error packPixels(const gl::FramebufferAttachment &readAttachment,
+ const PackPixelsParams &params);
+ size_t getTotalCPUBufferMemoryBytes() const;
// BufferD3D implementation
virtual size_t getSize() const { return mSize; }
virtual bool supportsDirectBinding() const;
+ gl::Error getData(const uint8_t **outData) override;
// BufferImpl implementation
virtual gl::Error setData(const void* data, size_t size, GLenum usage);
- gl::Error getData(const uint8_t **outData) override;
virtual gl::Error setSubData(const void* data, size_t size, size_t offset);
virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
- virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr);
- virtual gl::Error unmap();
+ virtual gl::Error map(GLenum access, GLvoid **mapPtr);
+ virtual gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr);
+ virtual gl::Error unmap(GLboolean *result);
virtual void markTransformFeedbackUsage();
private:
class BufferStorage;
+ class EmulatedIndexedStorage;
class NativeStorage;
class PackStorage;
class SystemMemoryStorage;
@@ -81,21 +97,41 @@ class Buffer11 : public BufferD3D
BufferStorage *mMappedStorage;
- std::map<BufferUsage, BufferStorage*> mBufferStorages;
+ std::vector<BufferStorage*> mBufferStorages;
+
+ struct ConstantBufferCacheEntry
+ {
+ ConstantBufferCacheEntry() : storage(nullptr), lruCount(0) { }
+
+ BufferStorage *storage;
+ unsigned int lruCount;
+ };
+
+ // Cache of D3D11 constant buffer for specific ranges of buffer data.
+ // This is used to emulate UBO ranges on 11.0 devices.
+ // Constant buffers are indexed by there start offset.
+ typedef std::map<GLintptr /*offset*/, ConstantBufferCacheEntry> ConstantBufferCache;
+ ConstantBufferCache mConstantBufferRangeStoragesCache;
+ size_t mConstantBufferStorageAdditionalSize;
+ unsigned int mMaxConstantBufferLruCount;
typedef std::pair<ID3D11Buffer *, ID3D11ShaderResourceView *> BufferSRVPair;
std::map<DXGI_FORMAT, BufferSRVPair> mBufferResourceViews;
unsigned int mReadUsageCount;
- bool mHasSystemMemoryStorage;
void markBufferUsage();
NativeStorage *getStagingStorage();
PackStorage *getPackStorage();
gl::Error getSystemMemoryStorage(SystemMemoryStorage **storageOut);
+ void updateBufferStorage(BufferStorage *storage, size_t sourceOffset, size_t storageSize);
BufferStorage *getBufferStorage(BufferUsage usage);
BufferStorage *getLatestBufferStorage() const;
+
+ BufferStorage *getConstantBufferRangeStorage(GLintptr offset, GLsizeiptr size);
+
+ void invalidateEmulatedIndexedBuffer();
};
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
index 057c3bed42..cd95c65d1c 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
@@ -17,6 +17,7 @@
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "third_party/trace_event/trace_event.h"
// Precompiled shaders
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11vs.h"
@@ -44,7 +45,7 @@ static void ApplyVertices(const gl::Extents &framebufferSize, const gl::Rectangl
float bottom = 1.0f;
// Clip the quad coordinates to the scissor if needed
- if (scissor != NULL)
+ if (scissor != nullptr)
{
left = std::max(left, (scissor->x / float(framebufferSize.width)) * 2.0f - 1.0f);
right = std::min(right, ((scissor->x + scissor->width) / float(framebufferSize.width)) * 2.0f - 1.0f);
@@ -58,35 +59,46 @@ static void ApplyVertices(const gl::Extents &framebufferSize, const gl::Rectangl
d3d11::SetPositionDepthColorVertex<T>(vertices + 3, right, top, depthClear, color);
}
-template <unsigned int vsSize, unsigned int psSize>
-Clear11::ClearShader Clear11::CreateClearShader(ID3D11Device *device, DXGI_FORMAT colorType, const BYTE (&vsByteCode)[vsSize], const BYTE (&psByteCode)[psSize])
+Clear11::ClearShader::ClearShader(DXGI_FORMAT colorType,
+ const char *inputLayoutName,
+ const BYTE *vsByteCode,
+ size_t vsSize,
+ const char *vsDebugName,
+ const BYTE *psByteCode,
+ size_t psSize,
+ const char *psDebugName)
+ : inputLayout(nullptr),
+ vertexShader(vsByteCode, vsSize, vsDebugName),
+ pixelShader(psByteCode, psSize, psDebugName)
{
- HRESULT result;
-
- ClearShader shader = { 0 };
-
D3D11_INPUT_ELEMENT_DESC quadLayout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, colorType, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
- result = device->CreateInputLayout(quadLayout, ArraySize(quadLayout), vsByteCode, vsSize, &shader.inputLayout);
- ASSERT(SUCCEEDED(result));
-
- result = device->CreateVertexShader(vsByteCode, vsSize, NULL, &shader.vertexShader);
- ASSERT(SUCCEEDED(result));
-
- result = device->CreatePixelShader(psByteCode, psSize, NULL, &shader.pixelShader);
- ASSERT(SUCCEEDED(result));
+ inputLayout = new d3d11::LazyInputLayout(quadLayout, 2, vsByteCode, vsSize, inputLayoutName);
+}
- return shader;
+Clear11::ClearShader::~ClearShader()
+{
+ SafeDelete(inputLayout);
+ vertexShader.release();
+ pixelShader.release();
}
Clear11::Clear11(Renderer11 *renderer)
- : mRenderer(renderer), mClearBlendStates(StructLessThan<ClearBlendInfo>), mClearDepthStencilStates(StructLessThan<ClearDepthStencilInfo>),
- mVertexBuffer(NULL), mRasterizerState(NULL), mSupportsClearView(false)
+ : mRenderer(renderer),
+ mClearBlendStates(StructLessThan<ClearBlendInfo>),
+ mFloatClearShader(nullptr),
+ mUintClearShader(nullptr),
+ mIntClearShader(nullptr),
+ mClearDepthStencilStates(StructLessThan<ClearDepthStencilInfo>),
+ mVertexBuffer(nullptr),
+ mRasterizerState(nullptr)
{
+ TRACE_EVENT0("gpu.angle", "Clear11::Clear11");
+
HRESULT result;
ID3D11Device *device = renderer->getDevice();
@@ -98,7 +110,7 @@ Clear11::Clear11(Renderer11 *renderer)
vbDesc.MiscFlags = 0;
vbDesc.StructureByteStride = 0;
- result = device->CreateBuffer(&vbDesc, NULL, &mVertexBuffer);
+ result = device->CreateBuffer(&vbDesc, nullptr, &mVertexBuffer);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mVertexBuffer, "Clear11 masked clear vertex buffer");
@@ -118,29 +130,48 @@ Clear11::Clear11(Renderer11 *renderer)
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mRasterizerState, "Clear11 masked clear rasterizer state");
- if (renderer->getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3)
+ if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
{
- mFloatClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_FLOAT, g_VS_ClearFloat, g_PS_ClearFloat_FL9);
+ mFloatClearShader = new ClearShader(DXGI_FORMAT_R32G32B32A32_FLOAT,
+ "Clear11 Float IL",
+ g_VS_ClearFloat,
+ ArraySize(g_VS_ClearFloat),
+ "Clear11 Float VS",
+ g_PS_ClearFloat_FL9,
+ ArraySize(g_PS_ClearFloat_FL9),
+ "Clear11 Float PS");
}
else
{
- mFloatClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_FLOAT, g_VS_ClearFloat, g_PS_ClearFloat);
+ mFloatClearShader = new ClearShader(DXGI_FORMAT_R32G32B32A32_FLOAT,
+ "Clear11 Float IL",
+ g_VS_ClearFloat,
+ ArraySize(g_VS_ClearFloat),
+ "Clear11 Float VS",
+ g_PS_ClearFloat,
+ ArraySize(g_PS_ClearFloat),
+ "Clear11 Float PS");
}
if (renderer->isES3Capable())
{
- mUintClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_UINT, g_VS_ClearUint, g_PS_ClearUint );
- mIntClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_SINT, g_VS_ClearSint, g_PS_ClearSint );
- }
-
-#if defined(ANGLE_ENABLE_D3D11_1)
- if (renderer->getDeviceContext1IfSupported())
- {
- D3D11_FEATURE_DATA_D3D11_OPTIONS d3d11Options;
- device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &d3d11Options, sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS));
- mSupportsClearView = (d3d11Options.ClearView != FALSE);
+ mUintClearShader = new ClearShader(DXGI_FORMAT_R32G32B32A32_UINT,
+ "Clear11 UINT IL",
+ g_VS_ClearUint,
+ ArraySize(g_VS_ClearUint),
+ "Clear11 UINT VS",
+ g_PS_ClearUint,
+ ArraySize(g_PS_ClearUint),
+ "Clear11 UINT PS");
+ mIntClearShader = new ClearShader(DXGI_FORMAT_R32G32B32A32_UINT,
+ "Clear11 SINT IL",
+ g_VS_ClearSint,
+ ArraySize(g_VS_ClearSint),
+ "Clear11 SINT VS",
+ g_PS_ClearSint,
+ ArraySize(g_PS_ClearSint),
+ "Clear11 SINT PS");
}
-#endif
}
Clear11::~Clear11()
@@ -151,20 +182,9 @@ Clear11::~Clear11()
}
mClearBlendStates.clear();
- SafeRelease(mFloatClearShader.inputLayout);
- SafeRelease(mFloatClearShader.vertexShader);
- SafeRelease(mFloatClearShader.pixelShader);
-
- if (mRenderer->isES3Capable())
- {
- SafeRelease(mUintClearShader.inputLayout);
- SafeRelease(mUintClearShader.vertexShader);
- SafeRelease(mUintClearShader.pixelShader);
-
- SafeRelease(mIntClearShader.inputLayout);
- SafeRelease(mIntClearShader.vertexShader);
- SafeRelease(mIntClearShader.pixelShader);
- }
+ SafeDelete(mFloatClearShader);
+ SafeDelete(mUintClearShader);
+ SafeDelete(mIntClearShader);
for (ClearDepthStencilStateMap::iterator i = mClearDepthStencilStates.begin(); i != mClearDepthStencilStates.end(); i++)
{
@@ -178,10 +198,10 @@ Clear11::~Clear11()
gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl::Framebuffer::Data &fboData)
{
- const auto &colorAttachments = fboData.mColorAttachments;
- const auto &drawBufferStates = fboData.mDrawBufferStates;
- const auto *depthAttachment = fboData.mDepthAttachment;
- const auto *stencilAttachment = fboData.mStencilAttachment;
+ const auto &colorAttachments = fboData.getColorAttachments();
+ const auto &drawBufferStates = fboData.getDrawBufferStates();
+ const auto *depthAttachment = fboData.getDepthAttachment();
+ const auto *stencilAttachment = fboData.getStencilAttachment();
ASSERT(colorAttachments.size() == drawBufferStates.size());
@@ -206,24 +226,18 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl
gl::Extents framebufferSize;
- auto iter = std::find_if(colorAttachments.begin(), colorAttachments.end(), [](const gl::FramebufferAttachment *attachment) { return attachment != nullptr; });
- if (iter != colorAttachments.end())
+ const gl::FramebufferAttachment *colorAttachment = fboData.getFirstColorAttachment();
+ if (colorAttachment != nullptr)
{
- framebufferSize.width = (*iter)->getWidth();
- framebufferSize.height = (*iter)->getHeight();
- framebufferSize.depth = 1;
+ framebufferSize = colorAttachment->getSize();
}
else if (depthAttachment != nullptr)
{
- framebufferSize.width = depthAttachment->getWidth();
- framebufferSize.height = depthAttachment->getHeight();
- framebufferSize.depth = 1;
+ framebufferSize = depthAttachment->getSize();
}
else if (stencilAttachment != nullptr)
{
- framebufferSize.width = stencilAttachment->getWidth();
- framebufferSize.height = stencilAttachment->getHeight();
- framebufferSize.depth = 1;
+ framebufferSize = stencilAttachment->getSize();
}
else
{
@@ -245,34 +259,40 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl
clearParams.scissor.y + clearParams.scissor.height < framebufferSize.height);
std::vector<MaskedRenderTarget> maskedClearRenderTargets;
- RenderTarget11* maskedClearDepthStencil = NULL;
+ RenderTarget11* maskedClearDepthStencil = nullptr;
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+#if defined(ANGLE_ENABLE_D3D11_1)
ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported();
+#endif
+ ID3D11Device *device = mRenderer->getDevice();
- for (size_t colorAttachment = 0; colorAttachment < colorAttachments.size(); colorAttachment++)
+ for (size_t colorAttachmentIndex = 0; colorAttachmentIndex < colorAttachments.size();
+ colorAttachmentIndex++)
{
- if (clearParams.clearColor[colorAttachment] &&
- colorAttachments[colorAttachment] != nullptr &&
- drawBufferStates[colorAttachment] != GL_NONE)
- {
- const gl::FramebufferAttachment *attachment = colorAttachments[colorAttachment];
+ const gl::FramebufferAttachment &attachment = colorAttachments[colorAttachmentIndex];
- RenderTarget11 *renderTarget = NULL;
- gl::Error error = d3d11::GetAttachmentRenderTarget(attachment, &renderTarget);
+ if (clearParams.clearColor[colorAttachmentIndex] && attachment.isAttached() &&
+ drawBufferStates[colorAttachmentIndex] != GL_NONE)
+ {
+ RenderTarget11 *renderTarget = nullptr;
+ gl::Error error = attachment.getRenderTarget(&renderTarget);
if (error.isError())
{
return error;
}
- const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment->getInternalFormat());
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment.getInternalFormat());
if (clearParams.colorClearType == GL_FLOAT &&
!(formatInfo.componentType == GL_FLOAT || formatInfo.componentType == GL_UNSIGNED_NORMALIZED || formatInfo.componentType == GL_SIGNED_NORMALIZED))
{
- ERR("It is undefined behaviour to clear a render buffer which is not normalized fixed point or floating-"
- "point to floating point values (color attachment %u has internal format 0x%X).", colorAttachment,
- attachment->getInternalFormat());
+ ERR(
+ "It is undefined behaviour to clear a render buffer which is not normalized "
+ "fixed point or floating-"
+ "point to floating point values (color attachment %u has internal format "
+ "0x%X).",
+ colorAttachmentIndex, attachment.getInternalFormat());
}
if ((formatInfo.redBits == 0 || !clearParams.colorMaskRed) &&
@@ -283,7 +303,7 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl
// Every channel either does not exist in the render target or is masked out
continue;
}
- else if ((!mSupportsClearView && needScissoredClear) || clearParams.colorClearType != GL_FLOAT ||
+ else if ((!(mRenderer->getRenderer11DeviceCaps().supportsClearView) && needScissoredClear) || clearParams.colorClearType != GL_FLOAT ||
(formatInfo.redBits > 0 && !clearParams.colorMaskRed) ||
(formatInfo.greenBits > 0 && !clearParams.colorMaskGreen) ||
(formatInfo.blueBits > 0 && !clearParams.colorMaskBlue) ||
@@ -291,7 +311,7 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl
{
// A masked clear is required, or a scissored clear is required and ID3D11DeviceContext1::ClearView is unavailable
MaskedRenderTarget maskAndRt;
- bool clearColor = clearParams.clearColor[colorAttachment];
+ bool clearColor = clearParams.clearColor[colorAttachmentIndex];
maskAndRt.colorMask[0] = (clearColor && clearParams.colorMaskRed);
maskAndRt.colorMask[1] = (clearColor && clearParams.colorMaskGreen);
maskAndRt.colorMask[2] = (clearColor && clearParams.colorMaskBlue);
@@ -313,7 +333,7 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl
// Check if the actual format has a channel that the internal format does not and set them to the
// default values
- const float clearValues[4] =
+ float clearValues[4] =
{
((formatInfo.redBits == 0 && dxgiFormatInfo.redBits > 0) ? 0.0f : clearParams.colorFClearValue.red),
((formatInfo.greenBits == 0 && dxgiFormatInfo.greenBits > 0) ? 0.0f : clearParams.colorFClearValue.green),
@@ -321,9 +341,17 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl
((formatInfo.alphaBits == 0 && dxgiFormatInfo.alphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha),
};
- if (needScissoredClear)
+ if (dxgiFormatInfo.alphaBits == 1)
{
+ // Some drivers do not correctly handle calling Clear() on a format with 1-bit alpha.
+ // They can incorrectly round all non-zero values up to 1.0f. Note that WARP does not do this.
+ // We should handle the rounding for them instead.
+ clearValues[3] = (clearParams.colorFClearValue.alpha >= 0.5f) ? 1.0f : 0.0f;
+ }
+
#if defined(ANGLE_ENABLE_D3D11_1)
+ if (needScissoredClear)
+ {
// We shouldn't reach here if deviceContext1 is unavailable.
ASSERT(deviceContext1);
@@ -334,9 +362,9 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl
rect.bottom = clearParams.scissor.y + clearParams.scissor.height;
deviceContext1->ClearView(framebufferRTV, clearValues, &rect, 1);
-#endif
}
else
+#endif
{
deviceContext->ClearRenderTargetView(framebufferRTV, clearValues);
}
@@ -349,8 +377,8 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl
const gl::FramebufferAttachment *attachment = (depthAttachment != nullptr) ? depthAttachment : stencilAttachment;
ASSERT(attachment != nullptr);
- RenderTarget11 *renderTarget = NULL;
- gl::Error error = d3d11::GetAttachmentRenderTarget(attachment, &renderTarget);
+ RenderTarget11 *renderTarget = nullptr;
+ gl::Error error = attachment->getRenderTarget(&renderTarget);
if (error.isError())
{
return error;
@@ -421,7 +449,7 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl
rtvs[i] = rtv;
}
- ID3D11DepthStencilView *dsv = maskedClearDepthStencil ? maskedClearDepthStencil->getDepthStencilView() : NULL;
+ ID3D11DepthStencilView *dsv = maskedClearDepthStencil ? maskedClearDepthStencil->getDepthStencilView() : nullptr;
ID3D11BlendState *blendState = getBlendState(maskedClearRenderTargets);
const FLOAT blendFactors[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
@@ -433,7 +461,7 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl
// Set the vertices
UINT vertexStride = 0;
const UINT startIdx = 0;
- const ClearShader* shader = NULL;
+ ClearShader *shader = nullptr;
D3D11_MAPPED_SUBRESOURCE mappedResource;
HRESULT result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
@@ -441,25 +469,25 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl
return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal masked clear vertex buffer, HRESULT: 0x%X.", result);
}
- const gl::Rectangle *scissorPtr = clearParams.scissorEnabled ? &clearParams.scissor : NULL;
+ const gl::Rectangle *scissorPtr = clearParams.scissorEnabled ? &clearParams.scissor : nullptr;
switch (clearParams.colorClearType)
{
case GL_FLOAT:
ApplyVertices(framebufferSize, scissorPtr, clearParams.colorFClearValue, clearParams.depthClearValue, mappedResource.pData);
vertexStride = sizeof(d3d11::PositionDepthColorVertex<float>);
- shader = &mFloatClearShader;
+ shader = mFloatClearShader;
break;
case GL_UNSIGNED_INT:
ApplyVertices(framebufferSize, scissorPtr, clearParams.colorUIClearValue, clearParams.depthClearValue, mappedResource.pData);
vertexStride = sizeof(d3d11::PositionDepthColorVertex<unsigned int>);
- shader = &mUintClearShader;
+ shader = mUintClearShader;
break;
case GL_INT:
ApplyVertices(framebufferSize, scissorPtr, clearParams.colorIClearValue, clearParams.depthClearValue, mappedResource.pData);
vertexStride = sizeof(d3d11::PositionDepthColorVertex<int>);
- shader = &mIntClearShader;
+ shader = mIntClearShader;
break;
default:
@@ -473,8 +501,8 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl
D3D11_VIEWPORT viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
- viewport.Width = framebufferSize.width;
- viewport.Height = framebufferSize.height;
+ viewport.Width = static_cast<FLOAT>(framebufferSize.width);
+ viewport.Height = static_cast<FLOAT>(framebufferSize.height);
viewport.MinDepth = 0;
viewport.MaxDepth = 1;
deviceContext->RSSetViewports(1, &viewport);
@@ -485,17 +513,18 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl
deviceContext->RSSetState(mRasterizerState);
// Apply shaders
- deviceContext->IASetInputLayout(shader->inputLayout);
- deviceContext->VSSetShader(shader->vertexShader, NULL, 0);
- deviceContext->PSSetShader(shader->pixelShader, NULL, 0);
- deviceContext->GSSetShader(NULL, NULL, 0);
+ deviceContext->IASetInputLayout(shader->inputLayout->resolve(device));
+ deviceContext->VSSetShader(shader->vertexShader.resolve(device), nullptr, 0);
+ deviceContext->PSSetShader(shader->pixelShader.resolve(device), nullptr, 0);
+ deviceContext->GSSetShader(nullptr, nullptr, 0);
// Apply vertex buffer
deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &vertexStride, &startIdx);
deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
// Apply render targets
- deviceContext->OMSetRenderTargets(rtvs.size(), (rtvs.empty() ? NULL : &rtvs[0]), dsv);
+ deviceContext->OMSetRenderTargets(static_cast<unsigned int>(rtvs.size()),
+ (rtvs.empty() ? nullptr : &rtvs[0]), dsv);
// Draw the clear quad
deviceContext->Draw(4, 0);
@@ -509,7 +538,7 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl
ID3D11BlendState *Clear11::getBlendState(const std::vector<MaskedRenderTarget>& rts)
{
- ClearBlendInfo blendKey = { 0 };
+ ClearBlendInfo blendKey = {};
for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
{
if (i < rts.size())
@@ -552,12 +581,12 @@ ID3D11BlendState *Clear11::getBlendState(const std::vector<MaskedRenderTarget>&
}
ID3D11Device *device = mRenderer->getDevice();
- ID3D11BlendState* blendState = NULL;
+ ID3D11BlendState* blendState = nullptr;
HRESULT result = device->CreateBlendState(&blendDesc, &blendState);
if (FAILED(result) || !blendState)
{
ERR("Unable to create a ID3D11BlendState, HRESULT: 0x%X.", result);
- return NULL;
+ return nullptr;
}
mClearBlendStates[blendKey] = blendState;
@@ -597,12 +626,12 @@ ID3D11DepthStencilState *Clear11::getDepthStencilState(const ClearParameters &cl
dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
ID3D11Device *device = mRenderer->getDevice();
- ID3D11DepthStencilState* dsState = NULL;
+ ID3D11DepthStencilState* dsState = nullptr;
HRESULT result = device->CreateDepthStencilState(&dsDesc, &dsState);
if (FAILED(result) || !dsState)
{
ERR("Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result);
- return NULL;
+ return nullptr;
}
mClearDepthStencilStates[dsKey] = dsState;
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.h
index 4797ca1aa0..3ff73c85d1 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.h
@@ -15,6 +15,7 @@
#include "libANGLE/angletypes.h"
#include "libANGLE/Error.h"
#include "libANGLE/Framebuffer.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
namespace rx
{
@@ -41,29 +42,32 @@ class Clear11 : angle::NonCopyable
ID3D11BlendState *getBlendState(const std::vector<MaskedRenderTarget> &rts);
ID3D11DepthStencilState *getDepthStencilState(const ClearParameters &clearParams);
- struct ClearShader
+ struct ClearShader final : public angle::NonCopyable
{
- ID3D11InputLayout *inputLayout;
- ID3D11VertexShader *vertexShader;
- ID3D11PixelShader *pixelShader;
+ ClearShader(DXGI_FORMAT colorType,
+ const char *inputLayoutName,
+ const BYTE *vsByteCode,
+ size_t vsSize,
+ const char *vsDebugName,
+ const BYTE *psByteCode,
+ size_t psSize,
+ const char *psDebugName);
+ ~ClearShader();
+
+ d3d11::LazyInputLayout *inputLayout;
+ d3d11::LazyShader<ID3D11VertexShader> vertexShader;
+ d3d11::LazyShader<ID3D11PixelShader> pixelShader;
};
template <unsigned int vsSize, unsigned int psSize>
static ClearShader CreateClearShader(ID3D11Device *device, DXGI_FORMAT colorType, const BYTE(&vsByteCode)[vsSize], const BYTE(&psByteCode)[psSize]);
- Renderer11 *mRenderer;
-
struct ClearBlendInfo
{
bool maskChannels[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT][4];
};
typedef bool(*ClearBlendInfoComparisonFunction)(const ClearBlendInfo&, const ClearBlendInfo &);
typedef std::map<ClearBlendInfo, ID3D11BlendState*, ClearBlendInfoComparisonFunction> ClearBlendStateMap;
- ClearBlendStateMap mClearBlendStates;
-
- ClearShader mFloatClearShader;
- ClearShader mUintClearShader;
- ClearShader mIntClearShader;
struct ClearDepthStencilInfo
{
@@ -71,14 +75,21 @@ class Clear11 : angle::NonCopyable
bool clearStencil;
UINT8 stencilWriteMask;
};
- typedef bool (*ClearDepthStencilInfoComparisonFunction)(const ClearDepthStencilInfo&, const ClearDepthStencilInfo &);
+ typedef bool(*ClearDepthStencilInfoComparisonFunction)(const ClearDepthStencilInfo&, const ClearDepthStencilInfo &);
typedef std::map<ClearDepthStencilInfo, ID3D11DepthStencilState*, ClearDepthStencilInfoComparisonFunction> ClearDepthStencilStateMap;
+
+ Renderer11 *mRenderer;
+
+ ClearBlendStateMap mClearBlendStates;
+
+ ClearShader *mFloatClearShader;
+ ClearShader *mUintClearShader;
+ ClearShader *mIntClearShader;
+
ClearDepthStencilStateMap mClearDepthStencilStates;
ID3D11Buffer *mVertexBuffer;
ID3D11RasterizerState *mRasterizerState;
-
- bool mSupportsClearView;
};
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp
index f1fe2bb2c7..1c35ab45cc 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp
@@ -37,50 +37,90 @@ DebugAnnotator11::~DebugAnnotator11()
}
}
-void DebugAnnotator11::beginEvent(const std::wstring &eventName)
+void DebugAnnotator11::beginEvent(const wchar_t *eventName)
{
initializeDevice();
+ if (mUserDefinedAnnotation != nullptr)
+ {
#if defined(ANGLE_ENABLE_D3D11_1)
- mUserDefinedAnnotation->BeginEvent(eventName.c_str());
+ mUserDefinedAnnotation->BeginEvent(eventName);
#endif
+ }
}
void DebugAnnotator11::endEvent()
{
initializeDevice();
+ if (mUserDefinedAnnotation != nullptr)
+ {
#if defined(ANGLE_ENABLE_D3D11_1)
- mUserDefinedAnnotation->EndEvent();
+ mUserDefinedAnnotation->EndEvent();
#endif
+ }
}
-void DebugAnnotator11::setMarker(const std::wstring &markerName)
+void DebugAnnotator11::setMarker(const wchar_t *markerName)
{
initializeDevice();
+ if (mUserDefinedAnnotation != nullptr)
+ {
#if defined(ANGLE_ENABLE_D3D11_1)
- mUserDefinedAnnotation->SetMarker(markerName.c_str());
+ mUserDefinedAnnotation->SetMarker(markerName);
#endif
+ }
}
bool DebugAnnotator11::getStatus()
{
- // ID3DUserDefinedAnnotation::GetStatus doesn't work with the Graphics Diagnostics tools in Visual Studio 2013.
+#if defined(ANGLE_ENABLE_WINDOWS_STORE)
+#if (NTDDI_VERSION == NTDDI_WIN10)
+ initializeDevice();
+
+ if (mUserDefinedAnnotation != nullptr)
+ {
+ return !!(mUserDefinedAnnotation->GetStatus());
+ }
+
+ return true; // Default if initializeDevice() failed
+#elif defined(_DEBUG) && (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
+ static bool underCapture = true;
-#if defined(_DEBUG) && defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
- // In the Windows Store, we can use IDXGraphicsAnalysis. The call to GetDebugInterface1 only succeeds if the app is under capture.
+ // ID3DUserDefinedAnnotation::GetStatus doesn't work with the Graphics Diagnostics tools in
+ // Windows 8.1/Visual Studio 2013. We can use IDXGraphicsAnalysis, though.
+ // The call to GetDebugInterface1 only succeeds if the app is under capture.
// This should only be called in DEBUG mode.
- // If an app links against DXGIGetDebugInterface1 in release mode then it will fail Windows Store ingestion checks.
- IDXGraphicsAnalysis *graphicsAnalysis;
- DXGIGetDebugInterface1(0, IID_PPV_ARGS(&graphicsAnalysis));
- bool underCapture = (graphicsAnalysis != nullptr);
- SafeRelease(graphicsAnalysis);
- return underCapture;
-#endif // _DEBUG && !ANGLE_ENABLE_WINDOWS_STORE
+ // If an app links against DXGIGetDebugInterface1 in release mode then it will fail Windows
+ // Store ingestion checks.
+
+ // Cache the result to reduce the number of calls to DXGIGetDebugInterface1
+ static bool triedIDXGraphicsAnalysis = false;
+
+ if (!triedIDXGraphicsAnalysis)
+ {
+ IDXGraphicsAnalysis *graphicsAnalysis = nullptr;
+
+ HRESULT result = DXGIGetDebugInterface1(0, IID_PPV_ARGS(&graphicsAnalysis));
+ if (SUCCEEDED(result))
+ {
+ underCapture = (graphicsAnalysis != nullptr);
+ }
- // Otherwise, we have to return true here.
+ SafeRelease(graphicsAnalysis);
+ triedIDXGraphicsAnalysis = true;
+ }
+
+ return underCapture;
+#else
+ // We can't detect GetStatus() on release WinRT 8.1 builds, so always return true.
+ return true;
+#endif // (NTDDI_VERSION == NTDDI_WIN10) or _DEBUG
+#else
+ // We can't detect GetStatus() on desktop ANGLE builds so always return true.
return true;
+#endif // ANGLE_ENABLE_WINDOWS_STORE
}
void DebugAnnotator11::initializeDevice()
@@ -103,16 +143,17 @@ void DebugAnnotator11::initializeDevice()
// Create a D3D_DRIVER_TYPE_NULL device, which is much cheaper than other types of device.
hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_NULL, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &device, nullptr, &context);
ASSERT(SUCCEEDED(hr));
-
+ if (SUCCEEDED(hr))
+ {
#if defined(ANGLE_ENABLE_D3D11_1)
- mUserDefinedAnnotation = d3d11::DynamicCastComObject<ID3DUserDefinedAnnotation>(context);
- ASSERT(mUserDefinedAnnotation != nullptr);
+ mUserDefinedAnnotation = d3d11::DynamicCastComObject<ID3DUserDefinedAnnotation>(context);
+ ASSERT(mUserDefinedAnnotation != nullptr);
#endif
+ mInitialized = true;
+ }
SafeRelease(device);
SafeRelease(context);
-
- mInitialized = true;
}
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h
index 3df62b015c..d1a0f7fd2e 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h
@@ -21,9 +21,9 @@ class DebugAnnotator11 : public gl::DebugAnnotator
public:
DebugAnnotator11();
~DebugAnnotator11() override;
- void beginEvent(const std::wstring &eventName) override;
+ void beginEvent(const wchar_t *eventName) override;
void endEvent() override;
- void setMarker(const std::wstring &markerName) override;
+ void setMarker(const wchar_t *markerName) override;
bool getStatus() override;
private:
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp
index 8552bc2beb..53fac65f2a 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp
@@ -76,23 +76,22 @@ FenceNV11::~FenceNV11()
SafeRelease(mQuery);
}
-gl::Error FenceNV11::set()
+gl::Error FenceNV11::set(GLenum condition)
{
return FenceSetHelper(this);
}
-gl::Error FenceNV11::test(bool flushCommandBuffer, GLboolean *outFinished)
+gl::Error FenceNV11::test(GLboolean *outFinished)
{
- return FenceTestHelper(this, flushCommandBuffer, outFinished);
+ return FenceTestHelper(this, true, outFinished);
}
-gl::Error FenceNV11::finishFence(GLboolean *outFinished)
+gl::Error FenceNV11::finish()
{
- ASSERT(outFinished);
-
- while (*outFinished != GL_TRUE)
+ GLboolean finished = GL_FALSE;
+ while (finished != GL_TRUE)
{
- gl::Error error = test(true, outFinished);
+ gl::Error error = FenceTestHelper(this, true, &finished);
if (error.isError())
{
return error;
@@ -124,7 +123,7 @@ FenceSync11::FenceSync11(Renderer11 *renderer)
mRenderer(renderer),
mQuery(NULL)
{
- LARGE_INTEGER counterFreqency = { 0 };
+ LARGE_INTEGER counterFreqency = {};
BOOL success = QueryPerformanceFrequency(&counterFreqency);
UNUSED_ASSERTION_VARIABLE(success);
ASSERT(success);
@@ -137,8 +136,9 @@ FenceSync11::~FenceSync11()
SafeRelease(mQuery);
}
-gl::Error FenceSync11::set()
+gl::Error FenceSync11::set(GLenum condition, GLbitfield flags)
{
+ ASSERT(condition == GL_SYNC_GPU_COMMANDS_COMPLETE && flags == 0);
return FenceSetHelper(this);
}
@@ -168,7 +168,7 @@ gl::Error FenceSync11::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *ou
return gl::Error(GL_NO_ERROR);
}
- LARGE_INTEGER currentCounter = { 0 };
+ LARGE_INTEGER currentCounter = {};
BOOL success = QueryPerformanceCounter(&currentCounter);
UNUSED_ASSERTION_VARIABLE(success);
ASSERT(success);
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.h
index 2d87f43e76..595978885b 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.h
@@ -20,11 +20,11 @@ class FenceNV11 : public FenceNVImpl
{
public:
explicit FenceNV11(Renderer11 *renderer);
- virtual ~FenceNV11();
+ ~FenceNV11() override;
- gl::Error set();
- gl::Error test(bool flushCommandBuffer, GLboolean *outFinished);
- gl::Error finishFence(GLboolean *outFinished);
+ gl::Error set(GLenum condition) override;
+ gl::Error test(GLboolean *outFinished) override;
+ gl::Error finish() override;
private:
template<class T> friend gl::Error FenceSetHelper(T *fence);
@@ -38,12 +38,12 @@ class FenceSync11 : public FenceSyncImpl
{
public:
explicit FenceSync11(Renderer11 *renderer);
- virtual ~FenceSync11();
+ ~FenceSync11() override;
- gl::Error set();
- gl::Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult);
- gl::Error serverWait(GLbitfield flags, GLuint64 timeout);
- gl::Error getStatus(GLint *outResult);
+ gl::Error set(GLenum condition, GLbitfield flags) override;
+ gl::Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult) override;
+ gl::Error serverWait(GLbitfield flags, GLuint64 timeout) override;
+ gl::Error getStatus(GLint *outResult) override;
private:
template<class T> friend gl::Error FenceSetHelper(T *fence);
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
index da01f320c0..186a035902 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
@@ -25,8 +25,7 @@ namespace rx
{
Framebuffer11::Framebuffer11(const gl::Framebuffer::Data &data, Renderer11 *renderer)
- : FramebufferD3D(data, renderer),
- mRenderer(renderer)
+ : FramebufferD3D(data, renderer), mRenderer(renderer)
{
ASSERT(mRenderer != nullptr);
}
@@ -43,7 +42,7 @@ static gl::Error InvalidateAttachmentSwizzles(const gl::FramebufferAttachment *a
TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture);
- TextureStorage *texStorage = NULL;
+ TextureStorage *texStorage = nullptr;
gl::Error error = textureD3D->getNativeTexture(&texStorage);
if (error.isError())
{
@@ -52,7 +51,7 @@ static gl::Error InvalidateAttachmentSwizzles(const gl::FramebufferAttachment *a
if (texStorage)
{
- TextureStorage11 *texStorage11 = TextureStorage11::makeTextureStorage11(texStorage);
+ TextureStorage11 *texStorage11 = GetAs<TextureStorage11>(texStorage);
ASSERT(texStorage11);
texStorage11->invalidateSwizzleCacheLevel(attachment->mipLevel());
@@ -64,23 +63,25 @@ static gl::Error InvalidateAttachmentSwizzles(const gl::FramebufferAttachment *a
gl::Error Framebuffer11::invalidateSwizzles() const
{
- for (auto it = mData.mColorAttachments.cbegin(); it != mData.mColorAttachments.cend(); ++it)
+ for (const auto &colorAttachment : mData.getColorAttachments())
{
- gl::FramebufferAttachment *colorAttachment = *it;
- gl::Error error = InvalidateAttachmentSwizzles(colorAttachment);
- if (error.isError())
+ if (colorAttachment.isAttached())
{
- return error;
+ gl::Error error = InvalidateAttachmentSwizzles(&colorAttachment);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
- gl::Error error = InvalidateAttachmentSwizzles(mData.mDepthAttachment);
+ gl::Error error = InvalidateAttachmentSwizzles(mData.getDepthAttachment());
if (error.isError())
{
return error;
}
- error = InvalidateAttachmentSwizzles(mData.mStencilAttachment);
+ error = InvalidateAttachmentSwizzles(mData.getStencilAttachment());
if (error.isError())
{
return error;
@@ -89,10 +90,30 @@ gl::Error Framebuffer11::invalidateSwizzles() const
return gl::Error(GL_NO_ERROR);
}
-gl::Error Framebuffer11::clear(const gl::State &state, const ClearParameters &clearParams)
+gl::Error Framebuffer11::clear(const gl::Data &data, const ClearParameters &clearParams)
{
Clear11 *clearer = mRenderer->getClearer();
- gl::Error error = clearer->clearFramebuffer(clearParams, mData);
+ gl::Error error(GL_NO_ERROR);
+
+ const gl::FramebufferAttachment *colorAttachment = mData.getFirstColorAttachment();
+ if (clearParams.scissorEnabled == true && colorAttachment != nullptr &&
+ UsePresentPathFast(mRenderer, colorAttachment))
+ {
+ // If the current framebuffer is using the default colorbuffer, and present path fast is
+ // active, and the scissor rect is enabled, then we should invert the scissor rect
+ // vertically
+ ClearParameters presentPathFastClearParams = clearParams;
+ gl::Extents framebufferSize = colorAttachment->getSize();
+ presentPathFastClearParams.scissor.y = framebufferSize.height -
+ presentPathFastClearParams.scissor.y -
+ presentPathFastClearParams.scissor.height;
+ error = clearer->clearFramebuffer(presentPathFastClearParams, mData);
+ }
+ else
+ {
+ error = clearer->clearFramebuffer(clearParams, mData);
+ }
+
if (error.isError())
{
return error;
@@ -107,76 +128,193 @@ gl::Error Framebuffer11::clear(const gl::State &state, const ClearParameters &cl
return gl::Error(GL_NO_ERROR);
}
-static gl::Error getRenderTargetResource(const gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndexOut,
- ID3D11Texture2D **texture2DOut)
+gl::Error Framebuffer11::invalidate(size_t count, const GLenum *attachments)
{
- ASSERT(colorbuffer);
+ return invalidateBase(count, attachments, false);
+}
- RenderTarget11 *renderTarget = NULL;
- gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &renderTarget);
- if (error.isError())
+gl::Error Framebuffer11::discard(size_t count, const GLenum *attachments)
+{
+ return invalidateBase(count, attachments, true);
+}
+
+gl::Error Framebuffer11::invalidateBase(size_t count, const GLenum *attachments, bool useEXTBehavior) const
+{
+#if defined(ANGLE_ENABLE_D3D11_1)
+ ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported();
+
+ if (!deviceContext1)
{
- return error;
+ // DiscardView() is only supported on ID3D11DeviceContext1
+ return gl::Error(GL_NO_ERROR);
}
- ID3D11Resource *renderTargetResource = renderTarget->getTexture();
- ASSERT(renderTargetResource);
-
- *subresourceIndexOut = renderTarget->getSubresourceIndex();
- *texture2DOut = d3d11::DynamicCastComObject<ID3D11Texture2D>(renderTargetResource);
+ bool foundDepth = false;
+ bool foundStencil = false;
- if (!(*texture2DOut))
+ for (size_t i = 0; i < count; ++i)
{
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to query the ID3D11Texture2D from a RenderTarget");
- }
+ switch (attachments[i])
+ {
+ // Handle depth and stencil attachments. Defer discarding until later.
+ case GL_DEPTH_STENCIL_ATTACHMENT:
+ foundDepth = true;
+ foundStencil = true;
+ break;
+ case GL_DEPTH_EXT:
+ case GL_DEPTH_ATTACHMENT:
+ foundDepth = true;
+ break;
+ case GL_STENCIL_EXT:
+ case GL_STENCIL_ATTACHMENT:
+ foundStencil = true;
+ break;
+ default:
+ {
+ // Handle color attachments
+ ASSERT((attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT15) ||
+ (attachments[i] == GL_COLOR));
- return gl::Error(GL_NO_ERROR);
-}
+ RenderTarget11 *renderTarget = nullptr;
+ ID3D11View *colorView = nullptr;
+ gl::Error error(GL_NO_ERROR);
+ size_t colorAttachmentID = 0;
-gl::Error Framebuffer11::readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) const
-{
- ID3D11Texture2D *colorBufferTexture = NULL;
- unsigned int subresourceIndex = 0;
+ if (attachments[i] == GL_COLOR)
+ {
+ colorAttachmentID = 0;
+ }
+ else
+ {
+ colorAttachmentID = attachments[i] - GL_COLOR_ATTACHMENT0;
+ }
- const gl::FramebufferAttachment *colorbuffer = mData.getReadAttachment();
- ASSERT(colorbuffer);
+ if (mData.getColorAttachment(static_cast<unsigned int>(colorAttachmentID)))
+ {
+ error = mData.getColorAttachment(static_cast<unsigned int>(colorAttachmentID))
+ ->getRenderTarget(&renderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ colorView = renderTarget->getRenderTargetView();
+
+ if (colorView != nullptr)
+ {
+ deviceContext1->DiscardView(colorView);
+ }
+ }
- gl::Error error = getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture);
- if (error.isError())
+ break;
+ }
+ }
+ }
+
+ bool discardDepth = false;
+ bool discardStencil = false;
+
+ // The D3D11 renderer uses the same view for depth and stencil buffers, so we must be careful.
+ if (useEXTBehavior)
{
- return error;
+ // In the extension, if the app discards only one of the depth and stencil attachments, but
+ // those are backed by the same packed_depth_stencil buffer, then both images become undefined.
+ discardDepth = foundDepth;
+
+ // Don't bother discarding the stencil buffer if the depth buffer will already do it
+ discardStencil = foundStencil && (!discardDepth || mData.getDepthAttachment() == nullptr);
+ }
+ else
+ {
+ // In ES 3.0.4, if a specified attachment has base internal format DEPTH_STENCIL but the
+ // attachments list does not include DEPTH_STENCIL_ATTACHMENT or both DEPTH_ATTACHMENT and
+ // STENCIL_ATTACHMENT, then only the specified portion of every pixel in the subregion of pixels
+ // of the DEPTH_STENCIL buffer may be invalidated, and the other portion must be preserved.
+ discardDepth = (foundDepth && foundStencil) || (foundDepth && (mData.getStencilAttachment() == nullptr));
+ discardStencil = (foundStencil && (mData.getDepthAttachment() == nullptr));
}
- gl::Buffer *packBuffer = pack.pixelBuffer.get();
- if (packBuffer != NULL)
+ if (discardDepth && mData.getDepthAttachment())
{
- Buffer11 *packBufferStorage = Buffer11::makeBuffer11(packBuffer->getImplementation());
- PackPixelsParams packParams(area, format, type, outputPitch, pack, reinterpret_cast<ptrdiff_t>(pixels));
+ RenderTarget11 *renderTarget = nullptr;
+ ID3D11View *depthView = nullptr;
+ gl::Error error(GL_NO_ERROR);
- error = packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams);
+ error = mData.getDepthAttachment()->getRenderTarget(&renderTarget);
if (error.isError())
{
- SafeRelease(colorBufferTexture);
return error;
}
- packBuffer->getIndexRangeCache()->clear();
+ depthView = renderTarget->getDepthStencilView();
+
+ if (depthView != nullptr)
+ {
+ deviceContext1->DiscardView(depthView);
+ }
}
- else
+
+ if (discardStencil && mData.getStencilAttachment())
{
- error = mRenderer->readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels);
+ RenderTarget11 *renderTarget = nullptr;
+ ID3D11View *stencilView = nullptr;
+ gl::Error error(GL_NO_ERROR);
+
+ error = mData.getStencilAttachment()->getRenderTarget(&renderTarget);
if (error.isError())
{
- SafeRelease(colorBufferTexture);
return error;
}
+
+ stencilView = renderTarget->getDepthStencilView();
+
+ if (stencilView != nullptr)
+ {
+ deviceContext1->DiscardView(stencilView);
+ }
}
+#endif // ANGLE_ENABLE_D3D11_1
- SafeRelease(colorBufferTexture);
+ return gl::Error(GL_NO_ERROR);
+}
+gl::Error Framebuffer11::invalidateSub(size_t, const GLenum *, const gl::Rectangle &)
+{
+ // A no-op implementation conforms to the spec, so don't call UNIMPLEMENTED()
return gl::Error(GL_NO_ERROR);
}
+gl::Error Framebuffer11::readPixelsImpl(const gl::Rectangle &area,
+ GLenum format,
+ GLenum type,
+ size_t outputPitch,
+ const gl::PixelPackState &pack,
+ uint8_t *pixels) const
+{
+ const gl::FramebufferAttachment *readAttachment = mData.getReadAttachment();
+ ASSERT(readAttachment);
+
+ gl::Buffer *packBuffer = pack.pixelBuffer.get();
+ if (packBuffer != nullptr)
+ {
+ if (pack.rowLength != 0 || pack.skipRows != 0 || pack.skipPixels != 0)
+ {
+ UNIMPLEMENTED();
+ return gl::Error(GL_INVALID_OPERATION,
+ "Unimplemented pixel store parameters in readPixelsImpl");
+ }
+
+ Buffer11 *packBufferStorage = GetImplAs<Buffer11>(packBuffer);
+ PackPixelsParams packParams(area, format, type, static_cast<GLuint>(outputPitch), pack,
+ reinterpret_cast<ptrdiff_t>(pixels));
+
+ return packBufferStorage->packPixels(*readAttachment, packParams);
+ }
+
+ return mRenderer->readFromAttachment(*readAttachment, area, format, type,
+ static_cast<GLuint>(outputPitch), pack, pixels);
+}
+
gl::Error Framebuffer11::blit(const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, const gl::Rectangle *scissor,
bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter,
const gl::Framebuffer *sourceFramebuffer)
@@ -186,31 +324,53 @@ gl::Error Framebuffer11::blit(const gl::Rectangle &sourceArea, const gl::Rectang
const gl::FramebufferAttachment *readBuffer = sourceFramebuffer->getReadColorbuffer();
ASSERT(readBuffer);
- RenderTargetD3D *readRenderTarget = NULL;
- gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
+ RenderTargetD3D *readRenderTarget = nullptr;
+ gl::Error error = readBuffer->getRenderTarget(&readRenderTarget);
if (error.isError())
{
return error;
}
ASSERT(readRenderTarget);
- for (size_t colorAttachment = 0; colorAttachment < mData.mColorAttachments.size(); colorAttachment++)
+ const auto &colorAttachments = mData.getColorAttachments();
+ const auto &drawBufferStates = mData.getDrawBufferStates();
+
+ for (size_t colorAttachment = 0; colorAttachment < colorAttachments.size(); colorAttachment++)
{
- if (mData.mColorAttachments[colorAttachment] != nullptr &&
- mData.mDrawBufferStates[colorAttachment] != GL_NONE)
- {
- const gl::FramebufferAttachment *drawBuffer = mData.mColorAttachments[colorAttachment];
+ const gl::FramebufferAttachment &drawBuffer = colorAttachments[colorAttachment];
- RenderTargetD3D *drawRenderTarget = NULL;
- error = GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
+ if (drawBuffer.isAttached() &&
+ drawBufferStates[colorAttachment] != GL_NONE)
+ {
+ RenderTargetD3D *drawRenderTarget = nullptr;
+ error = drawBuffer.getRenderTarget(&drawRenderTarget);
if (error.isError())
{
return error;
}
ASSERT(drawRenderTarget);
- error = mRenderer->blitRenderbufferRect(sourceArea, destArea, readRenderTarget, drawRenderTarget,
- filter, scissor, blitRenderTarget, false, false);
+ const bool invertColorSource = UsePresentPathFast(mRenderer, readBuffer);
+ gl::Rectangle actualSourceArea = sourceArea;
+ if (invertColorSource)
+ {
+ RenderTarget11 *readRenderTarget11 = GetAs<RenderTarget11>(readRenderTarget);
+ actualSourceArea.y = readRenderTarget11->getHeight() - sourceArea.y;
+ actualSourceArea.height = -sourceArea.height;
+ }
+
+ const bool invertColorDest = UsePresentPathFast(mRenderer, &drawBuffer);
+ gl::Rectangle actualDestArea = destArea;
+ if (invertColorDest)
+ {
+ RenderTarget11 *drawRenderTarget11 = GetAs<RenderTarget11>(drawRenderTarget);
+ actualDestArea.y = drawRenderTarget11->getHeight() - destArea.y;
+ actualDestArea.height = -destArea.height;
+ }
+
+ error = mRenderer->blitRenderbufferRect(actualSourceArea, actualDestArea,
+ readRenderTarget, drawRenderTarget, filter,
+ scissor, blitRenderTarget, false, false);
if (error.isError())
{
return error;
@@ -221,11 +381,11 @@ gl::Error Framebuffer11::blit(const gl::Rectangle &sourceArea, const gl::Rectang
if (blitDepth || blitStencil)
{
- gl::FramebufferAttachment *readBuffer = sourceFramebuffer->getDepthOrStencilbuffer();
+ const gl::FramebufferAttachment *readBuffer = sourceFramebuffer->getDepthOrStencilbuffer();
ASSERT(readBuffer);
- RenderTargetD3D *readRenderTarget = NULL;
- gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
+ RenderTargetD3D *readRenderTarget = nullptr;
+ gl::Error error = readBuffer->getRenderTarget(&readRenderTarget);
if (error.isError())
{
return error;
@@ -235,8 +395,8 @@ gl::Error Framebuffer11::blit(const gl::Rectangle &sourceArea, const gl::Rectang
const gl::FramebufferAttachment *drawBuffer = mData.getDepthOrStencilAttachment();
ASSERT(drawBuffer);
- RenderTargetD3D *drawRenderTarget = NULL;
- error = GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
+ RenderTargetD3D *drawRenderTarget = nullptr;
+ error = drawBuffer->getRenderTarget(&drawRenderTarget);
if (error.isError())
{
return error;
@@ -262,7 +422,7 @@ gl::Error Framebuffer11::blit(const gl::Rectangle &sourceArea, const gl::Rectang
GLenum Framebuffer11::getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const
{
- RenderTarget11 *renderTarget11 = RenderTarget11::makeRenderTarget11(renderTarget);
+ RenderTarget11 *renderTarget11 = GetAs<RenderTarget11>(renderTarget);
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(renderTarget11->getDXGIFormat());
return dxgiFormatInfo.internalFormat;
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
index 07fa480fa2..c8a33ec7e5 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
@@ -21,19 +21,28 @@ class Framebuffer11 : public FramebufferD3D
Framebuffer11(const gl::Framebuffer::Data &data, Renderer11 *renderer);
virtual ~Framebuffer11();
+ gl::Error discard(size_t count, const GLenum *attachments) override;
+ gl::Error invalidate(size_t count, const GLenum *attachments) override;
+ gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) override;
+
// Invalidate the cached swizzles of all bound texture attachments.
gl::Error invalidateSwizzles() const;
private:
- gl::Error clear(const gl::State &state, const ClearParameters &clearParams) override;
+ gl::Error clear(const gl::Data &data, const ClearParameters &clearParams) override;
- gl::Error readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch,
- const gl::PixelPackState &pack, uint8_t *pixels) const override;
+ gl::Error readPixelsImpl(const gl::Rectangle &area,
+ GLenum format,
+ GLenum type,
+ size_t outputPitch,
+ const gl::PixelPackState &pack,
+ uint8_t *pixels) const override;
gl::Error blit(const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, const gl::Rectangle *scissor,
bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter,
const gl::Framebuffer *sourceFramebuffer) override;
+ gl::Error invalidateBase(size_t count, const GLenum *attachments, bool useEXTBehavior) const;
GLenum getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const override;
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.cpp
index 956b78b5a6..c52092d81e 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.cpp
@@ -7,17 +7,18 @@
// Image11.h: Implements the rx::Image11 class, which acts as the interface to
// the actual underlying resources of a Texture
-#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/d3d11/Image11.h"
-#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
-#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
-#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
-#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
-#include "libANGLE/Framebuffer.h"
-#include "libANGLE/FramebufferAttachment.h"
-#include "libANGLE/formatutils.h"
#include "common/utilities.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
+#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
namespace rx
{
@@ -32,9 +33,6 @@ Image11::Image11(Renderer11 *renderer)
mAssociatedImageIndex(gl::ImageIndex::MakeInvalid()),
mRecoveredFromStorageCount(0)
{
- // mRenderer should remain unchanged during the lifetime of the Image11 object.
- // This lets us safely use mRenderer (and its Feature Level) in Image11's methods.
- mFeatureLevel = renderer->getFeatureLevel();
}
Image11::~Image11()
@@ -43,12 +41,6 @@ Image11::~Image11()
releaseStagingTexture();
}
-Image11 *Image11::makeImage11(ImageD3D *img)
-{
- ASSERT(HAS_DYNAMIC_TYPE(Image11*, img));
- return static_cast<Image11*>(img);
-}
-
gl::Error Image11::generateMipmap(Image11 *dest, Image11 *src)
{
ASSERT(src->getDXGIFormat() == dest->getDXGIFormat());
@@ -94,9 +86,14 @@ bool Image11::isDirty() const
// AND mStagingTexture doesn't exist AND mStagingTexture doesn't need to be recovered from TextureStorage
// AND the texture doesn't require init data (i.e. a blank new texture will suffice)
// then isDirty should still return false.
- if (mDirty && !mStagingTexture && !mRecoverFromStorage && !(d3d11::GetTextureFormatInfo(mInternalFormat, mFeatureLevel).dataInitializerFunction != NULL))
+ if (mDirty && !mStagingTexture && !mRecoverFromStorage)
{
- return false;
+ const Renderer11DeviceCaps &deviceCaps = mRenderer->getRenderer11DeviceCaps();
+ const d3d11::TextureFormat formatInfo = d3d11::GetTextureFormatInfo(mInternalFormat, deviceCaps);
+ if (formatInfo.dataInitializerFunction == nullptr)
+ {
+ return false;
+ }
}
return mDirty;
@@ -104,7 +101,7 @@ bool Image11::isDirty() const
gl::Error Image11::copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region)
{
- TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(storage);
+ TextureStorage11 *storage11 = GetAs<TextureStorage11>(storage);
// If an app's behavior results in an Image11 copying its data to/from to a TextureStorage multiple times,
// then we should just keep the staging texture around to prevent the copying from impacting perf.
@@ -222,7 +219,7 @@ bool Image11::redefine(GLenum target, GLenum internalformat, const gl::Extents &
mTarget = target;
// compute the d3d format that will be used
- const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, mFeatureLevel);
+ const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, mRenderer->getRenderer11DeviceCaps());
mDXGIFormat = formatInfo.texFormat;
mRenderable = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);
@@ -250,13 +247,16 @@ gl::Error Image11::loadData(const gl::Box &area, const gl::PixelUnpackState &unp
{
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
GLsizei inputRowPitch = formatInfo.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength);
- GLsizei inputDepthPitch = formatInfo.computeDepthPitch(type, area.width, area.height, unpack.alignment, unpack.rowLength);
+ GLsizei inputDepthPitch = formatInfo.computeDepthPitch(
+ type, area.width, area.height, unpack.alignment, unpack.rowLength, unpack.imageHeight);
+ GLsizei inputSkipBytes = formatInfo.computeSkipPixels(
+ inputRowPitch, inputDepthPitch, unpack.skipImages, unpack.skipRows, unpack.skipPixels);
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mDXGIFormat);
GLuint outputPixelSize = dxgiFormatInfo.pixelBytes;
- const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat, mFeatureLevel);
- LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(type);
+ const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat, mRenderer->getRenderer11DeviceCaps());
+ LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(type).loadFunction;
D3D11_MAPPED_SUBRESOURCE mappedImage;
gl::Error error = map(D3D11_MAP_WRITE, &mappedImage);
@@ -267,8 +267,8 @@ gl::Error Image11::loadData(const gl::Box &area, const gl::PixelUnpackState &unp
uint8_t *offsetMappedData = (reinterpret_cast<uint8_t*>(mappedImage.pData) + (area.y * mappedImage.RowPitch + area.x * outputPixelSize + area.z * mappedImage.DepthPitch));
loadFunction(area.width, area.height, area.depth,
- reinterpret_cast<const uint8_t*>(input), inputRowPitch, inputDepthPitch,
- offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch);
+ reinterpret_cast<const uint8_t *>(input) + inputSkipBytes, inputRowPitch,
+ inputDepthPitch, offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch);
unmap();
@@ -279,7 +279,8 @@ gl::Error Image11::loadCompressedData(const gl::Box &area, const void *input)
{
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, area.width, 1, 0);
- GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0);
+ GLsizei inputDepthPitch =
+ formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0, 0);
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mDXGIFormat);
GLuint outputPixelSize = dxgiFormatInfo.pixelBytes;
@@ -289,8 +290,8 @@ gl::Error Image11::loadCompressedData(const gl::Box &area, const void *input)
ASSERT(area.x % outputBlockWidth == 0);
ASSERT(area.y % outputBlockHeight == 0);
- const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat, mFeatureLevel);
- LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(GL_UNSIGNED_BYTE);
+ const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat, mRenderer->getRenderer11DeviceCaps());
+ LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(GL_UNSIGNED_BYTE).loadFunction;
D3D11_MAPPED_SUBRESOURCE mappedImage;
gl::Error error = map(D3D11_MAP_WRITE, &mappedImage);
@@ -312,180 +313,159 @@ gl::Error Image11::loadCompressedData(const gl::Box &area, const void *input)
return gl::Error(GL_NO_ERROR);
}
-gl::Error Image11::copy(const gl::Offset &destOffset, const gl::Rectangle &sourceArea, RenderTargetD3D *source)
-{
- RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(source);
- ASSERT(sourceRenderTarget->getTexture());
-
- ID3D11Resource *resource = sourceRenderTarget->getTexture();
- UINT subresourceIndex = sourceRenderTarget->getSubresourceIndex();
-
- gl::Box sourceBox(sourceArea.x, sourceArea.y, 0, sourceArea.width, sourceArea.height, 1);
- gl::Error error = copy(destOffset, sourceBox, resource, subresourceIndex);
-
- SafeRelease(resource);
-
- return error;
-}
-
-gl::Error Image11::copy(const gl::Offset &destOffset, const gl::Box &sourceArea, const gl::ImageIndex &sourceIndex, TextureStorage *source)
+gl::Error Image11::copyFromTexStorage(const gl::ImageIndex &imageIndex, TextureStorage *source)
{
- TextureStorage11 *sourceStorage11 = TextureStorage11::makeTextureStorage11(source);
+ TextureStorage11 *storage11 = GetAs<TextureStorage11>(source);
- UINT subresourceIndex = sourceStorage11->getSubresourceIndex(sourceIndex);
- ID3D11Resource *resource = NULL;
- gl::Error error = sourceStorage11->getResource(&resource);
+ ID3D11Resource *resource = nullptr;
+ gl::Error error = storage11->getResource(&resource);
if (error.isError())
{
return error;
}
- error = copy(destOffset, sourceArea, resource, subresourceIndex);
-
- SafeRelease(resource);
+ UINT subresourceIndex = storage11->getSubresourceIndex(imageIndex);
+ TextureHelper11 textureHelper = TextureHelper11::MakeAndReference(resource);
- return error;
+ gl::Box sourceBox(0, 0, 0, mWidth, mHeight, mDepth);
+ return copyWithoutConversion(gl::Offset(), sourceBox, textureHelper, subresourceIndex);
}
-gl::Error Image11::copy(const gl::Offset &destOffset, const gl::Box &sourceArea, ID3D11Resource *source, UINT sourceSubResource)
+gl::Error Image11::copyFromFramebuffer(const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ const gl::Framebuffer *sourceFBO)
{
- D3D11_RESOURCE_DIMENSION dim;
- source->GetType(&dim);
-
- DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
- gl::Extents extents;
- UINT sampleCount = 0;
+ const gl::FramebufferAttachment *srcAttachment = sourceFBO->getReadColorbuffer();
+ ASSERT(srcAttachment);
- ID3D11Texture2D *source2D = NULL;
+ const auto &d3d11Format = d3d11::GetTextureFormatInfo(srcAttachment->getInternalFormat(),
+ mRenderer->getRenderer11DeviceCaps());
- if (dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D)
- {
- D3D11_TEXTURE2D_DESC textureDesc2D;
- source2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(source);
- ASSERT(source2D);
- source2D->GetDesc(&textureDesc2D);
-
- format = textureDesc2D.Format;
- extents = gl::Extents(textureDesc2D.Width, textureDesc2D.Height, 1);
- sampleCount = textureDesc2D.SampleDesc.Count;
- }
- else if (dim == D3D11_RESOURCE_DIMENSION_TEXTURE3D)
+ if (d3d11Format.texFormat == mDXGIFormat)
{
- D3D11_TEXTURE3D_DESC textureDesc3D;
- ID3D11Texture3D *source3D = d3d11::DynamicCastComObject<ID3D11Texture3D>(source);
- ASSERT(source3D);
- source3D->GetDesc(&textureDesc3D);
-
- format = textureDesc3D.Format;
- extents = gl::Extents(textureDesc3D.Width, textureDesc3D.Height, textureDesc3D.Depth);
- sampleCount = 1;
- }
- else
- {
- UNREACHABLE();
- }
-
- if (format == mDXGIFormat)
- {
- // No conversion needed-- use copyback fastpath
- ID3D11Resource *stagingTexture = NULL;
- unsigned int stagingSubresourceIndex = 0;
- gl::Error error = getStagingTexture(&stagingTexture, &stagingSubresourceIndex);
+ RenderTargetD3D *renderTarget = nullptr;
+ gl::Error error = srcAttachment->getRenderTarget(&renderTarget);
if (error.isError())
{
return error;
}
- ID3D11Device *device = mRenderer->getDevice();
- ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ RenderTarget11 *rt11 = GetAs<RenderTarget11>(renderTarget);
+ ASSERT(rt11->getTexture());
- UINT subresourceAfterResolve = sourceSubResource;
+ TextureHelper11 textureHelper = TextureHelper11::MakeAndReference(rt11->getTexture());
+ unsigned int sourceSubResource = rt11->getSubresourceIndex();
- ID3D11Resource *srcTex = NULL;
+ gl::Box sourceBox(sourceArea.x, sourceArea.y, 0, sourceArea.width, sourceArea.height, 1);
+ return copyWithoutConversion(destOffset, sourceBox, textureHelper, sourceSubResource);
+ }
- bool needResolve = (dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D && sampleCount > 1);
+ // This format requires conversion, so we must copy the texture to staging and manually convert
+ // via readPixels
+ D3D11_MAPPED_SUBRESOURCE mappedImage;
+ gl::Error error = map(D3D11_MAP_WRITE, &mappedImage);
+ if (error.isError())
+ {
+ return error;
+ }
- if (needResolve)
- {
- D3D11_TEXTURE2D_DESC resolveDesc;
- resolveDesc.Width = extents.width;
- resolveDesc.Height = extents.height;
- resolveDesc.MipLevels = 1;
- resolveDesc.ArraySize = 1;
- resolveDesc.Format = format;
- resolveDesc.SampleDesc.Count = 1;
- resolveDesc.SampleDesc.Quality = 0;
- resolveDesc.Usage = D3D11_USAGE_DEFAULT;
- resolveDesc.BindFlags = 0;
- resolveDesc.CPUAccessFlags = 0;
- resolveDesc.MiscFlags = 0;
-
- ID3D11Texture2D *srcTex2D = NULL;
- HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex2D);
- if (FAILED(result))
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result);
- }
- srcTex = srcTex2D;
+ // determine the offset coordinate into the destination buffer
+ const auto &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mDXGIFormat);
+ GLsizei rowOffset = dxgiFormatInfo.pixelBytes * destOffset.x;
- deviceContext->ResolveSubresource(srcTex, 0, source, sourceSubResource, format);
- subresourceAfterResolve = 0;
- }
- else
- {
- srcTex = source;
- }
+ uint8_t *dataOffset = static_cast<uint8_t *>(mappedImage.pData) +
+ mappedImage.RowPitch * destOffset.y + rowOffset +
+ destOffset.z * mappedImage.DepthPitch;
- D3D11_BOX srcBox;
- srcBox.left = sourceArea.x;
- srcBox.right = sourceArea.x + sourceArea.width;
- srcBox.top = sourceArea.y;
- srcBox.bottom = sourceArea.y + sourceArea.height;
- srcBox.front = sourceArea.z;
- srcBox.back = sourceArea.z + sourceArea.depth;
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
- deviceContext->CopySubresourceRegion(stagingTexture, stagingSubresourceIndex, destOffset.x, destOffset.y,
- destOffset.z, srcTex, subresourceAfterResolve, &srcBox);
+ error = mRenderer->readFromAttachment(*srcAttachment, sourceArea, formatInfo.format,
+ formatInfo.type, mappedImage.RowPitch,
+ gl::PixelPackState(), dataOffset);
- if (needResolve)
- {
- SafeRelease(srcTex);
- }
- }
- else
+ unmap();
+ mDirty = true;
+
+ return error;
+}
+
+gl::Error Image11::copyWithoutConversion(const gl::Offset &destOffset,
+ const gl::Box &sourceArea,
+ const TextureHelper11 &textureHelper,
+ UINT sourceSubResource)
+{
+ // No conversion needed-- use copyback fastpath
+ ID3D11Resource *stagingTexture = nullptr;
+ unsigned int stagingSubresourceIndex = 0;
+ gl::Error error = getStagingTexture(&stagingTexture, &stagingSubresourceIndex);
+ if (error.isError())
{
- // This format requires conversion, so we must copy the texture to staging and manually convert via readPixels
- D3D11_MAPPED_SUBRESOURCE mappedImage;
- gl::Error error = map(D3D11_MAP_WRITE, &mappedImage);
- if (error.isError())
- {
- return error;
- }
+ return error;
+ }
- // determine the offset coordinate into the destination buffer
- const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mDXGIFormat);
- GLsizei rowOffset = dxgiFormatInfo.pixelBytes * destOffset.x;
- uint8_t *dataOffset = static_cast<uint8_t*>(mappedImage.pData) + mappedImage.RowPitch * destOffset.y + rowOffset + destOffset.z * mappedImage.DepthPitch;
+ ID3D11Device *device = mRenderer->getDevice();
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
- const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
+ UINT subresourceAfterResolve = sourceSubResource;
- // Currently in ANGLE, the source data may only need to be converted if the source is the current framebuffer
- // and OpenGL ES framebuffers must be 2D textures therefore we should not need to convert 3D textures between different formats.
- ASSERT(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D);
- ASSERT(sourceArea.z == 0 && sourceArea.depth == 1);
- gl::Rectangle sourceRect(sourceArea.x, sourceArea.y, sourceArea.width, sourceArea.height);
- error = mRenderer->readTextureData(source2D, sourceSubResource, sourceRect, formatInfo.format, formatInfo.type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset);
+ ID3D11Resource *srcTex = nullptr;
+ const gl::Extents &extents = textureHelper.getExtents();
- unmap();
+ bool needResolve =
+ (textureHelper.getTextureType() == GL_TEXTURE_2D && textureHelper.getSampleCount() > 1);
- if (error.isError())
+ if (needResolve)
+ {
+ D3D11_TEXTURE2D_DESC resolveDesc;
+ resolveDesc.Width = extents.width;
+ resolveDesc.Height = extents.height;
+ resolveDesc.MipLevels = 1;
+ resolveDesc.ArraySize = 1;
+ resolveDesc.Format = textureHelper.getFormat();
+ resolveDesc.SampleDesc.Count = 1;
+ resolveDesc.SampleDesc.Quality = 0;
+ resolveDesc.Usage = D3D11_USAGE_DEFAULT;
+ resolveDesc.BindFlags = 0;
+ resolveDesc.CPUAccessFlags = 0;
+ resolveDesc.MiscFlags = 0;
+
+ ID3D11Texture2D *srcTex2D = NULL;
+ HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex2D);
+ if (FAILED(result))
{
- return error;
+ return gl::Error(GL_OUT_OF_MEMORY,
+ "Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.",
+ result);
}
+ srcTex = srcTex2D;
+
+ deviceContext->ResolveSubresource(srcTex, 0, textureHelper.getTexture2D(),
+ sourceSubResource, textureHelper.getFormat());
+ subresourceAfterResolve = 0;
+ }
+ else
+ {
+ srcTex = textureHelper.getResource();
}
- mDirty = true;
+ D3D11_BOX srcBox;
+ srcBox.left = sourceArea.x;
+ srcBox.right = sourceArea.x + sourceArea.width;
+ srcBox.top = sourceArea.y;
+ srcBox.bottom = sourceArea.y + sourceArea.height;
+ srcBox.front = sourceArea.z;
+ srcBox.back = sourceArea.z + sourceArea.depth;
+
+ deviceContext->CopySubresourceRegion(stagingTexture, stagingSubresourceIndex, destOffset.x,
+ destOffset.y, destOffset.z, srcTex,
+ subresourceAfterResolve, &srcBox);
+
+ if (needResolve)
+ {
+ SafeRelease(srcTex);
+ }
+ mDirty = true;
return gl::Error(GL_NO_ERROR);
}
@@ -543,11 +523,11 @@ gl::Error Image11::createStagingTexture()
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
- if (d3d11::GetTextureFormatInfo(mInternalFormat, mFeatureLevel).dataInitializerFunction != NULL)
+ if (d3d11::GetTextureFormatInfo(mInternalFormat, mRenderer->getRenderer11DeviceCaps()).dataInitializerFunction != NULL)
{
std::vector<D3D11_SUBRESOURCE_DATA> initialData;
- std::vector< std::vector<BYTE> > textureData;
- d3d11::GenerateInitialTextureData(mInternalFormat, mFeatureLevel, width, height, mDepth,
+ std::vector<std::vector<BYTE>> textureData;
+ d3d11::GenerateInitialTextureData(mInternalFormat, mRenderer->getRenderer11DeviceCaps(), width, height, mDepth,
lodOffset + 1, &initialData, &textureData);
result = device->CreateTexture3D(&desc, initialData.data(), &newTexture);
@@ -583,11 +563,11 @@ gl::Error Image11::createStagingTexture()
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
- if (d3d11::GetTextureFormatInfo(mInternalFormat, mFeatureLevel).dataInitializerFunction != NULL)
+ if (d3d11::GetTextureFormatInfo(mInternalFormat, mRenderer->getRenderer11DeviceCaps()).dataInitializerFunction != NULL)
{
std::vector<D3D11_SUBRESOURCE_DATA> initialData;
- std::vector< std::vector<BYTE> > textureData;
- d3d11::GenerateInitialTextureData(mInternalFormat, mFeatureLevel, width, height, 1,
+ std::vector<std::vector<BYTE>> textureData;
+ d3d11::GenerateInitialTextureData(mInternalFormat, mRenderer->getRenderer11DeviceCaps(), width, height, 1,
lodOffset + 1, &initialData, &textureData);
result = device->CreateTexture2D(&desc, initialData.data(), &newTexture);
@@ -637,13 +617,13 @@ gl::Error Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map)
ASSERT(mStagingTexture);
HRESULT result = deviceContext->Map(stagingTexture, subresourceIndex, mapType, 0, map);
- // this can fail if the device is removed (from TDR)
- if (d3d11::isDeviceLostError(result))
- {
- mRenderer->notifyDeviceLost();
- }
- else if (FAILED(result))
+ if (FAILED(result))
{
+ // this can fail if the device is removed (from TDR)
+ if (d3d11::isDeviceLostError(result))
+ {
+ mRenderer->notifyDeviceLost();
+ }
return gl::Error(GL_OUT_OF_MEMORY, "Failed to map staging texture, result: 0x%X.", result);
}
@@ -661,4 +641,4 @@ void Image11::unmap()
}
}
-}
+} // namespace rx
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.h
index 5734f73b15..a5fcec84f8 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.h
@@ -23,6 +23,7 @@ class Framebuffer;
namespace rx
{
class Renderer11;
+class TextureHelper11;
class TextureStorage11;
class Image11 : public ImageD3D
@@ -31,8 +32,6 @@ class Image11 : public ImageD3D
Image11(Renderer11 *renderer);
virtual ~Image11();
- static Image11 *makeImage11(ImageD3D *img);
-
static gl::Error generateMipmap(Image11 *dest, Image11 *src);
virtual bool isDirty() const;
@@ -46,9 +45,10 @@ class Image11 : public ImageD3D
virtual gl::Error loadData(const gl::Box &area, const gl::PixelUnpackState &unpack, GLenum type, const void *input);
virtual gl::Error loadCompressedData(const gl::Box &area, const void *input);
- virtual gl::Error copy(const gl::Offset &destOffset, const gl::Rectangle &sourceArea, RenderTargetD3D *source);
- virtual gl::Error copy(const gl::Offset &destOffset, const gl::Box &sourceArea,
- const gl::ImageIndex &sourceIndex, TextureStorage *source);
+ gl::Error copyFromTexStorage(const gl::ImageIndex &imageIndex, TextureStorage *source) override;
+ gl::Error copyFromFramebuffer(const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ const gl::Framebuffer *source) override;
gl::Error recoverFromAssociatedStorage();
bool isAssociatedStorageValid(TextureStorage11* textureStorage) const;
@@ -59,15 +59,16 @@ class Image11 : public ImageD3D
void unmap();
private:
- gl::Error copyToStorageImpl(TextureStorage11 *storage11, const gl::ImageIndex &index, const gl::Box &region);
- gl::Error copy(const gl::Offset &destOffset, const gl::Box &sourceArea, ID3D11Resource *source, UINT sourceSubResource);
+ gl::Error copyWithoutConversion(const gl::Offset &destOffset,
+ const gl::Box &sourceArea,
+ const TextureHelper11 &textureHelper,
+ UINT sourceSubResource);
gl::Error getStagingTexture(ID3D11Resource **outStagingTexture, unsigned int *outSubresourceIndex);
gl::Error createStagingTexture();
void releaseStagingTexture();
Renderer11 *mRenderer;
- D3D_FEATURE_LEVEL mFeatureLevel;
DXGI_FORMAT mDXGIFormat;
ID3D11Resource *mStagingTexture;
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp
index 99c199f2b9..a5e78a245d 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp
@@ -7,7 +7,9 @@
// IndexBuffer11.cpp: Defines the D3D11 IndexBuffer implementation.
#include "libANGLE/renderer/d3d/d3d11/IndexBuffer11.h"
+
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
namespace rx
{
@@ -47,6 +49,15 @@ gl::Error IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, b
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal index buffer of size, %lu.", bufferSize);
}
+
+ if (dynamic)
+ {
+ d3d11::SetDebugName(mBuffer, "IndexBuffer11 (dynamic)");
+ }
+ else
+ {
+ d3d11::SetDebugName(mBuffer, "IndexBuffer11 (static)");
+ }
}
mBufferSize = bufferSize;
@@ -56,12 +67,6 @@ gl::Error IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, b
return gl::Error(GL_NO_ERROR);
}
-IndexBuffer11 *IndexBuffer11::makeIndexBuffer11(IndexBuffer *indexBuffer)
-{
- ASSERT(HAS_DYNAMIC_TYPE(IndexBuffer11*, indexBuffer));
- return static_cast<IndexBuffer11*>(indexBuffer);
-}
-
gl::Error IndexBuffer11::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory)
{
if (!mBuffer)
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h
index eadd03eb76..e730377e00 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h
@@ -23,8 +23,6 @@ class IndexBuffer11 : public IndexBuffer
virtual gl::Error initialize(unsigned int bufferSize, GLenum indexType, bool dynamic);
- static IndexBuffer11 *makeIndexBuffer11(IndexBuffer *indexBuffer);
-
virtual gl::Error mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory);
virtual gl::Error unmapBuffer();
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
index 242c09d6ce..3a6d797ea6 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
@@ -8,43 +8,141 @@
// D3D11 input layouts.
#include "libANGLE/renderer/d3d/d3d11/InputLayoutCache.h"
-#include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h"
+
+#include "common/utilities.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/VertexAttribute.h"
+#include "libANGLE/renderer/d3d/IndexDataManager.h"
+#include "libANGLE/renderer/d3d/ProgramD3D.h"
+#include "libANGLE/renderer/d3d/VertexDataManager.h"
#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
#include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h"
+#include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h"
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
-#include "libANGLE/renderer/d3d/ProgramD3D.h"
-#include "libANGLE/renderer/d3d/VertexDataManager.h"
-#include "libANGLE/Program.h"
-#include "libANGLE/VertexAttribute.h"
-
#include "third_party/murmurhash/MurmurHash3.h"
namespace rx
{
-static void GetInputLayout(const TranslatedAttribute translatedAttributes[gl::MAX_VERTEX_ATTRIBS],
- gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS])
+namespace
+{
+
+size_t GetReservedBufferCount(bool usesPointSpriteEmulation)
{
- for (unsigned int attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
+ return usesPointSpriteEmulation ? 1 : 0;
+}
+
+gl::InputLayout GetInputLayout(const SortedAttribArray &translatedAttributes, size_t attributeCount)
+{
+ gl::InputLayout inputLayout(attributeCount, gl::VERTEX_FORMAT_INVALID);
+
+ for (size_t attributeIndex = 0; attributeIndex < attributeCount; ++attributeIndex)
{
- const TranslatedAttribute &translatedAttribute = translatedAttributes[attributeIndex];
+ const TranslatedAttribute *translatedAttribute = translatedAttributes[attributeIndex];
+
+ if (translatedAttribute->active)
+ {
+ inputLayout[attributeIndex] = gl::GetVertexFormatType(
+ *translatedAttribute->attribute, translatedAttribute->currentValueType);
+ }
+ }
+ return inputLayout;
+}
+
+GLenum GetGLSLAttributeType(const std::vector<sh::Attribute> &shaderAttributes, int index)
+{
+ // Count matrices differently
+ for (const sh::Attribute &attrib : shaderAttributes)
+ {
+ if (attrib.location == -1)
+ {
+ continue;
+ }
+
+ GLenum transposedType = gl::TransposeMatrixType(attrib.type);
+ int rows = gl::VariableRowCount(transposedType);
+
+ if (index >= attrib.location && index < attrib.location + rows)
+ {
+ return transposedType;
+ }
+ }
+
+ UNREACHABLE();
+ return GL_NONE;
+}
+
+const unsigned int kDefaultCacheSize = 1024;
+
+struct PackedAttribute
+{
+ uint8_t attribType;
+ uint8_t semanticIndex;
+ uint8_t vertexFormatType;
+ uint8_t divisor;
+};
- if (translatedAttributes[attributeIndex].active)
+Optional<size_t> FindFirstNonInstanced(const SortedAttribArray &sortedAttributes, size_t maxIndex)
+{
+ for (size_t index = 0; index < maxIndex; ++index)
+ {
+ if (sortedAttributes[index]->divisor == 0)
{
- inputLayout[attributeIndex] = gl::VertexFormat(*translatedAttribute.attribute,
- translatedAttribute.currentValueType);
+ return Optional<size_t>(index);
}
}
+
+ return Optional<size_t>::Invalid();
}
-const unsigned int InputLayoutCache::kMaxInputLayouts = 1024;
+} // anonymous namespace
+
+void InputLayoutCache::PackedAttributeLayout::addAttributeData(
+ GLenum glType,
+ UINT semanticIndex,
+ gl::VertexFormatType vertexFormatType,
+ unsigned int divisor)
+{
+ gl::AttributeType attribType = gl::GetAttributeType(glType);
+
+ PackedAttribute packedAttrib;
+ packedAttrib.attribType = static_cast<uint8_t>(attribType);
+ packedAttrib.semanticIndex = static_cast<uint8_t>(semanticIndex);
+ packedAttrib.vertexFormatType = static_cast<uint8_t>(vertexFormatType);
+ packedAttrib.divisor = static_cast<uint8_t>(divisor);
+
+ ASSERT(static_cast<gl::AttributeType>(packedAttrib.attribType) == attribType);
+ ASSERT(static_cast<UINT>(packedAttrib.semanticIndex) == semanticIndex);
+ ASSERT(static_cast<gl::VertexFormatType>(packedAttrib.vertexFormatType) == vertexFormatType);
+ ASSERT(static_cast<unsigned int>(packedAttrib.divisor) == divisor);
+
+ static_assert(sizeof(uint32_t) == sizeof(PackedAttribute), "PackedAttributes must be 32-bits exactly.");
+
+ attributeData[numAttributes++] = gl::bitCast<uint32_t>(packedAttrib);
+}
+
+bool InputLayoutCache::PackedAttributeLayout::operator<(const PackedAttributeLayout &other) const
+{
+ if (numAttributes != other.numAttributes)
+ {
+ return numAttributes < other.numAttributes;
+ }
+
+ if (flags != other.flags)
+ {
+ return flags < other.flags;
+ }
+
+ return memcmp(attributeData, other.attributeData, sizeof(uint32_t) * numAttributes) < 0;
+}
-InputLayoutCache::InputLayoutCache() : mInputLayoutMap(kMaxInputLayouts, hashInputLayout, compareInputLayouts)
+InputLayoutCache::InputLayoutCache() : mUnsortedAttributesCount(0), mCacheSize(kDefaultCacheSize)
{
mCounter = 0;
mDevice = NULL;
mDeviceContext = NULL;
mCurrentIL = NULL;
+
for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
mCurrentBuffers[i] = NULL;
@@ -70,11 +168,11 @@ void InputLayoutCache::initialize(ID3D11Device *device, ID3D11DeviceContext *con
void InputLayoutCache::clear()
{
- for (InputLayoutMap::iterator i = mInputLayoutMap.begin(); i != mInputLayoutMap.end(); i++)
+ for (auto &layout : mLayoutMap)
{
- SafeRelease(i->second.inputLayout);
+ SafeRelease(layout.second);
}
- mInputLayoutMap.clear();
+ mLayoutMap.clear();
SafeRelease(mPointSpriteVertexBuffer);
SafeRelease(mPointSpriteIndexBuffer);
markDirty();
@@ -89,236 +187,135 @@ void InputLayoutCache::markDirty()
mCurrentVertexStrides[i] = static_cast<UINT>(-1);
mCurrentVertexOffsets[i] = static_cast<UINT>(-1);
}
+ mUnsortedAttributesCount = 0;
}
-gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
- GLenum mode, gl::Program *program)
+gl::Error InputLayoutCache::applyVertexBuffers(
+ const std::vector<TranslatedAttribute> &unsortedAttributes,
+ GLenum mode,
+ gl::Program *program,
+ TranslatedIndexData *indexInfo,
+ GLsizei numIndicesPerInstance)
{
+ ASSERT(mDevice && mDeviceContext);
+
ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
- int sortedSemanticIndices[gl::MAX_VERTEX_ATTRIBS];
- programD3D->sortAttributesByLayout(attributes, sortedSemanticIndices);
bool programUsesInstancedPointSprites = programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation();
bool instancedPointSpritesActive = programUsesInstancedPointSprites && (mode == GL_POINTS);
- if (!mDevice || !mDeviceContext)
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Internal input layout cache is not initialized.");
- }
-
- InputLayoutKey ilKey = { 0 };
-
- static const char* semanticName = "TEXCOORD";
+ SortedIndexArray sortedSemanticIndices;
+ mSortedAttributes.fill(nullptr);
+ mUnsortedAttributesCount = unsortedAttributes.size();
- unsigned int firstIndexedElement = gl::MAX_VERTEX_ATTRIBS;
- unsigned int firstInstancedElement = gl::MAX_VERTEX_ATTRIBS;
- unsigned int nextAvailableInputSlot = 0;
+ programD3D->sortAttributesByLayout(unsortedAttributes, sortedSemanticIndices.data(),
+ mSortedAttributes.data());
- for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ // If we are using FL 9_3, make sure the first attribute is not instanced
+ if (mFeatureLevel <= D3D_FEATURE_LEVEL_9_3 && !unsortedAttributes.empty())
{
- if (attributes[i].active)
+ if (mSortedAttributes[0]->divisor > 0)
{
- D3D11_INPUT_CLASSIFICATION inputClass = attributes[i].divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA;
- // If rendering points and instanced pointsprite emulation is being used, the inputClass is required to be configured as per instance data
- inputClass = instancedPointSpritesActive ? D3D11_INPUT_PER_INSTANCE_DATA : inputClass;
-
- gl::VertexFormat vertexFormat(*attributes[i].attribute, attributes[i].currentValueType);
- const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat, mFeatureLevel);
-
- // Record the type of the associated vertex shader vector in our key
- // This will prevent mismatched vertex shaders from using the same input layout
- GLint attributeSize;
- program->getActiveAttribute(ilKey.elementCount, 0, NULL, &attributeSize, &ilKey.elements[ilKey.elementCount].glslElementType, NULL);
-
- ilKey.elements[ilKey.elementCount].desc.SemanticName = semanticName;
- ilKey.elements[ilKey.elementCount].desc.SemanticIndex = sortedSemanticIndices[i];
- ilKey.elements[ilKey.elementCount].desc.Format = vertexFormatInfo.nativeFormat;
- ilKey.elements[ilKey.elementCount].desc.InputSlot = i;
- ilKey.elements[ilKey.elementCount].desc.AlignedByteOffset = 0;
- ilKey.elements[ilKey.elementCount].desc.InputSlotClass = inputClass;
- ilKey.elements[ilKey.elementCount].desc.InstanceDataStepRate = instancedPointSpritesActive ? 1 : attributes[i].divisor;
-
- if (inputClass == D3D11_INPUT_PER_VERTEX_DATA && firstIndexedElement == gl::MAX_VERTEX_ATTRIBS)
+ Optional<size_t> firstNonInstancedIndex =
+ FindFirstNonInstanced(mSortedAttributes, unsortedAttributes.size());
+ if (firstNonInstancedIndex.valid())
{
- firstIndexedElement = ilKey.elementCount;
+ size_t index = firstNonInstancedIndex.value();
+ std::swap(mSortedAttributes[0], mSortedAttributes[index]);
+ std::swap(sortedSemanticIndices[0], sortedSemanticIndices[index]);
}
- else if (inputClass == D3D11_INPUT_PER_INSTANCE_DATA && firstInstancedElement == gl::MAX_VERTEX_ATTRIBS)
- {
- firstInstancedElement = ilKey.elementCount;
- }
-
- ilKey.elementCount++;
- nextAvailableInputSlot = i + 1;
}
}
- // Instanced PointSprite emulation requires additional entries in the
- // inputlayout to support the vertices that make up the pointsprite quad.
- // We do this even if mode != GL_POINTS, since the shader signature has these inputs, and the input layout must match the shader
- if (programUsesInstancedPointSprites)
+ gl::Error error = updateInputLayout(program, mode, mSortedAttributes, sortedSemanticIndices,
+ unsortedAttributes.size(), numIndicesPerInstance);
+ if (error.isError())
{
- ilKey.elements[ilKey.elementCount].desc.SemanticName = "SPRITEPOSITION";
- ilKey.elements[ilKey.elementCount].desc.SemanticIndex = 0;
- ilKey.elements[ilKey.elementCount].desc.Format = DXGI_FORMAT_R32G32B32_FLOAT;
- ilKey.elements[ilKey.elementCount].desc.InputSlot = nextAvailableInputSlot;
- ilKey.elements[ilKey.elementCount].desc.AlignedByteOffset = 0;
- ilKey.elements[ilKey.elementCount].desc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
- ilKey.elements[ilKey.elementCount].desc.InstanceDataStepRate = 0;
-
- // The new elements are D3D11_INPUT_PER_VERTEX_DATA data so the indexed element
- // tracking must be applied. This ensures that the instancing specific
- // buffer swapping logic continues to work.
- if (firstIndexedElement == gl::MAX_VERTEX_ATTRIBS)
- {
- firstIndexedElement = ilKey.elementCount;
- }
-
- ilKey.elementCount++;
-
- ilKey.elements[ilKey.elementCount].desc.SemanticName = "SPRITETEXCOORD";
- ilKey.elements[ilKey.elementCount].desc.SemanticIndex = 0;
- ilKey.elements[ilKey.elementCount].desc.Format = DXGI_FORMAT_R32G32_FLOAT;
- ilKey.elements[ilKey.elementCount].desc.InputSlot = nextAvailableInputSlot;
- ilKey.elements[ilKey.elementCount].desc.AlignedByteOffset = sizeof(float) * 3;
- ilKey.elements[ilKey.elementCount].desc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
- ilKey.elements[ilKey.elementCount].desc.InstanceDataStepRate = 0;
-
- ilKey.elementCount++;
+ return error;
}
- // On 9_3, we must ensure that slot 0 contains non-instanced data.
- // If slot 0 currently contains instanced data then we swap it with a non-instanced element.
- // Note that instancing is only available on 9_3 via ANGLE_instanced_arrays, since 9_3 doesn't support OpenGL ES 3.0.
- // As per the spec for ANGLE_instanced_arrays, not all attributes can be instanced simultaneously, so a non-instanced element must exist.
- ASSERT(!(mFeatureLevel <= D3D_FEATURE_LEVEL_9_3 && firstIndexedElement == gl::MAX_VERTEX_ATTRIBS));
- bool moveFirstIndexedIntoSlotZero = mFeatureLevel <= D3D_FEATURE_LEVEL_9_3 && firstInstancedElement == 0 && firstIndexedElement != gl::MAX_VERTEX_ATTRIBS;
-
- if (moveFirstIndexedIntoSlotZero)
- {
- ilKey.elements[firstInstancedElement].desc.InputSlot = ilKey.elements[firstIndexedElement].desc.InputSlot;
- ilKey.elements[firstIndexedElement].desc.InputSlot = 0;
-
- // Instanced PointSprite emulation uses multiple layout entries across a single vertex buffer.
- // If an index swap is performed, we need to ensure that all elements get the proper InputSlot.
- if (programUsesInstancedPointSprites)
- {
- ilKey.elements[firstIndexedElement + 1].desc.InputSlot = 0;
- }
- }
+ bool dirtyBuffers = false;
+ size_t minDiff = gl::MAX_VERTEX_ATTRIBS;
+ size_t maxDiff = 0;
- ID3D11InputLayout *inputLayout = NULL;
+ // Note that if we use instance emulation, we reserve the first buffer slot.
+ size_t reservedBuffers = GetReservedBufferCount(programUsesInstancedPointSprites);
- InputLayoutMap::iterator keyIter = mInputLayoutMap.find(ilKey);
- if (keyIter != mInputLayoutMap.end())
- {
- inputLayout = keyIter->second.inputLayout;
- keyIter->second.lastUsedTime = mCounter++;
- }
- else
+ for (size_t attribIndex = 0; attribIndex < (gl::MAX_VERTEX_ATTRIBS - reservedBuffers);
+ ++attribIndex)
{
- gl::VertexFormat shaderInputLayout[gl::MAX_VERTEX_ATTRIBS];
- GetInputLayout(attributes, shaderInputLayout);
-
- ShaderExecutableD3D *shader = NULL;
- gl::Error error = programD3D->getVertexExecutableForInputLayout(shaderInputLayout, &shader, nullptr);
- if (error.isError())
- {
- return error;
- }
-
- ShaderExecutableD3D *shader11 = ShaderExecutable11::makeShaderExecutable11(shader);
+ ID3D11Buffer *buffer = NULL;
+ UINT vertexStride = 0;
+ UINT vertexOffset = 0;
- D3D11_INPUT_ELEMENT_DESC descs[gl::MAX_VERTEX_ATTRIBS];
- for (unsigned int j = 0; j < ilKey.elementCount; ++j)
- {
- descs[j] = ilKey.elements[j].desc;
- }
+ const auto &attrib = *mSortedAttributes[attribIndex];
- HRESULT result = mDevice->CreateInputLayout(descs, ilKey.elementCount, shader11->getFunction(), shader11->getLength(), &inputLayout);
- if (FAILED(result))
+ if (attribIndex < unsortedAttributes.size() && attrib.active)
{
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal input layout, HRESULT: 0x%08x", result);
- }
-
- if (mInputLayoutMap.size() >= kMaxInputLayouts)
- {
- TRACE("Overflowed the limit of %u input layouts, removing the least recently used "
- "to make room.", kMaxInputLayouts);
-
- InputLayoutMap::iterator leastRecentlyUsed = mInputLayoutMap.begin();
- for (InputLayoutMap::iterator i = mInputLayoutMap.begin(); i != mInputLayoutMap.end(); i++)
+ VertexBuffer11 *vertexBuffer = GetAs<VertexBuffer11>(attrib.vertexBuffer);
+ Buffer11 *bufferStorage = attrib.storage ? GetAs<Buffer11>(attrib.storage) : nullptr;
+
+ // If indexed pointsprite emulation is active, then we need to take a less efficent code path.
+ // Emulated indexed pointsprite rendering requires that the vertex buffers match exactly to
+ // the indices passed by the caller. This could expand or shrink the vertex buffer depending
+ // on the number of points indicated by the index list or how many duplicates are found on the index list.
+ if (bufferStorage == nullptr)
{
- if (i->second.lastUsedTime < leastRecentlyUsed->second.lastUsedTime)
+ buffer = vertexBuffer->getBuffer();
+ }
+ else if (instancedPointSpritesActive && (indexInfo != nullptr))
+ {
+ if (indexInfo->srcIndexData.srcBuffer != nullptr)
{
- leastRecentlyUsed = i;
+ const uint8_t *bufferData = nullptr;
+ error = indexInfo->srcIndexData.srcBuffer->getData(&bufferData);
+ if (error.isError())
+ {
+ return error;
+ }
+ ASSERT(bufferData != nullptr);
+
+ ptrdiff_t offset =
+ reinterpret_cast<ptrdiff_t>(indexInfo->srcIndexData.srcIndices);
+ indexInfo->srcIndexData.srcBuffer = nullptr;
+ indexInfo->srcIndexData.srcIndices = bufferData + offset;
}
- }
- SafeRelease(leastRecentlyUsed->second.inputLayout);
- mInputLayoutMap.erase(leastRecentlyUsed);
- }
-
- InputLayoutCounterPair inputCounterPair;
- inputCounterPair.inputLayout = inputLayout;
- inputCounterPair.lastUsedTime = mCounter++;
-
- mInputLayoutMap.insert(std::make_pair(ilKey, inputCounterPair));
- }
-
- if (inputLayout != mCurrentIL)
- {
- mDeviceContext->IASetInputLayout(inputLayout);
- mCurrentIL = inputLayout;
- }
- bool dirtyBuffers = false;
- size_t minDiff = gl::MAX_VERTEX_ATTRIBS;
- size_t maxDiff = 0;
- unsigned int nextAvailableIndex = 0;
-
- for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
- {
- ID3D11Buffer *buffer = NULL;
-
- if (attributes[i].active)
- {
- VertexBuffer11 *vertexBuffer = VertexBuffer11::makeVertexBuffer11(attributes[i].vertexBuffer);
- Buffer11 *bufferStorage = attributes[i].storage ? Buffer11::makeBuffer11(attributes[i].storage) : NULL;
+ buffer = bufferStorage->getEmulatedIndexedBuffer(&indexInfo->srcIndexData, &attrib);
+ }
+ else
+ {
+ buffer = bufferStorage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
+ }
- buffer = bufferStorage ? bufferStorage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK)
- : vertexBuffer->getBuffer();
+ vertexStride = attrib.stride;
+ vertexOffset = attrib.offset;
}
- UINT vertexStride = attributes[i].stride;
- UINT vertexOffset = attributes[i].offset;
+ size_t bufferIndex = reservedBuffers + attribIndex;
- if (buffer != mCurrentBuffers[i] || vertexStride != mCurrentVertexStrides[i] ||
- vertexOffset != mCurrentVertexOffsets[i])
+ if (buffer != mCurrentBuffers[bufferIndex] ||
+ vertexStride != mCurrentVertexStrides[bufferIndex] ||
+ vertexOffset != mCurrentVertexOffsets[bufferIndex])
{
dirtyBuffers = true;
- minDiff = std::min(minDiff, static_cast<size_t>(i));
- maxDiff = std::max(maxDiff, static_cast<size_t>(i));
-
- mCurrentBuffers[i] = buffer;
- mCurrentVertexStrides[i] = vertexStride;
- mCurrentVertexOffsets[i] = vertexOffset;
+ minDiff = std::min(minDiff, bufferIndex);
+ maxDiff = std::max(maxDiff, bufferIndex);
- // If a non null ID3D11Buffer is being assigned to mCurrentBuffers,
- // then the next available index needs to be tracked to ensure
- // that any instanced pointsprite emulation buffers will be properly packed.
- if (buffer)
- {
- nextAvailableIndex = i + 1;
- }
+ mCurrentBuffers[bufferIndex] = buffer;
+ mCurrentVertexStrides[bufferIndex] = vertexStride;
+ mCurrentVertexOffsets[bufferIndex] = vertexOffset;
}
}
- // Instanced PointSprite emulation requires two additional ID3D11Buffers.
- // A vertex buffer needs to be created and added to the list of current buffers,
- // strides and offsets collections. This buffer contains the vertices for a single
- // PointSprite quad.
- // An index buffer also needs to be created and applied because rendering instanced
- // data on D3D11 FL9_3 requires DrawIndexedInstanced() to be used.
- if (instancedPointSpritesActive)
+ // Instanced PointSprite emulation requires two additional ID3D11Buffers. A vertex buffer needs
+ // to be created and added to the list of current buffers, strides and offsets collections.
+ // This buffer contains the vertices for a single PointSprite quad.
+ // An index buffer also needs to be created and applied because rendering instanced data on
+ // D3D11 FL9_3 requires DrawIndexedInstanced() to be used. Shaders that contain gl_PointSize and
+ // used without the GL_POINTS rendering mode require a vertex buffer because some drivers cannot
+ // handle missing vertex data and will TDR the system.
+ if (programUsesInstancedPointSprites)
{
HRESULT result = S_OK;
const UINT pointSpriteVertexStride = sizeof(float) * 5;
@@ -352,9 +349,16 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl
}
}
- mCurrentBuffers[nextAvailableIndex] = mPointSpriteVertexBuffer;
- mCurrentVertexStrides[nextAvailableIndex] = pointSpriteVertexStride;
- mCurrentVertexOffsets[nextAvailableIndex] = 0;
+ mCurrentBuffers[0] = mPointSpriteVertexBuffer;
+ // Set the stride to 0 if GL_POINTS mode is not being used to instruct the driver to avoid
+ // indexing into the vertex buffer.
+ mCurrentVertexStrides[0] = instancedPointSpritesActive ? pointSpriteVertexStride : 0;
+ mCurrentVertexOffsets[0] = 0;
+
+ // Update maxDiff to include the additional point sprite vertex buffer
+ // to ensure that IASetVertexBuffers uses the correct buffer count.
+ minDiff = 0;
+ maxDiff = std::max(maxDiff, static_cast<size_t>(0));
if (!mPointSpriteIndexBuffer)
{
@@ -381,50 +385,265 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl
}
}
- // The index buffer is applied here because Instanced PointSprite emulation uses
- // the a non-indexed rendering path in ANGLE (DrawArrays). This means that applyIndexBuffer()
- // on the renderer will not be called and setting this buffer here ensures that the rendering
- // path will contain the correct index buffers.
- mDeviceContext->IASetIndexBuffer(mPointSpriteIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
- }
-
- if (moveFirstIndexedIntoSlotZero)
- {
- // In this case, we swapped the slots of the first instanced element and the first indexed element, to ensure
- // that the first slot contains non-instanced data (required by Feature Level 9_3).
- // We must also swap the corresponding buffers sent to IASetVertexBuffers so that the correct data is sent to each slot.
- std::swap(mCurrentBuffers[firstIndexedElement], mCurrentBuffers[firstInstancedElement]);
- std::swap(mCurrentVertexStrides[firstIndexedElement], mCurrentVertexStrides[firstInstancedElement]);
- std::swap(mCurrentVertexOffsets[firstIndexedElement], mCurrentVertexOffsets[firstInstancedElement]);
+ if (instancedPointSpritesActive)
+ {
+ // The index buffer is applied here because Instanced PointSprite emulation uses the a
+ // non-indexed rendering path in ANGLE (DrawArrays). This means that applyIndexBuffer()
+ // on the renderer will not be called and setting this buffer here ensures that the
+ // rendering path will contain the correct index buffers.
+ mDeviceContext->IASetIndexBuffer(mPointSpriteIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
+ }
}
if (dirtyBuffers)
{
ASSERT(minDiff <= maxDiff && maxDiff < gl::MAX_VERTEX_ATTRIBS);
- mDeviceContext->IASetVertexBuffers(minDiff, maxDiff - minDiff + 1, mCurrentBuffers + minDiff,
- mCurrentVertexStrides + minDiff, mCurrentVertexOffsets + minDiff);
+ mDeviceContext->IASetVertexBuffers(
+ static_cast<UINT>(minDiff), static_cast<UINT>(maxDiff - minDiff + 1),
+ mCurrentBuffers + minDiff, mCurrentVertexStrides + minDiff,
+ mCurrentVertexOffsets + minDiff);
}
return gl::Error(GL_NO_ERROR);
}
-std::size_t InputLayoutCache::hashInputLayout(const InputLayoutKey &inputLayout)
+gl::Error InputLayoutCache::updateVertexOffsetsForPointSpritesEmulation(GLsizei emulatedInstanceId)
{
- static const unsigned int seed = 0xDEADBEEF;
+ size_t reservedBuffers = GetReservedBufferCount(true);
+ for (size_t attribIndex = 0; attribIndex < mUnsortedAttributesCount; ++attribIndex)
+ {
+ const auto &attrib = *mSortedAttributes[attribIndex];
+ size_t bufferIndex = reservedBuffers + attribIndex;
+
+ if (attrib.active && attrib.divisor > 0)
+ {
+ mCurrentVertexOffsets[bufferIndex] =
+ attrib.offset + (attrib.stride * (emulatedInstanceId / attrib.divisor));
+ }
+ }
+
+ mDeviceContext->IASetVertexBuffers(0, gl::MAX_VERTEX_ATTRIBS, mCurrentBuffers,
+ mCurrentVertexStrides, mCurrentVertexOffsets);
- std::size_t hash = 0;
- MurmurHash3_x86_32(inputLayout.begin(), inputLayout.end() - inputLayout.begin(), seed, &hash);
- return hash;
+ return gl::Error(GL_NO_ERROR);
}
-bool InputLayoutCache::compareInputLayouts(const InputLayoutKey &a, const InputLayoutKey &b)
+gl::Error InputLayoutCache::updateInputLayout(gl::Program *program,
+ GLenum mode,
+ const SortedAttribArray &sortedAttributes,
+ const SortedIndexArray &sortedSemanticIndices,
+ size_t attribCount,
+ GLsizei numIndicesPerInstance)
{
- if (a.elementCount != b.elementCount)
+ const std::vector<sh::Attribute> &shaderAttributes = program->getAttributes();
+ PackedAttributeLayout layout;
+
+ ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
+ bool programUsesInstancedPointSprites =
+ programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation();
+ bool instancedPointSpritesActive = programUsesInstancedPointSprites && (mode == GL_POINTS);
+
+ if (programUsesInstancedPointSprites)
+ {
+ layout.flags |= PackedAttributeLayout::FLAG_USES_INSTANCED_SPRITES;
+ }
+
+ if (instancedPointSpritesActive)
{
- return false;
+ layout.flags |= PackedAttributeLayout::FLAG_INSTANCED_SPRITES_ACTIVE;
}
- return std::equal(a.begin(), a.end(), b.begin());
+ if (numIndicesPerInstance > 0)
+ {
+ layout.flags |= PackedAttributeLayout::FLAG_INSTANCED_RENDERING_ACTIVE;
+ }
+
+ const auto &semanticToLocation = programD3D->getAttributesByLayout();
+
+ for (size_t attribIndex = 0; attribIndex < attribCount; ++attribIndex)
+ {
+ const auto &attrib = *sortedAttributes[attribIndex];
+ int sortedIndex = sortedSemanticIndices[attribIndex];
+
+ if (!attrib.active)
+ continue;
+
+ gl::VertexFormatType vertexFormatType =
+ gl::GetVertexFormatType(*attrib.attribute, attrib.currentValueType);
+
+ // Record the type of the associated vertex shader vector in our key
+ // This will prevent mismatched vertex shaders from using the same input layout
+ GLenum glslElementType =
+ GetGLSLAttributeType(shaderAttributes, semanticToLocation[sortedIndex]);
+
+ layout.addAttributeData(glslElementType, sortedIndex, vertexFormatType, attrib.divisor);
+ }
+
+ ID3D11InputLayout *inputLayout = nullptr;
+ if (layout.numAttributes > 0 || layout.flags != 0)
+ {
+ auto layoutMapIt = mLayoutMap.find(layout);
+ if (layoutMapIt != mLayoutMap.end())
+ {
+ inputLayout = layoutMapIt->second;
+ }
+ else
+ {
+ gl::Error error =
+ createInputLayout(sortedAttributes, sortedSemanticIndices, attribCount, mode,
+ program, numIndicesPerInstance, &inputLayout);
+ if (error.isError())
+ {
+ return error;
+ }
+ if (mLayoutMap.size() >= mCacheSize)
+ {
+ TRACE("Overflowed the limit of %u input layouts, purging half the cache.",
+ mCacheSize);
+
+ // Randomly release every second element
+ auto it = mLayoutMap.begin();
+ while (it != mLayoutMap.end())
+ {
+ it++;
+ if (it != mLayoutMap.end())
+ {
+ // c++11 erase allows us to easily delete the current iterator.
+ SafeRelease(it->second);
+ it = mLayoutMap.erase(it);
+ }
+ }
+ }
+
+ mLayoutMap[layout] = inputLayout;
+ }
+ }
+
+ if (inputLayout != mCurrentIL)
+ {
+ mDeviceContext->IASetInputLayout(inputLayout);
+ mCurrentIL = inputLayout;
+ }
+
+ return gl::Error(GL_NO_ERROR);
}
+gl::Error InputLayoutCache::createInputLayout(const SortedAttribArray &sortedAttributes,
+ const SortedIndexArray &sortedSemanticIndices,
+ size_t attribCount,
+ GLenum mode,
+ gl::Program *program,
+ GLsizei numIndicesPerInstance,
+ ID3D11InputLayout **inputLayoutOut)
+{
+ ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
+
+ bool programUsesInstancedPointSprites =
+ programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation();
+
+ unsigned int inputElementCount = 0;
+ std::array<D3D11_INPUT_ELEMENT_DESC, gl::MAX_VERTEX_ATTRIBS> inputElements;
+
+ for (size_t attribIndex = 0; attribIndex < attribCount; ++attribIndex)
+ {
+ const auto &attrib = *sortedAttributes[attribIndex];
+ const int sortedIndex = sortedSemanticIndices[attribIndex];
+
+ if (!attrib.active)
+ continue;
+
+ D3D11_INPUT_CLASSIFICATION inputClass =
+ attrib.divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA;
+
+ const auto &vertexFormatType =
+ gl::GetVertexFormatType(*attrib.attribute, attrib.currentValueType);
+ const auto &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormatType, mFeatureLevel);
+
+ auto *inputElement = &inputElements[inputElementCount];
+
+ inputElement->SemanticName = "TEXCOORD";
+ inputElement->SemanticIndex = sortedIndex;
+ inputElement->Format = vertexFormatInfo.nativeFormat;
+ inputElement->InputSlot = static_cast<UINT>(attribIndex);
+ inputElement->AlignedByteOffset = 0;
+ inputElement->InputSlotClass = inputClass;
+ inputElement->InstanceDataStepRate = attrib.divisor;
+
+ inputElementCount++;
+ }
+
+ // Instanced PointSprite emulation requires additional entries in the
+ // inputlayout to support the vertices that make up the pointsprite quad.
+ // We do this even if mode != GL_POINTS, since the shader signature has these inputs, and the
+ // input layout must match the shader
+ if (programUsesInstancedPointSprites)
+ {
+ // On 9_3, we must ensure that slot 0 contains non-instanced data.
+ // If slot 0 currently contains instanced data then we swap it with a non-instanced element.
+ // Note that instancing is only available on 9_3 via ANGLE_instanced_arrays, since 9_3
+ // doesn't support OpenGL ES 3.0.
+ // As per the spec for ANGLE_instanced_arrays, not all attributes can be instanced
+ // simultaneously, so a non-instanced element must exist.
+ for (size_t elementIndex = 0; elementIndex < inputElementCount; ++elementIndex)
+ {
+ if (sortedAttributes[elementIndex]->active)
+ {
+ // If rendering points and instanced pointsprite emulation is being used, the
+ // inputClass is required to be configured as per instance data
+ if (mode == GL_POINTS)
+ {
+ inputElements[elementIndex].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
+ inputElements[elementIndex].InstanceDataStepRate = 1;
+ if (numIndicesPerInstance > 0 && sortedAttributes[elementIndex]->divisor > 0)
+ {
+ inputElements[elementIndex].InstanceDataStepRate = numIndicesPerInstance;
+ }
+ }
+ inputElements[elementIndex].InputSlot++;
+ }
+ }
+
+ inputElements[inputElementCount].SemanticName = "SPRITEPOSITION";
+ inputElements[inputElementCount].SemanticIndex = 0;
+ inputElements[inputElementCount].Format = DXGI_FORMAT_R32G32B32_FLOAT;
+ inputElements[inputElementCount].InputSlot = 0;
+ inputElements[inputElementCount].AlignedByteOffset = 0;
+ inputElements[inputElementCount].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
+ inputElements[inputElementCount].InstanceDataStepRate = 0;
+ inputElementCount++;
+
+ inputElements[inputElementCount].SemanticName = "SPRITETEXCOORD";
+ inputElements[inputElementCount].SemanticIndex = 0;
+ inputElements[inputElementCount].Format = DXGI_FORMAT_R32G32_FLOAT;
+ inputElements[inputElementCount].InputSlot = 0;
+ inputElements[inputElementCount].AlignedByteOffset = sizeof(float) * 3;
+ inputElements[inputElementCount].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
+ inputElements[inputElementCount].InstanceDataStepRate = 0;
+ inputElementCount++;
+ }
+
+ const gl::InputLayout &shaderInputLayout = GetInputLayout(sortedAttributes, attribCount);
+
+ ShaderExecutableD3D *shader = nullptr;
+ gl::Error error =
+ programD3D->getVertexExecutableForInputLayout(shaderInputLayout, &shader, nullptr);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ShaderExecutableD3D *shader11 = GetAs<ShaderExecutable11>(shader);
+
+ HRESULT result =
+ mDevice->CreateInputLayout(inputElements.data(), inputElementCount, shader11->getFunction(),
+ shader11->getLength(), inputLayoutOut);
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY,
+ "Failed to create internal input layout, HRESULT: 0x%08x", result);
+ }
+
+ return gl::Error(GL_NO_ERROR);
}
+
+} // namespace rx
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h
index 2c94c57595..e208ae3c64 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h
@@ -10,14 +10,17 @@
#ifndef LIBANGLE_RENDERER_D3D_D3D11_INPUTLAYOUTCACHE_H_
#define LIBANGLE_RENDERER_D3D_D3D11_INPUTLAYOUTCACHE_H_
-#include "libANGLE/Constants.h"
-#include "libANGLE/Error.h"
-#include "common/angleutils.h"
-
#include <GLES2/gl2.h>
#include <cstddef>
-#include <unordered_map>
+
+#include <array>
+#include <map>
+
+#include "common/angleutils.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/formatutils.h"
namespace gl
{
@@ -27,6 +30,12 @@ class Program;
namespace rx
{
struct TranslatedAttribute;
+struct TranslatedIndexData;
+struct SourceIndexData;
+class ProgramD3D;
+
+using SortedAttribArray = std::array<const TranslatedAttribute *, gl::MAX_VERTEX_ATTRIBS>;
+using SortedIndexArray = std::array<int, gl::MAX_VERTEX_ATTRIBS>;
class InputLayoutCache : angle::NonCopyable
{
@@ -38,59 +47,72 @@ class InputLayoutCache : angle::NonCopyable
void clear();
void markDirty();
- gl::Error applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
- GLenum mode, gl::Program *program);
+ gl::Error applyVertexBuffers(const std::vector<TranslatedAttribute> &attributes,
+ GLenum mode,
+ gl::Program *program,
+ TranslatedIndexData *indexInfo,
+ GLsizei numIndicesPerInstance);
- private:
- struct InputLayoutElement
- {
- D3D11_INPUT_ELEMENT_DESC desc;
- GLenum glslElementType;
- };
+ gl::Error updateVertexOffsetsForPointSpritesEmulation(GLsizei emulatedInstanceId);
- struct InputLayoutKey
- {
- unsigned int elementCount;
- InputLayoutElement elements[gl::MAX_VERTEX_ATTRIBS];
+ // Useful for testing
+ void setCacheSize(unsigned int cacheSize) { mCacheSize = cacheSize; }
- const char *begin() const
+ private:
+ struct PackedAttributeLayout
+ {
+ PackedAttributeLayout()
+ : numAttributes(0),
+ flags(0)
{
- return reinterpret_cast<const char*>(&elementCount);
}
- const char *end() const
+ void addAttributeData(GLenum glType,
+ UINT semanticIndex,
+ gl::VertexFormatType vertexFormatType,
+ unsigned int divisor);
+
+ bool operator<(const PackedAttributeLayout &other) const;
+
+ enum Flags
{
- return reinterpret_cast<const char*>(&elements[elementCount]);
- }
+ FLAG_USES_INSTANCED_SPRITES = 0x1,
+ FLAG_INSTANCED_SPRITES_ACTIVE = 0x2,
+ FLAG_INSTANCED_RENDERING_ACTIVE = 0x4,
+ };
+
+ size_t numAttributes;
+ unsigned int flags;
+ uint32_t attributeData[gl::MAX_VERTEX_ATTRIBS];
};
- struct InputLayoutCounterPair
- {
- ID3D11InputLayout *inputLayout;
- unsigned long long lastUsedTime;
- };
+ gl::Error updateInputLayout(gl::Program *program,
+ GLenum mode,
+ const SortedAttribArray &sortedAttributes,
+ const SortedIndexArray &sortedSemanticIndices,
+ size_t attribCount,
+ GLsizei numIndicesPerInstance);
+ gl::Error createInputLayout(const SortedAttribArray &sortedAttributes,
+ const SortedIndexArray &sortedSemanticIndices,
+ size_t attribCount,
+ GLenum mode,
+ gl::Program *program,
+ GLsizei numIndicesPerInstance,
+ ID3D11InputLayout **inputLayoutOut);
+
+ std::map<PackedAttributeLayout, ID3D11InputLayout *> mLayoutMap;
ID3D11InputLayout *mCurrentIL;
ID3D11Buffer *mCurrentBuffers[gl::MAX_VERTEX_ATTRIBS];
UINT mCurrentVertexStrides[gl::MAX_VERTEX_ATTRIBS];
UINT mCurrentVertexOffsets[gl::MAX_VERTEX_ATTRIBS];
+ SortedAttribArray mSortedAttributes;
+ size_t mUnsortedAttributesCount;
ID3D11Buffer *mPointSpriteVertexBuffer;
ID3D11Buffer *mPointSpriteIndexBuffer;
- static std::size_t hashInputLayout(const InputLayoutKey &inputLayout);
- static bool compareInputLayouts(const InputLayoutKey &a, const InputLayoutKey &b);
-
- typedef std::size_t (*InputLayoutHashFunction)(const InputLayoutKey &);
- typedef bool (*InputLayoutEqualityFunction)(const InputLayoutKey &, const InputLayoutKey &);
- typedef std::unordered_map<InputLayoutKey,
- InputLayoutCounterPair,
- InputLayoutHashFunction,
- InputLayoutEqualityFunction> InputLayoutMap;
- InputLayoutMap mInputLayoutMap;
-
- static const unsigned int kMaxInputLayouts;
-
+ unsigned int mCacheSize;
unsigned long long mCounter;
ID3D11Device *mDevice;
@@ -98,6 +120,6 @@ class InputLayoutCache : angle::NonCopyable
D3D_FEATURE_LEVEL mFeatureLevel;
};
-}
+} // namespace rx
#endif // LIBANGLE_RENDERER_D3D_D3D11_INPUTLAYOUTCACHE_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h
index 0f70fe4615..612b06bb10 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h
@@ -16,6 +16,7 @@
#include "common/platform.h"
#include <EGL/eglplatform.h>
+#include "libANGLE/Config.h"
// DXGISwapChain and DXGIFactory are typedef'd to specific required
// types. The HWND NativeWindow implementation requires IDXGISwapChain
@@ -43,6 +44,10 @@ typedef IDXGISwapChain DXGISwapChain;
typedef IDXGIFactory DXGIFactory;
#endif
+typedef interface IDCompositionDevice IDCompositionDevice;
+typedef interface IDCompositionTarget IDCompositionTarget;
+typedef interface IDCompositionVisual IDCompositionVisual;
+
namespace rx
{
@@ -50,8 +55,11 @@ class NativeWindow
{
public:
enum RotationFlags { RotateNone = 0, RotateLeft = 1, RotateRight = 2 };
- explicit NativeWindow(EGLNativeWindowType window);
+ explicit NativeWindow(EGLNativeWindowType window,
+ const egl::Config *config,
+ bool directComposition);
+ ~NativeWindow();
bool initialize();
bool getClientRect(LPRECT rect);
bool isIconic();
@@ -68,9 +76,16 @@ class NativeWindow
inline EGLNativeWindowType getNativeWindow() const { return mWindow; }
+ void commitChange();
+
private:
EGLNativeWindowType mWindow;
+ bool mDirectComposition;
+ IDCompositionDevice *mDevice;
+ IDCompositionTarget *mCompositionTarget;
+ IDCompositionVisual *mVisual;
+ const egl::Config *mConfig;
#if defined(ANGLE_ENABLE_WINDOWS_STORE)
std::shared_ptr<InspectableNativeWindow> mImpl;
#endif
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp
index 5fd5237d90..dfc521f14f 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp
@@ -10,23 +10,25 @@
//
#include "libANGLE/renderer/d3d/d3d11/PixelTransfer11.h"
+
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
-#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
-#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
-#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
-#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
+#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
#include "libANGLE/Texture.h"
-#include "libANGLE/Buffer.h"
-#include "libANGLE/Context.h"
// Precompiled shaders
-#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h"
namespace rx
{
@@ -202,14 +204,14 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac
GLenum unsizedFormat = gl::GetInternalFormatInfo(destinationFormat).format;
GLenum sourceFormat = gl::GetSizedInternalFormat(unsizedFormat, sourcePixelsType);
- const d3d11::TextureFormat &sourceFormatInfo = d3d11::GetTextureFormatInfo(sourceFormat, mRenderer->getFeatureLevel());
+ const d3d11::TextureFormat &sourceFormatInfo = d3d11::GetTextureFormatInfo(sourceFormat, mRenderer->getRenderer11DeviceCaps());
DXGI_FORMAT srvFormat = sourceFormatInfo.srvFormat;
ASSERT(srvFormat != DXGI_FORMAT_UNKNOWN);
- Buffer11 *bufferStorage11 = Buffer11::makeBuffer11(sourceBuffer.getImplementation());
+ Buffer11 *bufferStorage11 = GetAs<Buffer11>(sourceBuffer.getImplementation());
ID3D11ShaderResourceView *bufferSRV = bufferStorage11->getSRV(srvFormat);
ASSERT(bufferSRV != NULL);
- ID3D11RenderTargetView *textureRTV = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView();
+ ID3D11RenderTargetView *textureRTV = GetAs<RenderTarget11>(destRenderTarget)->getRenderTargetView();
ASSERT(textureRTV != NULL);
CopyShaderParams shaderParams;
@@ -222,11 +224,12 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac
// Are we doing a 2D or 3D copy?
ID3D11GeometryShader *geometryShader = ((destSize.depth > 1) ? mBufferToTextureGS : NULL);
+ auto stateManager = mRenderer->getStateManager();
deviceContext->VSSetShader(mBufferToTextureVS, NULL, 0);
deviceContext->GSSetShader(geometryShader, NULL, 0);
deviceContext->PSSetShader(pixelShader, NULL, 0);
- mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, bufferSRV);
+ stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, bufferSRV);
deviceContext->IASetInputLayout(NULL);
deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
@@ -249,8 +252,8 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac
D3D11_VIEWPORT viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
- viewport.Width = destSize.width;
- viewport.Height = destSize.height;
+ viewport.Width = static_cast<FLOAT>(destSize.width);
+ viewport.Height = static_cast<FLOAT>(destSize.height);
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
deviceContext->RSSetViewports(1, &viewport);
@@ -259,7 +262,7 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac
deviceContext->Draw(numPixels, 0);
// Unbind textures and render targets and vertex buffer
- mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
+ stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
deviceContext->VSSetConstantBuffers(0, 1, &nullBuffer);
mRenderer->markAllStateDirty();
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp
index 4979ff51a9..c0bed2b43a 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp
@@ -18,6 +18,11 @@ typedef struct D3D11_QUERY_DATA_SO_STATISTICS {
UINT64 NumPrimitivesWritten;
UINT64 PrimitivesStorageNeeded;
} D3D11_QUERY_DATA_SO_STATISTICS;
+
+typedef struct D3D11_QUERY_DATA_TIMESTAMP_DISJOINT {
+ UINT64 Frequency;
+ BOOL Disjoint;
+} D3D11_QUERY_DATA_TIMESTAMP_DISJOINT;
#endif
namespace rx
@@ -28,38 +33,81 @@ Query11::Query11(Renderer11 *renderer, GLenum type)
mResult(0),
mQueryFinished(false),
mRenderer(renderer),
- mQuery(NULL)
+ mQuery(nullptr),
+ mTimestampBeginQuery(nullptr),
+ mTimestampEndQuery(nullptr)
{
}
Query11::~Query11()
{
SafeRelease(mQuery);
+ SafeRelease(mTimestampBeginQuery);
+ SafeRelease(mTimestampEndQuery);
}
gl::Error Query11::begin()
{
- if (mQuery == NULL)
+ if (mQuery == nullptr)
{
D3D11_QUERY_DESC queryDesc;
queryDesc.Query = gl_d3d11::ConvertQueryType(getType());
queryDesc.MiscFlags = 0;
- HRESULT result = mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery);
+ ID3D11Device *device = mRenderer->getDevice();
+
+ HRESULT result = device->CreateQuery(&queryDesc, &mQuery);
if (FAILED(result))
{
return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.", result);
}
+
+ // If we are doing time elapsed we also need a query to actually query the timestamp
+ if (getType() == GL_TIME_ELAPSED_EXT)
+ {
+ D3D11_QUERY_DESC desc;
+ desc.Query = D3D11_QUERY_TIMESTAMP;
+ desc.MiscFlags = 0;
+ result = device->CreateQuery(&desc, &mTimestampBeginQuery);
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.",
+ result);
+ }
+ result = device->CreateQuery(&desc, &mTimestampEndQuery);
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.",
+ result);
+ }
+ }
}
- mRenderer->getDeviceContext()->Begin(mQuery);
+ ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+
+ context->Begin(mQuery);
+
+ // If we are doing time elapsed query the begin timestamp
+ if (getType() == GL_TIME_ELAPSED_EXT)
+ {
+ context->End(mTimestampBeginQuery);
+ }
return gl::Error(GL_NO_ERROR);
}
gl::Error Query11::end()
{
ASSERT(mQuery);
- mRenderer->getDeviceContext()->End(mQuery);
+
+ ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+
+ // If we are doing time elapsed query the end timestamp
+ if (getType() == GL_TIME_ELAPSED_EXT)
+ {
+ context->End(mTimestampEndQuery);
+ }
+
+ context->End(mQuery);
mQueryFinished = false;
mResult = GL_FALSE;
@@ -67,7 +115,17 @@ gl::Error Query11::end()
return gl::Error(GL_NO_ERROR);
}
-gl::Error Query11::getResult(GLuint *params)
+gl::Error Query11::queryCounter()
+{
+ // This doesn't do anything for D3D11 as we don't support timestamps
+ ASSERT(getType() == GL_TIMESTAMP_EXT);
+ mQueryFinished = true;
+ mResult = 0;
+ return gl::Error(GL_NO_ERROR);
+}
+
+template <typename T>
+gl::Error Query11::getResultBase(T *params)
{
while (!mQueryFinished)
{
@@ -84,12 +142,32 @@ gl::Error Query11::getResult(GLuint *params)
}
ASSERT(mQueryFinished);
- *params = mResult;
+ *params = static_cast<T>(mResult);
return gl::Error(GL_NO_ERROR);
}
-gl::Error Query11::isResultAvailable(GLuint *available)
+gl::Error Query11::getResult(GLint *params)
+{
+ return getResultBase(params);
+}
+
+gl::Error Query11::getResult(GLuint *params)
+{
+ return getResultBase(params);
+}
+
+gl::Error Query11::getResult(GLint64 *params)
+{
+ return getResultBase(params);
+}
+
+gl::Error Query11::getResult(GLuint64 *params)
+{
+ return getResultBase(params);
+}
+
+gl::Error Query11::isResultAvailable(bool *available)
{
gl::Error error = testQuery();
if (error.isError())
@@ -97,7 +175,7 @@ gl::Error Query11::isResultAvailable(GLuint *available)
return error;
}
- *available = (mQueryFinished ? GL_TRUE : GL_FALSE);
+ *available = mQueryFinished;
return gl::Error(GL_NO_ERROR);
}
@@ -141,8 +219,74 @@ gl::Error Query11::testQuery()
if (result == S_OK)
{
mQueryFinished = true;
- mResult = static_cast<GLuint>(soStats.NumPrimitivesWritten);
+ mResult = static_cast<GLuint64>(soStats.NumPrimitivesWritten);
+ }
+ }
+ break;
+
+ case GL_TIME_ELAPSED_EXT:
+ {
+ D3D11_QUERY_DATA_TIMESTAMP_DISJOINT timeStats = {0};
+ HRESULT result = context->GetData(mQuery, &timeStats, sizeof(timeStats), 0);
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY,
+ "Failed to get the data of an internal query, result: 0x%X.",
+ result);
}
+
+ if (result == S_OK)
+ {
+ UINT64 beginTime = 0;
+ HRESULT beginRes =
+ context->GetData(mTimestampBeginQuery, &beginTime, sizeof(UINT64), 0);
+ if (FAILED(beginRes))
+ {
+ return gl::Error(
+ GL_OUT_OF_MEMORY,
+ "Failed to get the data of an internal query, result: 0x%X.", beginRes);
+ }
+ UINT64 endTime = 0;
+ HRESULT endRes =
+ context->GetData(mTimestampEndQuery, &endTime, sizeof(UINT64), 0);
+ if (FAILED(endRes))
+ {
+ return gl::Error(
+ GL_OUT_OF_MEMORY,
+ "Failed to get the data of an internal query, result: 0x%X.", endRes);
+ }
+
+ if (beginRes == S_OK && endRes == S_OK)
+ {
+ mQueryFinished = true;
+ if (timeStats.Disjoint)
+ {
+ mRenderer->setGPUDisjoint();
+ }
+ static_assert(sizeof(UINT64) == sizeof(unsigned long long),
+ "D3D UINT64 isn't 64 bits");
+ if (rx::IsUnsignedMultiplicationSafe(endTime - beginTime, 1000000000ull))
+ {
+ mResult = ((endTime - beginTime) * 1000000000ull) / timeStats.Frequency;
+ }
+ else
+ {
+ mResult = std::numeric_limits<GLuint64>::max() / timeStats.Frequency;
+ // If an overflow does somehow occur, there is no way the elapsed time
+ // is accurate, so we generate a disjoint event
+ mRenderer->setGPUDisjoint();
+ }
+ }
+ }
+ }
+ break;
+
+ case GL_TIMESTAMP_EXT:
+ {
+ // D3D11 doesn't support GL timestamp queries as D3D timestamps are not guaranteed
+ // to have any sort of continuity outside of a disjoint timestamp query block, which
+ // GL depends on
+ mResult = 0;
}
break;
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.h
index bd53fed250..29a6e6f85d 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.h
@@ -23,18 +23,27 @@ class Query11 : public QueryImpl
virtual gl::Error begin();
virtual gl::Error end();
+ virtual gl::Error queryCounter();
+ virtual gl::Error getResult(GLint *params);
virtual gl::Error getResult(GLuint *params);
- virtual gl::Error isResultAvailable(GLuint *available);
+ virtual gl::Error getResult(GLint64 *params);
+ virtual gl::Error getResult(GLuint64 *params);
+ virtual gl::Error isResultAvailable(bool *available);
private:
gl::Error testQuery();
- GLuint mResult;
+ template <typename T>
+ gl::Error getResultBase(T *params);
+
+ GLuint64 mResult;
bool mQueryFinished;
Renderer11 *mRenderer;
ID3D11Query *mQuery;
+ ID3D11Query *mTimestampBeginQuery;
+ ID3D11Query *mTimestampEndQuery;
};
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp
index 4990e6bc6e..2ee25cfb6c 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp
@@ -21,6 +21,7 @@
namespace rx
{
+using namespace gl_d3d11;
template <typename mapType>
static void ClearStateMap(mapType &map)
@@ -42,12 +43,12 @@ const unsigned int RenderStateCache::kMaxSamplerStates = 4096;
RenderStateCache::RenderStateCache(Renderer11 *renderer)
: mRenderer(renderer),
- mDevice(NULL),
mCounter(0),
mBlendStateCache(kMaxBlendStates, hashBlendState, compareBlendStates),
mRasterizerStateCache(kMaxRasterizerStates, hashRasterizerState, compareRasterizerStates),
mDepthStencilStateCache(kMaxDepthStencilStates, hashDepthStencilState, compareDepthStencilStates),
- mSamplerStateCache(kMaxSamplerStates, hashSamplerState, compareSamplerStates)
+ mSamplerStateCache(kMaxSamplerStates, hashSamplerState, compareSamplerStates),
+ mDevice(NULL)
{
}
@@ -95,9 +96,9 @@ gl::Error RenderStateCache::getBlendState(const gl::Framebuffer *framebuffer, co
bool mrt = false;
const FramebufferD3D *framebufferD3D = GetImplAs<FramebufferD3D>(framebuffer);
- const gl::AttachmentList &colorbuffers = framebufferD3D->getColorAttachmentsForRender(mRenderer->getWorkarounds());
+ const gl::AttachmentList &colorbuffers = framebufferD3D->getColorAttachmentsForRender();
- BlendStateKey key = { 0 };
+ BlendStateKey key = {};
key.blendState = blendState;
for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
{
@@ -209,7 +210,7 @@ gl::Error RenderStateCache::getRasterizerState(const gl::RasterizerState &raster
return gl::Error(GL_OUT_OF_MEMORY, "Internal error, RenderStateCache is not initialized.");
}
- RasterizerStateKey key = { 0 };
+ RasterizerStateKey key = {};
key.rasterizerState = rasterState;
key.scissorEnabled = scissorEnabled;
@@ -297,14 +298,31 @@ bool RenderStateCache::compareDepthStencilStates(const gl::DepthStencilState &a,
return memcmp(&a, &b, sizeof(gl::DepthStencilState)) == 0;
}
-gl::Error RenderStateCache::getDepthStencilState(const gl::DepthStencilState &dsState, ID3D11DepthStencilState **outDSState)
+gl::Error RenderStateCache::getDepthStencilState(const gl::DepthStencilState &originalState,
+ bool disableDepth,
+ bool disableStencil,
+ ID3D11DepthStencilState **outDSState)
{
if (!mDevice)
{
return gl::Error(GL_OUT_OF_MEMORY, "Internal error, RenderStateCache is not initialized.");
}
- DepthStencilStateMap::iterator keyIter = mDepthStencilStateCache.find(dsState);
+ gl::DepthStencilState glState = originalState;
+ if (disableDepth)
+ {
+ glState.depthTest = false;
+ glState.depthMask = false;
+ }
+
+ if (disableStencil)
+ {
+ glState.stencilWritemask = 0;
+ glState.stencilBackWritemask = 0;
+ glState.stencilTest = false;
+ }
+
+ auto keyIter = mDepthStencilStateCache.find(glState);
if (keyIter != mDepthStencilStateCache.end())
{
DepthStencilStateCounterPair &state = keyIter->second;
@@ -312,53 +330,55 @@ gl::Error RenderStateCache::getDepthStencilState(const gl::DepthStencilState &ds
*outDSState = state.first;
return gl::Error(GL_NO_ERROR);
}
- else
+
+ if (mDepthStencilStateCache.size() >= kMaxDepthStencilStates)
{
- if (mDepthStencilStateCache.size() >= kMaxDepthStencilStates)
- {
- TRACE("Overflowed the limit of %u depth stencil states, removing the least recently used "
- "to make room.", kMaxDepthStencilStates);
+ TRACE(
+ "Overflowed the limit of %u depth stencil states, removing the least recently used "
+ "to make room.",
+ kMaxDepthStencilStates);
- DepthStencilStateMap::iterator leastRecentlyUsed = mDepthStencilStateCache.begin();
- for (DepthStencilStateMap::iterator i = mDepthStencilStateCache.begin(); i != mDepthStencilStateCache.end(); i++)
+ auto leastRecentlyUsed = mDepthStencilStateCache.begin();
+ for (auto i = mDepthStencilStateCache.begin(); i != mDepthStencilStateCache.end(); i++)
+ {
+ if (i->second.second < leastRecentlyUsed->second.second)
{
- if (i->second.second < leastRecentlyUsed->second.second)
- {
- leastRecentlyUsed = i;
- }
+ leastRecentlyUsed = i;
}
- SafeRelease(leastRecentlyUsed->second.first);
- mDepthStencilStateCache.erase(leastRecentlyUsed);
}
+ SafeRelease(leastRecentlyUsed->second.first);
+ mDepthStencilStateCache.erase(leastRecentlyUsed);
+ }
- D3D11_DEPTH_STENCIL_DESC dsDesc = { 0 };
- dsDesc.DepthEnable = dsState.depthTest ? TRUE : FALSE;
- dsDesc.DepthWriteMask = gl_d3d11::ConvertDepthMask(dsState.depthMask);
- dsDesc.DepthFunc = gl_d3d11::ConvertComparison(dsState.depthFunc);
- dsDesc.StencilEnable = dsState.stencilTest ? TRUE : FALSE;
- dsDesc.StencilReadMask = gl_d3d11::ConvertStencilMask(dsState.stencilMask);
- dsDesc.StencilWriteMask = gl_d3d11::ConvertStencilMask(dsState.stencilWritemask);
- dsDesc.FrontFace.StencilFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilFail);
- dsDesc.FrontFace.StencilDepthFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilPassDepthFail);
- dsDesc.FrontFace.StencilPassOp = gl_d3d11::ConvertStencilOp(dsState.stencilPassDepthPass);
- dsDesc.FrontFace.StencilFunc = gl_d3d11::ConvertComparison(dsState.stencilFunc);
- dsDesc.BackFace.StencilFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackFail);
- dsDesc.BackFace.StencilDepthFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackPassDepthFail);
- dsDesc.BackFace.StencilPassOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackPassDepthPass);
- dsDesc.BackFace.StencilFunc = gl_d3d11::ConvertComparison(dsState.stencilBackFunc);
-
- ID3D11DepthStencilState *dx11DepthStencilState = NULL;
- HRESULT result = mDevice->CreateDepthStencilState(&dsDesc, &dx11DepthStencilState);
- if (FAILED(result) || !dx11DepthStencilState)
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result);
- }
+ D3D11_DEPTH_STENCIL_DESC dsDesc = {0};
+ dsDesc.DepthEnable = glState.depthTest ? TRUE : FALSE;
+ dsDesc.DepthWriteMask = ConvertDepthMask(glState.depthMask);
+ dsDesc.DepthFunc = ConvertComparison(glState.depthFunc);
+ dsDesc.StencilEnable = glState.stencilTest ? TRUE : FALSE;
+ dsDesc.StencilReadMask = ConvertStencilMask(glState.stencilMask);
+ dsDesc.StencilWriteMask = ConvertStencilMask(glState.stencilWritemask);
+ dsDesc.FrontFace.StencilFailOp = ConvertStencilOp(glState.stencilFail);
+ dsDesc.FrontFace.StencilDepthFailOp = ConvertStencilOp(glState.stencilPassDepthFail);
+ dsDesc.FrontFace.StencilPassOp = ConvertStencilOp(glState.stencilPassDepthPass);
+ dsDesc.FrontFace.StencilFunc = ConvertComparison(glState.stencilFunc);
+ dsDesc.BackFace.StencilFailOp = ConvertStencilOp(glState.stencilBackFail);
+ dsDesc.BackFace.StencilDepthFailOp = ConvertStencilOp(glState.stencilBackPassDepthFail);
+ dsDesc.BackFace.StencilPassOp = ConvertStencilOp(glState.stencilBackPassDepthPass);
+ dsDesc.BackFace.StencilFunc = ConvertComparison(glState.stencilBackFunc);
+
+ ID3D11DepthStencilState *dx11DepthStencilState = NULL;
+ HRESULT result = mDevice->CreateDepthStencilState(&dsDesc, &dx11DepthStencilState);
+ if (FAILED(result) || !dx11DepthStencilState)
+ {
+ return gl::Error(GL_OUT_OF_MEMORY,
+ "Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result);
+ }
- mDepthStencilStateCache.insert(std::make_pair(dsState, std::make_pair(dx11DepthStencilState, mCounter++)));
+ mDepthStencilStateCache.insert(
+ std::make_pair(glState, std::make_pair(dx11DepthStencilState, mCounter++)));
- *outDSState = dx11DepthStencilState;
- return gl::Error(GL_NO_ERROR);
- }
+ *outDSState = dx11DepthStencilState;
+ return gl::Error(GL_NO_ERROR);
}
std::size_t RenderStateCache::hashSamplerState(const gl::SamplerState &samplerState)
@@ -416,7 +436,7 @@ gl::Error RenderStateCache::getSamplerState(const gl::SamplerState &samplerState
samplerDesc.AddressV = gl_d3d11::ConvertTextureWrap(samplerState.wrapT);
samplerDesc.AddressW = gl_d3d11::ConvertTextureWrap(samplerState.wrapR);
samplerDesc.MipLODBias = 0;
- samplerDesc.MaxAnisotropy = samplerState.maxAnisotropy;
+ samplerDesc.MaxAnisotropy = static_cast<UINT>(samplerState.maxAnisotropy);
samplerDesc.ComparisonFunc = gl_d3d11::ConvertComparison(samplerState.compareFunc);
samplerDesc.BorderColor[0] = 0.0f;
samplerDesc.BorderColor[1] = 0.0f;
@@ -425,7 +445,7 @@ gl::Error RenderStateCache::getSamplerState(const gl::SamplerState &samplerState
samplerDesc.MinLOD = samplerState.minLod;
samplerDesc.MaxLOD = samplerState.maxLod;
- if (mRenderer->getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3)
+ if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
{
// Check that maxLOD is nearly FLT_MAX (1000.0f is the default), since 9_3 doesn't support anything other than FLT_MAX.
// Note that Feature Level 9_* only supports GL ES 2.0, so the consumer of ANGLE can't modify the Max LOD themselves.
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h
index 0099b94a04..82cb13903c 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h
@@ -36,7 +36,10 @@ class RenderStateCache : angle::NonCopyable
gl::Error getBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, ID3D11BlendState **outBlendState);
gl::Error getRasterizerState(const gl::RasterizerState &rasterState, bool scissorEnabled, ID3D11RasterizerState **outRasterizerState);
- gl::Error getDepthStencilState(const gl::DepthStencilState &dsState, ID3D11DepthStencilState **outDSState);
+ gl::Error getDepthStencilState(const gl::DepthStencilState &dsState,
+ bool disableDepth,
+ bool disableStencil,
+ ID3D11DepthStencilState **outDSState);
gl::Error getSamplerState(const gl::SamplerState &samplerState, ID3D11SamplerState **outSamplerState);
private:
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp
index ecd9e13c90..cdfcacc287 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp
@@ -8,10 +8,12 @@
// retained by Renderbuffers.
#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "libANGLE/renderer/d3d/d3d11/SwapChain11.h"
-#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
namespace rx
{
@@ -176,12 +178,6 @@ static unsigned int getDSVSubresourceIndex(ID3D11Resource *resource, ID3D11Depth
return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
}
-RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTargetD3D *target)
-{
- ASSERT(HAS_DYNAMIC_TYPE(RenderTarget11*, target));
- return static_cast<RenderTarget11*>(target);
-}
-
TextureRenderTarget11::TextureRenderTarget11(ID3D11RenderTargetView *rtv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv,
GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples)
: mWidth(width),
@@ -352,7 +348,7 @@ GLsizei SurfaceRenderTarget11::getDepth() const
GLenum SurfaceRenderTarget11::getInternalFormat() const
{
- return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetBackBufferInternalFormat());
+ return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetRenderTargetInternalFormat());
}
GLsizei SurfaceRenderTarget11::getSamples() const
@@ -388,7 +384,7 @@ unsigned int SurfaceRenderTarget11::getSubresourceIndex() const
DXGI_FORMAT SurfaceRenderTarget11::getDXGIFormat() const
{
- return d3d11::GetTextureFormatInfo(getInternalFormat(), mRenderer->getFeatureLevel()).texFormat;
+ return d3d11::GetTextureFormatInfo(getInternalFormat(), mRenderer->getRenderer11DeviceCaps()).texFormat;
}
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h
index 4472a56175..d47b237c09 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h
@@ -23,8 +23,6 @@ class RenderTarget11 : public RenderTargetD3D
RenderTarget11() { }
virtual ~RenderTarget11() { }
- static RenderTarget11 *makeRenderTarget11(RenderTargetD3D *renderTarget);
-
virtual ID3D11Resource *getTexture() const = 0;
virtual ID3D11RenderTargetView *getRenderTargetView() const = 0;
virtual ID3D11DepthStencilView *getDepthStencilView() const = 0;
@@ -33,9 +31,6 @@ class RenderTarget11 : public RenderTargetD3D
virtual unsigned int getSubresourceIndex() const = 0;
virtual DXGI_FORMAT getDXGIFormat() const = 0;
-
- private:
- D3D_FEATURE_LEVEL mFeatureLevel;
};
class TextureRenderTarget11 : public RenderTarget11
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
index 223e2b019b..62badccefc 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
@@ -8,47 +8,63 @@
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
-#include "common/utilities.h"
+#include <EGL/eglext.h>
+#include <sstream>
+#if !defined(ANGLE_MINGW32_COMPAT) && WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
+#include <VersionHelpers.h>
+#endif
+
#include "common/tls.h"
+#include "common/utilities.h"
#include "libANGLE/Buffer.h"
#include "libANGLE/Display.h"
+#include "libANGLE/formatutils.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/histogram_macros.h"
#include "libANGLE/Program.h"
-#include "libANGLE/State.h"
-#include "libANGLE/Surface.h"
-#include "libANGLE/formatutils.h"
#include "libANGLE/renderer/d3d/CompilerD3D.h"
-#include "libANGLE/renderer/d3d/FramebufferD3D.h"
-#include "libANGLE/renderer/d3d/IndexDataManager.h"
-#include "libANGLE/renderer/d3d/ProgramD3D.h"
-#include "libANGLE/renderer/d3d/RenderbufferD3D.h"
-#include "libANGLE/renderer/d3d/ShaderD3D.h"
-#include "libANGLE/renderer/d3d/SurfaceD3D.h"
-#include "libANGLE/renderer/d3d/TextureD3D.h"
-#include "libANGLE/renderer/d3d/TransformFeedbackD3D.h"
-#include "libANGLE/renderer/d3d/VertexDataManager.h"
#include "libANGLE/renderer/d3d/d3d11/Blit11.h"
#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
#include "libANGLE/renderer/d3d/d3d11/Clear11.h"
+#include "libANGLE/renderer/d3d/d3d11/dxgi_support_table.h"
#include "libANGLE/renderer/d3d/d3d11/Fence11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h"
#include "libANGLE/renderer/d3d/d3d11/Image11.h"
#include "libANGLE/renderer/d3d/d3d11/IndexBuffer11.h"
#include "libANGLE/renderer/d3d/d3d11/PixelTransfer11.h"
#include "libANGLE/renderer/d3d/d3d11/Query11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
#include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h"
#include "libANGLE/renderer/d3d/d3d11/SwapChain11.h"
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
#include "libANGLE/renderer/d3d/d3d11/Trim11.h"
#include "libANGLE/renderer/d3d/d3d11/VertexArray11.h"
#include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h"
-#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
-#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/CompilerD3D.h"
+#include "libANGLE/renderer/d3d/DeviceD3D.h"
+#include "libANGLE/renderer/d3d/FramebufferD3D.h"
+#include "libANGLE/renderer/d3d/IndexDataManager.h"
+#include "libANGLE/renderer/d3d/ProgramD3D.h"
+#include "libANGLE/renderer/d3d/RenderbufferD3D.h"
+#include "libANGLE/renderer/d3d/ShaderD3D.h"
+#include "libANGLE/renderer/d3d/SurfaceD3D.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
+#include "libANGLE/renderer/d3d/TransformFeedbackD3D.h"
+#include "libANGLE/renderer/d3d/VertexDataManager.h"
+#include "libANGLE/State.h"
+#include "libANGLE/Surface.h"
+#include "third_party/trace_event/trace_event.h"
-#include <sstream>
-#include <EGL/eglext.h>
+// Include the D3D9 debug annotator header for use by the desktop D3D11 renderer
+// because the D3D11 interface method ID3DUserDefinedAnnotation::GetStatus
+// doesn't work with the Graphics Diagnostics tools in Visual Studio 2013.
+#ifdef ANGLE_ENABLE_D3D9
+#include "libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h"
+#endif
// Enable ANGLE_SKIP_DXGI_1_2_CHECK if there is not a possibility of using cross-process
// HWNDs or the Windows 7 Platform Update (KB2670838) is expected to be installed.
@@ -62,67 +78,6 @@
#define ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS 1
#endif
-#ifndef __d3d11sdklayers_h__
-#define D3D11_MESSAGE_CATEGORY UINT
-#define D3D11_MESSAGE_SEVERITY UINT
-#define D3D11_MESSAGE_ID UINT
-struct D3D11_MESSAGE;
-typedef struct D3D11_INFO_QUEUE_FILTER_DESC
-{
- UINT NumCategories;
- D3D11_MESSAGE_CATEGORY *pCategoryList;
- UINT NumSeverities;
- D3D11_MESSAGE_SEVERITY *pSeverityList;
- UINT NumIDs;
- D3D11_MESSAGE_ID *pIDList;
-} D3D11_INFO_QUEUE_FILTER_DESC;
-typedef struct D3D11_INFO_QUEUE_FILTER
-{
- D3D11_INFO_QUEUE_FILTER_DESC AllowList;
- D3D11_INFO_QUEUE_FILTER_DESC DenyList;
-} D3D11_INFO_QUEUE_FILTER;
-static const IID IID_ID3D11InfoQueue = { 0x6543dbb6, 0x1b48, 0x42f5, 0xab, 0x82, 0xe9, 0x7e, 0xc7, 0x43, 0x26, 0xf6 };
-MIDL_INTERFACE("6543dbb6-1b48-42f5-ab82-e97ec74326f6") ID3D11InfoQueue : public IUnknown
-{
-public:
- virtual HRESULT __stdcall SetMessageCountLimit(UINT64) = 0;
- virtual void __stdcall ClearStoredMessages() = 0;
- virtual HRESULT __stdcall GetMessage(UINT64, D3D11_MESSAGE *, SIZE_T *) = 0;
- virtual UINT64 __stdcall GetNumMessagesAllowedByStorageFilter() = 0;
- virtual UINT64 __stdcall GetNumMessagesDeniedByStorageFilter() = 0;
- virtual UINT64 __stdcall GetNumStoredMessages() = 0;
- virtual UINT64 __stdcall GetNumStoredMessagesAllowedByRetrievalFilter() = 0;
- virtual UINT64 __stdcall GetNumMessagesDiscardedByMessageCountLimit() = 0;
- virtual UINT64 __stdcall GetMessageCountLimit() = 0;
- virtual HRESULT __stdcall AddStorageFilterEntries(D3D11_INFO_QUEUE_FILTER *) = 0;
- virtual HRESULT __stdcall GetStorageFilter(D3D11_INFO_QUEUE_FILTER *, SIZE_T *) = 0;
- virtual void __stdcall ClearStorageFilter() = 0;
- virtual HRESULT __stdcall PushEmptyStorageFilter() = 0;
- virtual HRESULT __stdcall PushCopyOfStorageFilter() = 0;
- virtual HRESULT __stdcall PushStorageFilter(D3D11_INFO_QUEUE_FILTER *) = 0;
- virtual void __stdcall PopStorageFilter() = 0;
- virtual UINT __stdcall GetStorageFilterStackSize() = 0;
- virtual HRESULT __stdcall AddRetrievalFilterEntries(D3D11_INFO_QUEUE_FILTER *) = 0;
- virtual HRESULT __stdcall GetRetrievalFilter(D3D11_INFO_QUEUE_FILTER *, SIZE_T *) = 0;
- virtual void __stdcall ClearRetrievalFilter() = 0;
- virtual HRESULT __stdcall PushEmptyRetrievalFilter() = 0;
- virtual HRESULT __stdcall PushCopyOfRetrievalFilter() = 0;
- virtual HRESULT __stdcall PushRetrievalFilter(D3D11_INFO_QUEUE_FILTER *) = 0;
- virtual void __stdcall PopRetrievalFilter() = 0;
- virtual UINT __stdcall GetRetrievalFilterStackSize() = 0;
- virtual HRESULT __stdcall AddMessage(D3D11_MESSAGE_CATEGORY, D3D11_MESSAGE_SEVERITY, D3D11_MESSAGE_ID, LPCSTR) = 0;
- virtual HRESULT __stdcall AddApplicationMessage(D3D11_MESSAGE_SEVERITY, LPCSTR) = 0;
- virtual HRESULT __stdcall SetBreakOnCategory(D3D11_MESSAGE_CATEGORY, BOOL) = 0;
- virtual HRESULT __stdcall SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY, BOOL) = 0;
- virtual HRESULT __stdcall SetBreakOnID(D3D11_MESSAGE_ID, BOOL) = 0;
- virtual BOOL __stdcall GetBreakOnCategory(D3D11_MESSAGE_CATEGORY) = 0;
- virtual BOOL __stdcall GetBreakOnSeverity(D3D11_MESSAGE_SEVERITY) = 0;
- virtual BOOL __stdcall GetBreakOnID(D3D11_MESSAGE_ID) = 0;
- virtual void __stdcall SetMuteDebugOutput(BOOL) = 0;
- virtual BOOL __stdcall GetMuteDebugOutput() = 0;
-};
-#endif
-
namespace rx
{
@@ -134,107 +89,299 @@ enum
MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16
};
-// dirtyPointer is a special value that will make the comparison with any valid pointer fail and force the renderer to re-apply the state.
-static const uintptr_t DirtyPointer = static_cast<uintptr_t>(-1);
+#if defined(ANGLE_ENABLE_D3D11_1)
+void CalculateConstantBufferParams(GLintptr offset, GLsizeiptr size, UINT *outFirstConstant, UINT *outNumConstants)
+{
+ // The offset must be aligned to 256 bytes (should have been enforced by glBindBufferRange).
+ ASSERT(offset % 256 == 0);
+
+ // firstConstant and numConstants are expressed in constants of 16-bytes. Furthermore they must be a multiple of 16 constants.
+ *outFirstConstant = static_cast<UINT>(offset / 16);
+
+ // The GL size is not required to be aligned to a 256 bytes boundary.
+ // Round the size up to a 256 bytes boundary then express the results in constants of 16-bytes.
+ *outNumConstants = static_cast<UINT>(rx::roundUp(size, static_cast<GLsizeiptr>(256)) / 16);
-static bool ImageIndexConflictsWithSRV(const gl::ImageIndex *index, D3D11_SHADER_RESOURCE_VIEW_DESC desc)
+ // Since the size is rounded up, firstConstant + numConstants may be bigger than the actual size of the buffer.
+ // This behaviour is explictly allowed according to the documentation on ID3D11DeviceContext1::PSSetConstantBuffers1
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/hh404649%28v=vs.85%29.aspx
+}
+#endif
+
+enum ANGLEFeatureLevel
{
- unsigned mipLevel = index->mipIndex;
- unsigned layerIndex = index->layerIndex;
- GLenum type = index->type;
+ ANGLE_FEATURE_LEVEL_INVALID,
+ ANGLE_FEATURE_LEVEL_9_3,
+ ANGLE_FEATURE_LEVEL_10_0,
+ ANGLE_FEATURE_LEVEL_10_1,
+ ANGLE_FEATURE_LEVEL_11_0,
+ ANGLE_FEATURE_LEVEL_11_1,
+ NUM_ANGLE_FEATURE_LEVELS
+};
- switch (desc.ViewDimension)
+ANGLEFeatureLevel GetANGLEFeatureLevel(D3D_FEATURE_LEVEL d3dFeatureLevel)
+{
+ switch (d3dFeatureLevel)
{
- case D3D11_SRV_DIMENSION_TEXTURE2D:
- {
- unsigned maxSrvMip = desc.Texture2D.MipLevels + desc.Texture2D.MostDetailedMip;
- maxSrvMip = (desc.Texture2D.MipLevels == -1) ? INT_MAX : maxSrvMip;
+ case D3D_FEATURE_LEVEL_9_3: return ANGLE_FEATURE_LEVEL_9_3;
+ case D3D_FEATURE_LEVEL_10_0: return ANGLE_FEATURE_LEVEL_10_0;
+ case D3D_FEATURE_LEVEL_10_1: return ANGLE_FEATURE_LEVEL_10_1;
+ case D3D_FEATURE_LEVEL_11_0: return ANGLE_FEATURE_LEVEL_11_0;
+ // Note: we don't ever request a 11_1 device, because this gives
+ // an E_INVALIDARG error on systems that don't have the platform update.
+ case D3D_FEATURE_LEVEL_11_1: return ANGLE_FEATURE_LEVEL_11_1;
+ default: return ANGLE_FEATURE_LEVEL_INVALID;
+ }
+}
- unsigned mipMin = index->mipIndex;
- unsigned mipMax = (layerIndex == -1) ? INT_MAX : layerIndex;
+void SetLineLoopIndices(GLuint *dest, size_t count)
+{
+ for (size_t i = 0; i < count; i++)
+ {
+ dest[i] = static_cast<GLuint>(i);
+ }
+ dest[count] = 0;
+}
- return type == GL_TEXTURE_2D && RangeUI(mipMin, mipMax).intersects(RangeUI(desc.Texture2D.MostDetailedMip, maxSrvMip));
- }
+template <typename T>
+void CopyLineLoopIndices(const GLvoid *indices, GLuint *dest, size_t count)
+{
+ const T *srcPtr = static_cast<const T *>(indices);
+ for (size_t i = 0; i < count; ++i)
+ {
+ dest[i] = static_cast<GLuint>(srcPtr[i]);
+ }
+ dest[count] = static_cast<GLuint>(srcPtr[0]);
+}
- case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
- {
- unsigned maxSrvMip = desc.Texture2DArray.MipLevels + desc.Texture2DArray.MostDetailedMip;
- maxSrvMip = (desc.Texture2DArray.MipLevels == -1) ? INT_MAX : maxSrvMip;
+void SetTriangleFanIndices(GLuint *destPtr, size_t numTris)
+{
+ for (size_t i = 0; i < numTris; i++)
+ {
+ destPtr[i * 3 + 0] = 0;
+ destPtr[i * 3 + 1] = static_cast<GLuint>(i) + 1;
+ destPtr[i * 3 + 2] = static_cast<GLuint>(i) + 2;
+ }
+}
+
+template <typename T>
+void CopyLineLoopIndicesWithRestart(const GLvoid *indices,
+ size_t count,
+ GLenum indexType,
+ std::vector<GLuint> *bufferOut)
+{
+ GLuint restartIndex = gl::GetPrimitiveRestartIndex(indexType);
+ GLuint d3dRestartIndex = static_cast<GLuint>(d3d11::GetPrimitiveRestartIndex());
+ const T *srcPtr = static_cast<const T *>(indices);
+ Optional<GLuint> currentLoopStart;
- unsigned maxSlice = desc.Texture2DArray.FirstArraySlice + desc.Texture2DArray.ArraySize;
+ bufferOut->clear();
- // Cube maps can be mapped to Texture2DArray SRVs
- return (type == GL_TEXTURE_2D_ARRAY || gl::IsCubeMapTextureTarget(type)) &&
- desc.Texture2DArray.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip &&
- desc.Texture2DArray.FirstArraySlice <= layerIndex && layerIndex < maxSlice;
- }
+ for (size_t indexIdx = 0; indexIdx < count; ++indexIdx)
+ {
+ GLuint value = static_cast<GLuint>(srcPtr[indexIdx]);
- case D3D11_SRV_DIMENSION_TEXTURECUBE:
+ if (value == restartIndex)
{
- unsigned maxSrvMip = desc.TextureCube.MipLevels + desc.TextureCube.MostDetailedMip;
- maxSrvMip = (desc.TextureCube.MipLevels == -1) ? INT_MAX : maxSrvMip;
-
- return gl::IsCubeMapTextureTarget(type) &&
- desc.TextureCube.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip;
+ if (currentLoopStart.valid())
+ {
+ bufferOut->push_back(currentLoopStart.value());
+ bufferOut->push_back(d3dRestartIndex);
+ currentLoopStart.reset();
+ }
}
-
- case D3D11_SRV_DIMENSION_TEXTURE3D:
+ else
{
- unsigned maxSrvMip = desc.Texture3D.MipLevels + desc.Texture3D.MostDetailedMip;
- maxSrvMip = (desc.Texture3D.MipLevels == -1) ? INT_MAX : maxSrvMip;
-
- return type == GL_TEXTURE_3D &&
- desc.Texture3D.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip;
+ bufferOut->push_back(value);
+ if (!currentLoopStart.valid())
+ {
+ currentLoopStart = value;
+ }
}
- default:
- // We only handle the cases corresponding to valid image indexes
- UNIMPLEMENTED();
}
- return false;
+ if (currentLoopStart.valid())
+ {
+ bufferOut->push_back(currentLoopStart.value());
+ }
}
-// Does *not* increment the resource ref count!!
-ID3D11Resource *GetViewResource(ID3D11View *view)
+void GetLineLoopIndices(const GLvoid *indices,
+ GLenum indexType,
+ GLuint count,
+ bool usePrimitiveRestartFixedIndex,
+ std::vector<GLuint> *bufferOut)
{
- ID3D11Resource *resource = NULL;
- ASSERT(view);
- view->GetResource(&resource);
- resource->Release();
- return resource;
+ if (indexType != GL_NONE && usePrimitiveRestartFixedIndex)
+ {
+ switch (indexType)
+ {
+ case GL_UNSIGNED_BYTE:
+ CopyLineLoopIndicesWithRestart<GLubyte>(indices, count, indexType, bufferOut);
+ break;
+ case GL_UNSIGNED_SHORT:
+ CopyLineLoopIndicesWithRestart<GLushort>(indices, count, indexType, bufferOut);
+ break;
+ case GL_UNSIGNED_INT:
+ CopyLineLoopIndicesWithRestart<GLuint>(indices, count, indexType, bufferOut);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ return;
+ }
+
+ // For non-primitive-restart draws, the index count is static.
+ bufferOut->resize(static_cast<size_t>(count) + 1);
+
+ switch (indexType)
+ {
+ // Non-indexed draw
+ case GL_NONE:
+ SetLineLoopIndices(&(*bufferOut)[0], count);
+ break;
+ case GL_UNSIGNED_BYTE:
+ CopyLineLoopIndices<GLubyte>(indices, &(*bufferOut)[0], count);
+ break;
+ case GL_UNSIGNED_SHORT:
+ CopyLineLoopIndices<GLushort>(indices, &(*bufferOut)[0], count);
+ break;
+ case GL_UNSIGNED_INT:
+ CopyLineLoopIndices<GLuint>(indices, &(*bufferOut)[0], count);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
}
-void CalculateConstantBufferParams(GLintptr offset, GLsizeiptr size, UINT *outFirstConstant, UINT *outNumConstants)
+template <typename T>
+void CopyTriangleFanIndices(const GLvoid *indices, GLuint *destPtr, size_t numTris)
{
- // The offset must be aligned to 256 bytes (should have been enforced by glBindBufferRange).
- ASSERT(offset % 256 == 0);
+ const T *srcPtr = static_cast<const T *>(indices);
- // firstConstant and numConstants are expressed in constants of 16-bytes. Furthermore they must be a multiple of 16 constants.
- *outFirstConstant = offset / 16;
+ for (size_t i = 0; i < numTris; i++)
+ {
+ destPtr[i * 3 + 0] = static_cast<GLuint>(srcPtr[0]);
+ destPtr[i * 3 + 1] = static_cast<GLuint>(srcPtr[i + 1]);
+ destPtr[i * 3 + 2] = static_cast<GLuint>(srcPtr[i + 2]);
+ }
+}
- // The GL size is not required to be aligned to a 256 bytes boundary.
- // Round the size up to a 256 bytes boundary then express the results in constants of 16-bytes.
- *outNumConstants = rx::roundUp(size, static_cast<GLsizeiptr>(256)) / 16;
+template <typename T>
+void CopyTriangleFanIndicesWithRestart(const GLvoid *indices,
+ GLuint indexCount,
+ GLenum indexType,
+ std::vector<GLuint> *bufferOut)
+{
+ GLuint restartIndex = gl::GetPrimitiveRestartIndex(indexType);
+ GLuint d3dRestartIndex = gl::GetPrimitiveRestartIndex(GL_UNSIGNED_INT);
+ const T *srcPtr = static_cast<const T *>(indices);
+ Optional<GLuint> vertexA;
+ Optional<GLuint> vertexB;
- // Since the size is rounded up, firstConstant + numConstants may be bigger than the actual size of the buffer.
- // This behaviour is explictly allowed according to the documentation on ID3D11DeviceContext1::PSSetConstantBuffers1
- // https://msdn.microsoft.com/en-us/library/windows/desktop/hh404649%28v=vs.85%29.aspx
+ bufferOut->clear();
+
+ for (size_t indexIdx = 0; indexIdx < indexCount; ++indexIdx)
+ {
+ GLuint value = static_cast<GLuint>(srcPtr[indexIdx]);
+
+ if (value == restartIndex)
+ {
+ bufferOut->push_back(d3dRestartIndex);
+ vertexA.reset();
+ vertexB.reset();
+ }
+ else
+ {
+ if (!vertexA.valid())
+ {
+ vertexA = value;
+ }
+ else if (!vertexB.valid())
+ {
+ vertexB = value;
+ }
+ else
+ {
+ bufferOut->push_back(vertexA.value());
+ bufferOut->push_back(vertexB.value());
+ bufferOut->push_back(value);
+ vertexB = value;
+ }
+ }
+ }
}
+void GetTriFanIndices(const GLvoid *indices,
+ GLenum indexType,
+ GLuint count,
+ bool usePrimitiveRestartFixedIndex,
+ std::vector<GLuint> *bufferOut)
+{
+ if (indexType != GL_NONE && usePrimitiveRestartFixedIndex)
+ {
+ switch (indexType)
+ {
+ case GL_UNSIGNED_BYTE:
+ CopyTriangleFanIndicesWithRestart<GLubyte>(indices, count, indexType, bufferOut);
+ break;
+ case GL_UNSIGNED_SHORT:
+ CopyTriangleFanIndicesWithRestart<GLushort>(indices, count, indexType, bufferOut);
+ break;
+ case GL_UNSIGNED_INT:
+ CopyTriangleFanIndicesWithRestart<GLuint>(indices, count, indexType, bufferOut);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ return;
+ }
+
+ // For non-primitive-restart draws, the index count is static.
+ GLuint numTris = count - 2;
+ bufferOut->resize(numTris * 3);
+
+ switch (indexType)
+ {
+ // Non-indexed draw
+ case GL_NONE:
+ SetTriangleFanIndices(&(*bufferOut)[0], numTris);
+ break;
+ case GL_UNSIGNED_BYTE:
+ CopyTriangleFanIndices<GLubyte>(indices, &(*bufferOut)[0], numTris);
+ break;
+ case GL_UNSIGNED_SHORT:
+ CopyTriangleFanIndices<GLushort>(indices, &(*bufferOut)[0], numTris);
+ break;
+ case GL_UNSIGNED_INT:
+ CopyTriangleFanIndices<GLuint>(indices, &(*bufferOut)[0], numTris);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
}
+} // anonymous namespace
+
Renderer11::Renderer11(egl::Display *display)
: RendererD3D(display),
- mStateCache(this)
+ mStateCache(this),
+ mStateManager(this),
+ mLastHistogramUpdateTime(ANGLEPlatformCurrent()->monotonicallyIncreasingTime())
+#if !defined(ANGLE_MINGW32_COMPAT)
+ ,mDebug(nullptr)
+#endif
{
- // Initialize global annotator
- gl::InitializeDebugAnnotations(&mAnnotator);
-
mVertexDataManager = NULL;
mIndexDataManager = NULL;
mLineLoopIB = NULL;
mTriangleFanIB = NULL;
+ mAppliedIBChanged = false;
mBlit = NULL;
mPixelTransfer = NULL;
@@ -245,10 +392,18 @@ Renderer11::Renderer11(egl::Display *display)
mSyncQuery = NULL;
- mSupportsConstantBufferOffsets = false;
+ mRenderer11DeviceCaps.supportsClearView = false;
+ mRenderer11DeviceCaps.supportsConstantBufferOffsets = false;
+ mRenderer11DeviceCaps.supportsDXGI1_2 = false;
+ mRenderer11DeviceCaps.B5G6R5support = 0;
+ mRenderer11DeviceCaps.B4G4R4A4support = 0;
+ mRenderer11DeviceCaps.B5G5R5A1support = 0;
mD3d11Module = NULL;
mDxgiModule = NULL;
+ mDCompModule = NULL;
+ mCreatedWithDeviceEXT = false;
+ mEGLDevice = nullptr;
mDevice = NULL;
mDeviceContext = NULL;
@@ -265,89 +420,105 @@ Renderer11::Renderer11(egl::Display *display)
mAppliedNumXFBBindings = static_cast<size_t>(-1);
- const auto &attributes = mDisplay->getAttributeMap();
-
- EGLint requestedMajorVersion = attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, EGL_DONT_CARE);
- EGLint requestedMinorVersion = attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, EGL_DONT_CARE);
+ ZeroMemory(&mAdapterDescription, sizeof(mAdapterDescription));
- if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 11)
+ if (mDisplay->getPlatform() == EGL_PLATFORM_ANGLE_ANGLE)
{
- if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 0)
- {
- mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_11_0);
- }
- }
+ const auto &attributes = mDisplay->getAttributeMap();
- if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 10)
- {
- if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 1)
+ EGLint requestedMajorVersion =
+ attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, EGL_DONT_CARE);
+ EGLint requestedMinorVersion =
+ attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, EGL_DONT_CARE);
+
+ if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 11)
{
- mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_10_1);
+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 0)
+ {
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_11_0);
+ }
}
- if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 0)
+
+ if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 10)
{
- mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_10_0);
+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 1)
+ {
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_10_1);
+ }
+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 0)
+ {
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_10_0);
+ }
}
- }
#if defined(ANGLE_ENABLE_WINDOWS_STORE)
- if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 9)
+ if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 9)
#else
- if (requestedMajorVersion == 9 && requestedMinorVersion == 3)
+ if (requestedMajorVersion == 9 && requestedMinorVersion == 3)
#endif
- {
- if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 3)
{
- mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_3);
- }
+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 3)
+ {
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_3);
+ }
#if defined(ANGLE_ENABLE_WINDOWS_STORE)
- if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 2)
- {
- mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_2);
+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 2)
+ {
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_2);
+ }
+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 1)
+ {
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_1);
+ }
+#endif
}
- if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 1)
+
+ EGLint requestedDeviceType = attributes.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE,
+ EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE);
+ switch (requestedDeviceType)
{
- mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_1);
- }
-#endif
- }
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE:
+ mRequestedDriverType = D3D_DRIVER_TYPE_HARDWARE;
+ break;
- EGLint requestedDeviceType = attributes.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE,
- EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE);
- switch (requestedDeviceType)
- {
- case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE:
- mDriverType = D3D_DRIVER_TYPE_HARDWARE;
- break;
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE:
+ mRequestedDriverType = D3D_DRIVER_TYPE_WARP;
+ break;
- case EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE:
- mDriverType = D3D_DRIVER_TYPE_WARP;
- break;
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE:
+ mRequestedDriverType = D3D_DRIVER_TYPE_REFERENCE;
+ break;
- case EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE:
- mDriverType = D3D_DRIVER_TYPE_REFERENCE;
- break;
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE:
+ mRequestedDriverType = D3D_DRIVER_TYPE_NULL;
+ break;
- case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE:
- mDriverType = D3D_DRIVER_TYPE_NULL;
- break;
+ default:
+ UNREACHABLE();
+ }
- default:
- UNREACHABLE();
+ const EGLenum presentPath = attributes.get(EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE,
+ EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE);
+ mPresentPathFastEnabled = (presentPath == EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE);
}
-}
+ else if (display->getPlatform() == EGL_PLATFORM_DEVICE_EXT)
+ {
+ mEGLDevice = GetImplAs<DeviceD3D>(display->getDevice());
+ ASSERT(mEGLDevice != nullptr);
+ mCreatedWithDeviceEXT = true;
-Renderer11::~Renderer11()
-{
- release();
+ // Also set EGL_PLATFORM_ANGLE_ANGLE variables, in case they're used elsewhere in ANGLE
+ // mAvailableFeatureLevels defaults to empty
+ mRequestedDriverType = D3D_DRIVER_TYPE_UNKNOWN;
+ mPresentPathFastEnabled = false;
+ }
- gl::UninitializeDebugAnnotations();
+ initializeDebugAnnotator();
}
-Renderer11 *Renderer11::makeRenderer11(Renderer *renderer)
+Renderer11::~Renderer11()
{
- ASSERT(HAS_DYNAMIC_TYPE(Renderer11*, renderer));
- return static_cast<Renderer11*>(renderer);
+ release();
}
#ifndef __d3d11_1_h__
@@ -356,209 +527,268 @@ Renderer11 *Renderer11::makeRenderer11(Renderer *renderer)
egl::Error Renderer11::initialize()
{
- if (!mCompiler.initialize())
+ HRESULT result = S_OK;
+
+ egl::Error error = initializeD3DDevice();
+ if (error.isError())
{
- return egl::Error(EGL_NOT_INITIALIZED,
- D3D11_INIT_COMPILER_ERROR,
- "Failed to initialize compiler.");
+ return error;
}
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
- mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
- mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
-
- if (mD3d11Module == NULL || mDxgiModule == NULL)
+#if !ANGLE_SKIP_DXGI_1_2_CHECK
{
- return egl::Error(EGL_NOT_INITIALIZED,
- D3D11_INIT_MISSING_DEP,
- "Could not load D3D11 or DXGI library.");
- }
-
- // create the D3D11 device
- ASSERT(mDevice == NULL);
- PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
+ TRACE_EVENT0("gpu.angle", "Renderer11::initialize (DXGICheck)");
+ // In order to create a swap chain for an HWND owned by another process, DXGI 1.2 is required.
+ // The easiest way to check is to query for a IDXGIDevice2.
+ bool requireDXGI1_2 = false;
+ HWND hwnd = WindowFromDC(mDisplay->getNativeDisplayId());
+ if (hwnd)
+ {
+ DWORD currentProcessId = GetCurrentProcessId();
+ DWORD wndProcessId;
+ GetWindowThreadProcessId(hwnd, &wndProcessId);
+ requireDXGI1_2 = (currentProcessId != wndProcessId);
+ }
+ else
+ {
+ requireDXGI1_2 = true;
+ }
- if (D3D11CreateDevice == NULL)
- {
- return egl::Error(EGL_NOT_INITIALIZED,
- D3D11_INIT_MISSING_DEP,
- "Could not retrieve D3D11CreateDevice address.");
+ if (requireDXGI1_2)
+ {
+ IDXGIDevice2 *dxgiDevice2 = NULL;
+ result = mDevice->QueryInterface(__uuidof(IDXGIDevice2), (void**)&dxgiDevice2);
+ if (FAILED(result))
+ {
+ return egl::Error(EGL_NOT_INITIALIZED,
+ D3D11_INIT_INCOMPATIBLE_DXGI,
+ "DXGI 1.2 required to present to HWNDs owned by another process.");
+ }
+ SafeRelease(dxgiDevice2);
+ }
}
#endif
+#endif
- HRESULT result = S_OK;
-#ifdef _DEBUG
- result = D3D11CreateDevice(NULL,
- mDriverType,
- NULL,
- D3D11_CREATE_DEVICE_DEBUG,
- mAvailableFeatureLevels.data(),
- mAvailableFeatureLevels.size(),
- D3D11_SDK_VERSION,
- &mDevice,
- &mFeatureLevel,
- &mDeviceContext);
-
- if (!mDevice || FAILED(result))
{
- ERR("Failed creating Debug D3D11 device - falling back to release runtime.\n");
- }
-
- if (!mDevice || FAILED(result))
+ TRACE_EVENT0("gpu.angle", "Renderer11::initialize (ComQueries)");
+ // Cast the DeviceContext to a DeviceContext1.
+ // This could fail on Windows 7 without the Platform Update.
+ // Don't error in this case- just don't use mDeviceContext1.
+#if defined(ANGLE_ENABLE_D3D11_1)
+ mDeviceContext1 = d3d11::DynamicCastComObject<ID3D11DeviceContext1>(mDeviceContext);
#endif
- {
- result = D3D11CreateDevice(NULL,
- mDriverType,
- NULL,
- 0,
- mAvailableFeatureLevels.data(),
- mAvailableFeatureLevels.size(),
- D3D11_SDK_VERSION,
- &mDevice,
- &mFeatureLevel,
- &mDeviceContext);
- if (result == E_INVALIDARG)
+ IDXGIDevice *dxgiDevice = NULL;
+ result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
+
+ if (FAILED(result))
{
- // Cleanup done by destructor through glDestroyRenderer
return egl::Error(EGL_NOT_INITIALIZED,
- D3D11_INIT_CREATEDEVICE_INVALIDARG,
- "Could not create D3D11 device.");
+ D3D11_INIT_OTHER_ERROR,
+ "Could not query DXGI device.");
}
- if (!mDevice || FAILED(result))
+ result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&mDxgiAdapter);
+
+ if (FAILED(result))
{
- // Cleanup done by destructor through glDestroyRenderer
return egl::Error(EGL_NOT_INITIALIZED,
- D3D11_INIT_CREATEDEVICE_ERROR,
- "Could not create D3D11 device.");
+ D3D11_INIT_OTHER_ERROR,
+ "Could not retrieve DXGI adapter");
}
- }
-#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
-#if !ANGLE_SKIP_DXGI_1_2_CHECK
- // In order to create a swap chain for an HWND owned by another process, DXGI 1.2 is required.
- // The easiest way to check is to query for a IDXGIDevice2.
- bool requireDXGI1_2 = false;
- HWND hwnd = WindowFromDC(mDisplay->getNativeDisplayId());
- if (hwnd)
- {
- DWORD currentProcessId = GetCurrentProcessId();
- DWORD wndProcessId;
- GetWindowThreadProcessId(hwnd, &wndProcessId);
- requireDXGI1_2 = (currentProcessId != wndProcessId);
- }
- else
- {
- requireDXGI1_2 = true;
- }
+ SafeRelease(dxgiDevice);
- if (requireDXGI1_2)
- {
- IDXGIDevice2 *dxgiDevice2 = NULL;
- result = mDevice->QueryInterface(__uuidof(IDXGIDevice2), (void**)&dxgiDevice2);
- if (FAILED(result))
+#if defined(ANGLE_ENABLE_D3D11_1)
+ IDXGIAdapter2 *dxgiAdapter2 = d3d11::DynamicCastComObject<IDXGIAdapter2>(mDxgiAdapter);
+
+ // On D3D_FEATURE_LEVEL_9_*, IDXGIAdapter::GetDesc returns "Software Adapter" for the description string.
+ // If DXGI1.2 is available then IDXGIAdapter2::GetDesc2 can be used to get the actual hardware values.
+ if (mRenderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3 && dxgiAdapter2 != NULL)
{
- return egl::Error(EGL_NOT_INITIALIZED,
- D3D11_INIT_INCOMPATIBLE_DXGI,
- "DXGI 1.2 required to present to HWNDs owned by another process.");
+ DXGI_ADAPTER_DESC2 adapterDesc2 = {};
+ result = dxgiAdapter2->GetDesc2(&adapterDesc2);
+ if (SUCCEEDED(result))
+ {
+ // Copy the contents of the DXGI_ADAPTER_DESC2 into mAdapterDescription (a DXGI_ADAPTER_DESC).
+ memcpy(mAdapterDescription.Description, adapterDesc2.Description, sizeof(mAdapterDescription.Description));
+ mAdapterDescription.VendorId = adapterDesc2.VendorId;
+ mAdapterDescription.DeviceId = adapterDesc2.DeviceId;
+ mAdapterDescription.SubSysId = adapterDesc2.SubSysId;
+ mAdapterDescription.Revision = adapterDesc2.Revision;
+ mAdapterDescription.DedicatedVideoMemory = adapterDesc2.DedicatedVideoMemory;
+ mAdapterDescription.DedicatedSystemMemory = adapterDesc2.DedicatedSystemMemory;
+ mAdapterDescription.SharedSystemMemory = adapterDesc2.SharedSystemMemory;
+ mAdapterDescription.AdapterLuid = adapterDesc2.AdapterLuid;
+ }
}
- SafeRelease(dxgiDevice2);
- }
-#endif
+ else
#endif
+ {
+ result = mDxgiAdapter->GetDesc(&mAdapterDescription);
+ }
- // Cast the DeviceContext to a DeviceContext1.
- // This could fail on Windows 7 without the Platform Update.
- // Don't error in this case- just don't use mDeviceContext1.
#if defined(ANGLE_ENABLE_D3D11_1)
- mDeviceContext1 = d3d11::DynamicCastComObject<ID3D11DeviceContext1>(mDeviceContext);
+ SafeRelease(dxgiAdapter2);
#endif
- IDXGIDevice *dxgiDevice = NULL;
- result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
+ if (FAILED(result))
+ {
+ return egl::Error(EGL_NOT_INITIALIZED,
+ D3D11_INIT_OTHER_ERROR,
+ "Could not read DXGI adaptor description.");
+ }
- if (FAILED(result))
- {
- return egl::Error(EGL_NOT_INITIALIZED,
- D3D11_INIT_OTHER_ERROR,
- "Could not query DXGI device.");
- }
+ memset(mDescription, 0, sizeof(mDescription));
+ wcstombs(mDescription, mAdapterDescription.Description, sizeof(mDescription) - 1);
- result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&mDxgiAdapter);
+ result = mDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&mDxgiFactory);
- if (FAILED(result))
- {
- return egl::Error(EGL_NOT_INITIALIZED,
- D3D11_INIT_OTHER_ERROR,
- "Could not retrieve DXGI adapter");
+ if (!mDxgiFactory || FAILED(result))
+ {
+ return egl::Error(EGL_NOT_INITIALIZED,
+ D3D11_INIT_OTHER_ERROR,
+ "Could not create DXGI factory.");
+ }
}
- SafeRelease(dxgiDevice);
+#if !defined(ANGLE_MINGW32_COMPAT)
+ // Disable some spurious D3D11 debug warnings to prevent them from flooding the output log
+#if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG)
+ {
+ TRACE_EVENT0("gpu.angle", "Renderer11::initialize (HideWarnings)");
+ ID3D11InfoQueue *infoQueue;
+ result = mDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&infoQueue);
-#if defined(ANGLE_ENABLE_D3D11_1)
- IDXGIAdapter2 *dxgiAdapter2 = d3d11::DynamicCastComObject<IDXGIAdapter2>(mDxgiAdapter);
+ if (SUCCEEDED(result))
+ {
+ D3D11_MESSAGE_ID hideMessages[] =
+ {
+ D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET
+ };
- // On D3D_FEATURE_LEVEL_9_*, IDXGIAdapter::GetDesc returns "Software Adapter" for the description string.
- // If DXGI1.2 is available then IDXGIAdapter2::GetDesc2 can be used to get the actual hardware values.
- if (mFeatureLevel <= D3D_FEATURE_LEVEL_9_3 && dxgiAdapter2 != NULL)
- {
- DXGI_ADAPTER_DESC2 adapterDesc2 = {0};
- dxgiAdapter2->GetDesc2(&adapterDesc2);
+ D3D11_INFO_QUEUE_FILTER filter = {};
+ filter.DenyList.NumIDs = static_cast<unsigned int>(ArraySize(hideMessages));
+ filter.DenyList.pIDList = hideMessages;
- // Copy the contents of the DXGI_ADAPTER_DESC2 into mAdapterDescription (a DXGI_ADAPTER_DESC).
- memcpy(mAdapterDescription.Description, adapterDesc2.Description, sizeof(mAdapterDescription.Description));
- mAdapterDescription.VendorId = adapterDesc2.VendorId;
- mAdapterDescription.DeviceId = adapterDesc2.DeviceId;
- mAdapterDescription.SubSysId = adapterDesc2.SubSysId;
- mAdapterDescription.Revision = adapterDesc2.Revision;
- mAdapterDescription.DedicatedVideoMemory = adapterDesc2.DedicatedVideoMemory;
- mAdapterDescription.DedicatedSystemMemory = adapterDesc2.DedicatedSystemMemory;
- mAdapterDescription.SharedSystemMemory = adapterDesc2.SharedSystemMemory;
- mAdapterDescription.AdapterLuid = adapterDesc2.AdapterLuid;
- }
- else
- {
- mDxgiAdapter->GetDesc(&mAdapterDescription);
+ infoQueue->AddStorageFilterEntries(&filter);
+ SafeRelease(infoQueue);
+ }
}
+#endif
- SafeRelease(dxgiAdapter2);
+#if !defined(NDEBUG)
+ mDebug = d3d11::DynamicCastComObject<ID3D11Debug>(mDevice);
#endif
+#endif // !ANGLE_MINGW32_COMPAT
- memset(mDescription, 0, sizeof(mDescription));
- wcstombs(mDescription, mAdapterDescription.Description, sizeof(mDescription) - 1);
+ initializeDevice();
+
+ return egl::Error(EGL_SUCCESS);
+}
- result = mDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&mDxgiFactory);
+egl::Error Renderer11::initializeD3DDevice()
+{
+ HRESULT result = S_OK;
- if (!mDxgiFactory || FAILED(result))
+ if (!mCreatedWithDeviceEXT)
{
- return egl::Error(EGL_NOT_INITIALIZED,
- D3D11_INIT_OTHER_ERROR,
- "Could not create DXGI factory.");
- }
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+ PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = nullptr;
+ {
+ SCOPED_ANGLE_HISTOGRAM_TIMER("GPU.ANGLE.Renderer11InitializeDLLsMS");
+ TRACE_EVENT0("gpu.angle", "Renderer11::initialize (Load DLLs)");
+ mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
+ mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
+ mDCompModule = LoadLibrary(TEXT("dcomp.dll"));
- // Disable some spurious D3D11 debug warnings to prevent them from flooding the output log
-#if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG)
- ID3D11InfoQueue *infoQueue;
- result = mDevice->QueryInterface(IID_ID3D11InfoQueue, (void **)&infoQueue);
+ if (mD3d11Module == nullptr || mDxgiModule == nullptr)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, D3D11_INIT_MISSING_DEP,
+ "Could not load D3D11 or DXGI library.");
+ }
- if (SUCCEEDED(result))
+ // create the D3D11 device
+ ASSERT(mDevice == nullptr);
+ D3D11CreateDevice = reinterpret_cast<PFN_D3D11_CREATE_DEVICE>(
+ GetProcAddress(mD3d11Module, "D3D11CreateDevice"));
+
+ if (D3D11CreateDevice == nullptr)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, D3D11_INIT_MISSING_DEP,
+ "Could not retrieve D3D11CreateDevice address.");
+ }
+ }
+#endif
+
+#ifdef _DEBUG
+ {
+ TRACE_EVENT0("gpu.angle", "D3D11CreateDevice (Debug)");
+ result = D3D11CreateDevice(nullptr, mRequestedDriverType, nullptr,
+ D3D11_CREATE_DEVICE_DEBUG, mAvailableFeatureLevels.data(),
+ static_cast<unsigned int>(mAvailableFeatureLevels.size()),
+ D3D11_SDK_VERSION, &mDevice,
+ &(mRenderer11DeviceCaps.featureLevel), &mDeviceContext);
+ }
+
+ if (!mDevice || FAILED(result))
+ {
+ ERR("Failed creating Debug D3D11 device - falling back to release runtime.\n");
+ }
+
+ if (!mDevice || FAILED(result))
+#endif
+ {
+ SCOPED_ANGLE_HISTOGRAM_TIMER("GPU.ANGLE.D3D11CreateDeviceMS");
+ TRACE_EVENT0("gpu.angle", "D3D11CreateDevice");
+
+ result = D3D11CreateDevice(
+ nullptr, mRequestedDriverType, nullptr, 0, mAvailableFeatureLevels.data(),
+ static_cast<unsigned int>(mAvailableFeatureLevels.size()), D3D11_SDK_VERSION,
+ &mDevice, &(mRenderer11DeviceCaps.featureLevel), &mDeviceContext);
+
+ // Cleanup done by destructor
+ if (!mDevice || FAILED(result))
+ {
+ ANGLE_HISTOGRAM_SPARSE_SLOWLY("GPU.ANGLE.D3D11CreateDeviceError",
+ static_cast<int>(result));
+ return egl::Error(EGL_NOT_INITIALIZED, D3D11_INIT_CREATEDEVICE_ERROR,
+ "Could not create D3D11 device.");
+ }
+ }
+ }
+ else
{
- D3D11_MESSAGE_ID hideMessages[] =
+ // We should use the inputted D3D11 device instead
+ void *device = nullptr;
+ egl::Error error = mEGLDevice->getDevice(&device);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ID3D11Device *d3dDevice = reinterpret_cast<ID3D11Device *>(device);
+ if (FAILED(d3dDevice->GetDeviceRemovedReason()))
{
- D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET
- };
+ return egl::Error(EGL_NOT_INITIALIZED, "Inputted D3D11 device has been lost.");
+ }
- D3D11_INFO_QUEUE_FILTER filter = {0};
- filter.DenyList.NumIDs = ArraySize(hideMessages);
- filter.DenyList.pIDList = hideMessages;
+ if (d3dDevice->GetFeatureLevel() < D3D_FEATURE_LEVEL_9_3)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED,
+ "Inputted D3D11 device must be Feature Level 9_3 or greater.");
+ }
- infoQueue->AddStorageFilterEntries(&filter);
- SafeRelease(infoQueue);
+ // The Renderer11 adds a ref to the inputted D3D11 device, like D3D11CreateDevice does.
+ mDevice = d3dDevice;
+ mDevice->AddRef();
+ mDevice->GetImmediateContext(&mDeviceContext);
+ mRenderer11DeviceCaps.featureLevel = mDevice->GetFeatureLevel();
}
-#endif
- initializeDevice();
+ d3d11::SetDebugName(mDeviceContext, "DeviceContext");
return egl::Error(EGL_SUCCESS);
}
@@ -568,6 +798,11 @@ egl::Error Renderer11::initialize()
// to reset the scene status and ensure the default states are reset.
void Renderer11::initializeDevice()
{
+ SCOPED_ANGLE_HISTOGRAM_TIMER("GPU.ANGLE.Renderer11InitializeDeviceMS");
+ TRACE_EVENT0("gpu.angle", "Renderer11::initializeDevice");
+
+ populateRenderer11DeviceCaps();
+
mStateCache.initialize(mDevice);
mInputLayoutCache.initialize(mDevice, mDeviceContext);
@@ -598,14 +833,7 @@ void Renderer11::initializeDevice()
const gl::Caps &rendererCaps = getRendererCaps();
-#if defined(ANGLE_ENABLE_D3D11_1)
- if (getDeviceContext1IfSupported())
- {
- D3D11_FEATURE_DATA_D3D11_OPTIONS d3d11Options;
- mDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &d3d11Options, sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS));
- mSupportsConstantBufferOffsets = (d3d11Options.ConstantBufferOffsetting != FALSE);
- }
-#endif
+ mStateManager.initialize(rendererCaps);
mForceSetVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
@@ -613,19 +841,94 @@ void Renderer11::initializeDevice()
mForceSetPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits);
mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits);
- mCurVertexSRVs.resize(rendererCaps.maxVertexTextureImageUnits);
- mCurPixelSRVs.resize(rendererCaps.maxTextureImageUnits);
+ mStateManager.initialize(rendererCaps);
markAllStateDirty();
+
+ // Gather stats on DXGI and D3D feature level
+ ANGLE_HISTOGRAM_BOOLEAN("GPU.ANGLE.SupportsDXGI1_2", mRenderer11DeviceCaps.supportsDXGI1_2);
+
+ ANGLEFeatureLevel angleFeatureLevel = GetANGLEFeatureLevel(mRenderer11DeviceCaps.featureLevel);
+
+ // We don't actually request a 11_1 device, because of complications with the platform
+ // update. Instead we check if the mDeviceContext1 pointer cast succeeded.
+ // Note: we should support D3D11_0 always, but we aren't guaranteed to be at FL11_0
+ // because the app can specify a lower version (such as 9_3) on Display creation.
+ if (mDeviceContext1 != nullptr)
+ {
+ angleFeatureLevel = ANGLE_FEATURE_LEVEL_11_1;
+ }
+
+ ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3D11FeatureLevel",
+ angleFeatureLevel,
+ NUM_ANGLE_FEATURE_LEVELS);
+
+ // TODO(jmadill): use context caps, and place in common D3D location
+ mTranslatedAttribCache.resize(getRendererCaps().maxVertexAttributes);
+}
+
+void Renderer11::populateRenderer11DeviceCaps()
+{
+ HRESULT hr = S_OK;
+
+#if defined(ANGLE_ENABLE_D3D11_1)
+ if (mDeviceContext1)
+ {
+ D3D11_FEATURE_DATA_D3D11_OPTIONS d3d11Options;
+ HRESULT result = mDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &d3d11Options, sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS));
+ if (SUCCEEDED(result))
+ {
+ mRenderer11DeviceCaps.supportsClearView = (d3d11Options.ClearView != FALSE);
+ mRenderer11DeviceCaps.supportsConstantBufferOffsets = (d3d11Options.ConstantBufferOffsetting != FALSE);
+ }
+ }
+#endif
+
+ hr = mDevice->CheckFormatSupport(DXGI_FORMAT_B5G6R5_UNORM, &(mRenderer11DeviceCaps.B5G6R5support));
+ if (FAILED(hr))
+ {
+ mRenderer11DeviceCaps.B5G6R5support = 0;
+ }
+
+ hr = mDevice->CheckFormatSupport(DXGI_FORMAT_B4G4R4A4_UNORM, &(mRenderer11DeviceCaps.B4G4R4A4support));
+ if (FAILED(hr))
+ {
+ mRenderer11DeviceCaps.B4G4R4A4support = 0;
+ }
+
+ hr = mDevice->CheckFormatSupport(DXGI_FORMAT_B5G5R5A1_UNORM, &(mRenderer11DeviceCaps.B5G5R5A1support));
+ if (FAILED(hr))
+ {
+ mRenderer11DeviceCaps.B5G5R5A1support = 0;
+ }
+
+#if defined(ANGLE_ENABLE_D3D11_1)
+ IDXGIAdapter2 *dxgiAdapter2 = d3d11::DynamicCastComObject<IDXGIAdapter2>(mDxgiAdapter);
+ mRenderer11DeviceCaps.supportsDXGI1_2 = (dxgiAdapter2 != nullptr);
+ SafeRelease(dxgiAdapter2);
+#endif
}
egl::ConfigSet Renderer11::generateConfigs() const
{
- static const GLenum colorBufferFormats[] =
+ std::vector<GLenum> colorBufferFormats;
+
+ // 32-bit supported formats
+ colorBufferFormats.push_back(GL_BGRA8_EXT);
+ colorBufferFormats.push_back(GL_RGBA8_OES);
+
+ // 24-bit supported formats
+ colorBufferFormats.push_back(GL_RGB8_OES);
+
+ if (!mPresentPathFastEnabled)
{
- GL_BGRA8_EXT,
- GL_RGBA8_OES,
- };
+ // 16-bit supported formats
+ // These aren't valid D3D11 swapchain formats, so don't expose them as configs
+ // if present path fast is active
+ colorBufferFormats.push_back(GL_RGBA4);
+ colorBufferFormats.push_back(GL_RGB5_A1);
+ colorBufferFormats.push_back(GL_RGB565);
+ }
static const GLenum depthStencilBufferFormats[] =
{
@@ -637,64 +940,87 @@ egl::ConfigSet Renderer11::generateConfigs() const
const gl::Caps &rendererCaps = getRendererCaps();
const gl::TextureCapsMap &rendererTextureCaps = getRendererTextureCaps();
+ const EGLint optimalSurfaceOrientation =
+ mPresentPathFastEnabled ? 0 : EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE;
+
egl::ConfigSet configs;
- for (size_t formatIndex = 0; formatIndex < ArraySize(colorBufferFormats); formatIndex++)
+ for (GLenum colorBufferInternalFormat : colorBufferFormats)
{
- GLenum colorBufferInternalFormat = colorBufferFormats[formatIndex];
const gl::TextureCaps &colorBufferFormatCaps = rendererTextureCaps.get(colorBufferInternalFormat);
- if (colorBufferFormatCaps.renderable)
+ if (!colorBufferFormatCaps.renderable)
{
- for (size_t depthStencilIndex = 0; depthStencilIndex < ArraySize(depthStencilBufferFormats); depthStencilIndex++)
+ continue;
+ }
+
+ for (GLenum depthStencilBufferInternalFormat : depthStencilBufferFormats)
+ {
+ const gl::TextureCaps &depthStencilBufferFormatCaps =
+ rendererTextureCaps.get(depthStencilBufferInternalFormat);
+ if (!depthStencilBufferFormatCaps.renderable &&
+ depthStencilBufferInternalFormat != GL_NONE)
{
- GLenum depthStencilBufferInternalFormat = depthStencilBufferFormats[depthStencilIndex];
- const gl::TextureCaps &depthStencilBufferFormatCaps = rendererTextureCaps.get(depthStencilBufferInternalFormat);
- if (depthStencilBufferFormatCaps.renderable || depthStencilBufferInternalFormat == GL_NONE)
- {
- const gl::InternalFormat &colorBufferFormatInfo = gl::GetInternalFormatInfo(colorBufferInternalFormat);
- const gl::InternalFormat &depthStencilBufferFormatInfo = gl::GetInternalFormatInfo(depthStencilBufferInternalFormat);
-
- egl::Config config;
- config.renderTargetFormat = colorBufferInternalFormat;
- config.depthStencilFormat = depthStencilBufferInternalFormat;
- config.bufferSize = colorBufferFormatInfo.pixelBytes * 8;
- config.redSize = colorBufferFormatInfo.redBits;
- config.greenSize = colorBufferFormatInfo.greenBits;
- config.blueSize = colorBufferFormatInfo.blueBits;
- config.luminanceSize = colorBufferFormatInfo.luminanceBits;
- config.alphaSize = colorBufferFormatInfo.alphaBits;
- config.alphaMaskSize = 0;
- config.bindToTextureRGB = (colorBufferFormatInfo.format == GL_RGB);
- config.bindToTextureRGBA = (colorBufferFormatInfo.format == GL_RGBA || colorBufferFormatInfo.format == GL_BGRA_EXT);
- config.colorBufferType = EGL_RGB_BUFFER;
- config.configID = static_cast<EGLint>(configs.size() + 1);
- // Can only support a conformant ES2 with feature level greater than 10.0.
- config.conformant = (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) ? (EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT_KHR) : EGL_NONE;
- config.configCaveat = config.conformant == EGL_NONE ? EGL_NON_CONFORMANT_CONFIG : EGL_NONE;
- config.depthSize = depthStencilBufferFormatInfo.depthBits;
- config.level = 0;
- config.matchNativePixmap = EGL_NONE;
- config.maxPBufferWidth = rendererCaps.max2DTextureSize;
- config.maxPBufferHeight = rendererCaps.max2DTextureSize;
- config.maxPBufferPixels = rendererCaps.max2DTextureSize * rendererCaps.max2DTextureSize;
- config.maxSwapInterval = 4;
- config.minSwapInterval = 0;
- config.nativeRenderable = EGL_FALSE;
- config.nativeVisualID = 0;
- config.nativeVisualType = EGL_NONE;
- // Can't support ES3 at all without feature level 10.0
- config.renderableType = EGL_OPENGL_ES2_BIT | ((mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) ? EGL_OPENGL_ES3_BIT_KHR : 0);
- config.sampleBuffers = 0; // FIXME: enumerate multi-sampling
- config.samples = 0;
- config.stencilSize = depthStencilBufferFormatInfo.stencilBits;
- config.surfaceType = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
- config.transparentType = EGL_NONE;
- config.transparentRedValue = 0;
- config.transparentGreenValue = 0;
- config.transparentBlueValue = 0;
-
- configs.add(config);
- }
+ continue;
+ }
+
+ const gl::InternalFormat &colorBufferFormatInfo =
+ gl::GetInternalFormatInfo(colorBufferInternalFormat);
+ const gl::InternalFormat &depthStencilBufferFormatInfo =
+ gl::GetInternalFormatInfo(depthStencilBufferInternalFormat);
+
+ egl::Config config;
+ config.renderTargetFormat = colorBufferInternalFormat;
+ config.depthStencilFormat = depthStencilBufferInternalFormat;
+ config.bufferSize = colorBufferFormatInfo.pixelBytes * 8;
+ config.redSize = colorBufferFormatInfo.redBits;
+ config.greenSize = colorBufferFormatInfo.greenBits;
+ config.blueSize = colorBufferFormatInfo.blueBits;
+ config.luminanceSize = colorBufferFormatInfo.luminanceBits;
+ config.alphaSize = colorBufferFormatInfo.alphaBits;
+ config.alphaMaskSize = 0;
+ config.bindToTextureRGB = (colorBufferFormatInfo.format == GL_RGB);
+ config.bindToTextureRGBA = (colorBufferFormatInfo.format == GL_RGBA ||
+ colorBufferFormatInfo.format == GL_BGRA_EXT);
+ config.colorBufferType = EGL_RGB_BUFFER;
+ config.configID = static_cast<EGLint>(configs.size() + 1);
+ // Can only support a conformant ES2 with feature level greater than 10.0.
+ config.conformant = (mRenderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0)
+ ? (EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT_KHR)
+ : 0;
+ config.configCaveat = config.conformant == EGL_NONE ? EGL_NON_CONFORMANT_CONFIG : EGL_NONE;
+
+ // PresentPathFast may not be conformant
+ if (mPresentPathFastEnabled)
+ {
+ config.conformant = 0;
}
+
+ config.depthSize = depthStencilBufferFormatInfo.depthBits;
+ config.level = 0;
+ config.matchNativePixmap = EGL_NONE;
+ config.maxPBufferWidth = rendererCaps.max2DTextureSize;
+ config.maxPBufferHeight = rendererCaps.max2DTextureSize;
+ config.maxPBufferPixels = rendererCaps.max2DTextureSize * rendererCaps.max2DTextureSize;
+ config.maxSwapInterval = 4;
+ config.minSwapInterval = 0;
+ config.nativeRenderable = EGL_FALSE;
+ config.nativeVisualID = 0;
+ config.nativeVisualType = EGL_NONE;
+ // Can't support ES3 at all without feature level 10.0
+ config.renderableType =
+ EGL_OPENGL_ES2_BIT | ((mRenderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0)
+ ? EGL_OPENGL_ES3_BIT_KHR
+ : 0);
+ config.sampleBuffers = 0; // FIXME: enumerate multi-sampling
+ config.samples = 0;
+ config.stencilSize = depthStencilBufferFormatInfo.stencilBits;
+ config.surfaceType = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
+ config.transparentType = EGL_NONE;
+ config.transparentRedValue = 0;
+ config.transparentGreenValue = 0;
+ config.transparentBlueValue = 0;
+ config.optimalOrientation = optimalSurfaceOrientation;
+
+ configs.add(config);
}
}
@@ -702,6 +1028,42 @@ egl::ConfigSet Renderer11::generateConfigs() const
return configs;
}
+void Renderer11::generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const
+{
+ outExtensions->createContextRobustness = true;
+
+ if (getShareHandleSupport())
+ {
+ outExtensions->d3dShareHandleClientBuffer = true;
+ outExtensions->surfaceD3DTexture2DShareHandle = true;
+ }
+
+ outExtensions->keyedMutex = true;
+ outExtensions->querySurfacePointer = true;
+ outExtensions->windowFixedSize = true;
+
+ // If present path fast is active then the surface orientation extension isn't supported
+ outExtensions->surfaceOrientation = !mPresentPathFastEnabled;
+
+ // D3D11 does not support present with dirty rectangles until DXGI 1.2.
+ outExtensions->postSubBuffer = mRenderer11DeviceCaps.supportsDXGI1_2;
+
+ outExtensions->createContext = true;
+
+ outExtensions->deviceQuery = true;
+
+ outExtensions->createContextNoError = true;
+
+ outExtensions->image = true;
+ outExtensions->imageBase = true;
+ outExtensions->glTexture2DImage = true;
+ outExtensions->glTextureCubemapImage = true;
+ outExtensions->glRenderbufferImage = true;
+
+ outExtensions->flexibleSurfaceCompatibility = true;
+ outExtensions->directComposition = !!mDCompModule;
+}
+
gl::Error Renderer11::flush()
{
mDeviceContext->Flush();
@@ -751,9 +1113,31 @@ gl::Error Renderer11::finish()
return gl::Error(GL_NO_ERROR);
}
-SwapChainD3D *Renderer11::createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
+SwapChainD3D *Renderer11::createSwapChain(NativeWindow nativeWindow,
+ HANDLE shareHandle,
+ GLenum backBufferFormat,
+ GLenum depthBufferFormat,
+ EGLint orientation)
+{
+ return new SwapChain11(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat,
+ orientation);
+}
+
+CompilerImpl *Renderer11::createCompiler()
+{
+ if (mRenderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3)
+ {
+ return new CompilerD3D(SH_HLSL_4_0_FL9_3_OUTPUT);
+ }
+ else
+ {
+ return new CompilerD3D(SH_HLSL_4_1_OUTPUT);
+ }
+}
+
+void *Renderer11::getD3DDevice()
{
- return new SwapChain11(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat);
+ return reinterpret_cast<void*>(mDevice);
}
gl::Error Renderer11::generateSwizzle(gl::Texture *texture)
@@ -772,11 +1156,11 @@ gl::Error Renderer11::generateSwizzle(gl::Texture *texture)
if (texStorage)
{
- TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage);
- error = storage11->generateSwizzles(texture->getSamplerState().swizzleRed,
- texture->getSamplerState().swizzleGreen,
- texture->getSamplerState().swizzleBlue,
- texture->getSamplerState().swizzleAlpha);
+ TextureStorage11 *storage11 = GetAs<TextureStorage11>(texStorage);
+ const gl::TextureState &textureState = texture->getTextureState();
+ error =
+ storage11->generateSwizzles(textureState.swizzleRed, textureState.swizzleGreen,
+ textureState.swizzleBlue, textureState.swizzleAlpha);
if (error.isError())
{
return error;
@@ -787,11 +1171,13 @@ gl::Error Renderer11::generateSwizzle(gl::Texture *texture)
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &samplerStateParam)
+gl::Error Renderer11::setSamplerState(gl::SamplerType type,
+ int index,
+ gl::Texture *texture,
+ const gl::SamplerState &samplerState)
{
// Make sure to add the level offset for our tiny compressed texture workaround
TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture);
- gl::SamplerState samplerStateInternal = samplerStateParam;
TextureStorage *storage = nullptr;
gl::Error error = textureD3D->getNativeTexture(&storage);
@@ -803,16 +1189,15 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, gl::Textu
// Storage should exist, texture should be complete
ASSERT(storage);
- samplerStateInternal.baseLevel += storage->getTopLevel();
-
if (type == gl::SAMPLER_PIXEL)
{
ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits);
- if (mForceSetPixelSamplerStates[index] || memcmp(&samplerStateInternal, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0)
+ if (mForceSetPixelSamplerStates[index] ||
+ memcmp(&samplerState, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0)
{
ID3D11SamplerState *dxSamplerState = NULL;
- error = mStateCache.getSamplerState(samplerStateInternal, &dxSamplerState);
+ error = mStateCache.getSamplerState(samplerState, &dxSamplerState);
if (error.isError())
{
return error;
@@ -821,7 +1206,7 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, gl::Textu
ASSERT(dxSamplerState != NULL);
mDeviceContext->PSSetSamplers(index, 1, &dxSamplerState);
- mCurPixelSamplerStates[index] = samplerStateInternal;
+ mCurPixelSamplerStates[index] = samplerState;
}
mForceSetPixelSamplerStates[index] = false;
@@ -830,10 +1215,11 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, gl::Textu
{
ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits);
- if (mForceSetVertexSamplerStates[index] || memcmp(&samplerStateInternal, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0)
+ if (mForceSetVertexSamplerStates[index] ||
+ memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0)
{
ID3D11SamplerState *dxSamplerState = NULL;
- error = mStateCache.getSamplerState(samplerStateInternal, &dxSamplerState);
+ error = mStateCache.getSamplerState(samplerState, &dxSamplerState);
if (error.isError())
{
return error;
@@ -842,7 +1228,7 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, gl::Textu
ASSERT(dxSamplerState != NULL);
mDeviceContext->VSSetSamplers(index, 1, &dxSamplerState);
- mCurVertexSamplerStates[index] = samplerStateInternal;
+ mCurVertexSamplerStates[index] = samplerState;
}
mForceSetVertexSamplerStates[index] = false;
@@ -870,13 +1256,13 @@ gl::Error Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *t
// Texture should be complete and have a storage
ASSERT(texStorage);
- TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage);
+ TextureStorage11 *storage11 = GetAs<TextureStorage11>(texStorage);
// Make sure to add the level offset for our tiny compressed texture workaround
- gl::SamplerState samplerState = texture->getSamplerState();
- samplerState.baseLevel += storage11->getTopLevel();
+ gl::TextureState textureState = texture->getTextureState();
+ textureState.baseLevel += storage11->getTopLevel();
- error = storage11->getSRV(samplerState, &textureSRV);
+ error = storage11->getSRV(textureState, &textureSRV);
if (error.isError())
{
return error;
@@ -892,16 +1278,16 @@ gl::Error Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *t
ASSERT((type == gl::SAMPLER_PIXEL && static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits) ||
(type == gl::SAMPLER_VERTEX && static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits));
- setShaderResource(type, index, textureSRV);
+ mStateManager.setShaderResource(type, index, textureSRV);
return gl::Error(GL_NO_ERROR);
}
gl::Error Renderer11::setUniformBuffers(const gl::Data &data,
- const GLint vertexUniformBuffers[],
- const GLint fragmentUniformBuffers[])
+ const std::vector<GLint> &vertexUniformBuffers,
+ const std::vector<GLint> &fragmentUniformBuffers)
{
- for (unsigned int uniformBufferIndex = 0; uniformBufferIndex < data.caps->maxVertexUniformBlocks; uniformBufferIndex++)
+ for (size_t uniformBufferIndex = 0; uniformBufferIndex < vertexUniformBuffers.size(); uniformBufferIndex++)
{
GLint binding = vertexUniformBuffers[uniformBufferIndex];
@@ -910,14 +1296,24 @@ gl::Error Renderer11::setUniformBuffers(const gl::Data &data,
continue;
}
- gl::Buffer *uniformBuffer = data.state->getIndexedUniformBuffer(binding);
- GLintptr uniformBufferOffset = data.state->getIndexedUniformBufferOffset(binding);
- GLsizeiptr uniformBufferSize = data.state->getIndexedUniformBufferSize(binding);
+ const OffsetBindingPointer<gl::Buffer> &uniformBuffer =
+ data.state->getIndexedUniformBuffer(binding);
+ GLintptr uniformBufferOffset = uniformBuffer.getOffset();
+ GLsizeiptr uniformBufferSize = uniformBuffer.getSize();
- if (uniformBuffer)
+ if (uniformBuffer.get() != nullptr)
{
- Buffer11 *bufferStorage = Buffer11::makeBuffer11(uniformBuffer->getImplementation());
- ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM);
+ Buffer11 *bufferStorage = GetImplAs<Buffer11>(uniformBuffer.get());
+ ID3D11Buffer *constantBuffer;
+
+ if (mRenderer11DeviceCaps.supportsConstantBufferOffsets)
+ {
+ constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM);
+ }
+ else
+ {
+ constantBuffer = bufferStorage->getConstantBufferRange(uniformBufferOffset, uniformBufferSize);
+ }
if (!constantBuffer)
{
@@ -929,19 +1325,22 @@ gl::Error Renderer11::setUniformBuffers(const gl::Data &data,
mCurrentConstantBufferVSSize[uniformBufferIndex] != uniformBufferSize)
{
#if defined(ANGLE_ENABLE_D3D11_1)
- if (mSupportsConstantBufferOffsets && uniformBufferSize != 0)
+ if (mRenderer11DeviceCaps.supportsConstantBufferOffsets && uniformBufferSize != 0)
{
UINT firstConstant = 0, numConstants = 0;
CalculateConstantBufferParams(uniformBufferOffset, uniformBufferSize, &firstConstant, &numConstants);
- mDeviceContext1->VSSetConstantBuffers1(getReservedVertexUniformBuffers() + uniformBufferIndex,
- 1, &constantBuffer, &firstConstant, &numConstants);
+ mDeviceContext1->VSSetConstantBuffers1(
+ getReservedVertexUniformBuffers() +
+ static_cast<unsigned int>(uniformBufferIndex),
+ 1, &constantBuffer, &firstConstant, &numConstants);
}
else
#endif
{
- ASSERT(uniformBufferOffset == 0);
- mDeviceContext->VSSetConstantBuffers(getReservedVertexUniformBuffers() + uniformBufferIndex,
- 1, &constantBuffer);
+ mDeviceContext->VSSetConstantBuffers(
+ getReservedVertexUniformBuffers() +
+ static_cast<unsigned int>(uniformBufferIndex),
+ 1, &constantBuffer);
}
mCurrentConstantBufferVS[uniformBufferIndex] = bufferStorage->getSerial();
@@ -951,7 +1350,7 @@ gl::Error Renderer11::setUniformBuffers(const gl::Data &data,
}
}
- for (unsigned int uniformBufferIndex = 0; uniformBufferIndex < data.caps->maxFragmentUniformBlocks; uniformBufferIndex++)
+ for (size_t uniformBufferIndex = 0; uniformBufferIndex < fragmentUniformBuffers.size(); uniformBufferIndex++)
{
GLint binding = fragmentUniformBuffers[uniformBufferIndex];
@@ -960,14 +1359,24 @@ gl::Error Renderer11::setUniformBuffers(const gl::Data &data,
continue;
}
- gl::Buffer *uniformBuffer = data.state->getIndexedUniformBuffer(binding);
- GLintptr uniformBufferOffset = data.state->getIndexedUniformBufferOffset(binding);
- GLsizeiptr uniformBufferSize = data.state->getIndexedUniformBufferSize(binding);
+ const OffsetBindingPointer<gl::Buffer> &uniformBuffer =
+ data.state->getIndexedUniformBuffer(binding);
+ GLintptr uniformBufferOffset = uniformBuffer.getOffset();
+ GLsizeiptr uniformBufferSize = uniformBuffer.getSize();
- if (uniformBuffer)
+ if (uniformBuffer.get() != nullptr)
{
- Buffer11 *bufferStorage = Buffer11::makeBuffer11(uniformBuffer->getImplementation());
- ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM);
+ Buffer11 *bufferStorage = GetImplAs<Buffer11>(uniformBuffer.get());
+ ID3D11Buffer *constantBuffer;
+
+ if (mRenderer11DeviceCaps.supportsConstantBufferOffsets)
+ {
+ constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM);
+ }
+ else
+ {
+ constantBuffer = bufferStorage->getConstantBufferRange(uniformBufferOffset, uniformBufferSize);
+ }
if (!constantBuffer)
{
@@ -979,19 +1388,22 @@ gl::Error Renderer11::setUniformBuffers(const gl::Data &data,
mCurrentConstantBufferPSSize[uniformBufferIndex] != uniformBufferSize)
{
#if defined(ANGLE_ENABLE_D3D11_1)
- if (mSupportsConstantBufferOffsets && uniformBufferSize != 0)
+ if (mRenderer11DeviceCaps.supportsConstantBufferOffsets && uniformBufferSize != 0)
{
UINT firstConstant = 0, numConstants = 0;
CalculateConstantBufferParams(uniformBufferOffset, uniformBufferSize, &firstConstant, &numConstants);
- mDeviceContext1->PSSetConstantBuffers1(getReservedFragmentUniformBuffers() + uniformBufferIndex,
- 1, &constantBuffer, &firstConstant, &numConstants);
+ mDeviceContext1->PSSetConstantBuffers1(
+ getReservedFragmentUniformBuffers() +
+ static_cast<unsigned int>(uniformBufferIndex),
+ 1, &constantBuffer, &firstConstant, &numConstants);
}
else
#endif
{
- ASSERT(uniformBufferOffset == 0);
- mDeviceContext->PSSetConstantBuffers(getReservedFragmentUniformBuffers() + uniformBufferIndex,
- 1, &constantBuffer);
+ mDeviceContext->PSSetConstantBuffers(
+ getReservedFragmentUniformBuffers() +
+ static_cast<unsigned int>(uniformBufferIndex),
+ 1, &constantBuffer);
}
mCurrentConstantBufferPS[uniformBufferIndex] = bufferStorage->getSerial();
@@ -1004,229 +1416,60 @@ gl::Error Renderer11::setUniformBuffers(const gl::Data &data,
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::setRasterizerState(const gl::RasterizerState &rasterState)
+gl::Error Renderer11::updateState(const gl::Data &data, GLenum drawMode)
{
- if (mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0)
+ // Applies the render target surface, depth stencil surface, viewport rectangle and
+ // scissor rectangle to the renderer
+ const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer();
+ ASSERT(framebufferObject && framebufferObject->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE);
+ gl::Error error = applyRenderTarget(framebufferObject);
+ if (error.isError())
{
- ID3D11RasterizerState *dxRasterState = NULL;
- gl::Error error = mStateCache.getRasterizerState(rasterState, mScissorEnabled, &dxRasterState);
- if (error.isError())
- {
- return error;
- }
-
- mDeviceContext->RSSetState(dxRasterState);
-
- mCurRasterState = rasterState;
+ return error;
}
- mForceSetRasterState = false;
+ // Set the present path state
+ const bool presentPathFastActive =
+ UsePresentPathFast(this, framebufferObject->getFirstColorbuffer());
+ mStateManager.updatePresentPath(presentPathFastActive,
+ framebufferObject->getFirstColorbuffer());
- return gl::Error(GL_NO_ERROR);
-}
+ // Setting viewport state
+ mStateManager.setViewport(data.caps, data.state->getViewport(), data.state->getNearPlane(),
+ data.state->getFarPlane());
-gl::Error Renderer11::setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
- unsigned int sampleMask)
-{
- if (mForceSetBlendState ||
- memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0 ||
- memcmp(&blendColor, &mCurBlendColor, sizeof(gl::ColorF)) != 0 ||
- sampleMask != mCurSampleMask)
- {
- ID3D11BlendState *dxBlendState = NULL;
- gl::Error error = mStateCache.getBlendState(framebuffer, blendState, &dxBlendState);
- if (error.isError())
- {
- return error;
- }
-
- ASSERT(dxBlendState != NULL);
-
- float blendColors[4] = {0.0f};
- if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA && blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA &&
- blendState.destBlendRGB != GL_CONSTANT_ALPHA && blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA)
- {
- blendColors[0] = blendColor.red;
- blendColors[1] = blendColor.green;
- blendColors[2] = blendColor.blue;
- blendColors[3] = blendColor.alpha;
- }
- else
- {
- blendColors[0] = blendColor.alpha;
- blendColors[1] = blendColor.alpha;
- blendColors[2] = blendColor.alpha;
- blendColors[3] = blendColor.alpha;
- }
-
- mDeviceContext->OMSetBlendState(dxBlendState, blendColors, sampleMask);
-
- mCurBlendState = blendState;
- mCurBlendColor = blendColor;
- mCurSampleMask = sampleMask;
- }
+ // Setting scissor state
+ mStateManager.setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled());
- mForceSetBlendState = false;
+ // Applying rasterizer state to D3D11 device
+ int samples = framebufferObject->getSamples(data);
+ gl::RasterizerState rasterizer = data.state->getRasterizerState();
+ rasterizer.pointDrawMode = (drawMode == GL_POINTS);
+ rasterizer.multiSample = (samples != 0);
- return gl::Error(GL_NO_ERROR);
-}
-
-gl::Error Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
- int stencilBackRef, bool frontFaceCCW)
-{
- if (mForceSetDepthStencilState ||
- memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0 ||
- stencilRef != mCurStencilRef || stencilBackRef != mCurStencilBackRef)
+ error = mStateManager.setRasterizerState(rasterizer);
+ if (error.isError())
{
- ASSERT(depthStencilState.stencilWritemask == depthStencilState.stencilBackWritemask);
- ASSERT(stencilRef == stencilBackRef);
- ASSERT(depthStencilState.stencilMask == depthStencilState.stencilBackMask);
-
- ID3D11DepthStencilState *dxDepthStencilState = NULL;
- gl::Error error = mStateCache.getDepthStencilState(depthStencilState, &dxDepthStencilState);
- if (error.isError())
- {
- return error;
- }
-
- ASSERT(dxDepthStencilState);
-
- // Max D3D11 stencil reference value is 0xFF, corresponding to the max 8 bits in a stencil buffer
- // GL specifies we should clamp the ref value to the nearest bit depth when doing stencil ops
- static_assert(D3D11_DEFAULT_STENCIL_READ_MASK == 0xFF, "Unexpected value of D3D11_DEFAULT_STENCIL_READ_MASK");
- static_assert(D3D11_DEFAULT_STENCIL_WRITE_MASK == 0xFF, "Unexpected value of D3D11_DEFAULT_STENCIL_WRITE_MASK");
- UINT dxStencilRef = std::min<UINT>(stencilRef, 0xFFu);
-
- mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, dxStencilRef);
-
- mCurDepthStencilState = depthStencilState;
- mCurStencilRef = stencilRef;
- mCurStencilBackRef = stencilBackRef;
+ return error;
}
- mForceSetDepthStencilState = false;
-
- return gl::Error(GL_NO_ERROR);
-}
-
-void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
-{
- if (mForceSetScissor || memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 ||
- enabled != mScissorEnabled)
+ // Setting blend state
+ unsigned int mask = GetBlendSampleMask(data, samples);
+ error = mStateManager.setBlendState(framebufferObject, data.state->getBlendState(),
+ data.state->getBlendColor(), mask);
+ if (error.isError())
{
- if (enabled)
- {
- D3D11_RECT rect;
- rect.left = std::max(0, scissor.x);
- rect.top = std::max(0, scissor.y);
- rect.right = scissor.x + std::max(0, scissor.width);
- rect.bottom = scissor.y + std::max(0, scissor.height);
-
- mDeviceContext->RSSetScissorRects(1, &rect);
- }
-
- if (enabled != mScissorEnabled)
- {
- mForceSetRasterState = true;
- }
-
- mCurScissor = scissor;
- mScissorEnabled = enabled;
+ return error;
}
- mForceSetScissor = false;
+ // Setting depth stencil state
+ error = mStateManager.setDepthStencilState(*data.state);
+ return error;
}
-void Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
- bool ignoreViewport)
+void Renderer11::syncState(const gl::State &state, const gl::State::DirtyBits &bitmask)
{
- gl::Rectangle actualViewport = viewport;
- float actualZNear = gl::clamp01(zNear);
- float actualZFar = gl::clamp01(zFar);
- if (ignoreViewport)
- {
- actualViewport.x = 0;
- actualViewport.y = 0;
- actualViewport.width = mRenderTargetDesc.width;
- actualViewport.height = mRenderTargetDesc.height;
- actualZNear = 0.0f;
- actualZFar = 1.0f;
- }
-
- bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 ||
- actualZNear != mCurNear || actualZFar != mCurFar;
-
- if (viewportChanged)
- {
- const gl::Caps& caps = getRendererCaps();
-
- int dxMaxViewportBoundsX = static_cast<int>(caps.maxViewportWidth);
- int dxMaxViewportBoundsY = static_cast<int>(caps.maxViewportHeight);
- int dxMinViewportBoundsX = -dxMaxViewportBoundsX;
- int dxMinViewportBoundsY = -dxMaxViewportBoundsY;
-
- if (mFeatureLevel <= D3D_FEATURE_LEVEL_9_3)
- {
- // Feature Level 9 viewports shouldn't exceed the dimensions of the rendertarget.
- dxMaxViewportBoundsX = mRenderTargetDesc.width;
- dxMaxViewportBoundsY = mRenderTargetDesc.height;
- dxMinViewportBoundsX = 0;
- dxMinViewportBoundsY = 0;
- }
-
- int dxViewportTopLeftX = gl::clamp(actualViewport.x, dxMinViewportBoundsX, dxMaxViewportBoundsX);
- int dxViewportTopLeftY = gl::clamp(actualViewport.y, dxMinViewportBoundsY, dxMaxViewportBoundsY);
- int dxViewportWidth = gl::clamp(actualViewport.width, 0, dxMaxViewportBoundsX - dxViewportTopLeftX);
- int dxViewportHeight = gl::clamp(actualViewport.height, 0, dxMaxViewportBoundsY - dxViewportTopLeftY);
-
- D3D11_VIEWPORT dxViewport;
- dxViewport.TopLeftX = static_cast<float>(dxViewportTopLeftX);
- dxViewport.TopLeftY = static_cast<float>(dxViewportTopLeftY);
- dxViewport.Width = static_cast<float>(dxViewportWidth);
- dxViewport.Height = static_cast<float>(dxViewportHeight);
- dxViewport.MinDepth = actualZNear;
- dxViewport.MaxDepth = actualZFar;
-
- mDeviceContext->RSSetViewports(1, &dxViewport);
-
- mCurViewport = actualViewport;
- mCurNear = actualZNear;
- mCurFar = actualZFar;
-
- // On Feature Level 9_*, we must emulate large and/or negative viewports in the shaders using viewAdjust (like the D3D9 renderer).
- if (mFeatureLevel <= D3D_FEATURE_LEVEL_9_3)
- {
- mVertexConstants.viewAdjust[0] = static_cast<float>((actualViewport.width - dxViewportWidth) + 2 * (actualViewport.x - dxViewportTopLeftX)) / dxViewport.Width;
- mVertexConstants.viewAdjust[1] = static_cast<float>((actualViewport.height - dxViewportHeight) + 2 * (actualViewport.y - dxViewportTopLeftY)) / dxViewport.Height;
- mVertexConstants.viewAdjust[2] = static_cast<float>(actualViewport.width) / dxViewport.Width;
- mVertexConstants.viewAdjust[3] = static_cast<float>(actualViewport.height) / dxViewport.Height;
- }
-
- mPixelConstants.viewCoords[0] = actualViewport.width * 0.5f;
- mPixelConstants.viewCoords[1] = actualViewport.height * 0.5f;
- mPixelConstants.viewCoords[2] = actualViewport.x + (actualViewport.width * 0.5f);
- mPixelConstants.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f);
-
- // Instanced pointsprite emulation requires ViewCoords to be defined in the
- // the vertex shader.
- mVertexConstants.viewCoords[0] = mPixelConstants.viewCoords[0];
- mVertexConstants.viewCoords[1] = mPixelConstants.viewCoords[1];
- mVertexConstants.viewCoords[2] = mPixelConstants.viewCoords[2];
- mVertexConstants.viewCoords[3] = mPixelConstants.viewCoords[3];
-
- mPixelConstants.depthFront[0] = (actualZFar - actualZNear) * 0.5f;
- mPixelConstants.depthFront[1] = (actualZNear + actualZFar) * 0.5f;
-
- mVertexConstants.depthRange[0] = actualZNear;
- mVertexConstants.depthRange[1] = actualZFar;
- mVertexConstants.depthRange[2] = actualZFar - actualZNear;
-
- mPixelConstants.depthRange[0] = actualZNear;
- mPixelConstants.depthRange[1] = actualZFar;
- mPixelConstants.depthRange[2] = actualZFar - actualZNear;
- }
-
- mForceSetViewport = false;
+ mStateManager.syncState(state, bitmask);
}
bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize)
@@ -1267,176 +1510,51 @@ bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSi
return count >= minCount;
}
-void Renderer11::unsetConflictingSRVs(gl::SamplerType samplerType, uintptr_t resource, const gl::ImageIndex *index)
+gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer)
{
- auto &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
-
- for (size_t resourceIndex = 0; resourceIndex < currentSRVs.size(); ++resourceIndex)
- {
- auto &record = currentSRVs[resourceIndex];
-
- if (record.srv && record.resource == resource && ImageIndexConflictsWithSRV(index, record.desc))
- {
- setShaderResource(samplerType, static_cast<UINT>(resourceIndex), NULL);
- }
- }
+ return mStateManager.syncFramebuffer(framebuffer);
}
-gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer)
+gl::Error Renderer11::applyVertexBuffer(const gl::State &state,
+ GLenum mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instances,
+ TranslatedIndexData *indexInfo)
{
- // Get the color render buffer and serial
- // Also extract the render target dimensions and view
- unsigned int renderTargetWidth = 0;
- unsigned int renderTargetHeight = 0;
- DXGI_FORMAT renderTargetFormat = DXGI_FORMAT_UNKNOWN;
- ID3D11RenderTargetView* framebufferRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL};
- bool missingColorRenderTarget = true;
-
- const FramebufferD3D *framebufferD3D = GetImplAs<FramebufferD3D>(framebuffer);
- const gl::AttachmentList &colorbuffers = framebufferD3D->getColorAttachmentsForRender(getWorkarounds());
-
- for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
- {
- gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment];
-
- if (colorbuffer)
- {
- // the draw buffer must be either "none", "back" for the default buffer or the same index as this color (in order)
-
- // check for zero-sized default framebuffer, which is a special case.
- // in this case we do not wish to modify any state and just silently return false.
- // this will not report any gl error but will cause the calling method to return.
- if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
- {
- return gl::Error(GL_NO_ERROR);
- }
-
- // Extract the render target dimensions and view
- RenderTarget11 *renderTarget = NULL;
- gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &renderTarget);
- if (error.isError())
- {
- return error;
- }
- ASSERT(renderTarget);
-
- framebufferRTVs[colorAttachment] = renderTarget->getRenderTargetView();
- ASSERT(framebufferRTVs[colorAttachment]);
-
- if (missingColorRenderTarget)
- {
- renderTargetWidth = renderTarget->getWidth();
- renderTargetHeight = renderTarget->getHeight();
- renderTargetFormat = renderTarget->getDXGIFormat();
- missingColorRenderTarget = false;
- }
-
- // Unbind render target SRVs from the shader here to prevent D3D11 warnings.
- if (colorbuffer->type() == GL_TEXTURE)
- {
- uintptr_t rtResource = reinterpret_cast<uintptr_t>(GetViewResource(framebufferRTVs[colorAttachment]));
- const gl::ImageIndex *index = colorbuffer->getTextureImageIndex();
- ASSERT(index);
- // The index doesn't need to be corrected for the small compressed texture workaround
- // because a rendertarget is never compressed.
- unsetConflictingSRVs(gl::SAMPLER_VERTEX, rtResource, index);
- unsetConflictingSRVs(gl::SAMPLER_PIXEL, rtResource, index);
- }
- }
- }
-
- // Get the depth stencil buffers
- ID3D11DepthStencilView* framebufferDSV = NULL;
- gl::FramebufferAttachment *depthStencil = framebuffer->getDepthOrStencilbuffer();
- if (depthStencil)
- {
- RenderTarget11 *depthStencilRenderTarget = NULL;
- gl::Error error = d3d11::GetAttachmentRenderTarget(depthStencil, &depthStencilRenderTarget);
- if (error.isError())
- {
- SafeRelease(framebufferRTVs);
- return error;
- }
- ASSERT(depthStencilRenderTarget);
-
- framebufferDSV = depthStencilRenderTarget->getDepthStencilView();
- ASSERT(framebufferDSV);
-
- // If there is no render buffer, the width, height and format values come from
- // the depth stencil
- if (missingColorRenderTarget)
- {
- renderTargetWidth = depthStencilRenderTarget->getWidth();
- renderTargetHeight = depthStencilRenderTarget->getHeight();
- renderTargetFormat = depthStencilRenderTarget->getDXGIFormat();
- }
-
- // Unbind render target SRVs from the shader here to prevent D3D11 warnings.
- if (depthStencil->type() == GL_TEXTURE)
- {
- uintptr_t depthStencilResource = reinterpret_cast<uintptr_t>(GetViewResource(framebufferDSV));
- const gl::ImageIndex *index = depthStencil->getTextureImageIndex();
- ASSERT(index);
- // The index doesn't need to be corrected for the small compressed texture workaround
- // because a rendertarget is never compressed.
- unsetConflictingSRVs(gl::SAMPLER_VERTEX, depthStencilResource, index);
- unsetConflictingSRVs(gl::SAMPLER_PIXEL, depthStencilResource, index);
- }
- }
-
- // Apply the render target and depth stencil
- if (!mRenderTargetDescInitialized || !mDepthStencilInitialized ||
- memcmp(framebufferRTVs, mAppliedRTVs, sizeof(framebufferRTVs)) != 0 ||
- reinterpret_cast<uintptr_t>(framebufferDSV) != mAppliedDSV)
- {
- mDeviceContext->OMSetRenderTargets(getRendererCaps().maxDrawBuffers, framebufferRTVs, framebufferDSV);
-
- mRenderTargetDesc.width = renderTargetWidth;
- mRenderTargetDesc.height = renderTargetHeight;
- mRenderTargetDesc.format = renderTargetFormat;
- mForceSetViewport = true;
- mForceSetScissor = true;
- mForceSetBlendState = true;
-
- if (!mDepthStencilInitialized)
- {
- mForceSetRasterState = true;
- }
-
- for (size_t rtIndex = 0; rtIndex < ArraySize(framebufferRTVs); rtIndex++)
- {
- mAppliedRTVs[rtIndex] = reinterpret_cast<uintptr_t>(framebufferRTVs[rtIndex]);
- }
- mAppliedDSV = reinterpret_cast<uintptr_t>(framebufferDSV);
- mRenderTargetDescInitialized = true;
- mDepthStencilInitialized = true;
- }
-
- const Framebuffer11 *framebuffer11 = GetImplAs<Framebuffer11>(framebuffer);
- gl::Error error = framebuffer11->invalidateSwizzles();
+ gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, &mTranslatedAttribCache, instances);
if (error.isError())
{
return error;
}
- return gl::Error(GL_NO_ERROR);
-}
-
-gl::Error Renderer11::applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances)
-{
- TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
- gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, attributes, instances);
- if (error.isError())
+ // If index information is passed, mark it with the current changed status.
+ if (indexInfo)
{
- return error;
+ indexInfo->srcIndexData.srcIndicesChanged = mAppliedIBChanged;
}
- return mInputLayoutCache.applyVertexBuffers(attributes, mode, state.getProgram());
+ GLsizei numIndicesPerInstance = 0;
+ if (instances > 0)
+ {
+ numIndicesPerInstance = count;
+ }
+ return mInputLayoutCache.applyVertexBuffers(mTranslatedAttribCache, mode, state.getProgram(),
+ indexInfo, numIndicesPerInstance);
}
-gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
+gl::Error Renderer11::applyIndexBuffer(const gl::Data &data,
+ const GLvoid *indices,
+ GLsizei count,
+ GLenum mode,
+ GLenum type,
+ TranslatedIndexData *indexInfo)
{
- gl::Error error = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo);
+ gl::VertexArray *vao = data.state->getVertexArray();
+ gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
+ gl::Error error =
+ mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo,
+ data.state->isPrimitiveRestartEnabled());
if (error.isError())
{
return error;
@@ -1447,15 +1565,16 @@ gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elemen
if (indexInfo->storage)
{
- Buffer11 *storage = Buffer11::makeBuffer11(indexInfo->storage);
+ Buffer11 *storage = GetAs<Buffer11>(indexInfo->storage);
buffer = storage->getBuffer(BUFFER_USAGE_INDEX);
}
else
{
- IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer);
+ IndexBuffer11* indexBuffer = GetAs<IndexBuffer11>(indexInfo->indexBuffer);
buffer = indexBuffer->getBuffer();
}
+ mAppliedIBChanged = false;
if (buffer != mAppliedIB || bufferFormat != mAppliedIBFormat || indexInfo->startOffset != mAppliedIBOffset)
{
mDeviceContext->IASetIndexBuffer(buffer, bufferFormat, indexInfo->startOffset);
@@ -1463,6 +1582,7 @@ gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elemen
mAppliedIB = buffer;
mAppliedIBFormat = bufferFormat;
mAppliedIBOffset = indexInfo->startOffset;
+ mAppliedIBChanged = true;
}
return gl::Error(GL_NO_ERROR);
@@ -1475,22 +1595,23 @@ void Renderer11::applyTransformFeedbackBuffers(const gl::State &state)
if (state.isTransformFeedbackActiveUnpaused())
{
- numXFBBindings = state.getTransformFeedbackBufferIndexRange();
+ const gl::TransformFeedback *transformFeedback = state.getCurrentTransformFeedback();
+ numXFBBindings = transformFeedback->getIndexedBufferCount();
ASSERT(numXFBBindings <= gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
for (size_t i = 0; i < numXFBBindings; i++)
{
- gl::Buffer *curXFBBuffer = state.getIndexedTransformFeedbackBuffer(i);
- GLintptr curXFBOffset = state.getIndexedTransformFeedbackBufferOffset(i);
+ const OffsetBindingPointer<gl::Buffer> &binding = transformFeedback->getIndexedBuffer(i);
+
ID3D11Buffer *d3dBuffer = NULL;
- if (curXFBBuffer)
+ if (binding.get() != nullptr)
{
- Buffer11 *storage = Buffer11::makeBuffer11(curXFBBuffer->getImplementation());
+ Buffer11 *storage = GetImplAs<Buffer11>(binding.get());
d3dBuffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
}
// TODO: mAppliedTFBuffers and friends should also be kept in a vector.
- if (d3dBuffer != mAppliedTFBuffers[i] || curXFBOffset != mAppliedTFOffsets[i])
+ if (d3dBuffer != mAppliedTFBuffers[i] || binding.getOffset() != mAppliedTFOffsets[i])
{
requiresUpdate = true;
}
@@ -1499,18 +1620,17 @@ void Renderer11::applyTransformFeedbackBuffers(const gl::State &state)
if (requiresUpdate || numXFBBindings != mAppliedNumXFBBindings)
{
+ const gl::TransformFeedback *transformFeedback = state.getCurrentTransformFeedback();
for (size_t i = 0; i < numXFBBindings; ++i)
{
- gl::Buffer *curXFBBuffer = state.getIndexedTransformFeedbackBuffer(i);
- GLintptr curXFBOffset = state.getIndexedTransformFeedbackBufferOffset(i);
-
- if (curXFBBuffer)
+ const OffsetBindingPointer<gl::Buffer> &binding = transformFeedback->getIndexedBuffer(i);
+ if (binding.get() != nullptr)
{
- Buffer11 *storage = Buffer11::makeBuffer11(curXFBBuffer->getImplementation());
+ Buffer11 *storage = GetImplAs<Buffer11>(binding.get());
ID3D11Buffer *d3dBuffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
- mCurrentD3DOffsets[i] = (mAppliedTFBuffers[i] != d3dBuffer || mAppliedTFOffsets[i] != curXFBOffset) ?
- static_cast<UINT>(curXFBOffset) : -1;
+ mCurrentD3DOffsets[i] = (mAppliedTFBuffers[i] != d3dBuffer || mAppliedTFOffsets[i] != binding.getOffset()) ?
+ static_cast<UINT>(binding.getOffset()) : -1;
mAppliedTFBuffers[i] = d3dBuffer;
}
else
@@ -1518,26 +1638,30 @@ void Renderer11::applyTransformFeedbackBuffers(const gl::State &state)
mAppliedTFBuffers[i] = NULL;
mCurrentD3DOffsets[i] = 0;
}
- mAppliedTFOffsets[i] = curXFBOffset;
+ mAppliedTFOffsets[i] = binding.getOffset();
}
mAppliedNumXFBBindings = numXFBBindings;
- mDeviceContext->SOSetTargets(numXFBBindings, mAppliedTFBuffers, mCurrentD3DOffsets);
+ mDeviceContext->SOSetTargets(static_cast<unsigned int>(numXFBBindings), mAppliedTFBuffers,
+ mCurrentD3DOffsets);
}
}
-gl::Error Renderer11::drawArrays(const gl::Data &data, GLenum mode, GLsizei count, GLsizei instances, bool usesPointSize)
+gl::Error Renderer11::drawArraysImpl(const gl::Data &data,
+ GLenum mode,
+ GLsizei count,
+ GLsizei instances)
{
- bool useInstancedPointSpriteEmulation = usesPointSize && getWorkarounds().useInstancedPointSpriteEmulation;
- if (mode == GL_POINTS && data.state->isTransformFeedbackActiveUnpaused())
- {
- // Since point sprites are generated with a geometry shader, too many vertices will
- // be written if transform feedback is active. To work around this, draw only the points
- // with the stream out shader and no pixel shader to feed the stream out buffers and then
- // draw again with the point sprite geometry shader to rasterize the point sprites.
+ ProgramD3D *programD3D = GetImplAs<ProgramD3D>(data.state->getProgram());
- mDeviceContext->PSSetShader(NULL, NULL, 0);
+ if (programD3D->usesGeometryShader(mode) && data.state->isTransformFeedbackActiveUnpaused())
+ {
+ // Since we use a geometry if-and-only-if we rewrite vertex streams, transform feedback
+ // won't get the correct output. To work around this, draw with *only* the stream out
+ // first (no pixel shader) to feed the stream out buffers and then draw again with the
+ // geometry shader + pixel shader to rasterize the primitives.
+ mDeviceContext->PSSetShader(nullptr, nullptr, 0);
if (instances > 0)
{
@@ -1548,98 +1672,192 @@ gl::Error Renderer11::drawArrays(const gl::Data &data, GLenum mode, GLsizei coun
mDeviceContext->Draw(count, 0);
}
- ProgramD3D *programD3D = GetImplAs<ProgramD3D>(data.state->getProgram());
-
- rx::ShaderExecutableD3D *pixelExe = NULL;
+ rx::ShaderExecutableD3D *pixelExe = nullptr;
gl::Error error = programD3D->getPixelExecutableForFramebuffer(data.state->getDrawFramebuffer(), &pixelExe);
if (error.isError())
{
return error;
}
- // Skip this step if we're doing rasterizer discard.
- if (pixelExe && !data.state->getRasterizerState().rasterizerDiscard && usesPointSize)
+ // Skip the draw call if rasterizer discard is enabled (or no fragment shader).
+ if (!pixelExe || data.state->getRasterizerState().rasterizerDiscard)
{
- ID3D11PixelShader *pixelShader = ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader();
- ASSERT(reinterpret_cast<uintptr_t>(pixelShader) == mAppliedPixelShader);
- mDeviceContext->PSSetShader(pixelShader, NULL, 0);
+ return gl::Error(GL_NO_ERROR);
+ }
- // Retrieve the point sprite geometry shader
- rx::ShaderExecutableD3D *geometryExe = programD3D->getGeometryExecutable();
- ID3D11GeometryShader *geometryShader = (geometryExe ? ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader() : NULL);
- mAppliedGeometryShader = reinterpret_cast<uintptr_t>(geometryShader);
- ASSERT(geometryShader);
- mDeviceContext->GSSetShader(geometryShader, NULL, 0);
+ ID3D11PixelShader *pixelShader = GetAs<ShaderExecutable11>(pixelExe)->getPixelShader();
+ ASSERT(reinterpret_cast<uintptr_t>(pixelShader) == mAppliedPixelShader);
+ mDeviceContext->PSSetShader(pixelShader, NULL, 0);
- if (instances > 0)
- {
- mDeviceContext->DrawInstanced(count, instances, 0, 0);
- }
- else
- {
- mDeviceContext->Draw(count, 0);
- }
+ // Retrieve the geometry shader.
+ rx::ShaderExecutableD3D *geometryExe = nullptr;
+ error =
+ programD3D->getGeometryExecutableForPrimitiveType(data, mode, &geometryExe, nullptr);
+ if (error.isError())
+ {
+ return error;
}
+ ID3D11GeometryShader *geometryShader =
+ (geometryExe ? GetAs<ShaderExecutable11>(geometryExe)->getGeometryShader() : NULL);
+ mAppliedGeometryShader = reinterpret_cast<uintptr_t>(geometryShader);
+ ASSERT(geometryShader);
+ mDeviceContext->GSSetShader(geometryShader, NULL, 0);
+
+ if (instances > 0)
+ {
+ mDeviceContext->DrawInstanced(count, instances, 0, 0);
+ }
+ else
+ {
+ mDeviceContext->Draw(count, 0);
+ }
return gl::Error(GL_NO_ERROR);
}
- else if (mode == GL_LINE_LOOP)
- {
- return drawLineLoop(count, GL_NONE, NULL, 0, NULL);
- }
- else if (mode == GL_TRIANGLE_FAN)
+
+ if (mode == GL_LINE_LOOP)
{
- return drawTriangleFan(count, GL_NONE, NULL, 0, NULL, instances);
+ return drawLineLoop(data, count, GL_NONE, nullptr, nullptr, instances);
}
- else if (instances > 0)
+
+ if (mode == GL_TRIANGLE_FAN)
{
- mDeviceContext->DrawInstanced(count, instances, 0, 0);
- return gl::Error(GL_NO_ERROR);
+ return drawTriangleFan(data, count, GL_NONE, nullptr, 0, instances);
}
- else
+
+ bool useInstancedPointSpriteEmulation =
+ programD3D->usesPointSize() && getWorkarounds().useInstancedPointSpriteEmulation;
+
+ if (instances > 0)
{
- // If gl_PointSize is used and GL_POINTS is specified, then it is expected to render pointsprites.
- // If instanced pointsprite emulation is being used the topology is expexted to be
- // D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST and DrawIndexedInstanced must be used.
if (mode == GL_POINTS && useInstancedPointSpriteEmulation)
{
- mDeviceContext->DrawIndexedInstanced(6, count, 0, 0, 0);
+ // If pointsprite emulation is used with glDrawArraysInstanced then we need to take a
+ // less efficent code path.
+ // Instanced rendering of emulated pointsprites requires a loop to draw each batch of
+ // points. An offset into the instanced data buffer is calculated and applied on each
+ // iteration to ensure all instances are rendered correctly.
+
+ // Each instance being rendered requires the inputlayout cache to reapply buffers and
+ // offsets.
+ for (GLsizei i = 0; i < instances; i++)
+ {
+ gl::Error error = mInputLayoutCache.updateVertexOffsetsForPointSpritesEmulation(i);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ mDeviceContext->DrawIndexedInstanced(6, count, 0, 0, 0);
+ }
}
else
{
- mDeviceContext->Draw(count, 0);
+ mDeviceContext->DrawInstanced(count, instances, 0, 0);
}
return gl::Error(GL_NO_ERROR);
}
+
+ // If the shader is writing to gl_PointSize, then pointsprites are being rendered.
+ // Emulating instanced point sprites for FL9_3 requires the topology to be
+ // D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST and DrawIndexedInstanced is called instead.
+ if (mode == GL_POINTS && useInstancedPointSpriteEmulation)
+ {
+ mDeviceContext->DrawIndexedInstanced(6, count, 0, 0, 0);
+ }
+ else
+ {
+ mDeviceContext->Draw(count, 0);
+ }
+ return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
- gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances)
+gl::Error Renderer11::drawElementsImpl(const gl::Data &data,
+ const TranslatedIndexData &indexInfo,
+ GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ GLsizei instances)
{
int minIndex = static_cast<int>(indexInfo.indexRange.start);
if (mode == GL_LINE_LOOP)
{
- return drawLineLoop(count, type, indices, minIndex, elementArrayBuffer);
+ return drawLineLoop(data, count, type, indices, &indexInfo, instances);
}
- else if (mode == GL_TRIANGLE_FAN)
+
+ if (mode == GL_TRIANGLE_FAN)
{
- return drawTriangleFan(count, type, indices, minIndex, elementArrayBuffer, instances);
+ return drawTriangleFan(data, count, type, indices, minIndex, instances);
}
- else if (instances > 0)
+
+ const ProgramD3D *programD3D = GetImplAs<ProgramD3D>(data.state->getProgram());
+ if (instances > 0)
{
- mDeviceContext->DrawIndexedInstanced(count, instances, 0, -minIndex, 0);
+ if (mode == GL_POINTS && programD3D->usesInstancedPointSpriteEmulation())
+ {
+ // If pointsprite emulation is used with glDrawElementsInstanced then we need to take a
+ // less efficent code path.
+ // Instanced rendering of emulated pointsprites requires a loop to draw each batch of
+ // points. An offset into the instanced data buffer is calculated and applied on each
+ // iteration to ensure all instances are rendered correctly.
+ GLsizei elementsToRender = static_cast<GLsizei>(indexInfo.indexRange.vertexCount());
+
+ // Each instance being rendered requires the inputlayout cache to reapply buffers and
+ // offsets.
+ for (GLsizei i = 0; i < instances; i++)
+ {
+ gl::Error error = mInputLayoutCache.updateVertexOffsetsForPointSpritesEmulation(i);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ mDeviceContext->DrawIndexedInstanced(6, elementsToRender, 0, 0, 0);
+ }
+ }
+ else
+ {
+ mDeviceContext->DrawIndexedInstanced(count, instances, 0, -minIndex, 0);
+ }
return gl::Error(GL_NO_ERROR);
}
+
+ // If the shader is writing to gl_PointSize, then pointsprites are being rendered.
+ // Emulating instanced point sprites for FL9_3 requires the topology to be
+ // D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST and DrawIndexedInstanced is called instead.
+ if (mode == GL_POINTS && programD3D->usesInstancedPointSpriteEmulation())
+ {
+ // The count parameter passed to drawElements represents the total number of instances
+ // to be rendered. Each instance is referenced by the bound index buffer from the
+ // the caller.
+ //
+ // Indexed pointsprite emulation replicates data for duplicate entries found
+ // in the index buffer.
+ // This is not an efficent rendering mechanism and is only used on downlevel renderers
+ // that do not support geometry shaders.
+ mDeviceContext->DrawIndexedInstanced(6, count, 0, 0, 0);
+ }
else
{
mDeviceContext->DrawIndexed(count, 0, -minIndex);
- return gl::Error(GL_NO_ERROR);
}
+ return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer)
+gl::Error Renderer11::drawLineLoop(const gl::Data &data,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indexPointer,
+ const TranslatedIndexData *indexInfo,
+ int instances)
{
+ gl::VertexArray *vao = data.state->getVertexArray();
+ gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
+
+ const GLvoid *indices = indexPointer;
+
// Get the raw indices for an indexed draw
if (type != GL_NONE && elementArrayBuffer)
{
@@ -1675,7 +1893,11 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required.");
}
- const unsigned int spaceNeeded = (static_cast<unsigned int>(count) + 1) * sizeof(unsigned int);
+ GetLineLoopIndices(indices, type, static_cast<GLuint>(count),
+ data.state->isPrimitiveRestartEnabled(), &mScratchIndexDataBuffer);
+
+ unsigned int spaceNeeded =
+ static_cast<unsigned int>(sizeof(GLuint) * mScratchIndexDataBuffer.size());
gl::Error error = mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT);
if (error.isError())
{
@@ -1690,41 +1912,9 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind
return error;
}
- unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
- unsigned int indexBufferOffset = offset;
-
- switch (type)
- {
- case GL_NONE: // Non-indexed draw
- for (int i = 0; i < count; i++)
- {
- data[i] = i;
- }
- data[count] = 0;
- break;
- case GL_UNSIGNED_BYTE:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLubyte*>(indices)[i];
- }
- data[count] = static_cast<const GLubyte*>(indices)[0];
- break;
- case GL_UNSIGNED_SHORT:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLushort*>(indices)[i];
- }
- data[count] = static_cast<const GLushort*>(indices)[0];
- break;
- case GL_UNSIGNED_INT:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLuint*>(indices)[i];
- }
- data[count] = static_cast<const GLuint*>(indices)[0];
- break;
- default: UNREACHABLE();
- }
+ // Copy over the converted index data.
+ memcpy(mappedMemory, &mScratchIndexDataBuffer[0],
+ sizeof(GLuint) * mScratchIndexDataBuffer.size());
error = mLineLoopIB->unmapBuffer();
if (error.isError())
@@ -1732,25 +1922,46 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind
return error;
}
- IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mLineLoopIB->getIndexBuffer());
+ IndexBuffer11 *indexBuffer = GetAs<IndexBuffer11>(mLineLoopIB->getIndexBuffer());
ID3D11Buffer *d3dIndexBuffer = indexBuffer->getBuffer();
DXGI_FORMAT indexFormat = indexBuffer->getIndexFormat();
- if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat || mAppliedIBOffset != indexBufferOffset)
+ if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat ||
+ mAppliedIBOffset != offset)
{
- mDeviceContext->IASetIndexBuffer(d3dIndexBuffer, indexFormat, indexBufferOffset);
+ mDeviceContext->IASetIndexBuffer(d3dIndexBuffer, indexFormat, offset);
mAppliedIB = d3dIndexBuffer;
mAppliedIBFormat = indexFormat;
- mAppliedIBOffset = indexBufferOffset;
+ mAppliedIBOffset = offset;
}
- mDeviceContext->DrawIndexed(count + 1, 0, -minIndex);
+ INT baseVertexLocation = (indexInfo ? -static_cast<int>(indexInfo->indexRange.start) : 0);
+ UINT indexCount = static_cast<UINT>(mScratchIndexDataBuffer.size());
+
+ if (instances > 0)
+ {
+ mDeviceContext->DrawIndexedInstanced(indexCount, instances, 0, baseVertexLocation, 0);
+ }
+ else
+ {
+ mDeviceContext->DrawIndexed(indexCount, 0, baseVertexLocation);
+ }
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances)
+gl::Error Renderer11::drawTriangleFan(const gl::Data &data,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ int minIndex,
+ int instances)
{
+ gl::VertexArray *vao = data.state->getVertexArray();
+ gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
+
+ const GLvoid *indexPointer = indices;
+
// Get the raw indices for an indexed draw
if (type != GL_NONE && elementArrayBuffer)
{
@@ -1764,7 +1975,7 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
return error;
}
- indices = bufferData + offset;
+ indexPointer = bufferData + offset;
}
if (!mTriangleFanIB)
@@ -1781,21 +1992,25 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
// Checked by Renderer11::applyPrimitiveType
ASSERT(count >= 3);
- const unsigned int numTris = count - 2;
+ const GLuint numTris = count - 2;
if (numTris > (std::numeric_limits<unsigned int>::max() / (sizeof(unsigned int) * 3)))
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a scratch index buffer for GL_TRIANGLE_FAN, too many indices required.");
}
- const unsigned int spaceNeeded = (numTris * 3) * sizeof(unsigned int);
+ GetTriFanIndices(indexPointer, type, count, data.state->isPrimitiveRestartEnabled(),
+ &mScratchIndexDataBuffer);
+
+ const unsigned int spaceNeeded =
+ static_cast<unsigned int>(mScratchIndexDataBuffer.size() * sizeof(unsigned int));
gl::Error error = mTriangleFanIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT);
if (error.isError())
{
return error;
}
- void* mappedMemory = NULL;
+ void *mappedMemory = nullptr;
unsigned int offset;
error = mTriangleFanIB->mapBuffer(spaceNeeded, &mappedMemory, &offset);
if (error.isError())
@@ -1803,45 +2018,7 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
return error;
}
- unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
- unsigned int indexBufferOffset = offset;
-
- switch (type)
- {
- case GL_NONE: // Non-indexed draw
- for (unsigned int i = 0; i < numTris; i++)
- {
- data[i*3 + 0] = 0;
- data[i*3 + 1] = i + 1;
- data[i*3 + 2] = i + 2;
- }
- break;
- case GL_UNSIGNED_BYTE:
- for (unsigned int i = 0; i < numTris; i++)
- {
- data[i*3 + 0] = static_cast<const GLubyte*>(indices)[0];
- data[i*3 + 1] = static_cast<const GLubyte*>(indices)[i + 1];
- data[i*3 + 2] = static_cast<const GLubyte*>(indices)[i + 2];
- }
- break;
- case GL_UNSIGNED_SHORT:
- for (unsigned int i = 0; i < numTris; i++)
- {
- data[i*3 + 0] = static_cast<const GLushort*>(indices)[0];
- data[i*3 + 1] = static_cast<const GLushort*>(indices)[i + 1];
- data[i*3 + 2] = static_cast<const GLushort*>(indices)[i + 2];
- }
- break;
- case GL_UNSIGNED_INT:
- for (unsigned int i = 0; i < numTris; i++)
- {
- data[i*3 + 0] = static_cast<const GLuint*>(indices)[0];
- data[i*3 + 1] = static_cast<const GLuint*>(indices)[i + 1];
- data[i*3 + 2] = static_cast<const GLuint*>(indices)[i + 2];
- }
- break;
- default: UNREACHABLE();
- }
+ memcpy(mappedMemory, &mScratchIndexDataBuffer[0], spaceNeeded);
error = mTriangleFanIB->unmapBuffer();
if (error.isError())
@@ -1849,34 +2026,37 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
return error;
}
- IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mTriangleFanIB->getIndexBuffer());
+ IndexBuffer11 *indexBuffer = GetAs<IndexBuffer11>(mTriangleFanIB->getIndexBuffer());
ID3D11Buffer *d3dIndexBuffer = indexBuffer->getBuffer();
DXGI_FORMAT indexFormat = indexBuffer->getIndexFormat();
- if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat || mAppliedIBOffset != indexBufferOffset)
+ if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat ||
+ mAppliedIBOffset != offset)
{
- mDeviceContext->IASetIndexBuffer(d3dIndexBuffer, indexFormat, indexBufferOffset);
+ mDeviceContext->IASetIndexBuffer(d3dIndexBuffer, indexFormat, offset);
mAppliedIB = d3dIndexBuffer;
mAppliedIBFormat = indexFormat;
- mAppliedIBOffset = indexBufferOffset;
+ mAppliedIBOffset = offset;
}
+ UINT indexCount = static_cast<UINT>(mScratchIndexDataBuffer.size());
+
if (instances > 0)
{
- mDeviceContext->DrawIndexedInstanced(numTris * 3, instances, 0, -minIndex, 0);
+ mDeviceContext->DrawIndexedInstanced(indexCount, instances, 0, -minIndex, 0);
}
else
{
- mDeviceContext->DrawIndexed(numTris * 3, 0, -minIndex);
+ mDeviceContext->DrawIndexed(indexCount, 0, -minIndex);
}
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::applyShaders(gl::Program *program, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
- bool rasterizerDiscard, bool transformFeedbackActive)
+gl::Error Renderer11::applyShadersImpl(const gl::Data &data, GLenum drawMode)
{
- ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
+ ProgramD3D *programD3D = GetImplAs<ProgramD3D>(data.state->getProgram());
+ const auto &inputLayout = programD3D->getCachedInputLayout();
ShaderExecutableD3D *vertexExe = NULL;
gl::Error error = programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe, nullptr);
@@ -1885,32 +2065,41 @@ gl::Error Renderer11::applyShaders(gl::Program *program, const gl::VertexFormat
return error;
}
+ const gl::Framebuffer *drawFramebuffer = data.state->getDrawFramebuffer();
ShaderExecutableD3D *pixelExe = NULL;
- error = programD3D->getPixelExecutableForFramebuffer(framebuffer, &pixelExe);
+ error = programD3D->getPixelExecutableForFramebuffer(drawFramebuffer, &pixelExe);
if (error.isError())
{
return error;
}
- ShaderExecutableD3D *geometryExe = programD3D->getGeometryExecutable();
+ ShaderExecutableD3D *geometryExe = nullptr;
+ error =
+ programD3D->getGeometryExecutableForPrimitiveType(data, drawMode, &geometryExe, nullptr);
+ if (error.isError())
+ {
+ return error;
+ }
- ID3D11VertexShader *vertexShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader() : NULL);
+ ID3D11VertexShader *vertexShader = (vertexExe ? GetAs<ShaderExecutable11>(vertexExe)->getVertexShader() : NULL);
ID3D11PixelShader *pixelShader = NULL;
// Skip pixel shader if we're doing rasterizer discard.
+ bool rasterizerDiscard = data.state->getRasterizerState().rasterizerDiscard;
if (!rasterizerDiscard)
{
- pixelShader = (pixelExe ? ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader() : NULL);
+ pixelShader = (pixelExe ? GetAs<ShaderExecutable11>(pixelExe)->getPixelShader() : NULL);
}
ID3D11GeometryShader *geometryShader = NULL;
+ bool transformFeedbackActive = data.state->isTransformFeedbackActiveUnpaused();
if (transformFeedbackActive)
{
- geometryShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getStreamOutShader() : NULL);
+ geometryShader = (vertexExe ? GetAs<ShaderExecutable11>(vertexExe)->getStreamOutShader() : NULL);
}
- else if (mCurRasterState.pointDrawMode)
+ else
{
- geometryShader = (geometryExe ? ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader() : NULL);
+ geometryShader = (geometryExe ? GetAs<ShaderExecutable11>(geometryExe)->getGeometryShader() : NULL);
}
bool dirtyUniforms = false;
@@ -1944,7 +2133,9 @@ gl::Error Renderer11::applyShaders(gl::Program *program, const gl::VertexFormat
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray)
+gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D,
+ GLenum drawMode,
+ const std::vector<D3DUniform *> &uniformArray)
{
unsigned int totalRegisterCountVS = 0;
unsigned int totalRegisterCountPS = 0;
@@ -1952,26 +2143,25 @@ gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vecto
bool vertexUniformsDirty = false;
bool pixelUniformsDirty = false;
- for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++)
+ for (const D3DUniform *uniform : uniformArray)
{
- const gl::LinkedUniform &uniform = *uniformArray[uniformIndex];
-
- if (uniform.isReferencedByVertexShader() && !uniform.isSampler())
+ if (uniform->isReferencedByVertexShader() && !uniform->isSampler())
{
- totalRegisterCountVS += uniform.registerCount;
- vertexUniformsDirty = (vertexUniformsDirty || uniform.dirty);
+ totalRegisterCountVS += uniform->registerCount;
+ vertexUniformsDirty = (vertexUniformsDirty || uniform->dirty);
}
- if (uniform.isReferencedByFragmentShader() && !uniform.isSampler())
+ if (uniform->isReferencedByFragmentShader() && !uniform->isSampler())
{
- totalRegisterCountPS += uniform.registerCount;
- pixelUniformsDirty = (pixelUniformsDirty || uniform.dirty);
+ totalRegisterCountPS += uniform->registerCount;
+ pixelUniformsDirty = (pixelUniformsDirty || uniform->dirty);
}
}
- const ProgramD3D *programD3D = GetAs<ProgramD3D>(&program);
- const UniformStorage11 *vertexUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getVertexUniformStorage());
- const UniformStorage11 *fragmentUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getFragmentUniformStorage());
+ const UniformStorage11 *vertexUniformStorage =
+ GetAs<UniformStorage11>(&programD3D.getVertexUniformStorage());
+ const UniformStorage11 *fragmentUniformStorage =
+ GetAs<UniformStorage11>(&programD3D.getFragmentUniformStorage());
ASSERT(vertexUniformStorage);
ASSERT(fragmentUniformStorage);
@@ -1999,26 +2189,26 @@ gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vecto
mapPS = (float(*)[4])map.pData;
}
- for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++)
+ for (const D3DUniform *uniform : uniformArray)
{
- gl::LinkedUniform *uniform = uniformArray[uniformIndex];
+ if (uniform->isSampler())
+ continue;
- if (!uniform->isSampler())
- {
- unsigned int componentCount = (4 - uniform->registerElement);
+ unsigned int componentCount = (4 - uniform->registerElement);
- // we assume that uniforms from structs are arranged in struct order in our uniforms list. otherwise we would
- // overwrite previously written regions of memory.
+ // we assume that uniforms from structs are arranged in struct order in our uniforms list.
+ // otherwise we would overwrite previously written regions of memory.
- if (uniform->isReferencedByVertexShader() && mapVS)
- {
- memcpy(&mapVS[uniform->vsRegisterIndex][uniform->registerElement], uniform->data, uniform->registerCount * sizeof(float) * componentCount);
- }
+ if (uniform->isReferencedByVertexShader() && mapVS)
+ {
+ memcpy(&mapVS[uniform->vsRegisterIndex][uniform->registerElement], uniform->data,
+ uniform->registerCount * sizeof(float) * componentCount);
+ }
- if (uniform->isReferencedByFragmentShader() && mapPS)
- {
- memcpy(&mapPS[uniform->psRegisterIndex][uniform->registerElement], uniform->data, uniform->registerCount * sizeof(float) * componentCount);
- }
+ if (uniform->isReferencedByFragmentShader() && mapPS)
+ {
+ memcpy(&mapPS[uniform->psRegisterIndex][uniform->registerElement], uniform->data,
+ uniform->registerCount * sizeof(float) * componentCount);
}
}
@@ -2048,7 +2238,7 @@ gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vecto
if (!mDriverConstantBufferVS)
{
D3D11_BUFFER_DESC constantBufferDescription = {0};
- constantBufferDescription.ByteWidth = sizeof(dx_VertexConstants);
+ constantBufferDescription.ByteWidth = sizeof(dx_VertexConstants11);
constantBufferDescription.Usage = D3D11_USAGE_DEFAULT;
constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
constantBufferDescription.CPUAccessFlags = 0;
@@ -2056,16 +2246,18 @@ gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vecto
constantBufferDescription.StructureByteStride = 0;
HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferVS);
- UNUSED_ASSERTION_VARIABLE(result);
ASSERT(SUCCEEDED(result));
-
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create vertex shader constant buffer, result: 0x%X.", result);
+ }
mDeviceContext->VSSetConstantBuffers(1, 1, &mDriverConstantBufferVS);
}
if (!mDriverConstantBufferPS)
{
D3D11_BUFFER_DESC constantBufferDescription = {0};
- constantBufferDescription.ByteWidth = sizeof(dx_PixelConstants);
+ constantBufferDescription.ByteWidth = sizeof(dx_PixelConstants11);
constantBufferDescription.Usage = D3D11_USAGE_DEFAULT;
constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
constantBufferDescription.CPUAccessFlags = 0;
@@ -2073,32 +2265,50 @@ gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vecto
constantBufferDescription.StructureByteStride = 0;
HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferPS);
- UNUSED_ASSERTION_VARIABLE(result);
ASSERT(SUCCEEDED(result));
-
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create pixel shader constant buffer, result: 0x%X.", result);
+ }
mDeviceContext->PSSetConstantBuffers(1, 1, &mDriverConstantBufferPS);
}
- if (memcmp(&mVertexConstants, &mAppliedVertexConstants, sizeof(dx_VertexConstants)) != 0)
+ const dx_VertexConstants11 &vertexConstants = mStateManager.getVertexConstants();
+ if (memcmp(&vertexConstants, &mAppliedVertexConstants, sizeof(dx_VertexConstants11)) != 0)
{
- mDeviceContext->UpdateSubresource(mDriverConstantBufferVS, 0, NULL, &mVertexConstants, 16, 0);
- memcpy(&mAppliedVertexConstants, &mVertexConstants, sizeof(dx_VertexConstants));
+ ASSERT(mDriverConstantBufferVS != nullptr);
+ if (mDriverConstantBufferVS)
+ {
+ mDeviceContext->UpdateSubresource(mDriverConstantBufferVS, 0, NULL, &vertexConstants,
+ 16, 0);
+ memcpy(&mAppliedVertexConstants, &vertexConstants, sizeof(dx_VertexConstants11));
+ }
}
- if (memcmp(&mPixelConstants, &mAppliedPixelConstants, sizeof(dx_PixelConstants)) != 0)
+ const dx_PixelConstants11 &pixelConstants = mStateManager.getPixelConstants();
+ if (memcmp(&pixelConstants, &mAppliedPixelConstants, sizeof(dx_PixelConstants11)) != 0)
{
- mDeviceContext->UpdateSubresource(mDriverConstantBufferPS, 0, NULL, &mPixelConstants, 16, 0);
- memcpy(&mAppliedPixelConstants, &mPixelConstants, sizeof(dx_PixelConstants));
+ ASSERT(mDriverConstantBufferPS != nullptr);
+ if (mDriverConstantBufferPS)
+ {
+ mDeviceContext->UpdateSubresource(mDriverConstantBufferPS, 0, NULL, &pixelConstants, 16,
+ 0);
+ memcpy(&mAppliedPixelConstants, &pixelConstants, sizeof(dx_PixelConstants11));
+ }
}
// GSSetConstantBuffers triggers device removal on 9_3, so we should only call it if necessary
- if (programD3D->usesGeometryShader())
+ if (programD3D.usesGeometryShader(drawMode))
{
// needed for the point sprite geometry shader
if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS)
{
- mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS);
- mCurrentGeometryConstantBuffer = mDriverConstantBufferPS;
+ ASSERT(mDriverConstantBufferPS != nullptr);
+ if (mDriverConstantBufferPS)
+ {
+ mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS);
+ mCurrentGeometryConstantBuffer = mDriverConstantBufferPS;
+ }
}
}
@@ -2107,45 +2317,27 @@ gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vecto
void Renderer11::markAllStateDirty()
{
- for (size_t rtIndex = 0; rtIndex < ArraySize(mAppliedRTVs); rtIndex++)
- {
- mAppliedRTVs[rtIndex] = DirtyPointer;
- }
- mAppliedDSV = DirtyPointer;
- mDepthStencilInitialized = false;
- mRenderTargetDescInitialized = false;
-
- // We reset the current SRV data because it might not be in sync with D3D's state
- // anymore. For example when a currently used SRV is used as an RTV, D3D silently
- // remove it from its state.
- memset(mCurVertexSRVs.data(), 0, sizeof(SRVRecord) * mCurVertexSRVs.size());
- memset(mCurPixelSRVs.data(), 0, sizeof(SRVRecord) * mCurPixelSRVs.size());
+ TRACE_EVENT0("gpu.angle", "Renderer11::markAllStateDirty");
- ASSERT(mForceSetVertexSamplerStates.size() == mCurVertexSRVs.size());
for (size_t vsamplerId = 0; vsamplerId < mForceSetVertexSamplerStates.size(); ++vsamplerId)
{
mForceSetVertexSamplerStates[vsamplerId] = true;
}
- ASSERT(mForceSetPixelSamplerStates.size() == mCurPixelSRVs.size());
for (size_t fsamplerId = 0; fsamplerId < mForceSetPixelSamplerStates.size(); ++fsamplerId)
{
mForceSetPixelSamplerStates[fsamplerId] = true;
}
- mForceSetBlendState = true;
- mForceSetRasterState = true;
- mForceSetDepthStencilState = true;
- mForceSetScissor = true;
- mForceSetViewport = true;
+ mStateManager.invalidateEverything();
mAppliedIB = NULL;
mAppliedIBFormat = DXGI_FORMAT_UNKNOWN;
mAppliedIBOffset = 0;
- mAppliedVertexShader = DirtyPointer;
- mAppliedGeometryShader = DirtyPointer;
- mAppliedPixelShader = DirtyPointer;
+ mAppliedVertexShader = angle::DirtyPointer;
+ mAppliedGeometryShader = angle::DirtyPointer;
+ mAppliedPixelShader = angle::DirtyPointer;
mAppliedNumXFBBindings = static_cast<size_t>(-1);
@@ -2155,8 +2347,8 @@ void Renderer11::markAllStateDirty()
mAppliedTFOffsets[i] = 0;
}
- memset(&mAppliedVertexConstants, 0, sizeof(dx_VertexConstants));
- memset(&mAppliedPixelConstants, 0, sizeof(dx_PixelConstants));
+ memset(&mAppliedVertexConstants, 0, sizeof(dx_VertexConstants11));
+ memset(&mAppliedPixelConstants, 0, sizeof(dx_PixelConstants11));
mInputLayoutCache.markDirty();
@@ -2238,20 +2430,16 @@ bool Renderer11::testDeviceResettable()
D3D_FEATURE_LEVEL dummyFeatureLevel;
ID3D11DeviceContext* dummyContext;
- HRESULT result = D3D11CreateDevice(NULL,
- mDriverType,
- NULL,
+ ASSERT(mRequestedDriverType != D3D_DRIVER_TYPE_UNKNOWN);
+ HRESULT result = D3D11CreateDevice(
+ NULL, mRequestedDriverType, NULL,
#if defined(_DEBUG)
- D3D11_CREATE_DEVICE_DEBUG,
+ D3D11_CREATE_DEVICE_DEBUG,
#else
- 0,
+ 0,
#endif
- mAvailableFeatureLevels.data(),
- mAvailableFeatureLevels.size(),
- D3D11_SDK_VERSION,
- &dummyDevice,
- &dummyFeatureLevel,
- &dummyContext);
+ mAvailableFeatureLevels.data(), static_cast<unsigned int>(mAvailableFeatureLevels.size()),
+ D3D11_SDK_VERSION, &dummyDevice, &dummyFeatureLevel, &dummyContext);
if (!mDevice || FAILED(result))
{
@@ -2270,6 +2458,13 @@ void Renderer11::release()
releaseDeviceResources();
+ if (!mCreatedWithDeviceEXT)
+ {
+ // Only delete the device if the Renderer11 owns it
+ // Otherwise we should keep it around in case we try to reinitialize the renderer later
+ SafeDelete(mEGLDevice);
+ }
+
SafeRelease(mDxgiFactory);
SafeRelease(mDxgiAdapter);
@@ -2285,6 +2480,9 @@ void Renderer11::release()
}
SafeRelease(mDevice);
+#if !defined(ANGLE_MINGW32_COMPAT)
+ SafeRelease(mDebug);
+#endif
if (mD3d11Module)
{
@@ -2298,7 +2496,15 @@ void Renderer11::release()
mDxgiModule = NULL;
}
+ if (mDCompModule)
+ {
+ FreeLibrary(mDCompModule);
+ mDCompModule = NULL;
+ }
+
mCompiler.release();
+
+ mSupportsShareHandles.reset();
}
bool Renderer11::resetDevice()
@@ -2318,11 +2524,6 @@ bool Renderer11::resetDevice()
return true;
}
-VendorID Renderer11::getVendorId() const
-{
- return static_cast<VendorID>(mAdapterDescription.VendorId);
-}
-
std::string Renderer11::getRendererDescription() const
{
std::ostringstream rendererString;
@@ -2336,24 +2537,29 @@ std::string Renderer11::getRendererDescription() const
return rendererString.str();
}
-GUID Renderer11::getAdapterIdentifier() const
+DeviceIdentifier Renderer11::getAdapterIdentifier() const
{
- // Use the adapter LUID as our adapter ID
- // This number is local to a machine is only guaranteed to be unique between restarts
- static_assert(sizeof(LUID) <= sizeof(GUID), "Size of GUID must be at least as large as LUID.");
- GUID adapterId = {0};
- memcpy(&adapterId, &mAdapterDescription.AdapterLuid, sizeof(LUID));
- return adapterId;
+ // Don't use the AdapterLuid here, since that doesn't persist across reboot.
+ DeviceIdentifier deviceIdentifier = { 0 };
+ deviceIdentifier.VendorId = mAdapterDescription.VendorId;
+ deviceIdentifier.DeviceId = mAdapterDescription.DeviceId;
+ deviceIdentifier.SubSysId = mAdapterDescription.SubSysId;
+ deviceIdentifier.Revision = mAdapterDescription.Revision;
+ deviceIdentifier.FeatureLevel = static_cast<UINT>(mRenderer11DeviceCaps.featureLevel);
+
+ return deviceIdentifier;
}
unsigned int Renderer11::getReservedVertexUniformVectors() const
{
- return 0; // Driver uniforms are stored in a separate constant buffer
+ // Driver uniforms are stored in a separate constant buffer
+ return d3d11_gl::GetReservedVertexUniformVectors(mRenderer11DeviceCaps.featureLevel);
}
unsigned int Renderer11::getReservedFragmentUniformVectors() const
{
- return 0; // Driver uniforms are stored in a separate constant buffer
+ // Driver uniforms are stored in a separate constant buffer
+ return d3d11_gl::GetReservedFragmentUniformVectors(mRenderer11DeviceCaps.featureLevel);
}
unsigned int Renderer11::getReservedVertexUniformBuffers() const
@@ -2368,24 +2574,100 @@ unsigned int Renderer11::getReservedFragmentUniformBuffers() const
return 2;
}
+d3d11::ANGLED3D11DeviceType Renderer11::getDeviceType() const
+{
+ if (mCreatedWithDeviceEXT)
+ {
+ return d3d11::GetDeviceType(mDevice);
+ }
+
+ if ((mRequestedDriverType == D3D_DRIVER_TYPE_SOFTWARE) ||
+ (mRequestedDriverType == D3D_DRIVER_TYPE_REFERENCE) ||
+ (mRequestedDriverType == D3D_DRIVER_TYPE_NULL))
+ {
+ return d3d11::ANGLE_D3D11_DEVICE_TYPE_SOFTWARE_REF_OR_NULL;
+ }
+
+ if (mRequestedDriverType == D3D_DRIVER_TYPE_WARP)
+ {
+ return d3d11::ANGLE_D3D11_DEVICE_TYPE_WARP;
+ }
+
+ return d3d11::ANGLE_D3D11_DEVICE_TYPE_HARDWARE;
+}
+
bool Renderer11::getShareHandleSupport() const
{
+ if (mSupportsShareHandles.valid())
+ {
+ return mSupportsShareHandles.value();
+ }
+
// We only currently support share handles with BGRA surfaces, because
// chrome needs BGRA. Once chrome fixes this, we should always support them.
+ if (!getRendererExtensions().textureFormatBGRA8888)
+ {
+ mSupportsShareHandles = false;
+ return false;
+ }
+
// PIX doesn't seem to support using share handles, so disable them.
+ if (gl::DebugAnnotationsActive())
+ {
+ mSupportsShareHandles = false;
+ return false;
+ }
+
// Also disable share handles on Feature Level 9_3, since it doesn't support share handles on RGBA8 textures/swapchains.
- return getRendererExtensions().textureFormatBGRA8888 && !gl::DebugAnnotationsActive();// && !(mFeatureLevel <= D3D_FEATURE_LEVEL_9_3); Qt: we don't care about the 9_3 limitation
-}
+ if (mRenderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3)
+ {
+ mSupportsShareHandles = false;
+ return false;
+ }
-bool Renderer11::getPostSubBufferSupport() const
-{
- // D3D11 does not support present with dirty rectangles until D3D11.1 and DXGI 1.2.
- return false;
+ // Find out which type of D3D11 device the Renderer11 is using
+ d3d11::ANGLED3D11DeviceType deviceType = getDeviceType();
+ if (deviceType == d3d11::ANGLE_D3D11_DEVICE_TYPE_UNKNOWN)
+ {
+ mSupportsShareHandles = false;
+ return false;
+ }
+
+ if (deviceType == d3d11::ANGLE_D3D11_DEVICE_TYPE_SOFTWARE_REF_OR_NULL)
+ {
+ // Software/Reference/NULL devices don't support share handles
+ mSupportsShareHandles = false;
+ return false;
+ }
+
+ if (deviceType == d3d11::ANGLE_D3D11_DEVICE_TYPE_WARP)
+ {
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE) && !defined(__GNUC__)
+ if (!IsWindows8OrGreater())
+ {
+ // WARP on Windows 7 doesn't support shared handles
+ mSupportsShareHandles = false;
+ return false;
+ }
+#endif // ANGLE_ENABLE_WINDOWS_STORE
+
+ // WARP on Windows 8.0+ supports shared handles when shared with another WARP device
+ // TODO: allow applications to query for HARDWARE or WARP-specific share handles,
+ // to prevent them trying to use a WARP share handle with an a HW device (or
+ // vice-versa)
+ // e.g. by creating EGL_D3D11_[HARDWARE/WARP]_DEVICE_SHARE_HANDLE_ANGLE
+ mSupportsShareHandles = true;
+ return true;
+ }
+
+ ASSERT(mCreatedWithDeviceEXT || mRequestedDriverType == D3D_DRIVER_TYPE_HARDWARE);
+ mSupportsShareHandles = true;
+ return true;
}
int Renderer11::getMajorShaderModel() const
{
- switch (mFeatureLevel)
+ switch (mRenderer11DeviceCaps.featureLevel)
{
case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MAJOR_VERSION; // 5
case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MAJOR_VERSION; // 4
@@ -2397,7 +2679,7 @@ int Renderer11::getMajorShaderModel() const
int Renderer11::getMinorShaderModel() const
{
- switch (mFeatureLevel)
+ switch (mRenderer11DeviceCaps.featureLevel)
{
case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MINOR_VERSION; // 0
case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MINOR_VERSION; // 1
@@ -2409,7 +2691,7 @@ int Renderer11::getMinorShaderModel() const
std::string Renderer11::getShaderModelSuffix() const
{
- switch (mFeatureLevel)
+ switch (mRenderer11DeviceCaps.featureLevel)
{
case D3D_FEATURE_LEVEL_11_0: return "";
case D3D_FEATURE_LEVEL_10_1: return "";
@@ -2419,14 +2701,25 @@ std::string Renderer11::getShaderModelSuffix() const
}
}
+const WorkaroundsD3D &RendererD3D::getWorkarounds() const
+{
+ if (!mWorkaroundsInitialized)
+ {
+ mWorkarounds = generateWorkarounds();
+ mWorkaroundsInitialized = true;
+ }
+
+ return mWorkarounds;
+}
+
gl::Error Renderer11::copyImage2D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
const gl::Offset &destOffset, TextureStorage *storage, GLint level)
{
- gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
+ const gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
ASSERT(colorbuffer);
RenderTarget11 *sourceRenderTarget = NULL;
- gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget);
+ gl::Error error = colorbuffer->getRenderTarget(&sourceRenderTarget);
if (error.isError())
{
return error;
@@ -2436,7 +2729,7 @@ gl::Error Renderer11::copyImage2D(const gl::Framebuffer *framebuffer, const gl::
ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
ASSERT(source);
- TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage);
+ TextureStorage11_2D *storage11 = GetAs<TextureStorage11_2D>(storage);
ASSERT(storage11);
gl::ImageIndex index = gl::ImageIndex::Make2D(level);
@@ -2448,18 +2741,26 @@ gl::Error Renderer11::copyImage2D(const gl::Framebuffer *framebuffer, const gl::
}
ASSERT(destRenderTarget);
- ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView();
+ ID3D11RenderTargetView *dest = GetAs<RenderTarget11>(destRenderTarget)->getRenderTargetView();
ASSERT(dest);
gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
+ const bool invertSource = UsePresentPathFast(this, colorbuffer);
+ if (invertSource)
+ {
+ sourceArea.y = sourceSize.height - sourceRect.y;
+ sourceArea.height = -sourceArea.height;
+ }
+
gl::Box destArea(destOffset.x, destOffset.y, 0, sourceRect.width, sourceRect.height, 1);
gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1);
// Use nearest filtering because source and destination are the same size for the direct
// copy
- mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST);
+ error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
+ destFormat, GL_NEAREST, false);
if (error.isError())
{
return error;
@@ -2473,11 +2774,11 @@ gl::Error Renderer11::copyImage2D(const gl::Framebuffer *framebuffer, const gl::
gl::Error Renderer11::copyImageCube(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
const gl::Offset &destOffset, TextureStorage *storage, GLenum target, GLint level)
{
- gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
+ const gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
ASSERT(colorbuffer);
RenderTarget11 *sourceRenderTarget = NULL;
- gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget);
+ gl::Error error = colorbuffer->getRenderTarget(&sourceRenderTarget);
if (error.isError())
{
return error;
@@ -2487,7 +2788,7 @@ gl::Error Renderer11::copyImageCube(const gl::Framebuffer *framebuffer, const gl
ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
ASSERT(source);
- TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage);
+ TextureStorage11_Cube *storage11 = GetAs<TextureStorage11_Cube>(storage);
ASSERT(storage11);
gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
@@ -2499,18 +2800,26 @@ gl::Error Renderer11::copyImageCube(const gl::Framebuffer *framebuffer, const gl
}
ASSERT(destRenderTarget);
- ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView();
+ ID3D11RenderTargetView *dest = GetAs<RenderTarget11>(destRenderTarget)->getRenderTargetView();
ASSERT(dest);
gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
+ const bool invertSource = UsePresentPathFast(this, colorbuffer);
+ if (invertSource)
+ {
+ sourceArea.y = sourceSize.height - sourceRect.y;
+ sourceArea.height = -sourceArea.height;
+ }
+
gl::Box destArea(destOffset.x, destOffset.y, 0, sourceRect.width, sourceRect.height, 1);
gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1);
// Use nearest filtering because source and destination are the same size for the direct
// copy
- error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST);
+ error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
+ destFormat, GL_NEAREST, false);
if (error.isError())
{
return error;
@@ -2524,11 +2833,11 @@ gl::Error Renderer11::copyImageCube(const gl::Framebuffer *framebuffer, const gl
gl::Error Renderer11::copyImage3D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
const gl::Offset &destOffset, TextureStorage *storage, GLint level)
{
- gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
+ const gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
ASSERT(colorbuffer);
RenderTarget11 *sourceRenderTarget = NULL;
- gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget);
+ gl::Error error = colorbuffer->getRenderTarget(&sourceRenderTarget);
if (error.isError())
{
return error;
@@ -2538,7 +2847,7 @@ gl::Error Renderer11::copyImage3D(const gl::Framebuffer *framebuffer, const gl::
ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
ASSERT(source);
- TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage);
+ TextureStorage11_3D *storage11 = GetAs<TextureStorage11_3D>(storage);
ASSERT(storage11);
gl::ImageIndex index = gl::ImageIndex::Make3D(level, destOffset.z);
@@ -2550,7 +2859,7 @@ gl::Error Renderer11::copyImage3D(const gl::Framebuffer *framebuffer, const gl::
}
ASSERT(destRenderTarget);
- ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView();
+ ID3D11RenderTargetView *dest = GetAs<RenderTarget11>(destRenderTarget)->getRenderTargetView();
ASSERT(dest);
gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
@@ -2561,7 +2870,8 @@ gl::Error Renderer11::copyImage3D(const gl::Framebuffer *framebuffer, const gl::
// Use nearest filtering because source and destination are the same size for the direct
// copy
- error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST);
+ error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
+ destFormat, GL_NEAREST, false);
if (error.isError())
{
return error;
@@ -2575,11 +2885,11 @@ gl::Error Renderer11::copyImage3D(const gl::Framebuffer *framebuffer, const gl::
gl::Error Renderer11::copyImage2DArray(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
const gl::Offset &destOffset, TextureStorage *storage, GLint level)
{
- gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
+ const gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
ASSERT(colorbuffer);
RenderTarget11 *sourceRenderTarget = NULL;
- gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget);
+ gl::Error error = colorbuffer->getRenderTarget(&sourceRenderTarget);
if (error.isError())
{
return error;
@@ -2589,7 +2899,7 @@ gl::Error Renderer11::copyImage2DArray(const gl::Framebuffer *framebuffer, const
ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
ASSERT(source);
- TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage);
+ TextureStorage11_2DArray *storage11 = GetAs<TextureStorage11_2DArray>(storage);
ASSERT(storage11);
gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, destOffset.z);
@@ -2601,7 +2911,7 @@ gl::Error Renderer11::copyImage2DArray(const gl::Framebuffer *framebuffer, const
}
ASSERT(destRenderTarget);
- ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView();
+ ID3D11RenderTargetView *dest = GetAs<RenderTarget11>(destRenderTarget)->getRenderTargetView();
ASSERT(dest);
gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
@@ -2612,7 +2922,8 @@ gl::Error Renderer11::copyImage2DArray(const gl::Framebuffer *framebuffer, const
// Use nearest filtering because source and destination are the same size for the direct
// copy
- error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST);
+ error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
+ destFormat, GL_NEAREST, false);
if (error.isError())
{
return error;
@@ -2640,14 +2951,14 @@ void Renderer11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView
// Do not preserve the serial for this one-time-use render target
for (size_t rtIndex = 0; rtIndex < ArraySize(mAppliedRTVs); rtIndex++)
{
- mAppliedRTVs[rtIndex] = DirtyPointer;
+ mAppliedRTVs[rtIndex] = angle::DirtyPointer;
}
- mAppliedDSV = DirtyPointer;
+ mAppliedDSV = angle::DirtyPointer;
}
gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT)
{
- const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(format, mFeatureLevel);
+ const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(format, mRenderer11DeviceCaps);
const gl::TextureCaps &textureCaps = getRendererTextureCaps().get(format);
GLuint supportedSamples = textureCaps.getNearestSamples(samples);
@@ -2779,9 +3090,26 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G
return gl::Error(GL_NO_ERROR);
}
-FramebufferImpl *Renderer11::createDefaultFramebuffer(const gl::Framebuffer::Data &data)
+gl::Error Renderer11::createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT)
{
- return createFramebuffer(data);
+ ASSERT(source != nullptr);
+
+ RenderTargetD3D *newRT = nullptr;
+ gl::Error error = createRenderTarget(source->getWidth(), source->getHeight(),
+ source->getInternalFormat(), source->getSamples(), &newRT);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ RenderTarget11 *source11 = GetAs<RenderTarget11>(source);
+ RenderTarget11 *dest11 = GetAs<RenderTarget11>(newRT);
+
+ mDeviceContext->CopySubresourceRegion(dest11->getTexture(), dest11->getSubresourceIndex(), 0, 0,
+ 0, source11->getTexture(),
+ source11->getSubresourceIndex(), nullptr);
+ *outRT = newRT;
+ return gl::Error(GL_NO_ERROR);
}
FramebufferImpl *Renderer11::createFramebuffer(const gl::Framebuffer::Data &data)
@@ -2789,24 +3117,22 @@ FramebufferImpl *Renderer11::createFramebuffer(const gl::Framebuffer::Data &data
return new Framebuffer11(data, this);
}
-CompilerImpl *Renderer11::createCompiler(const gl::Data &data)
+ShaderImpl *Renderer11::createShader(const gl::Shader::Data &data)
{
- return new CompilerD3D(data, SH_HLSL11_OUTPUT);
+ return new ShaderD3D(data);
}
-ShaderImpl *Renderer11::createShader(GLenum type)
+ProgramImpl *Renderer11::createProgram(const gl::Program::Data &data)
{
- return new ShaderD3D(type);
+ return new ProgramD3D(data, this);
}
-ProgramImpl *Renderer11::createProgram()
-{
- return new ProgramD3D(this);
-}
-
-gl::Error Renderer11::loadExecutable(const void *function, size_t length, ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, ShaderExecutableD3D **outExecutable)
+gl::Error Renderer11::loadExecutable(const void *function,
+ size_t length,
+ ShaderType type,
+ const std::vector<D3DVarying> &streamOutVaryings,
+ bool separatedOutputBuffers,
+ ShaderExecutableD3D **outExecutable)
{
switch (type)
{
@@ -2822,29 +3148,28 @@ gl::Error Renderer11::loadExecutable(const void *function, size_t length, Shader
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create vertex shader, result: 0x%X.", result);
}
- if (transformFeedbackVaryings.size() > 0)
+ if (!streamOutVaryings.empty())
{
std::vector<D3D11_SO_DECLARATION_ENTRY> soDeclaration;
- for (size_t i = 0; i < transformFeedbackVaryings.size(); i++)
+ soDeclaration.reserve(streamOutVaryings.size());
+
+ for (const auto &streamOutVarying : streamOutVaryings)
{
- const gl::LinkedVarying &varying = transformFeedbackVaryings[i];
- GLenum transposedType = gl::TransposeMatrixType(varying.type);
-
- for (size_t j = 0; j < varying.semanticIndexCount; j++)
- {
- D3D11_SO_DECLARATION_ENTRY entry = { 0 };
- entry.Stream = 0;
- entry.SemanticName = varying.semanticName.c_str();
- entry.SemanticIndex = varying.semanticIndex + j;
- entry.StartComponent = 0;
- entry.ComponentCount = gl::VariableColumnCount(transposedType);
- entry.OutputSlot = (separatedOutputBuffers ? i : 0);
- soDeclaration.push_back(entry);
- }
+ D3D11_SO_DECLARATION_ENTRY entry = {0};
+ entry.Stream = 0;
+ entry.SemanticName = streamOutVarying.semanticName.c_str();
+ entry.SemanticIndex = streamOutVarying.semanticIndex;
+ entry.StartComponent = 0;
+ entry.ComponentCount = static_cast<BYTE>(streamOutVarying.componentCount);
+ entry.OutputSlot = static_cast<BYTE>(
+ (separatedOutputBuffers ? streamOutVarying.outputSlot : 0));
+ soDeclaration.push_back(entry);
}
- result = mDevice->CreateGeometryShaderWithStreamOutput(function, length, soDeclaration.data(), soDeclaration.size(),
- NULL, 0, 0, NULL, &streamOutShader);
+ result = mDevice->CreateGeometryShaderWithStreamOutput(
+ function, static_cast<unsigned int>(length), soDeclaration.data(),
+ static_cast<unsigned int>(soDeclaration.size()), NULL, 0, 0, NULL,
+ &streamOutShader);
ASSERT(SUCCEEDED(result));
if (FAILED(result))
{
@@ -2891,9 +3216,12 @@ gl::Error Renderer11::loadExecutable(const void *function, size_t length, Shader
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, const D3DCompilerWorkarounds &workarounds,
+gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog,
+ const std::string &shaderHLSL,
+ ShaderType type,
+ const std::vector<D3DVarying> &streamOutVaryings,
+ bool separatedOutputBuffers,
+ const D3DCompilerWorkarounds &workarounds,
ShaderExecutableD3D **outExectuable)
{
const char *profileType = NULL;
@@ -2936,6 +3264,15 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::strin
configs.push_back(CompileConfig(flags | D3DCOMPILE_SKIP_VALIDATION, "skip validation" ));
configs.push_back(CompileConfig(flags | D3DCOMPILE_SKIP_OPTIMIZATION, "skip optimization"));
+ if (getMajorShaderModel() == 4 && getShaderModelSuffix() != "")
+ {
+ // Some shaders might cause a "blob content mismatch between level9 and d3d10 shader".
+ // e.g. dEQP-GLES2.functional.shaders.struct.local.loop_nested_struct_array_*.
+ // Using the [unroll] directive works around this, as does this D3DCompile flag.
+ configs.push_back(
+ CompileConfig(flags | D3DCOMPILE_AVOID_FLOW_CONTROL, "avoid flow control"));
+ }
+
D3D_SHADER_MACRO loopMacros[] = { {"ANGLE_ENABLE_LOOP_FLATTEN", "1"}, {0, 0} };
ID3DBlob *binary = NULL;
@@ -2955,7 +3292,7 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::strin
}
error = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type,
- transformFeedbackVaryings, separatedOutputBuffers, outExectuable);
+ streamOutVaryings, separatedOutputBuffers, outExectuable);
SafeRelease(binary);
if (error.isError())
@@ -2988,12 +3325,14 @@ IndexBuffer *Renderer11::createIndexBuffer()
BufferImpl *Renderer11::createBuffer()
{
- return new Buffer11(this);
+ Buffer11 *buffer = new Buffer11(this);
+ mAliveBuffers.insert(buffer);
+ return buffer;
}
-VertexArrayImpl *Renderer11::createVertexArray()
+VertexArrayImpl *Renderer11::createVertexArray(const gl::VertexArray::Data &data)
{
- return new VertexArray11(this);
+ return new VertexArray11(data);
}
QueryImpl *Renderer11::createQuery(GLenum type)
@@ -3021,7 +3360,7 @@ bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const
ASSERT(getRendererExtensions().pixelBufferObject);
const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
- const d3d11::TextureFormat &d3d11FormatInfo = d3d11::GetTextureFormatInfo(internalFormat, mFeatureLevel);
+ const d3d11::TextureFormat &d3d11FormatInfo = d3d11::GetTextureFormatInfo(internalFormat, mRenderer11DeviceCaps);
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3d11FormatInfo.texFormat);
// sRGB formats do not work with D3D11 buffer SRVs
@@ -3065,17 +3404,42 @@ ImageD3D *Renderer11::createImage()
gl::Error Renderer11::generateMipmap(ImageD3D *dest, ImageD3D *src)
{
- Image11 *dest11 = Image11::makeImage11(dest);
- Image11 *src11 = Image11::makeImage11(src);
+ Image11 *dest11 = GetAs<Image11>(dest);
+ Image11 *src11 = GetAs<Image11>(src);
return Image11::generateMipmap(dest11, src11);
}
+gl::Error Renderer11::generateMipmapsUsingD3D(TextureStorage *storage,
+ const gl::TextureState &textureState)
+{
+ TextureStorage11 *storage11 = GetAs<TextureStorage11>(storage);
+
+ ASSERT(storage11->isRenderTarget());
+ ASSERT(storage11->supportsNativeMipmapFunction());
+
+ ID3D11ShaderResourceView *srv;
+ gl::Error error = storage11->getSRVLevels(textureState.baseLevel, textureState.maxLevel, &srv);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ mDeviceContext->GenerateMips(srv);
+
+ return gl::Error(GL_NO_ERROR);
+}
+
TextureStorage *Renderer11::createTextureStorage2D(SwapChainD3D *swapChain)
{
- SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain);
+ SwapChain11 *swapChain11 = GetAs<SwapChain11>(swapChain);
return new TextureStorage11_2D(this, swapChain11);
}
+TextureStorage *Renderer11::createTextureStorageEGLImage(EGLImageD3D *eglImage)
+{
+ return new TextureStorage11_EGLImage(this, eglImage);
+}
+
TextureStorage *Renderer11::createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly)
{
return new TextureStorage11_2D(this, internalformat, renderTarget, width, height, levels, hintLevelZeroOnly);
@@ -3117,28 +3481,53 @@ RenderbufferImpl *Renderer11::createRenderbuffer()
return renderbuffer;
}
-gl::Error Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format,
- GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels)
+gl::Error Renderer11::readFromAttachment(const gl::FramebufferAttachment &srcAttachment,
+ const gl::Rectangle &sourceArea,
+ GLenum format,
+ GLenum type,
+ GLuint outputPitch,
+ const gl::PixelPackState &pack,
+ uint8_t *pixelsOut)
{
- ASSERT(area.width >= 0);
- ASSERT(area.height >= 0);
+ ASSERT(sourceArea.width >= 0);
+ ASSERT(sourceArea.height >= 0);
- D3D11_TEXTURE2D_DESC textureDesc;
- texture->GetDesc(&textureDesc);
+ const bool invertTexture = UsePresentPathFast(this, &srcAttachment);
+
+ RenderTargetD3D *renderTarget = nullptr;
+ gl::Error error = srcAttachment.getRenderTarget(&renderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ RenderTarget11 *rt11 = GetAs<RenderTarget11>(renderTarget);
+ ASSERT(rt11->getTexture());
+
+ TextureHelper11 textureHelper = TextureHelper11::MakeAndReference(rt11->getTexture());
+ unsigned int sourceSubResource = rt11->getSubresourceIndex();
+
+ const gl::Extents &texSize = textureHelper.getExtents();
+
+ gl::Rectangle actualArea = sourceArea;
+ if (invertTexture)
+ {
+ actualArea.y = texSize.height - actualArea.y - actualArea.height;
+ }
// Clamp read region to the defined texture boundaries, preventing out of bounds reads
// and reads of uninitialized data.
gl::Rectangle safeArea;
- safeArea.x = gl::clamp(area.x, 0, static_cast<int>(textureDesc.Width));
- safeArea.y = gl::clamp(area.y, 0, static_cast<int>(textureDesc.Height));
- safeArea.width = gl::clamp(area.width + std::min(area.x, 0), 0,
- static_cast<int>(textureDesc.Width) - safeArea.x);
- safeArea.height = gl::clamp(area.height + std::min(area.y, 0), 0,
- static_cast<int>(textureDesc.Height) - safeArea.y);
+ safeArea.x = gl::clamp(actualArea.x, 0, texSize.width);
+ safeArea.y = gl::clamp(actualArea.y, 0, texSize.height);
+ safeArea.width =
+ gl::clamp(actualArea.width + std::min(actualArea.x, 0), 0, texSize.width - safeArea.x);
+ safeArea.height =
+ gl::clamp(actualArea.height + std::min(actualArea.y, 0), 0, texSize.height - safeArea.y);
ASSERT(safeArea.x >= 0 && safeArea.y >= 0);
- ASSERT(safeArea.x + safeArea.width <= static_cast<int>(textureDesc.Width));
- ASSERT(safeArea.y + safeArea.height <= static_cast<int>(textureDesc.Height));
+ ASSERT(safeArea.x + safeArea.width <= texSize.width);
+ ASSERT(safeArea.y + safeArea.height <= texSize.height);
if (safeArea.width == 0 || safeArea.height == 0)
{
@@ -3146,35 +3535,29 @@ gl::Error Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int sub
return gl::Error(GL_NO_ERROR);
}
- D3D11_TEXTURE2D_DESC stagingDesc;
- stagingDesc.Width = safeArea.width;
- stagingDesc.Height = safeArea.height;
- stagingDesc.MipLevels = 1;
- stagingDesc.ArraySize = 1;
- stagingDesc.Format = textureDesc.Format;
- stagingDesc.SampleDesc.Count = 1;
- stagingDesc.SampleDesc.Quality = 0;
- stagingDesc.Usage = D3D11_USAGE_STAGING;
- stagingDesc.BindFlags = 0;
- stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
- stagingDesc.MiscFlags = 0;
-
- ID3D11Texture2D* stagingTex = NULL;
- HRESULT result = mDevice->CreateTexture2D(&stagingDesc, NULL, &stagingTex);
- if (FAILED(result))
+ gl::Extents safeSize(safeArea.width, safeArea.height, 1);
+ auto errorOrResult = CreateStagingTexture(textureHelper.getTextureType(),
+ textureHelper.getFormat(), safeSize, mDevice);
+ if (errorOrResult.isError())
{
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal staging texture for ReadPixels, HRESULT: 0x%X.", result);
+ return errorOrResult.getError();
}
- ID3D11Texture2D* srcTex = NULL;
- if (textureDesc.SampleDesc.Count > 1)
+ TextureHelper11 stagingHelper(errorOrResult.getResult());
+ TextureHelper11 resolvedTextureHelper;
+
+ // "srcTexture" usually points to the source texture.
+ // For 2D multisampled textures, it points to the multisampled resolve texture.
+ const TextureHelper11 *srcTexture = &textureHelper;
+
+ if (textureHelper.getTextureType() == GL_TEXTURE_2D && textureHelper.getSampleCount() > 1)
{
D3D11_TEXTURE2D_DESC resolveDesc;
- resolveDesc.Width = textureDesc.Width;
- resolveDesc.Height = textureDesc.Height;
+ resolveDesc.Width = static_cast<UINT>(texSize.width);
+ resolveDesc.Height = static_cast<UINT>(texSize.height);
resolveDesc.MipLevels = 1;
resolveDesc.ArraySize = 1;
- resolveDesc.Format = textureDesc.Format;
+ resolveDesc.Format = textureHelper.getFormat();
resolveDesc.SampleDesc.Count = 1;
resolveDesc.SampleDesc.Quality = 0;
resolveDesc.Usage = D3D11_USAGE_DEFAULT;
@@ -3182,20 +3565,22 @@ gl::Error Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int sub
resolveDesc.CPUAccessFlags = 0;
resolveDesc.MiscFlags = 0;
- result = mDevice->CreateTexture2D(&resolveDesc, NULL, &srcTex);
+ ID3D11Texture2D *resolveTex2D = nullptr;
+ HRESULT result = mDevice->CreateTexture2D(&resolveDesc, nullptr, &resolveTex2D);
if (FAILED(result))
{
- SafeRelease(stagingTex);
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal resolve texture for ReadPixels, HRESULT: 0x%X.", result);
+ return gl::Error(GL_OUT_OF_MEMORY,
+ "Renderer11::readTextureData failed to create internal resolve "
+ "texture for ReadPixels, HRESULT: 0x%X.",
+ result);
}
- mDeviceContext->ResolveSubresource(srcTex, 0, texture, subResource, textureDesc.Format);
- subResource = 0;
- }
- else
- {
- srcTex = texture;
- srcTex->AddRef();
+ mDeviceContext->ResolveSubresource(resolveTex2D, 0, textureHelper.getTexture2D(),
+ sourceSubResource, textureHelper.getFormat());
+ resolvedTextureHelper = TextureHelper11::MakeAndReference(resolveTex2D);
+
+ sourceSubResource = 0;
+ srcTexture = &resolvedTextureHelper;
}
D3D11_BOX srcBox;
@@ -3203,28 +3588,52 @@ gl::Error Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int sub
srcBox.right = static_cast<UINT>(safeArea.x + safeArea.width);
srcBox.top = static_cast<UINT>(safeArea.y);
srcBox.bottom = static_cast<UINT>(safeArea.y + safeArea.height);
- srcBox.front = 0;
- srcBox.back = 1;
- mDeviceContext->CopySubresourceRegion(stagingTex, 0, 0, 0, 0, srcTex, subResource, &srcBox);
+ // Select the correct layer from a 3D attachment
+ srcBox.front = 0;
+ if (textureHelper.getTextureType() == GL_TEXTURE_3D)
+ {
+ srcBox.front = static_cast<UINT>(srcAttachment.layer());
+ }
+ srcBox.back = srcBox.front + 1;
- SafeRelease(srcTex);
+ mDeviceContext->CopySubresourceRegion(stagingHelper.getResource(), 0, 0, 0, 0,
+ srcTexture->getResource(), sourceSubResource, &srcBox);
- PackPixelsParams packParams(safeArea, format, type, outputPitch, pack, 0);
- gl::Error error = packPixels(stagingTex, packParams, pixels);
+ if (invertTexture)
+ {
+ gl::PixelPackState invertTexturePack;
- SafeRelease(stagingTex);
+ // Create a new PixelPackState with reversed row order. Note that we can't just assign
+ // 'invertTexturePack' to be 'pack' (or memcpy) since that breaks the ref counting/object
+ // tracking in the 'pixelBuffer' members, causing leaks. Instead we must use
+ // pixelBuffer.set() twice, which performs the addRef/release correctly
+ invertTexturePack.alignment = pack.alignment;
+ invertTexturePack.pixelBuffer.set(pack.pixelBuffer.get());
+ invertTexturePack.reverseRowOrder = !pack.reverseRowOrder;
- return error;
+ PackPixelsParams packParams(safeArea, format, type, outputPitch, invertTexturePack, 0);
+ error = packPixels(stagingHelper, packParams, pixelsOut);
+
+ invertTexturePack.pixelBuffer.set(nullptr);
+
+ return error;
+ }
+ else
+ {
+ PackPixelsParams packParams(safeArea, format, type, outputPitch, pack, 0);
+ return packPixels(stagingHelper, packParams, pixelsOut);
+ }
}
-gl::Error Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams &params, uint8_t *pixelsOut)
+gl::Error Renderer11::packPixels(const TextureHelper11 &textureHelper,
+ const PackPixelsParams &params,
+ uint8_t *pixelsOut)
{
- D3D11_TEXTURE2D_DESC textureDesc;
- readTexture->GetDesc(&textureDesc);
+ ID3D11Resource *readResource = textureHelper.getResource();
D3D11_MAPPED_SUBRESOURCE mapping;
- HRESULT hr = mDeviceContext->Map(readTexture, 0, D3D11_MAP_READ, 0, &mapping);
+ HRESULT hr = mDeviceContext->Map(readResource, 0, D3D11_MAP_READ, 0, &mapping);
if (FAILED(hr))
{
ASSERT(hr == E_OUTOFMEMORY);
@@ -3244,7 +3653,7 @@ gl::Error Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsP
inputPitch = static_cast<int>(mapping.RowPitch);
}
- const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(textureDesc.Format);
+ const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(textureHelper.getFormat());
const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(dxgiFormatInfo.internalFormat);
if (sourceFormatInfo.format == params.format && sourceFormatInfo.type == params.type)
{
@@ -3256,9 +3665,8 @@ gl::Error Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsP
}
else
{
- const d3d11::DXGIFormat &sourceDXGIFormatInfo = d3d11::GetDXGIFormatInfo(textureDesc.Format);
- ColorCopyFunction fastCopyFunc = sourceDXGIFormatInfo.getFastCopyFunction(params.format, params.type);
-
+ ColorCopyFunction fastCopyFunc =
+ dxgiFormatInfo.getFastCopyFunction(params.format, params.type);
GLenum sizedDestInternalFormat = gl::GetSizedInternalFormat(params.format, params.type);
const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(sizedDestInternalFormat);
@@ -3278,7 +3686,7 @@ gl::Error Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsP
}
else
{
- ColorReadFunction colorReadFunction = sourceDXGIFormatInfo.colorReadFunction;
+ ColorReadFunction colorReadFunction = dxgiFormatInfo.colorReadFunction;
ColorWriteFunction colorWriteFunction = GetColorWriteFunction(params.format, params.type);
uint8_t temp[16]; // Maximum size of any Color<T> type used.
@@ -3303,21 +3711,27 @@ gl::Error Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsP
}
}
- mDeviceContext->Unmap(readTexture, 0);
+ mDeviceContext->Unmap(readResource, 0);
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTargetD3D *readRenderTarget,
- RenderTargetD3D *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor,
- bool colorBlit, bool depthBlit, bool stencilBlit)
+gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn,
+ const gl::Rectangle &drawRectIn,
+ RenderTargetD3D *readRenderTarget,
+ RenderTargetD3D *drawRenderTarget,
+ GLenum filter,
+ const gl::Rectangle *scissor,
+ bool colorBlit,
+ bool depthBlit,
+ bool stencilBlit)
{
// Since blitRenderbufferRect is called for each render buffer that needs to be blitted,
// it should never be the case that both color and depth/stencil need to be blitted at
// at the same time.
ASSERT(colorBlit != (depthBlit || stencilBlit));
- RenderTarget11 *drawRenderTarget11 = RenderTarget11::makeRenderTarget11(drawRenderTarget);
+ RenderTarget11 *drawRenderTarget11 = GetAs<RenderTarget11>(drawRenderTarget);
if (!drawRenderTarget)
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal draw render target from the draw framebuffer.");
@@ -3328,7 +3742,7 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const
ID3D11RenderTargetView *drawRTV = drawRenderTarget11->getRenderTargetView();
ID3D11DepthStencilView *drawDSV = drawRenderTarget11->getDepthStencilView();
- RenderTarget11 *readRenderTarget11 = RenderTarget11::makeRenderTarget11(readRenderTarget);
+ RenderTarget11 *readRenderTarget11 = GetAs<RenderTarget11>(readRenderTarget);
if (!readRenderTarget)
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal read render target from the read framebuffer.");
@@ -3376,13 +3790,94 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const
gl::Extents readSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1);
gl::Extents drawSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1);
+ // From the spec:
+ // "The actual region taken from the read framebuffer is limited to the intersection of the
+ // source buffers being transferred, which may include the color buffer selected by the read
+ // buffer, the depth buffer, and / or the stencil buffer depending on mask."
+ // This means negative x and y are out of bounds, and not to be read from. We handle this here
+ // by internally scaling the read and draw rectangles.
+ gl::Rectangle readRect = readRectIn;
+ gl::Rectangle drawRect = drawRectIn;
+ auto readToDrawX = [&drawRectIn, &readRectIn](int readOffset)
+ {
+ double readToDrawScale =
+ static_cast<double>(drawRectIn.width) / static_cast<double>(readRectIn.width);
+ return static_cast<int>(round(static_cast<double>(readOffset) * readToDrawScale));
+ };
+ if (readRect.x < 0)
+ {
+ int readOffset = -readRect.x;
+ readRect.x += readOffset;
+ readRect.width -= readOffset;
+
+ int drawOffset = readToDrawX(readOffset);
+ drawRect.x += drawOffset;
+ drawRect.width -= drawOffset;
+ }
+
+ auto readToDrawY = [&drawRectIn, &readRectIn](int readOffset)
+ {
+ double readToDrawScale =
+ static_cast<double>(drawRectIn.height) / static_cast<double>(readRectIn.height);
+ return static_cast<int>(round(static_cast<double>(readOffset) * readToDrawScale));
+ };
+ if (readRect.y < 0)
+ {
+ int readOffset = -readRect.y;
+ readRect.y += readOffset;
+ readRect.height -= readOffset;
+
+ int drawOffset = readToDrawY(readOffset);
+ drawRect.y += drawOffset;
+ drawRect.height -= drawOffset;
+ }
+
+ if (readRect.x1() < 0)
+ {
+ int readOffset = -readRect.x1();
+ readRect.width += readOffset;
+
+ int drawOffset = readToDrawX(readOffset);
+ drawRect.width += drawOffset;
+ }
+
+ if (readRect.y1() < 0)
+ {
+ int readOffset = -readRect.y1();
+ readRect.height += readOffset;
+
+ int drawOffset = readToDrawY(readOffset);
+ drawRect.height += drawOffset;
+ }
+
bool scissorNeeded = scissor && gl::ClipRectangle(drawRect, *scissor, NULL);
- bool wholeBufferCopy = !scissorNeeded &&
- readRect.x == 0 && readRect.width == readSize.width &&
- readRect.y == 0 && readRect.height == readSize.height &&
- drawRect.x == 0 && drawRect.width == drawSize.width &&
- drawRect.y == 0 && drawRect.height == drawSize.height;
+ const auto &destFormatInfo = gl::GetInternalFormatInfo(drawRenderTarget->getInternalFormat());
+ const auto &srcFormatInfo = gl::GetInternalFormatInfo(readRenderTarget->getInternalFormat());
+ const auto &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(drawRenderTarget11->getDXGIFormat());
+
+ // Some blits require masking off emulated texture channels. eg: from RGBA8 to RGB8, we
+ // emulate RGB8 with RGBA8, so we need to mask off the alpha channel when we copy.
+
+ gl::Color<bool> colorMask;
+ colorMask.red = (srcFormatInfo.redBits > 0) && (destFormatInfo.redBits == 0) &&
+ (dxgiFormatInfo.redBits > 0);
+ colorMask.green = (srcFormatInfo.greenBits > 0) && (destFormatInfo.greenBits == 0) &&
+ (dxgiFormatInfo.greenBits > 0);
+ colorMask.blue = (srcFormatInfo.blueBits > 0) && (destFormatInfo.blueBits == 0) &&
+ (dxgiFormatInfo.blueBits > 0);
+ colorMask.alpha = (srcFormatInfo.alphaBits > 0) && (destFormatInfo.alphaBits == 0) &&
+ (dxgiFormatInfo.alphaBits > 0);
+
+ // We only currently support masking off the alpha channel.
+ bool colorMaskingNeeded = colorMask.alpha;
+ ASSERT(!colorMask.red && !colorMask.green && !colorMask.blue);
+
+ bool wholeBufferCopy = !scissorNeeded && !colorMaskingNeeded && readRect.x == 0 &&
+ readRect.width == readSize.width && readRect.y == 0 &&
+ readRect.height == readSize.height && drawRect.x == 0 &&
+ drawRect.width == drawSize.width && drawRect.y == 0 &&
+ drawRect.height == drawSize.height;
bool stretchRequired = readRect.width != drawRect.width || readRect.height != drawRect.height;
@@ -3393,14 +3888,13 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const
drawRect.x < 0 || drawRect.x + drawRect.width > drawSize.width ||
drawRect.y < 0 || drawRect.y + drawRect.height > drawSize.height;
- const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(drawRenderTarget11->getDXGIFormat());
bool partialDSBlit = (dxgiFormatInfo.depthBits > 0 && depthBlit) != (dxgiFormatInfo.stencilBits > 0 && stencilBlit);
gl::Error result(GL_NO_ERROR);
if (readRenderTarget11->getDXGIFormat() == drawRenderTarget11->getDXGIFormat() &&
!stretchRequired && !outOfBounds && !flipRequired && !partialDSBlit &&
- (!(depthBlit || stencilBlit) || wholeBufferCopy))
+ !colorMaskingNeeded && (!(depthBlit || stencilBlit) || wholeBufferCopy))
{
UINT dstX = drawRect.x;
UINT dstY = drawRect.y;
@@ -3470,9 +3964,10 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const
}
else
{
- GLenum format = gl::GetInternalFormatInfo(drawRenderTarget->getInternalFormat()).format;
+ // We don't currently support masking off any other channel than alpha
+ bool maskOffAlpha = colorMaskingNeeded && colorMask.alpha;
result = mBlit->copyTexture(readSRV, readArea, readSize, drawRTV, drawArea, drawSize,
- scissor, format, filter);
+ scissor, destFormatInfo.format, filter, maskOffAlpha);
}
}
@@ -3484,9 +3979,44 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const
bool Renderer11::isES3Capable() const
{
- return (d3d11_gl::GetMaximumClientVersion(mFeatureLevel) > 2);
+ return (d3d11_gl::GetMaximumClientVersion(mRenderer11DeviceCaps.featureLevel) > 2);
};
+void Renderer11::onSwap()
+{
+ // Send histogram updates every half hour
+ const double kHistogramUpdateInterval = 30 * 60;
+
+ const double currentTime = ANGLEPlatformCurrent()->monotonicallyIncreasingTime();
+ const double timeSinceLastUpdate = currentTime - mLastHistogramUpdateTime;
+
+ if (timeSinceLastUpdate > kHistogramUpdateInterval)
+ {
+ updateHistograms();
+ mLastHistogramUpdateTime = currentTime;
+ }
+}
+
+void Renderer11::updateHistograms()
+{
+ // Update the buffer CPU memory histogram
+ {
+ size_t sizeSum = 0;
+ for (auto &buffer : mAliveBuffers)
+ {
+ sizeSum += buffer->getTotalCPUBufferMemoryBytes();
+ }
+ const int kOneMegaByte = 1024 * 1024;
+ ANGLE_HISTOGRAM_MEMORY_MB("GPU.ANGLE.Buffer11CPUMemoryMB",
+ static_cast<int>(sizeSum) / kOneMegaByte);
+ }
+}
+
+void Renderer11::onBufferDelete(const Buffer11 *deleted)
+{
+ mAliveBuffers.erase(deleted);
+}
+
ID3D11Texture2D *Renderer11::resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource)
{
D3D11_TEXTURE2D_DESC textureDesc;
@@ -3545,54 +4075,64 @@ bool Renderer11::getLUID(LUID *adapterLuid) const
return true;
}
-VertexConversionType Renderer11::getVertexConversionType(const gl::VertexFormat &vertexFormat) const
+VertexConversionType Renderer11::getVertexConversionType(gl::VertexFormatType vertexFormatType) const
{
- return d3d11::GetVertexFormatInfo(vertexFormat, mFeatureLevel).conversionType;
+ return d3d11::GetVertexFormatInfo(vertexFormatType, mRenderer11DeviceCaps.featureLevel).conversionType;
}
-GLenum Renderer11::getVertexComponentType(const gl::VertexFormat &vertexFormat) const
+GLenum Renderer11::getVertexComponentType(gl::VertexFormatType vertexFormatType) const
{
- return d3d11::GetDXGIFormatInfo(d3d11::GetVertexFormatInfo(vertexFormat, mFeatureLevel).nativeFormat).componentType;
+ return d3d11::GetDXGIFormatInfo(d3d11::GetVertexFormatInfo(vertexFormatType, mRenderer11DeviceCaps.featureLevel).nativeFormat).componentType;
}
-void Renderer11::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const
+void Renderer11::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps,
+ gl::Extensions *outExtensions, gl::Limitations *outLimitations) const
{
- d3d11_gl::GenerateCaps(mDevice, mDeviceContext, outCaps, outTextureCaps, outExtensions);
+ d3d11_gl::GenerateCaps(mDevice, mDeviceContext, mRenderer11DeviceCaps, outCaps, outTextureCaps,
+ outExtensions, outLimitations);
}
-Workarounds Renderer11::generateWorkarounds() const
+WorkaroundsD3D Renderer11::generateWorkarounds() const
{
- return d3d11::GenerateWorkarounds(mFeatureLevel);
+ return d3d11::GenerateWorkarounds(mRenderer11DeviceCaps.featureLevel);
}
-void Renderer11::setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, ID3D11ShaderResourceView *srv)
+void Renderer11::createAnnotator()
{
- auto &currentSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
+ // The D3D11 renderer must choose the D3D9 debug annotator because the D3D11 interface
+ // method ID3DUserDefinedAnnotation::GetStatus on desktop builds doesn't work with the Graphics
+ // Diagnostics tools in Visual Studio 2013.
+ // The D3D9 annotator works properly for both D3D11 and D3D9.
+ // Incorrect status reporting can cause ANGLE to log unnecessary debug events.
+#ifdef ANGLE_ENABLE_D3D9
+ mAnnotator = new DebugAnnotator9();
+#else
+ mAnnotator = new DebugAnnotator11();
+#endif
+}
- ASSERT(static_cast<size_t>(resourceSlot) < currentSRVs.size());
- auto &record = currentSRVs[resourceSlot];
+gl::Error Renderer11::clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd)
+{
+ return mStateManager.clearTextures(samplerType, rangeStart, rangeEnd);
+}
- if (record.srv != reinterpret_cast<uintptr_t>(srv))
+egl::Error Renderer11::getEGLDevice(DeviceImpl **device)
+{
+ if (mEGLDevice == nullptr)
{
- if (shaderType == gl::SAMPLER_VERTEX)
- {
- mDeviceContext->VSSetShaderResources(resourceSlot, 1, &srv);
- }
- else
- {
- mDeviceContext->PSSetShaderResources(resourceSlot, 1, &srv);
- }
+ ASSERT(mDevice != nullptr);
+ mEGLDevice = new DeviceD3D();
+ egl::Error error = mEGLDevice->initialize(reinterpret_cast<void *>(mDevice),
+ EGL_D3D11_DEVICE_ANGLE, EGL_FALSE);
- record.srv = reinterpret_cast<uintptr_t>(srv);
- if (srv)
- {
- record.resource = reinterpret_cast<uintptr_t>(GetViewResource(srv));
- srv->GetDesc(&record.desc);
- }
- else
+ if (error.isError())
{
- record.resource = 0;
+ SafeDelete(mEGLDevice);
+ return error;
}
}
+
+ *device = static_cast<DeviceImpl *>(mEGLDevice);
+ return egl::Error(EGL_SUCCESS);
}
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
index cc7d6c237b..b4e7761ffc 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
@@ -18,9 +18,9 @@
#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
#include "libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h"
#include "libANGLE/renderer/d3d/d3d11/InputLayoutCache.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h"
-
-struct ID3D11DeviceContext1;
+#include "libANGLE/renderer/d3d/d3d11/StateManager11.h"
namespace gl
{
@@ -28,6 +28,8 @@ class FramebufferAttachment;
struct ImageIndex;
}
+struct ID3D11DeviceContext1;
+
namespace rx
{
@@ -35,12 +37,24 @@ class VertexDataManager;
class IndexDataManager;
class StreamingIndexBufferInterface;
class Blit11;
+class Buffer11;
class Clear11;
class PixelTransfer11;
class RenderTarget11;
class Trim11;
struct PackPixelsParams;
+struct Renderer11DeviceCaps
+{
+ D3D_FEATURE_LEVEL featureLevel;
+ bool supportsDXGI1_2; // Support for DXGI 1.2
+ bool supportsClearView; // Support for ID3D11DeviceContext1::ClearView
+ bool supportsConstantBufferOffsets; // Support for Constant buffer offset
+ UINT B5G6R5support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B5G6R5_UNORM
+ UINT B4G4R4A4support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B4G4R4A4_UNORM
+ UINT B5G5R5A1support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B5G5R5A1_UNORM
+};
+
enum
{
MAX_VERTEX_UNIFORM_VECTORS_D3D11 = 1024,
@@ -64,6 +78,24 @@ enum D3D11InitError
D3D11_INIT_INCOMPATIBLE_DXGI,
// Other initialization error
D3D11_INIT_OTHER_ERROR,
+ // CreateDevice returned E_FAIL
+ D3D11_INIT_CREATEDEVICE_FAIL,
+ // CreateDevice returned E_NOTIMPL
+ D3D11_INIT_CREATEDEVICE_NOTIMPL,
+ // CreateDevice returned E_OUTOFMEMORY
+ D3D11_INIT_CREATEDEVICE_OUTOFMEMORY,
+ // CreateDevice returned DXGI_ERROR_INVALID_CALL
+ D3D11_INIT_CREATEDEVICE_INVALIDCALL,
+ // CreateDevice returned DXGI_ERROR_SDK_COMPONENT_MISSING
+ D3D11_INIT_CREATEDEVICE_COMPONENTMISSING,
+ // CreateDevice returned DXGI_ERROR_WAS_STILL_DRAWING
+ D3D11_INIT_CREATEDEVICE_WASSTILLDRAWING,
+ // CreateDevice returned DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
+ D3D11_INIT_CREATEDEVICE_NOTAVAILABLE,
+ // CreateDevice returned DXGI_ERROR_DEVICE_HUNG
+ D3D11_INIT_CREATEDEVICE_DEVICEHUNG,
+ // CreateDevice returned NULL
+ D3D11_INIT_CREATEDEVICE_NULL,
NUM_D3D11_INIT_ERRORS
};
@@ -73,66 +105,65 @@ class Renderer11 : public RendererD3D
explicit Renderer11(egl::Display *display);
virtual ~Renderer11();
- static Renderer11 *makeRenderer11(Renderer *renderer);
-
egl::Error initialize() override;
virtual bool resetDevice();
egl::ConfigSet generateConfigs() const override;
+ void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const override;
gl::Error flush() override;
gl::Error finish() override;
- virtual SwapChainD3D *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
+ SwapChainD3D *createSwapChain(NativeWindow nativeWindow,
+ HANDLE shareHandle,
+ GLenum backBufferFormat,
+ GLenum depthBufferFormat,
+ EGLint orientation) override;
+
+ CompilerImpl *createCompiler() override;
virtual gl::Error generateSwizzle(gl::Texture *texture);
virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler);
virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture);
gl::Error setUniformBuffers(const gl::Data &data,
- const GLint vertexUniformBuffers[],
- const GLint fragmentUniformBuffers[]) override;
+ const std::vector<GLint> &vertexUniformBuffers,
+ const std::vector<GLint> &fragmentUniformBuffers) override;
- virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState);
- gl::Error setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
- unsigned int sampleMask) override;
- virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
- int stencilBackRef, bool frontFaceCCW);
-
- virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled);
- virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
- bool ignoreViewport);
+ gl::Error updateState(const gl::Data &data, GLenum drawMode) override;
virtual bool applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize);
gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override;
- virtual gl::Error applyShaders(gl::Program *program, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
- bool rasterizerDiscard, bool transformFeedbackActive);
-
- virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray);
- virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances);
- virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
+ gl::Error applyUniforms(const ProgramD3D &programD3D,
+ GLenum drawMode,
+ const std::vector<D3DUniform *> &uniformArray) override;
+ virtual gl::Error applyVertexBuffer(const gl::State &state,
+ GLenum mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instances,
+ TranslatedIndexData *indexInfo);
+ gl::Error applyIndexBuffer(const gl::Data &data,
+ const GLvoid *indices,
+ GLsizei count,
+ GLenum mode,
+ GLenum type,
+ TranslatedIndexData *indexInfo) override;
void applyTransformFeedbackBuffers(const gl::State &state) override;
- gl::Error drawArrays(const gl::Data &data, GLenum mode, GLsizei count, GLsizei instances, bool usesPointSize) override;
- virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
- gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances);
-
- virtual void markAllStateDirty();
-
// lost device
bool testDeviceLost() override;
bool testDeviceResettable() override;
- VendorID getVendorId() const override;
std::string getRendererDescription() const override;
- GUID getAdapterIdentifier() const override;
+ DeviceIdentifier getAdapterIdentifier() const override;
virtual unsigned int getReservedVertexUniformVectors() const;
virtual unsigned int getReservedFragmentUniformVectors() const;
virtual unsigned int getReservedVertexUniformBuffers() const;
virtual unsigned int getReservedFragmentUniformBuffers() const;
- virtual bool getShareHandleSupport() const;
- virtual bool getPostSubBufferSupport() const;
+
+ bool getShareHandleSupport() const;
virtual int getMajorShaderModel() const;
int getMinorShaderModel() const override;
@@ -150,30 +181,38 @@ class Renderer11 : public RendererD3D
// RenderTarget creation
virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT);
+ gl::Error createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) override;
// Framebuffer creation
- FramebufferImpl *createDefaultFramebuffer(const gl::Framebuffer::Data &data) override;
FramebufferImpl *createFramebuffer(const gl::Framebuffer::Data &data) override;
// Shader creation
- virtual CompilerImpl *createCompiler(const gl::Data &data);
- virtual ShaderImpl *createShader(GLenum type);
- virtual ProgramImpl *createProgram();
+ ShaderImpl *createShader(const gl::Shader::Data &data) override;
+ ProgramImpl *createProgram(const gl::Program::Data &data) override;
// Shader operations
- virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, ShaderExecutableD3D **outExecutable);
- virtual gl::Error compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, const D3DCompilerWorkarounds &workarounds,
- ShaderExecutableD3D **outExectuable);
- virtual UniformStorageD3D *createUniformStorage(size_t storageSize);
+ gl::Error loadExecutable(const void *function,
+ size_t length,
+ ShaderType type,
+ const std::vector<D3DVarying> &streamOutVaryings,
+ bool separatedOutputBuffers,
+ ShaderExecutableD3D **outExecutable) override;
+ gl::Error compileToExecutable(gl::InfoLog &infoLog,
+ const std::string &shaderHLSL,
+ ShaderType type,
+ const std::vector<D3DVarying> &streamOutVaryings,
+ bool separatedOutputBuffers,
+ const D3DCompilerWorkarounds &workarounds,
+ ShaderExecutableD3D **outExectuable) override;
+ UniformStorageD3D *createUniformStorage(size_t storageSize) override;
// Image operations
virtual ImageD3D *createImage();
gl::Error generateMipmap(ImageD3D *dest, ImageD3D *source) override;
+ gl::Error generateMipmapsUsingD3D(TextureStorage *storage,
+ const gl::TextureState &textureState) override;
virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain);
+ TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage) override;
virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly);
virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly);
virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels);
@@ -191,7 +230,7 @@ class Renderer11 : public RendererD3D
virtual IndexBuffer *createIndexBuffer();
// Vertex Array creation
- virtual VertexArrayImpl *createVertexArray();
+ VertexArrayImpl *createVertexArray(const gl::VertexArray::Data &data) override;
// Query and Fence creation
virtual QueryImpl *createQuery(GLenum type);
@@ -203,10 +242,13 @@ class Renderer11 : public RendererD3D
// D3D11-renderer specific methods
ID3D11Device *getDevice() { return mDevice; }
+ void *getD3DDevice() override;
ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; };
ID3D11DeviceContext1 *getDeviceContext1IfSupported() { return mDeviceContext1; };
DXGIFactory *getDxgiFactory() { return mDxgiFactory; };
+ RenderStateCache &getStateCache() { return mStateCache; }
+
Blit11 *getBlitter() { return mBlit; }
Clear11 *getClearer() { return mClear; }
@@ -215,64 +257,108 @@ class Renderer11 : public RendererD3D
virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget,
GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea);
+ void markAllStateDirty();
void unapplyRenderTargets();
void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView);
- gl::Error packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams &params, uint8_t *pixelsOut);
+ gl::Error packPixels(const TextureHelper11 &textureHelper,
+ const PackPixelsParams &params,
+ uint8_t *pixelsOut);
bool getLUID(LUID *adapterLuid) const override;
- virtual VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const;
- virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const;
-
- gl::Error readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format,
- GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels);
+ VertexConversionType getVertexConversionType(gl::VertexFormatType vertexFormatType) const override;
+ GLenum getVertexComponentType(gl::VertexFormatType vertexFormatType) const override;
- void setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, ID3D11ShaderResourceView *srv);
+ gl::Error readFromAttachment(const gl::FramebufferAttachment &srcAttachment,
+ const gl::Rectangle &sourceArea,
+ GLenum format,
+ GLenum type,
+ GLuint outputPitch,
+ const gl::PixelPackState &pack,
+ uint8_t *pixels);
gl::Error blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTargetD3D *readRenderTarget,
RenderTargetD3D *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor,
bool colorBlit, bool depthBlit, bool stencilBlit);
bool isES3Capable() const;
- D3D_FEATURE_LEVEL getFeatureLevel() const { return mFeatureLevel; };
+ const Renderer11DeviceCaps &getRenderer11DeviceCaps() { return mRenderer11DeviceCaps; };
RendererClass getRendererClass() const override { return RENDERER_D3D11; }
+ InputLayoutCache *getInputLayoutCache() { return &mInputLayoutCache; }
+ StateManager11 *getStateManager() { return &mStateManager; }
- private:
- void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const override;
- Workarounds generateWorkarounds() const override;
+ void onSwap();
+ void onBufferDelete(const Buffer11 *deleted);
+
+ egl::Error getEGLDevice(DeviceImpl **device) override;
- gl::Error drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer);
- gl::Error drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances);
+ protected:
+ void createAnnotator() override;
+ gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) override;
+ gl::Error applyShadersImpl(const gl::Data &data, GLenum drawMode) override;
+
+ void syncState(const gl::State &state, const gl::State::DirtyBits &bitmask) override;
+
+ private:
+ gl::Error drawArraysImpl(const gl::Data &data,
+ GLenum mode,
+ GLsizei count,
+ GLsizei instances) override;
+ gl::Error drawElementsImpl(const gl::Data &data,
+ const TranslatedIndexData &indexInfo,
+ GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ GLsizei instances) override;
+
+ void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps,
+ gl::Extensions *outExtensions,
+ gl::Limitations *outLimitations) const override;
+
+ WorkaroundsD3D generateWorkarounds() const override;
+
+ gl::Error drawLineLoop(const gl::Data &data,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ const TranslatedIndexData *indexInfo,
+ int instances);
+ gl::Error drawTriangleFan(const gl::Data &data,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ int minIndex,
+ int instances);
ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource);
- void unsetConflictingSRVs(gl::SamplerType shaderType, uintptr_t resource, const gl::ImageIndex *index);
+
+ void populateRenderer11DeviceCaps();
+
+ void updateHistograms();
HMODULE mD3d11Module;
HMODULE mDxgiModule;
+ HMODULE mDCompModule;
std::vector<D3D_FEATURE_LEVEL> mAvailableFeatureLevels;
- D3D_DRIVER_TYPE mDriverType;
+ D3D_DRIVER_TYPE mRequestedDriverType;
+ bool mCreatedWithDeviceEXT;
+ DeviceD3D *mEGLDevice;
HLSLCompiler mCompiler;
+ egl::Error initializeD3DDevice();
void initializeDevice();
void releaseDeviceResources();
void release();
+ d3d11::ANGLED3D11DeviceType getDeviceType() const;
+
RenderStateCache mStateCache;
// current render target states
uintptr_t mAppliedRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS];
uintptr_t mAppliedDSV;
- bool mDepthStencilInitialized;
- bool mRenderTargetDescInitialized;
-
- struct RenderTargetDesc
- {
- size_t width;
- size_t height;
- DXGI_FORMAT format;
- };
- RenderTargetDesc mRenderTargetDesc;
// Currently applied sampler states
std::vector<bool> mForceSetVertexSamplerStates;
@@ -281,42 +367,7 @@ class Renderer11 : public RendererD3D
std::vector<bool> mForceSetPixelSamplerStates;
std::vector<gl::SamplerState> mCurPixelSamplerStates;
- // Currently applied textures
- struct SRVRecord
- {
- uintptr_t srv;
- uintptr_t resource;
- D3D11_SHADER_RESOURCE_VIEW_DESC desc;
- };
- std::vector<SRVRecord> mCurVertexSRVs;
- std::vector<SRVRecord> mCurPixelSRVs;
-
- // Currently applied blend state
- bool mForceSetBlendState;
- gl::BlendState mCurBlendState;
- gl::ColorF mCurBlendColor;
- unsigned int mCurSampleMask;
-
- // Currently applied rasterizer state
- bool mForceSetRasterState;
- gl::RasterizerState mCurRasterState;
-
- // Currently applied depth stencil state
- bool mForceSetDepthStencilState;
- gl::DepthStencilState mCurDepthStencilState;
- int mCurStencilRef;
- int mCurStencilBackRef;
-
- // Currently applied scissor rectangle
- bool mForceSetScissor;
- bool mScissorEnabled;
- gl::Rectangle mCurScissor;
-
- // Currently applied viewport
- bool mForceSetViewport;
- gl::Rectangle mCurViewport;
- float mCurNear;
- float mCurFar;
+ StateManager11 mStateManager;
// Currently applied primitive topology
D3D11_PRIMITIVE_TOPOLOGY mCurrentPrimitiveTopology;
@@ -325,6 +376,7 @@ class Renderer11 : public RendererD3D
ID3D11Buffer *mAppliedIB;
DXGI_FORMAT mAppliedIBFormat;
unsigned int mAppliedIBOffset;
+ bool mAppliedIBChanged;
// Currently applied transform feedback buffers
size_t mAppliedNumXFBBindings;
@@ -342,16 +394,14 @@ class Renderer11 : public RendererD3D
uintptr_t mAppliedGeometryShader;
uintptr_t mAppliedPixelShader;
- dx_VertexConstants mVertexConstants;
- dx_VertexConstants mAppliedVertexConstants;
+ dx_VertexConstants11 mAppliedVertexConstants;
ID3D11Buffer *mDriverConstantBufferVS;
ID3D11Buffer *mCurrentVertexConstantBuffer;
unsigned int mCurrentConstantBufferVS[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS];
GLintptr mCurrentConstantBufferVSOffset[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS];
GLsizeiptr mCurrentConstantBufferVSSize[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS];
- dx_PixelConstants mPixelConstants;
- dx_PixelConstants mAppliedPixelConstants;
+ dx_PixelConstants11 mAppliedPixelConstants;
ID3D11Buffer *mDriverConstantBufferPS;
ID3D11Buffer *mCurrentPixelConstantBuffer;
unsigned int mCurrentConstantBufferPS[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS];
@@ -381,19 +431,26 @@ class Renderer11 : public RendererD3D
// Sync query
ID3D11Query *mSyncQuery;
- // Constant buffer offset support
- bool mSupportsConstantBufferOffsets;
+ // Created objects state tracking
+ std::set<const Buffer11*> mAliveBuffers;
+
+ double mLastHistogramUpdateTime;
ID3D11Device *mDevice;
- D3D_FEATURE_LEVEL mFeatureLevel;
+ Renderer11DeviceCaps mRenderer11DeviceCaps;
ID3D11DeviceContext *mDeviceContext;
ID3D11DeviceContext1 *mDeviceContext1;
IDXGIAdapter *mDxgiAdapter;
DXGI_ADAPTER_DESC mAdapterDescription;
char mDescription[128];
DXGIFactory *mDxgiFactory;
+#if !defined(ANGLE_MINGW32_COMPAT)
+ ID3D11Debug *mDebug;
+#endif
+
+ std::vector<GLuint> mScratchIndexDataBuffer;
- DebugAnnotator11 mAnnotator;
+ mutable Optional<bool> mSupportsShareHandles;
};
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp
index 7e64c3183d..4da51afe49 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp
@@ -48,12 +48,6 @@ ShaderExecutable11::~ShaderExecutable11()
SafeRelease(mStreamOutExecutable);
}
-ShaderExecutable11 *ShaderExecutable11::makeShaderExecutable11(ShaderExecutableD3D *executable)
-{
- ASSERT(HAS_DYNAMIC_TYPE(ShaderExecutable11*, executable));
- return static_cast<ShaderExecutable11*>(executable);
-}
-
ID3D11VertexShader *ShaderExecutable11::getVertexShader() const
{
return mVertexExecutable;
@@ -83,7 +77,7 @@ UniformStorage11::UniformStorage11(Renderer11 *renderer, size_t initialSize)
if (initialSize > 0)
{
D3D11_BUFFER_DESC constantBufferDescription = {0};
- constantBufferDescription.ByteWidth = initialSize;
+ constantBufferDescription.ByteWidth = static_cast<unsigned int>(initialSize);
constantBufferDescription.Usage = D3D11_USAGE_DYNAMIC;
constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
constantBufferDescription.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
@@ -101,10 +95,4 @@ UniformStorage11::~UniformStorage11()
SafeRelease(mConstantBuffer);
}
-const UniformStorage11 *UniformStorage11::makeUniformStorage11(const UniformStorageD3D *uniformStorage)
-{
- ASSERT(HAS_DYNAMIC_TYPE(const UniformStorage11*, uniformStorage));
- return static_cast<const UniformStorage11*>(uniformStorage);
-}
-
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h
index 02558ee4dc..379f39fe53 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h
@@ -26,8 +26,6 @@ class ShaderExecutable11 : public ShaderExecutableD3D
virtual ~ShaderExecutable11();
- static ShaderExecutable11 *makeShaderExecutable11(ShaderExecutableD3D *executable);
-
ID3D11PixelShader *getPixelShader() const;
ID3D11VertexShader *getVertexShader() const;
ID3D11GeometryShader *getGeometryShader() const;
@@ -46,8 +44,6 @@ class UniformStorage11 : public UniformStorageD3D
UniformStorage11(Renderer11 *renderer, size_t initialSize);
virtual ~UniformStorage11();
- static const UniformStorage11 *makeUniformStorage11(const UniformStorageD3D *uniformStorage);
-
ID3D11Buffer *getConstantBuffer() const { return mConstantBuffer; }
private:
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
new file mode 100644
index 0000000000..aa34fd4de8
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
@@ -0,0 +1,1040 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// StateManager11.cpp: Defines a class for caching D3D11 state
+
+#include "libANGLE/renderer/d3d/d3d11/StateManager11.h"
+
+#include "common/BitSetIterator.h"
+#include "common/utilities.h"
+#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+
+namespace rx
+{
+
+namespace
+{
+bool ImageIndexConflictsWithSRV(const gl::ImageIndex &index, D3D11_SHADER_RESOURCE_VIEW_DESC desc)
+{
+ unsigned mipLevel = index.mipIndex;
+ unsigned layerIndex = index.layerIndex;
+ GLenum type = index.type;
+
+ switch (desc.ViewDimension)
+ {
+ case D3D11_SRV_DIMENSION_TEXTURE2D:
+ {
+ unsigned maxSrvMip = desc.Texture2D.MipLevels + desc.Texture2D.MostDetailedMip;
+ maxSrvMip = (desc.Texture2D.MipLevels == -1) ? INT_MAX : maxSrvMip;
+
+ unsigned mipMin = index.mipIndex;
+ unsigned mipMax = (layerIndex == -1) ? INT_MAX : layerIndex;
+
+ return type == GL_TEXTURE_2D &&
+ gl::RangeUI(mipMin, mipMax)
+ .intersects(gl::RangeUI(desc.Texture2D.MostDetailedMip, maxSrvMip));
+ }
+
+ case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
+ {
+ unsigned maxSrvMip =
+ desc.Texture2DArray.MipLevels + desc.Texture2DArray.MostDetailedMip;
+ maxSrvMip = (desc.Texture2DArray.MipLevels == -1) ? INT_MAX : maxSrvMip;
+
+ unsigned maxSlice = desc.Texture2DArray.FirstArraySlice + desc.Texture2DArray.ArraySize;
+
+ // Cube maps can be mapped to Texture2DArray SRVs
+ return (type == GL_TEXTURE_2D_ARRAY || gl::IsCubeMapTextureTarget(type)) &&
+ desc.Texture2DArray.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip &&
+ desc.Texture2DArray.FirstArraySlice <= layerIndex && layerIndex < maxSlice;
+ }
+
+ case D3D11_SRV_DIMENSION_TEXTURECUBE:
+ {
+ unsigned maxSrvMip = desc.TextureCube.MipLevels + desc.TextureCube.MostDetailedMip;
+ maxSrvMip = (desc.TextureCube.MipLevels == -1) ? INT_MAX : maxSrvMip;
+
+ return gl::IsCubeMapTextureTarget(type) &&
+ desc.TextureCube.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip;
+ }
+
+ case D3D11_SRV_DIMENSION_TEXTURE3D:
+ {
+ unsigned maxSrvMip = desc.Texture3D.MipLevels + desc.Texture3D.MostDetailedMip;
+ maxSrvMip = (desc.Texture3D.MipLevels == -1) ? INT_MAX : maxSrvMip;
+
+ return type == GL_TEXTURE_3D && desc.Texture3D.MostDetailedMip <= mipLevel &&
+ mipLevel < maxSrvMip;
+ }
+ default:
+ // We only handle the cases corresponding to valid image indexes
+ UNIMPLEMENTED();
+ }
+
+ return false;
+}
+
+// Does *not* increment the resource ref count!!
+ID3D11Resource *GetViewResource(ID3D11View *view)
+{
+ ID3D11Resource *resource = NULL;
+ ASSERT(view);
+ view->GetResource(&resource);
+ resource->Release();
+ return resource;
+}
+
+} // anonymous namespace
+
+void StateManager11::SRVCache::update(size_t resourceIndex, ID3D11ShaderResourceView *srv)
+{
+ ASSERT(resourceIndex < mCurrentSRVs.size());
+ SRVRecord *record = &mCurrentSRVs[resourceIndex];
+
+ record->srv = reinterpret_cast<uintptr_t>(srv);
+ if (srv)
+ {
+ record->resource = reinterpret_cast<uintptr_t>(GetViewResource(srv));
+ srv->GetDesc(&record->desc);
+ mHighestUsedSRV = std::max(resourceIndex + 1, mHighestUsedSRV);
+ }
+ else
+ {
+ record->resource = 0;
+
+ if (resourceIndex + 1 == mHighestUsedSRV)
+ {
+ do
+ {
+ --mHighestUsedSRV;
+ } while (mHighestUsedSRV > 0 && mCurrentSRVs[mHighestUsedSRV].srv == 0);
+ }
+ }
+}
+
+void StateManager11::SRVCache::clear()
+{
+ if (mCurrentSRVs.empty())
+ {
+ return;
+ }
+
+ memset(&mCurrentSRVs[0], 0, sizeof(SRVRecord) * mCurrentSRVs.size());
+ mHighestUsedSRV = 0;
+}
+
+StateManager11::StateManager11(Renderer11 *renderer)
+ : mRenderer(renderer),
+ mBlendStateIsDirty(false),
+ mCurBlendColor(0, 0, 0, 0),
+ mCurSampleMask(0),
+ mDepthStencilStateIsDirty(false),
+ mCurStencilRef(0),
+ mCurStencilBackRef(0),
+ mCurStencilSize(0),
+ mRasterizerStateIsDirty(false),
+ mScissorStateIsDirty(false),
+ mCurScissorEnabled(false),
+ mCurScissorRect(),
+ mViewportStateIsDirty(false),
+ mCurViewport(),
+ mCurNear(0.0f),
+ mCurFar(0.0f),
+ mViewportBounds(),
+ mCurPresentPathFastEnabled(false),
+ mCurPresentPathFastColorBufferHeight(0),
+ mAppliedDSV(angle::DirtyPointer)
+{
+ mCurBlendState.blend = false;
+ mCurBlendState.sourceBlendRGB = GL_ONE;
+ mCurBlendState.destBlendRGB = GL_ZERO;
+ mCurBlendState.sourceBlendAlpha = GL_ONE;
+ mCurBlendState.destBlendAlpha = GL_ZERO;
+ mCurBlendState.blendEquationRGB = GL_FUNC_ADD;
+ mCurBlendState.blendEquationAlpha = GL_FUNC_ADD;
+ mCurBlendState.colorMaskRed = true;
+ mCurBlendState.colorMaskBlue = true;
+ mCurBlendState.colorMaskGreen = true;
+ mCurBlendState.colorMaskAlpha = true;
+ mCurBlendState.sampleAlphaToCoverage = false;
+ mCurBlendState.dither = false;
+
+ mCurDepthStencilState.depthTest = false;
+ mCurDepthStencilState.depthFunc = GL_LESS;
+ mCurDepthStencilState.depthMask = true;
+ mCurDepthStencilState.stencilTest = false;
+ mCurDepthStencilState.stencilMask = true;
+ mCurDepthStencilState.stencilFail = GL_KEEP;
+ mCurDepthStencilState.stencilPassDepthFail = GL_KEEP;
+ mCurDepthStencilState.stencilPassDepthPass = GL_KEEP;
+ mCurDepthStencilState.stencilWritemask = static_cast<GLuint>(-1);
+ mCurDepthStencilState.stencilBackFunc = GL_ALWAYS;
+ mCurDepthStencilState.stencilBackMask = static_cast<GLuint>(-1);
+ mCurDepthStencilState.stencilBackFail = GL_KEEP;
+ mCurDepthStencilState.stencilBackPassDepthFail = GL_KEEP;
+ mCurDepthStencilState.stencilBackPassDepthPass = GL_KEEP;
+ mCurDepthStencilState.stencilBackWritemask = static_cast<GLuint>(-1);
+
+ mCurRasterState.rasterizerDiscard = false;
+ mCurRasterState.cullFace = false;
+ mCurRasterState.cullMode = GL_BACK;
+ mCurRasterState.frontFace = GL_CCW;
+ mCurRasterState.polygonOffsetFill = false;
+ mCurRasterState.polygonOffsetFactor = 0.0f;
+ mCurRasterState.polygonOffsetUnits = 0.0f;
+ mCurRasterState.pointDrawMode = false;
+ mCurRasterState.multiSample = false;
+}
+
+StateManager11::~StateManager11()
+{
+}
+
+void StateManager11::updateStencilSizeIfChanged(bool depthStencilInitialized,
+ unsigned int stencilSize)
+{
+ if (!depthStencilInitialized || stencilSize != mCurStencilSize)
+ {
+ mCurStencilSize = stencilSize;
+ mDepthStencilStateIsDirty = true;
+ }
+}
+
+void StateManager11::setViewportBounds(const int width, const int height)
+{
+ if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3 &&
+ (mViewportBounds.width != width || mViewportBounds.height != height))
+ {
+ mViewportBounds = gl::Extents(width, height, 1);
+ mViewportStateIsDirty = true;
+ }
+}
+
+void StateManager11::updatePresentPath(bool presentPathFastActive,
+ const gl::FramebufferAttachment *framebufferAttachment)
+{
+ const int colorBufferHeight =
+ framebufferAttachment ? framebufferAttachment->getSize().height : 0;
+
+ if ((mCurPresentPathFastEnabled != presentPathFastActive) ||
+ (presentPathFastActive && (colorBufferHeight != mCurPresentPathFastColorBufferHeight)))
+ {
+ mCurPresentPathFastEnabled = presentPathFastActive;
+ mCurPresentPathFastColorBufferHeight = colorBufferHeight;
+ mViewportStateIsDirty = true; // Viewport may need to be vertically inverted
+ mScissorStateIsDirty = true; // Scissor rect may need to be vertically inverted
+ mRasterizerStateIsDirty = true; // Cull Mode may need to be inverted
+ }
+}
+
+void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits)
+{
+ if (!dirtyBits.any())
+ {
+ return;
+ }
+
+ for (unsigned int dirtyBit : angle::IterateBitSet(dirtyBits))
+ {
+ switch (dirtyBit)
+ {
+ case gl::State::DIRTY_BIT_BLEND_EQUATIONS:
+ {
+ const gl::BlendState &blendState = state.getBlendState();
+ if (blendState.blendEquationRGB != mCurBlendState.blendEquationRGB ||
+ blendState.blendEquationAlpha != mCurBlendState.blendEquationAlpha)
+ {
+ mBlendStateIsDirty = true;
+ }
+ break;
+ }
+ case gl::State::DIRTY_BIT_BLEND_FUNCS:
+ {
+ const gl::BlendState &blendState = state.getBlendState();
+ if (blendState.sourceBlendRGB != mCurBlendState.sourceBlendRGB ||
+ blendState.destBlendRGB != mCurBlendState.destBlendRGB ||
+ blendState.sourceBlendAlpha != mCurBlendState.sourceBlendAlpha ||
+ blendState.destBlendAlpha != mCurBlendState.destBlendAlpha)
+ {
+ mBlendStateIsDirty = true;
+ }
+ break;
+ }
+ case gl::State::DIRTY_BIT_BLEND_ENABLED:
+ if (state.getBlendState().blend != mCurBlendState.blend)
+ {
+ mBlendStateIsDirty = true;
+ }
+ break;
+ case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED:
+ if (state.getBlendState().sampleAlphaToCoverage !=
+ mCurBlendState.sampleAlphaToCoverage)
+ {
+ mBlendStateIsDirty = true;
+ }
+ break;
+ case gl::State::DIRTY_BIT_DITHER_ENABLED:
+ if (state.getBlendState().dither != mCurBlendState.dither)
+ {
+ mBlendStateIsDirty = true;
+ }
+ break;
+ case gl::State::DIRTY_BIT_COLOR_MASK:
+ {
+ const gl::BlendState &blendState = state.getBlendState();
+ if (blendState.colorMaskRed != mCurBlendState.colorMaskRed ||
+ blendState.colorMaskGreen != mCurBlendState.colorMaskGreen ||
+ blendState.colorMaskBlue != mCurBlendState.colorMaskBlue ||
+ blendState.colorMaskAlpha != mCurBlendState.colorMaskAlpha)
+ {
+ mBlendStateIsDirty = true;
+ }
+ break;
+ }
+ case gl::State::DIRTY_BIT_BLEND_COLOR:
+ if (state.getBlendColor() != mCurBlendColor)
+ {
+ mBlendStateIsDirty = true;
+ }
+ break;
+ case gl::State::DIRTY_BIT_DEPTH_MASK:
+ if (state.getDepthStencilState().depthMask != mCurDepthStencilState.depthMask)
+ {
+ mDepthStencilStateIsDirty = true;
+ }
+ break;
+ case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED:
+ if (state.getDepthStencilState().depthTest != mCurDepthStencilState.depthTest)
+ {
+ mDepthStencilStateIsDirty = true;
+ }
+ break;
+ case gl::State::DIRTY_BIT_DEPTH_FUNC:
+ if (state.getDepthStencilState().depthFunc != mCurDepthStencilState.depthFunc)
+ {
+ mDepthStencilStateIsDirty = true;
+ }
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED:
+ if (state.getDepthStencilState().stencilTest != mCurDepthStencilState.stencilTest)
+ {
+ mDepthStencilStateIsDirty = true;
+ }
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT:
+ {
+ const gl::DepthStencilState &depthStencil = state.getDepthStencilState();
+ if (depthStencil.stencilFunc != mCurDepthStencilState.stencilFunc ||
+ depthStencil.stencilMask != mCurDepthStencilState.stencilMask ||
+ state.getStencilRef() != mCurStencilRef)
+ {
+ mDepthStencilStateIsDirty = true;
+ }
+ break;
+ }
+ case gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK:
+ {
+ const gl::DepthStencilState &depthStencil = state.getDepthStencilState();
+ if (depthStencil.stencilBackFunc != mCurDepthStencilState.stencilBackFunc ||
+ depthStencil.stencilBackMask != mCurDepthStencilState.stencilBackMask ||
+ state.getStencilBackRef() != mCurStencilBackRef)
+ {
+ mDepthStencilStateIsDirty = true;
+ }
+ break;
+ }
+ case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT:
+ if (state.getDepthStencilState().stencilWritemask !=
+ mCurDepthStencilState.stencilWritemask)
+ {
+ mDepthStencilStateIsDirty = true;
+ }
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK:
+ if (state.getDepthStencilState().stencilBackWritemask !=
+ mCurDepthStencilState.stencilBackWritemask)
+ {
+ mDepthStencilStateIsDirty = true;
+ }
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT:
+ {
+ const gl::DepthStencilState &depthStencil = state.getDepthStencilState();
+ if (depthStencil.stencilFail != mCurDepthStencilState.stencilFail ||
+ depthStencil.stencilPassDepthFail !=
+ mCurDepthStencilState.stencilPassDepthFail ||
+ depthStencil.stencilPassDepthPass != mCurDepthStencilState.stencilPassDepthPass)
+ {
+ mDepthStencilStateIsDirty = true;
+ }
+ break;
+ }
+ case gl::State::DIRTY_BIT_STENCIL_OPS_BACK:
+ {
+ const gl::DepthStencilState &depthStencil = state.getDepthStencilState();
+ if (depthStencil.stencilBackFail != mCurDepthStencilState.stencilBackFail ||
+ depthStencil.stencilBackPassDepthFail !=
+ mCurDepthStencilState.stencilBackPassDepthFail ||
+ depthStencil.stencilBackPassDepthPass !=
+ mCurDepthStencilState.stencilBackPassDepthPass)
+ {
+ mDepthStencilStateIsDirty = true;
+ }
+ break;
+ }
+ case gl::State::DIRTY_BIT_CULL_FACE_ENABLED:
+ if (state.getRasterizerState().cullFace != mCurRasterState.cullFace)
+ {
+ mRasterizerStateIsDirty = true;
+ }
+ break;
+ case gl::State::DIRTY_BIT_CULL_FACE:
+ if (state.getRasterizerState().cullMode != mCurRasterState.cullMode)
+ {
+ mRasterizerStateIsDirty = true;
+ }
+ break;
+ case gl::State::DIRTY_BIT_FRONT_FACE:
+ if (state.getRasterizerState().frontFace != mCurRasterState.frontFace)
+ {
+ mRasterizerStateIsDirty = true;
+ }
+ break;
+ case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED:
+ if (state.getRasterizerState().polygonOffsetFill !=
+ mCurRasterState.polygonOffsetFill)
+ {
+ mRasterizerStateIsDirty = true;
+ }
+ break;
+ case gl::State::DIRTY_BIT_POLYGON_OFFSET:
+ {
+ const gl::RasterizerState &rasterState = state.getRasterizerState();
+ if (rasterState.polygonOffsetFactor != mCurRasterState.polygonOffsetFactor ||
+ rasterState.polygonOffsetUnits != mCurRasterState.polygonOffsetUnits)
+ {
+ mRasterizerStateIsDirty = true;
+ }
+ break;
+ }
+ case gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED:
+ if (state.getRasterizerState().rasterizerDiscard !=
+ mCurRasterState.rasterizerDiscard)
+ {
+ mRasterizerStateIsDirty = true;
+ }
+ break;
+ case gl::State::DIRTY_BIT_SCISSOR:
+ if (state.getScissor() != mCurScissorRect)
+ {
+ mScissorStateIsDirty = true;
+ }
+ break;
+ case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED:
+ if (state.isScissorTestEnabled() != mCurScissorEnabled)
+ {
+ mScissorStateIsDirty = true;
+ // Rasterizer state update needs mCurScissorsEnabled and updates when it changes
+ mRasterizerStateIsDirty = true;
+ }
+ break;
+ case gl::State::DIRTY_BIT_DEPTH_RANGE:
+ if (state.getNearPlane() != mCurNear || state.getFarPlane() != mCurFar)
+ {
+ mViewportStateIsDirty = true;
+ }
+ break;
+ case gl::State::DIRTY_BIT_VIEWPORT:
+ if (state.getViewport() != mCurViewport)
+ {
+ mViewportStateIsDirty = true;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+gl::Error StateManager11::setBlendState(const gl::Framebuffer *framebuffer,
+ const gl::BlendState &blendState,
+ const gl::ColorF &blendColor,
+ unsigned int sampleMask)
+{
+ if (!mBlendStateIsDirty && sampleMask == mCurSampleMask)
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ ID3D11BlendState *dxBlendState = nullptr;
+ gl::Error error =
+ mRenderer->getStateCache().getBlendState(framebuffer, blendState, &dxBlendState);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ASSERT(dxBlendState != nullptr);
+
+ float blendColors[4] = {0.0f};
+ if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA &&
+ blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA &&
+ blendState.destBlendRGB != GL_CONSTANT_ALPHA &&
+ blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA)
+ {
+ blendColors[0] = blendColor.red;
+ blendColors[1] = blendColor.green;
+ blendColors[2] = blendColor.blue;
+ blendColors[3] = blendColor.alpha;
+ }
+ else
+ {
+ blendColors[0] = blendColor.alpha;
+ blendColors[1] = blendColor.alpha;
+ blendColors[2] = blendColor.alpha;
+ blendColors[3] = blendColor.alpha;
+ }
+
+ mRenderer->getDeviceContext()->OMSetBlendState(dxBlendState, blendColors, sampleMask);
+
+ mCurBlendState = blendState;
+ mCurBlendColor = blendColor;
+ mCurSampleMask = sampleMask;
+
+ mBlendStateIsDirty = false;
+
+ return error;
+}
+
+gl::Error StateManager11::setDepthStencilState(const gl::State &glState)
+{
+ const auto &fbo = *glState.getDrawFramebuffer();
+
+ // Disable the depth test/depth write if we are using a stencil-only attachment.
+ // This is because ANGLE emulates stencil-only with D24S8 on D3D11 - we should neither read
+ // nor write to the unused depth part of this emulated texture.
+ bool disableDepth = (!fbo.hasDepth() && fbo.hasStencil());
+
+ // Similarly we disable the stencil portion of the DS attachment if the app only binds depth.
+ bool disableStencil = (fbo.hasDepth() && !fbo.hasStencil());
+
+ // CurDisableDepth/Stencil are reset automatically after we call forceSetDepthStencilState.
+ if (!mDepthStencilStateIsDirty && mCurDisableDepth.valid() &&
+ disableDepth == mCurDisableDepth.value() && mCurDisableStencil.valid() &&
+ disableStencil == mCurDisableStencil.value())
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ const auto &depthStencilState = glState.getDepthStencilState();
+ int stencilRef = glState.getStencilRef();
+ int stencilBackRef = glState.getStencilBackRef();
+
+ // get the maximum size of the stencil ref
+ unsigned int maxStencil = 0;
+ if (depthStencilState.stencilTest && mCurStencilSize > 0)
+ {
+ maxStencil = (1 << mCurStencilSize) - 1;
+ }
+ ASSERT((depthStencilState.stencilWritemask & maxStencil) ==
+ (depthStencilState.stencilBackWritemask & maxStencil));
+ ASSERT(stencilRef == stencilBackRef);
+ ASSERT((depthStencilState.stencilMask & maxStencil) ==
+ (depthStencilState.stencilBackMask & maxStencil));
+
+ ID3D11DepthStencilState *dxDepthStencilState = NULL;
+ gl::Error error = mRenderer->getStateCache().getDepthStencilState(
+ depthStencilState, disableDepth, disableStencil, &dxDepthStencilState);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ASSERT(dxDepthStencilState);
+
+ // Max D3D11 stencil reference value is 0xFF,
+ // corresponding to the max 8 bits in a stencil buffer
+ // GL specifies we should clamp the ref value to the
+ // nearest bit depth when doing stencil ops
+ static_assert(D3D11_DEFAULT_STENCIL_READ_MASK == 0xFF,
+ "Unexpected value of D3D11_DEFAULT_STENCIL_READ_MASK");
+ static_assert(D3D11_DEFAULT_STENCIL_WRITE_MASK == 0xFF,
+ "Unexpected value of D3D11_DEFAULT_STENCIL_WRITE_MASK");
+ UINT dxStencilRef = std::min<UINT>(stencilRef, 0xFFu);
+
+ mRenderer->getDeviceContext()->OMSetDepthStencilState(dxDepthStencilState, dxStencilRef);
+
+ mCurDepthStencilState = depthStencilState;
+ mCurStencilRef = stencilRef;
+ mCurStencilBackRef = stencilBackRef;
+ mCurDisableDepth = disableDepth;
+ mCurDisableStencil = disableStencil;
+
+ mDepthStencilStateIsDirty = false;
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error StateManager11::setRasterizerState(const gl::RasterizerState &rasterState)
+{
+ if (!mRasterizerStateIsDirty)
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ ID3D11RasterizerState *dxRasterState = nullptr;
+ gl::Error error(GL_NO_ERROR);
+
+ if (mCurPresentPathFastEnabled)
+ {
+ gl::RasterizerState modifiedRasterState = rasterState;
+
+ // If prseent path fast is active then we need invert the front face state.
+ // This ensures that both gl_FrontFacing is correct, and front/back culling
+ // is performed correctly.
+ if (modifiedRasterState.frontFace == GL_CCW)
+ {
+ modifiedRasterState.frontFace = GL_CW;
+ }
+ else
+ {
+ ASSERT(modifiedRasterState.frontFace == GL_CW);
+ modifiedRasterState.frontFace = GL_CCW;
+ }
+
+ error = mRenderer->getStateCache().getRasterizerState(modifiedRasterState,
+ mCurScissorEnabled, &dxRasterState);
+ }
+ else
+ {
+ error = mRenderer->getStateCache().getRasterizerState(rasterState, mCurScissorEnabled,
+ &dxRasterState);
+ }
+
+ if (error.isError())
+ {
+ return error;
+ }
+
+ mRenderer->getDeviceContext()->RSSetState(dxRasterState);
+
+ mCurRasterState = rasterState;
+ mRasterizerStateIsDirty = false;
+
+ return error;
+}
+
+void StateManager11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
+{
+ if (!mScissorStateIsDirty)
+ return;
+
+ int modifiedScissorY = scissor.y;
+ if (mCurPresentPathFastEnabled)
+ {
+ modifiedScissorY = mCurPresentPathFastColorBufferHeight - scissor.height - scissor.y;
+ }
+
+ if (enabled)
+ {
+ D3D11_RECT rect;
+ rect.left = std::max(0, scissor.x);
+ rect.top = std::max(0, modifiedScissorY);
+ rect.right = scissor.x + std::max(0, scissor.width);
+ rect.bottom = modifiedScissorY + std::max(0, scissor.height);
+
+ mRenderer->getDeviceContext()->RSSetScissorRects(1, &rect);
+ }
+
+ mCurScissorRect = scissor;
+ mCurScissorEnabled = enabled;
+ mScissorStateIsDirty = false;
+}
+
+void StateManager11::setViewport(const gl::Caps *caps,
+ const gl::Rectangle &viewport,
+ float zNear,
+ float zFar)
+{
+ if (!mViewportStateIsDirty)
+ return;
+
+ float actualZNear = gl::clamp01(zNear);
+ float actualZFar = gl::clamp01(zFar);
+
+ int dxMaxViewportBoundsX = static_cast<int>(caps->maxViewportWidth);
+ int dxMaxViewportBoundsY = static_cast<int>(caps->maxViewportHeight);
+ int dxMinViewportBoundsX = -dxMaxViewportBoundsX;
+ int dxMinViewportBoundsY = -dxMaxViewportBoundsY;
+
+ if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
+ {
+ // Feature Level 9 viewports shouldn't exceed the dimensions of the rendertarget.
+ dxMaxViewportBoundsX = static_cast<int>(mViewportBounds.width);
+ dxMaxViewportBoundsY = static_cast<int>(mViewportBounds.height);
+ dxMinViewportBoundsX = 0;
+ dxMinViewportBoundsY = 0;
+ }
+
+ int dxViewportTopLeftX = gl::clamp(viewport.x, dxMinViewportBoundsX, dxMaxViewportBoundsX);
+ int dxViewportTopLeftY = gl::clamp(viewport.y, dxMinViewportBoundsY, dxMaxViewportBoundsY);
+ int dxViewportWidth = gl::clamp(viewport.width, 0, dxMaxViewportBoundsX - dxViewportTopLeftX);
+ int dxViewportHeight = gl::clamp(viewport.height, 0, dxMaxViewportBoundsY - dxViewportTopLeftY);
+
+ D3D11_VIEWPORT dxViewport;
+ dxViewport.TopLeftX = static_cast<float>(dxViewportTopLeftX);
+
+ if (mCurPresentPathFastEnabled)
+ {
+ // When present path fast is active and we're rendering to framebuffer 0, we must invert
+ // the viewport in Y-axis.
+ // NOTE: We delay the inversion until right before the call to RSSetViewports, and leave
+ // dxViewportTopLeftY unchanged. This allows us to calculate viewAdjust below using the
+ // unaltered dxViewportTopLeftY value.
+ dxViewport.TopLeftY = static_cast<float>(mCurPresentPathFastColorBufferHeight -
+ dxViewportTopLeftY - dxViewportHeight);
+ }
+ else
+ {
+ dxViewport.TopLeftY = static_cast<float>(dxViewportTopLeftY);
+ }
+
+ dxViewport.Width = static_cast<float>(dxViewportWidth);
+ dxViewport.Height = static_cast<float>(dxViewportHeight);
+ dxViewport.MinDepth = actualZNear;
+ dxViewport.MaxDepth = actualZFar;
+
+ mRenderer->getDeviceContext()->RSSetViewports(1, &dxViewport);
+
+ mCurViewport = viewport;
+ mCurNear = actualZNear;
+ mCurFar = actualZFar;
+
+ // On Feature Level 9_*, we must emulate large and/or negative viewports in the shaders
+ // using viewAdjust (like the D3D9 renderer).
+ if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
+ {
+ mVertexConstants.viewAdjust[0] = static_cast<float>((viewport.width - dxViewportWidth) +
+ 2 * (viewport.x - dxViewportTopLeftX)) /
+ dxViewport.Width;
+ mVertexConstants.viewAdjust[1] = static_cast<float>((viewport.height - dxViewportHeight) +
+ 2 * (viewport.y - dxViewportTopLeftY)) /
+ dxViewport.Height;
+ mVertexConstants.viewAdjust[2] = static_cast<float>(viewport.width) / dxViewport.Width;
+ mVertexConstants.viewAdjust[3] = static_cast<float>(viewport.height) / dxViewport.Height;
+ }
+
+ mPixelConstants.viewCoords[0] = viewport.width * 0.5f;
+ mPixelConstants.viewCoords[1] = viewport.height * 0.5f;
+ mPixelConstants.viewCoords[2] = viewport.x + (viewport.width * 0.5f);
+ mPixelConstants.viewCoords[3] = viewport.y + (viewport.height * 0.5f);
+
+ // Instanced pointsprite emulation requires ViewCoords to be defined in the
+ // the vertex shader.
+ mVertexConstants.viewCoords[0] = mPixelConstants.viewCoords[0];
+ mVertexConstants.viewCoords[1] = mPixelConstants.viewCoords[1];
+ mVertexConstants.viewCoords[2] = mPixelConstants.viewCoords[2];
+ mVertexConstants.viewCoords[3] = mPixelConstants.viewCoords[3];
+
+ mPixelConstants.depthFront[0] = (actualZFar - actualZNear) * 0.5f;
+ mPixelConstants.depthFront[1] = (actualZNear + actualZFar) * 0.5f;
+
+ mVertexConstants.depthRange[0] = actualZNear;
+ mVertexConstants.depthRange[1] = actualZFar;
+ mVertexConstants.depthRange[2] = actualZFar - actualZNear;
+
+ mPixelConstants.depthRange[0] = actualZNear;
+ mPixelConstants.depthRange[1] = actualZFar;
+ mPixelConstants.depthRange[2] = actualZFar - actualZNear;
+
+ mPixelConstants.viewScale[0] = 1.0f;
+ mPixelConstants.viewScale[1] = mCurPresentPathFastEnabled ? 1.0f : -1.0f;
+ mPixelConstants.viewScale[2] = 1.0f;
+ mPixelConstants.viewScale[3] = 1.0f;
+
+ mVertexConstants.viewScale[0] = mPixelConstants.viewScale[0];
+ mVertexConstants.viewScale[1] = mPixelConstants.viewScale[1];
+ mVertexConstants.viewScale[2] = mPixelConstants.viewScale[2];
+ mVertexConstants.viewScale[3] = mPixelConstants.viewScale[3];
+
+ mViewportStateIsDirty = false;
+}
+
+void StateManager11::invalidateRenderTarget()
+{
+ for (auto &appliedRTV : mAppliedRTVs)
+ {
+ appliedRTV = angle::DirtyPointer;
+ }
+ mAppliedDSV = angle::DirtyPointer;
+}
+
+void StateManager11::invalidateEverything()
+{
+ mBlendStateIsDirty = true;
+ mDepthStencilStateIsDirty = true;
+ mRasterizerStateIsDirty = true;
+ mScissorStateIsDirty = true;
+ mViewportStateIsDirty = true;
+
+ // We reset the current SRV data because it might not be in sync with D3D's state
+ // anymore. For example when a currently used SRV is used as an RTV, D3D silently
+ // remove it from its state.
+ mCurVertexSRVs.clear();
+ mCurPixelSRVs.clear();
+
+ invalidateRenderTarget();
+}
+
+bool StateManager11::setRenderTargets(const RenderTargetArray &renderTargets,
+ ID3D11DepthStencilView *depthStencil)
+{
+ // TODO(jmadill): Use context caps?
+ UINT drawBuffers = mRenderer->getRendererCaps().maxDrawBuffers;
+
+ // Apply the render target and depth stencil
+ size_t arraySize = sizeof(uintptr_t) * drawBuffers;
+ if (memcmp(renderTargets.data(), mAppliedRTVs.data(), arraySize) == 0 &&
+ reinterpret_cast<uintptr_t>(depthStencil) == mAppliedDSV)
+ {
+ return false;
+ }
+
+ // The D3D11 blend state is heavily dependent on the current render target.
+ mBlendStateIsDirty = true;
+
+ for (UINT rtIndex = 0; rtIndex < drawBuffers; rtIndex++)
+ {
+ mAppliedRTVs[rtIndex] = reinterpret_cast<uintptr_t>(renderTargets[rtIndex]);
+ }
+ mAppliedDSV = reinterpret_cast<uintptr_t>(depthStencil);
+
+ mRenderer->getDeviceContext()->OMSetRenderTargets(drawBuffers, renderTargets.data(),
+ depthStencil);
+ return true;
+}
+
+void StateManager11::setRenderTarget(ID3D11RenderTargetView *renderTarget,
+ ID3D11DepthStencilView *depthStencil)
+{
+ mRenderer->getDeviceContext()->OMSetRenderTargets(1, &renderTarget, depthStencil);
+}
+
+void StateManager11::setShaderResource(gl::SamplerType shaderType,
+ UINT resourceSlot,
+ ID3D11ShaderResourceView *srv)
+{
+ auto &currentSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
+
+ ASSERT(static_cast<size_t>(resourceSlot) < currentSRVs.size());
+ const SRVRecord &record = currentSRVs[resourceSlot];
+
+ if (record.srv != reinterpret_cast<uintptr_t>(srv))
+ {
+ auto deviceContext = mRenderer->getDeviceContext();
+ if (shaderType == gl::SAMPLER_VERTEX)
+ {
+ deviceContext->VSSetShaderResources(resourceSlot, 1, &srv);
+ }
+ else
+ {
+ deviceContext->PSSetShaderResources(resourceSlot, 1, &srv);
+ }
+
+ currentSRVs.update(resourceSlot, srv);
+ }
+}
+
+gl::Error StateManager11::clearTextures(gl::SamplerType samplerType,
+ size_t rangeStart,
+ size_t rangeEnd)
+{
+ if (rangeStart == rangeEnd)
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ auto &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
+
+ gl::Range<size_t> clearRange(rangeStart, rangeStart);
+ clearRange.extend(std::min(rangeEnd, currentSRVs.highestUsed()));
+
+ if (clearRange.empty())
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ auto deviceContext = mRenderer->getDeviceContext();
+ if (samplerType == gl::SAMPLER_VERTEX)
+ {
+ deviceContext->VSSetShaderResources(static_cast<unsigned int>(rangeStart),
+ static_cast<unsigned int>(rangeEnd - rangeStart),
+ &mNullSRVs[0]);
+ }
+ else
+ {
+ deviceContext->PSSetShaderResources(static_cast<unsigned int>(rangeStart),
+ static_cast<unsigned int>(rangeEnd - rangeStart),
+ &mNullSRVs[0]);
+ }
+
+ for (size_t samplerIndex = rangeStart; samplerIndex < rangeEnd; ++samplerIndex)
+ {
+ currentSRVs.update(samplerIndex, nullptr);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+void StateManager11::unsetConflictingSRVs(gl::SamplerType samplerType,
+ uintptr_t resource,
+ const gl::ImageIndex &index)
+{
+ auto &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
+
+ for (size_t resourceIndex = 0; resourceIndex < currentSRVs.size(); ++resourceIndex)
+ {
+ auto &record = currentSRVs[resourceIndex];
+
+ if (record.srv && record.resource == resource &&
+ ImageIndexConflictsWithSRV(index, record.desc))
+ {
+ setShaderResource(samplerType, static_cast<UINT>(resourceIndex), NULL);
+ }
+ }
+}
+
+void StateManager11::initialize(const gl::Caps &caps)
+{
+ mCurVertexSRVs.initialize(caps.maxVertexTextureImageUnits);
+ mCurPixelSRVs.initialize(caps.maxTextureImageUnits);
+
+ // Initialize cached NULL SRV block
+ mNullSRVs.resize(caps.maxTextureImageUnits, nullptr);
+}
+
+gl::Error StateManager11::syncFramebuffer(const gl::Framebuffer *framebuffer)
+{
+ // Get the color render buffer and serial
+ // Also extract the render target dimensions and view
+ unsigned int renderTargetWidth = 0;
+ unsigned int renderTargetHeight = 0;
+ DXGI_FORMAT renderTargetFormat = DXGI_FORMAT_UNKNOWN;
+ RenderTargetArray framebufferRTVs;
+ bool missingColorRenderTarget = true;
+
+ framebufferRTVs.fill(nullptr);
+
+ const Framebuffer11 *framebuffer11 = GetImplAs<Framebuffer11>(framebuffer);
+ const gl::AttachmentList &colorbuffers = framebuffer11->getColorAttachmentsForRender();
+
+ for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
+ {
+ const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment];
+
+ if (colorbuffer)
+ {
+ // the draw buffer must be either "none", "back" for the default buffer or the same
+ // index as this color (in order)
+
+ // check for zero-sized default framebuffer, which is a special case.
+ // in this case we do not wish to modify any state and just silently return false.
+ // this will not report any gl error but will cause the calling method to return.
+ const gl::Extents &size = colorbuffer->getSize();
+ if (size.width == 0 || size.height == 0)
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ // Extract the render target dimensions and view
+ RenderTarget11 *renderTarget = NULL;
+ gl::Error error = colorbuffer->getRenderTarget(&renderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+ ASSERT(renderTarget);
+
+ framebufferRTVs[colorAttachment] = renderTarget->getRenderTargetView();
+ ASSERT(framebufferRTVs[colorAttachment]);
+
+ if (missingColorRenderTarget)
+ {
+ renderTargetWidth = renderTarget->getWidth();
+ renderTargetHeight = renderTarget->getHeight();
+ renderTargetFormat = renderTarget->getDXGIFormat();
+ missingColorRenderTarget = false;
+ }
+
+ // Unbind render target SRVs from the shader here to prevent D3D11 warnings.
+ if (colorbuffer->type() == GL_TEXTURE)
+ {
+ uintptr_t rtResource =
+ reinterpret_cast<uintptr_t>(GetViewResource(framebufferRTVs[colorAttachment]));
+ const gl::ImageIndex &index = colorbuffer->getTextureImageIndex();
+ // The index doesn't need to be corrected for the small compressed texture
+ // workaround
+ // because a rendertarget is never compressed.
+ unsetConflictingSRVs(gl::SAMPLER_VERTEX, rtResource, index);
+ unsetConflictingSRVs(gl::SAMPLER_PIXEL, rtResource, index);
+ }
+ }
+ }
+
+ // Get the depth stencil buffers
+ ID3D11DepthStencilView *framebufferDSV = NULL;
+ const gl::FramebufferAttachment *depthStencil = framebuffer->getDepthOrStencilbuffer();
+ if (depthStencil)
+ {
+ RenderTarget11 *depthStencilRenderTarget = NULL;
+ gl::Error error = depthStencil->getRenderTarget(&depthStencilRenderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+ ASSERT(depthStencilRenderTarget);
+
+ framebufferDSV = depthStencilRenderTarget->getDepthStencilView();
+ ASSERT(framebufferDSV);
+
+ // If there is no render buffer, the width, height and format values come from
+ // the depth stencil
+ if (missingColorRenderTarget)
+ {
+ renderTargetWidth = depthStencilRenderTarget->getWidth();
+ renderTargetHeight = depthStencilRenderTarget->getHeight();
+ }
+
+ // Unbind render target SRVs from the shader here to prevent D3D11 warnings.
+ if (depthStencil->type() == GL_TEXTURE)
+ {
+ uintptr_t depthStencilResource =
+ reinterpret_cast<uintptr_t>(GetViewResource(framebufferDSV));
+ const gl::ImageIndex &index = depthStencil->getTextureImageIndex();
+ // The index doesn't need to be corrected for the small compressed texture workaround
+ // because a rendertarget is never compressed.
+ unsetConflictingSRVs(gl::SAMPLER_VERTEX, depthStencilResource, index);
+ unsetConflictingSRVs(gl::SAMPLER_PIXEL, depthStencilResource, index);
+ }
+ }
+
+ if (setRenderTargets(framebufferRTVs, framebufferDSV))
+ {
+ setViewportBounds(renderTargetWidth, renderTargetHeight);
+ }
+
+ gl::Error error = framebuffer11->invalidateSwizzles();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+} // namespace rx
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.h
new file mode 100644
index 0000000000..f900882d7e
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.h
@@ -0,0 +1,181 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// StateManager11.h: Defines a class for caching D3D11 state
+
+#ifndef LIBANGLE_RENDERER_D3D11_STATEMANAGER11_H_
+#define LIBANGLE_RENDERER_D3D11_STATEMANAGER11_H_
+
+#include <array>
+
+#include "libANGLE/angletypes.h"
+#include "libANGLE/Data.h"
+#include "libANGLE/State.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+
+namespace rx
+{
+
+struct RenderTargetDesc;
+struct Renderer11DeviceCaps;
+
+struct dx_VertexConstants11
+{
+ float depthRange[4];
+ float viewAdjust[4];
+ float viewCoords[4];
+ float viewScale[4];
+};
+
+struct dx_PixelConstants11
+{
+ float depthRange[4];
+ float viewCoords[4];
+ float depthFront[4];
+ float viewScale[4];
+};
+
+class StateManager11 final : angle::NonCopyable
+{
+ public:
+ StateManager11(Renderer11 *renderer);
+ ~StateManager11();
+
+ void initialize(const gl::Caps &caps);
+ void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits);
+
+ gl::Error setBlendState(const gl::Framebuffer *framebuffer,
+ const gl::BlendState &blendState,
+ const gl::ColorF &blendColor,
+ unsigned int sampleMask);
+
+ gl::Error setDepthStencilState(const gl::State &glState);
+
+ gl::Error setRasterizerState(const gl::RasterizerState &rasterState);
+
+ void setScissorRectangle(const gl::Rectangle &scissor, bool enabled);
+
+ void setViewport(const gl::Caps *caps, const gl::Rectangle &viewport, float zNear, float zFar);
+
+ void updatePresentPath(bool presentPathFastActive,
+ const gl::FramebufferAttachment *framebufferAttachment);
+
+ const dx_VertexConstants11 &getVertexConstants() const { return mVertexConstants; }
+ const dx_PixelConstants11 &getPixelConstants() const { return mPixelConstants; }
+
+ void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize);
+
+ void setShaderResource(gl::SamplerType shaderType,
+ UINT resourceSlot,
+ ID3D11ShaderResourceView *srv);
+ gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd);
+
+ gl::Error syncFramebuffer(const gl::Framebuffer *framebuffer);
+
+ void invalidateRenderTarget();
+ void invalidateEverything();
+ bool setRenderTargets(const RenderTargetArray &renderTargets,
+ ID3D11DepthStencilView *depthStencil);
+ void setRenderTarget(ID3D11RenderTargetView *renderTarget,
+ ID3D11DepthStencilView *depthStencil);
+
+ private:
+ void unsetConflictingSRVs(gl::SamplerType shaderType,
+ uintptr_t resource,
+ const gl::ImageIndex &index);
+ void setViewportBounds(const int width, const int height);
+
+ Renderer11 *mRenderer;
+
+ // Blend State
+ bool mBlendStateIsDirty;
+ // TODO(dianx) temporary representation of a dirty bit. once we move enough states in,
+ // try experimenting with dirty bit instead of a bool
+ gl::BlendState mCurBlendState;
+ gl::ColorF mCurBlendColor;
+ unsigned int mCurSampleMask;
+
+ // Currently applied depth stencil state
+ bool mDepthStencilStateIsDirty;
+ gl::DepthStencilState mCurDepthStencilState;
+ int mCurStencilRef;
+ int mCurStencilBackRef;
+ unsigned int mCurStencilSize;
+ Optional<bool> mCurDisableDepth;
+ Optional<bool> mCurDisableStencil;
+
+ // Currently applied rasterizer state
+ bool mRasterizerStateIsDirty;
+ gl::RasterizerState mCurRasterState;
+
+ // Currently applied scissor rectangle state
+ bool mScissorStateIsDirty;
+ bool mCurScissorEnabled;
+ gl::Rectangle mCurScissorRect;
+
+ // Currently applied viewport state
+ bool mViewportStateIsDirty;
+ gl::Rectangle mCurViewport;
+ float mCurNear;
+ float mCurFar;
+
+ // Things needed in viewport state
+ dx_VertexConstants11 mVertexConstants;
+ dx_PixelConstants11 mPixelConstants;
+
+ // Render target variables
+ gl::Extents mViewportBounds;
+
+ // EGL_ANGLE_experimental_present_path variables
+ bool mCurPresentPathFastEnabled;
+ int mCurPresentPathFastColorBufferHeight;
+
+ // Current RenderTarget state
+ std::array<uintptr_t, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS> mAppliedRTVs;
+ uintptr_t mAppliedDSV;
+
+ // Currently applied textures
+ struct SRVRecord
+ {
+ uintptr_t srv;
+ uintptr_t resource;
+ D3D11_SHADER_RESOURCE_VIEW_DESC desc;
+ };
+
+ // A cache of current SRVs that also tracks the highest 'used' (non-NULL) SRV
+ // We might want to investigate a more robust approach that is also fast when there's
+ // a large gap between used SRVs (e.g. if SRV 0 and 7 are non-NULL, this approach will
+ // waste time on SRVs 1-6.)
+ class SRVCache : angle::NonCopyable
+ {
+ public:
+ SRVCache() : mHighestUsedSRV(0) {}
+
+ void initialize(size_t size) { mCurrentSRVs.resize(size); }
+
+ size_t size() const { return mCurrentSRVs.size(); }
+ size_t highestUsed() const { return mHighestUsedSRV; }
+
+ const SRVRecord &operator[](size_t index) const { return mCurrentSRVs[index]; }
+ void clear();
+ void update(size_t resourceIndex, ID3D11ShaderResourceView *srv);
+
+ private:
+ std::vector<SRVRecord> mCurrentSRVs;
+ size_t mHighestUsedSRV;
+ };
+
+ SRVCache mCurVertexSRVs;
+ SRVCache mCurPixelSRVs;
+
+ // A block of NULL pointers, cached so we don't re-allocate every draw call
+ std::vector<ID3D11ShaderResourceView *> mNullSRVs;
+};
+
+} // namespace rx
+#endif // LIBANGLE_RENDERER_D3D11_STATEMANAGER11_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
index 0af2cf12c6..785a83cd77 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
@@ -7,46 +7,82 @@
// SwapChain11.cpp: Implements a back-end specific class for the D3D11 swap chain.
#include "libANGLE/renderer/d3d/d3d11/SwapChain11.h"
-#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+#include <EGL/eglext.h>
+
+#include "libANGLE/features.h"
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
-#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/d3d11/NativeWindow.h"
-#include "libANGLE/features.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
+#include "third_party/trace_event/trace_event.h"
// Precompiled shaders
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h"
+#ifdef ANGLE_ENABLE_KEYEDMUTEX
+#define ANGLE_RESOURCE_SHARE_TYPE D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX
+#else
+#define ANGLE_RESOURCE_SHARE_TYPE D3D11_RESOURCE_MISC_SHARED
+#endif
namespace rx
{
-SwapChain11::SwapChain11(Renderer11 *renderer, NativeWindow nativeWindow, HANDLE shareHandle,
- GLenum backBufferFormat, GLenum depthBufferFormat)
- : mRenderer(renderer),
- SwapChainD3D(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat),
+namespace
+{
+bool NeedsOffscreenTexture(Renderer11 *renderer, NativeWindow nativeWindow, EGLint orientation)
+{
+ // We don't need an offscreen texture if either orientation = INVERT_Y,
+ // or present path fast is enabled and we're not rendering onto an offscreen surface.
+ return orientation != EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE &&
+ !(renderer->presentPathFastEnabled() && nativeWindow.getNativeWindow());
+}
+} // anonymous namespace
+
+SwapChain11::SwapChain11(Renderer11 *renderer,
+ NativeWindow nativeWindow,
+ HANDLE shareHandle,
+ GLenum backBufferFormat,
+ GLenum depthBufferFormat,
+ EGLint orientation)
+ : SwapChainD3D(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat),
+ mRenderer(renderer),
+ mWidth(-1),
+ mHeight(-1),
+ mOrientation(orientation),
+ mAppCreatedShareHandle(mShareHandle != nullptr),
+ mSwapInterval(0),
+ mPassThroughResourcesInit(false),
+ mFirstSwap(true),
+ mSwapChain(nullptr),
+#if defined(ANGLE_ENABLE_D3D11_1)
+ mSwapChain1(nullptr),
+#endif
+ mKeyedMutex(nullptr),
+ mBackBufferTexture(nullptr),
+ mBackBufferRTView(nullptr),
+ mBackBufferSRView(nullptr),
+ mNeedsOffscreenTexture(NeedsOffscreenTexture(renderer, nativeWindow, orientation)),
+ mOffscreenTexture(nullptr),
+ mOffscreenRTView(nullptr),
+ mOffscreenSRView(nullptr),
+ mDepthStencilTexture(nullptr),
+ mDepthStencilDSView(nullptr),
+ mDepthStencilSRView(nullptr),
+ mQuadVB(nullptr),
+ mPassThroughSampler(nullptr),
+ mPassThroughIL(nullptr),
+ mPassThroughVS(nullptr),
+ mPassThroughPS(nullptr),
+ mPassThroughRS(nullptr),
mColorRenderTarget(this, renderer, false),
mDepthStencilRenderTarget(this, renderer, true)
{
- mSwapChain = NULL;
- mBackBufferTexture = NULL;
- mBackBufferRTView = NULL;
- mOffscreenTexture = NULL;
- mOffscreenRTView = NULL;
- mOffscreenSRView = NULL;
- mDepthStencilTexture = NULL;
- mDepthStencilDSView = NULL;
- mDepthStencilSRView = NULL;
- mQuadVB = NULL;
- mPassThroughSampler = NULL;
- mPassThroughIL = NULL;
- mPassThroughVS = NULL;
- mPassThroughPS = NULL;
- mWidth = -1;
- mHeight = -1;
- mSwapInterval = 0;
- mAppCreatedShareHandle = mShareHandle != NULL;
- mPassThroughResourcesInit = false;
+ // Sanity check that if present path fast is active then we're using the default orientation
+ ASSERT(!mRenderer->presentPathFastEnabled() || orientation == 0);
}
SwapChain11::~SwapChain11()
@@ -56,9 +92,14 @@ SwapChain11::~SwapChain11()
void SwapChain11::release()
{
+#if defined(ANGLE_ENABLE_D3D11_1)
+ SafeRelease(mSwapChain1);
+#endif
SafeRelease(mSwapChain);
+ SafeRelease(mKeyedMutex);
SafeRelease(mBackBufferTexture);
SafeRelease(mBackBufferRTView);
+ SafeRelease(mBackBufferSRView);
SafeRelease(mOffscreenTexture);
SafeRelease(mOffscreenRTView);
SafeRelease(mOffscreenSRView);
@@ -70,6 +111,7 @@ void SwapChain11::release()
SafeRelease(mPassThroughIL);
SafeRelease(mPassThroughVS);
SafeRelease(mPassThroughPS);
+ SafeRelease(mPassThroughRS);
if (!mAppCreatedShareHandle)
{
@@ -77,18 +119,48 @@ void SwapChain11::release()
}
}
-void SwapChain11::releaseOffscreenTexture()
+void SwapChain11::releaseOffscreenColorBuffer()
{
SafeRelease(mOffscreenTexture);
SafeRelease(mOffscreenRTView);
SafeRelease(mOffscreenSRView);
+}
+
+void SwapChain11::releaseOffscreenDepthBuffer()
+{
SafeRelease(mDepthStencilTexture);
SafeRelease(mDepthStencilDSView);
SafeRelease(mDepthStencilSRView);
}
-EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHeight)
+EGLint SwapChain11::resetOffscreenBuffers(int backbufferWidth, int backbufferHeight)
+{
+ if (mNeedsOffscreenTexture)
+ {
+ EGLint result = resetOffscreenColorBuffer(backbufferWidth, backbufferHeight);
+ if (result != EGL_SUCCESS)
+ {
+ return result;
+ }
+ }
+
+ EGLint result = resetOffscreenDepthBuffer(backbufferWidth, backbufferHeight);
+ if (result != EGL_SUCCESS)
+ {
+ return result;
+ }
+
+ mWidth = backbufferWidth;
+ mHeight = backbufferHeight;
+
+ return EGL_SUCCESS;
+}
+
+EGLint SwapChain11::resetOffscreenColorBuffer(int backbufferWidth, int backbufferHeight)
{
+ ASSERT(mNeedsOffscreenTexture);
+
+ TRACE_EVENT0("gpu.angle", "SwapChain11::resetOffscreenTexture");
ID3D11Device *device = mRenderer->getDevice();
ASSERT(device != NULL);
@@ -106,9 +178,9 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
const int previousWidth = mWidth;
const int previousHeight = mHeight;
- releaseOffscreenTexture();
+ releaseOffscreenColorBuffer();
- const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat, mRenderer->getFeatureLevel());
+ const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps());
// If the app passed in a share handle, open the resource
// See EGL_ANGLE_d3d_share_handle_client_buffer
@@ -164,7 +236,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT;
offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
offscreenTextureDesc.CPUAccessFlags = 0;
- offscreenTextureDesc.MiscFlags = useSharedResource ? D3D11_RESOURCE_MISC_SHARED : 0;
+ offscreenTextureDesc.MiscFlags = useSharedResource ? ANGLE_RESOURCE_SHARE_TYPE : 0;
HRESULT result = device->CreateTexture2D(&offscreenTextureDesc, NULL, &mOffscreenTexture);
@@ -210,6 +282,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
}
}
+ // This may return null if the original texture was created without a keyed mutex.
+ mKeyedMutex = d3d11::DynamicCastComObject<IDXGIKeyedMutex>(mOffscreenTexture);
D3D11_RENDER_TARGET_VIEW_DESC offscreenRTVDesc;
offscreenRTVDesc.Format = backbufferFormatInfo.rtvFormat;
@@ -230,10 +304,41 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mOffscreenSRView, "Offscreen back buffer shader resource");
- const d3d11::TextureFormat &depthBufferFormatInfo = d3d11::GetTextureFormatInfo(mDepthBufferFormat, mRenderer->getFeatureLevel());
+ if (previousOffscreenTexture != nullptr)
+ {
+ D3D11_BOX sourceBox = {0};
+ sourceBox.left = 0;
+ sourceBox.right = std::min(previousWidth, backbufferWidth);
+ sourceBox.top = std::max(previousHeight - backbufferHeight, 0);
+ sourceBox.bottom = previousHeight;
+ sourceBox.front = 0;
+ sourceBox.back = 1;
+
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ const int yoffset = std::max(backbufferHeight - previousHeight, 0);
+ deviceContext->CopySubresourceRegion(mOffscreenTexture, 0, 0, yoffset, 0,
+ previousOffscreenTexture, 0, &sourceBox);
+
+ SafeRelease(previousOffscreenTexture);
+
+ if (mSwapChain)
+ {
+ swapRect(0, 0, backbufferWidth, backbufferHeight);
+ }
+ }
+
+ return EGL_SUCCESS;
+}
+
+EGLint SwapChain11::resetOffscreenDepthBuffer(int backbufferWidth, int backbufferHeight)
+{
+ releaseOffscreenDepthBuffer();
if (mDepthBufferFormat != GL_NONE)
{
+ const d3d11::TextureFormat &depthBufferFormatInfo =
+ d3d11::GetTextureFormatInfo(mDepthBufferFormat, mRenderer->getRenderer11DeviceCaps());
+
D3D11_TEXTURE2D_DESC depthStencilTextureDesc;
depthStencilTextureDesc.Width = backbufferWidth;
depthStencilTextureDesc.Height = backbufferHeight;
@@ -253,7 +358,9 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
depthStencilTextureDesc.CPUAccessFlags = 0;
depthStencilTextureDesc.MiscFlags = 0;
- result = device->CreateTexture2D(&depthStencilTextureDesc, NULL, &mDepthStencilTexture);
+ ID3D11Device *device = mRenderer->getDevice();
+ HRESULT result =
+ device->CreateTexture2D(&depthStencilTextureDesc, NULL, &mDepthStencilTexture);
if (FAILED(result))
{
ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result);
@@ -294,36 +401,12 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
}
}
- mWidth = backbufferWidth;
- mHeight = backbufferHeight;
-
- if (previousOffscreenTexture != NULL)
- {
- D3D11_BOX sourceBox = {0};
- sourceBox.left = 0;
- sourceBox.right = std::min(previousWidth, mWidth);
- sourceBox.top = std::max(previousHeight - mHeight, 0);
- sourceBox.bottom = previousHeight;
- sourceBox.front = 0;
- sourceBox.back = 1;
-
- ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
- const int yoffset = std::max(mHeight - previousHeight, 0);
- deviceContext->CopySubresourceRegion(mOffscreenTexture, 0, 0, yoffset, 0, previousOffscreenTexture, 0, &sourceBox);
-
- SafeRelease(previousOffscreenTexture);
-
- if (mSwapChain)
- {
- swapRect(0, 0, mWidth, mHeight);
- }
- }
-
return EGL_SUCCESS;
}
EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
{
+ TRACE_EVENT0("gpu.angle", "SwapChain11::resize");
ID3D11Device *device = mRenderer->getDevice();
if (device == NULL)
@@ -337,17 +420,30 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
return EGL_SUCCESS;
}
+ // Don't resize unnecessarily
+ if (mWidth == backbufferWidth && mHeight == backbufferHeight)
+ {
+ return EGL_SUCCESS;
+ }
+
// Can only call resize if we have already created our swap buffer and resources
- ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView);
+ ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView && mBackBufferSRView);
SafeRelease(mBackBufferTexture);
SafeRelease(mBackBufferRTView);
+ SafeRelease(mBackBufferSRView);
// Resize swap chain
DXGI_SWAP_CHAIN_DESC desc;
- mSwapChain->GetDesc(&desc);
- const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat, mRenderer->getFeatureLevel());
- HRESULT result = mSwapChain->ResizeBuffers(desc.BufferCount, backbufferWidth, backbufferHeight, backbufferFormatInfo.texFormat, 0);
+ HRESULT result = mSwapChain->GetDesc(&desc);
+ if (FAILED(result))
+ {
+ ERR("Error reading swap chain description: 0x%08X", result);
+ release();
+ return EGL_BAD_ALLOC;
+ }
+
+ result = mSwapChain->ResizeBuffers(desc.BufferCount, backbufferWidth, backbufferHeight, getSwapChainNativeFormat(), 0);
if (FAILED(result))
{
@@ -369,20 +465,50 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
if (SUCCEEDED(result))
{
d3d11::SetDebugName(mBackBufferTexture, "Back buffer texture");
- }
+ result = device->CreateRenderTargetView(mBackBufferTexture, NULL, &mBackBufferRTView);
+ ASSERT(SUCCEEDED(result));
+ if (SUCCEEDED(result))
+ {
+ d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target");
+ }
- result = device->CreateRenderTargetView(mBackBufferTexture, NULL, &mBackBufferRTView);
- ASSERT(SUCCEEDED(result));
- if (SUCCEEDED(result))
- {
- d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target");
+ result = device->CreateShaderResourceView(mBackBufferTexture, nullptr, &mBackBufferSRView);
+ ASSERT(SUCCEEDED(result));
+ if (SUCCEEDED(result))
+ {
+ d3d11::SetDebugName(mBackBufferSRView, "Back buffer shader resource");
+ }
}
- return resetOffscreenTexture(backbufferWidth, backbufferHeight);
+ mFirstSwap = true;
+
+ return resetOffscreenBuffers(backbufferWidth, backbufferHeight);
+}
+
+DXGI_FORMAT SwapChain11::getSwapChainNativeFormat() const
+{
+ // Return a render target format for offscreen rendering is supported by IDXGISwapChain.
+ // MSDN https://msdn.microsoft.com/en-us/library/windows/desktop/bb173064(v=vs.85).aspx
+ return (mOffscreenRenderTargetFormat == GL_BGRA8_EXT) ? DXGI_FORMAT_B8G8R8A8_UNORM : DXGI_FORMAT_R8G8B8A8_UNORM;
}
EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)
{
+ mSwapInterval = static_cast<unsigned int>(swapInterval);
+ if (mSwapInterval > 4)
+ {
+ // IDXGISwapChain::Present documentation states that valid sync intervals are in the [0,4]
+ // range
+ return EGL_BAD_PARAMETER;
+ }
+
+ // If the swap chain already exists, just resize
+ if (mSwapChain != nullptr)
+ {
+ return resize(backbufferWidth, backbufferHeight);
+ }
+
+ TRACE_EVENT0("gpu.angle", "SwapChain11::reset");
ID3D11Device *device = mRenderer->getDevice();
if (device == NULL)
@@ -392,30 +518,24 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
// Release specific resources to free up memory for the new render target, while the
// old render target still exists for the purpose of preserving its contents.
+#if defined(ANGLE_ENABLE_D3D11_1)
+ SafeRelease(mSwapChain1);
+#endif
SafeRelease(mSwapChain);
SafeRelease(mBackBufferTexture);
SafeRelease(mBackBufferRTView);
- mSwapInterval = static_cast<unsigned int>(swapInterval);
- if (mSwapInterval > 4)
- {
- // IDXGISwapChain::Present documentation states that valid sync intervals are in the [0,4] range
- return EGL_BAD_PARAMETER;
- }
-
// EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains
if (backbufferWidth < 1 || backbufferHeight < 1)
{
- releaseOffscreenTexture();
+ releaseOffscreenColorBuffer();
return EGL_SUCCESS;
}
if (mNativeWindow.getNativeWindow())
{
- const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat, mRenderer->getFeatureLevel());
-
HRESULT result = mNativeWindow.createSwapChain(device, mRenderer->getDxgiFactory(),
- backbufferFormatInfo.texFormat,
+ getSwapChainNativeFormat(),
backbufferWidth, backbufferHeight, &mSwapChain);
if (FAILED(result))
@@ -433,6 +553,13 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
}
}
+ if (mRenderer->getRenderer11DeviceCaps().supportsDXGI1_2)
+ {
+#if defined(ANGLE_ENABLE_D3D11_1)
+ mSwapChain1 = d3d11::DynamicCastComObject<IDXGISwapChain1>(mSwapChain);
+#endif
+ }
+
result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mBackBufferTexture, "Back buffer texture");
@@ -440,20 +567,25 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
result = device->CreateRenderTargetView(mBackBufferTexture, NULL, &mBackBufferRTView);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target");
- }
- // If we are resizing the swap chain, we don't wish to recreate all the static resources
- if (!mPassThroughResourcesInit)
- {
- mPassThroughResourcesInit = true;
- initPassThroughResources();
+ result = device->CreateShaderResourceView(mBackBufferTexture, nullptr, &mBackBufferSRView);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mBackBufferSRView, "Back buffer shader resource view");
}
- return resetOffscreenTexture(backbufferWidth, backbufferHeight);
+ mFirstSwap = true;
+
+ return resetOffscreenBuffers(backbufferWidth, backbufferHeight);
}
void SwapChain11::initPassThroughResources()
{
+ if (mPassThroughResourcesInit)
+ {
+ return;
+ }
+
+ TRACE_EVENT0("gpu.angle", "SwapChain11::initPassThroughResources");
ID3D11Device *device = mRenderer->getDevice();
ASSERT(device != NULL);
@@ -510,17 +642,58 @@ void SwapChain11::initPassThroughResources()
result = device->CreatePixelShader(g_PS_PassthroughRGBA2D, sizeof(g_PS_PassthroughRGBA2D), NULL, &mPassThroughPS);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mPassThroughPS, "Swap chain pass through pixel shader");
+
+ // Use the default rasterizer state but without culling
+ D3D11_RASTERIZER_DESC rasterizerDesc;
+ rasterizerDesc.FillMode = D3D11_FILL_SOLID;
+ rasterizerDesc.CullMode = D3D11_CULL_NONE;
+ rasterizerDesc.FrontCounterClockwise = FALSE;
+ rasterizerDesc.DepthBias = 0;
+ rasterizerDesc.SlopeScaledDepthBias = 0.0f;
+ rasterizerDesc.DepthBiasClamp = 0.0f;
+ rasterizerDesc.DepthClipEnable = TRUE;
+ rasterizerDesc.ScissorEnable = FALSE;
+ rasterizerDesc.MultisampleEnable = FALSE;
+ rasterizerDesc.AntialiasedLineEnable = FALSE;
+ result = device->CreateRasterizerState(&rasterizerDesc, &mPassThroughRS);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mPassThroughRS, "Swap chain pass through rasterizer state");
+
+ mPassThroughResourcesInit = true;
}
// parameters should be validated/clamped by caller
EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
{
+ if (mNeedsOffscreenTexture)
+ {
+ EGLint result = copyOffscreenToBackbuffer(x, y, width, height);
+ if (result != EGL_SUCCESS)
+ {
+ return result;
+ }
+ }
+
+ EGLint result = present(x, y, width, height);
+ if (result != EGL_SUCCESS)
+ {
+ return result;
+ }
+
+ mRenderer->onSwap();
+
+ return EGL_SUCCESS;
+}
+
+EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, EGLint height)
+{
if (!mSwapChain)
{
return EGL_SUCCESS;
}
- ID3D11Device *device = mRenderer->getDevice();
+ initPassThroughResources();
+
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
// Set vertices
@@ -544,6 +717,16 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
float u2 = (x + width) / float(mWidth);
float v2 = (y + height) / float(mHeight);
+ // Invert the quad vertices depending on the surface orientation.
+ if ((mOrientation & EGL_SURFACE_ORIENTATION_INVERT_X_ANGLE) != 0)
+ {
+ std::swap(x1, x2);
+ }
+ if ((mOrientation & EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE) != 0)
+ {
+ std::swap(y1, y2);
+ }
+
d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v1);
d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v2);
d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v1);
@@ -561,7 +744,7 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
static const float blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
deviceContext->OMSetBlendState(NULL, blendFactor, 0xFFFFFFF);
- deviceContext->RSSetState(NULL);
+ deviceContext->RSSetState(mPassThroughRS);
// Apply shaders
deviceContext->IASetInputLayout(mPassThroughIL);
@@ -577,30 +760,79 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
D3D11_VIEWPORT viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
- viewport.Width = mWidth;
- viewport.Height = mHeight;
+ viewport.Width = static_cast<FLOAT>(mWidth);
+ viewport.Height = static_cast<FLOAT>(mHeight);
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
deviceContext->RSSetViewports(1, &viewport);
// Apply textures
- mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, mOffscreenSRView);
+ auto stateManager = mRenderer->getStateManager();
+ stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, mOffscreenSRView);
deviceContext->PSSetSamplers(0, 1, &mPassThroughSampler);
// Draw
deviceContext->Draw(4, 0);
+ // Rendering to the swapchain is now complete. Now we can call Present().
+ // Before that, we perform any cleanup on the D3D device. We do this before Present() to make sure the
+ // cleanup is caught under the current eglSwapBuffers() PIX/Graphics Diagnostics call rather than the next one.
+ stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
+
+ mRenderer->unapplyRenderTargets();
+ mRenderer->markAllStateDirty();
+
+ return EGL_SUCCESS;
+}
+
+EGLint SwapChain11::present(EGLint x, EGLint y, EGLint width, EGLint height)
+{
+ if (!mSwapChain)
+ {
+ return EGL_SUCCESS;
+ }
+
+ UINT swapInterval = mSwapInterval;
#if ANGLE_VSYNC == ANGLE_DISABLED
- result = mSwapChain->Present(0, 0);
-#else
- result = mSwapChain->Present(mSwapInterval, 0);
+ swapInterval = 0;
#endif
+ HRESULT result = S_OK;
+
+#if defined(ANGLE_ENABLE_D3D11_1)
+ // Use IDXGISwapChain1::Present1 with a dirty rect if DXGI 1.2 is available.
+ if (mSwapChain1 != nullptr)
+ {
+ if (mFirstSwap)
+ {
+ // Can't swap with a dirty rect if this swap chain has never swapped before
+ DXGI_PRESENT_PARAMETERS params = {0, nullptr, nullptr, nullptr};
+ result = mSwapChain1->Present1(swapInterval, 0, &params);
+ }
+ else
+ {
+ RECT rect = {static_cast<LONG>(x), static_cast<LONG>(mHeight - y - height),
+ static_cast<LONG>(x + width), static_cast<LONG>(mHeight - y)};
+ DXGI_PRESENT_PARAMETERS params = {1, &rect, nullptr, nullptr};
+ result = mSwapChain1->Present1(swapInterval, 0, &params);
+ }
+ }
+ else
+#endif
+ {
+ result = mSwapChain->Present(swapInterval, 0);
+ }
+
+ mFirstSwap = false;
+
+ // Some swapping mechanisms such as DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL unbind the current render
+ // target. Mark it dirty.
+ mRenderer->getStateManager()->invalidateRenderTarget();
+
if (result == DXGI_ERROR_DEVICE_REMOVED)
{
- HRESULT removedReason = device->GetDeviceRemovedReason();
- UNUSED_TRACE_VARIABLE(removedReason);
- ERR("Present failed: the D3D11 device was removed: 0x%08X", removedReason);
+ ERR("Present failed: the D3D11 device was removed: 0x%08X",
+ mRenderer->getDevice()->GetDeviceRemovedReason());
return EGL_CONTEXT_LOST;
}
else if (result == DXGI_ERROR_DEVICE_RESET)
@@ -613,28 +845,24 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
ERR("Present failed with error code 0x%08X", result);
}
- // Unbind
- mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
-
- mRenderer->unapplyRenderTargets();
- mRenderer->markAllStateDirty();
+ mNativeWindow.commitChange();
return EGL_SUCCESS;
}
ID3D11Texture2D *SwapChain11::getOffscreenTexture()
{
- return mOffscreenTexture;
+ return mNeedsOffscreenTexture ? mOffscreenTexture : mBackBufferTexture;
}
ID3D11RenderTargetView *SwapChain11::getRenderTarget()
{
- return mOffscreenRTView;
+ return mNeedsOffscreenTexture ? mOffscreenRTView : mBackBufferRTView;
}
ID3D11ShaderResourceView *SwapChain11::getRenderTargetShaderResource()
{
- return mOffscreenSRView;
+ return mNeedsOffscreenTexture ? mOffscreenSRView : mBackBufferSRView;
}
ID3D11DepthStencilView *SwapChain11::getDepthStencil()
@@ -652,12 +880,6 @@ ID3D11Texture2D *SwapChain11::getDepthStencilTexture()
return mDepthStencilTexture;
}
-SwapChain11 *SwapChain11::makeSwapChain11(SwapChainD3D *swapChain)
-{
- ASSERT(HAS_DYNAMIC_TYPE(SwapChain11*, swapChain));
- return static_cast<SwapChain11*>(swapChain);
-}
-
void SwapChain11::recreate()
{
// possibly should use this method instead of reset
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h
index 48c808a261..adcd07adb0 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h
@@ -20,8 +20,12 @@ class Renderer11;
class SwapChain11 : public SwapChainD3D
{
public:
- SwapChain11(Renderer11 *renderer, NativeWindow nativeWindow, HANDLE shareHandle,
- GLenum backBufferFormat, GLenum depthBufferFormat);
+ SwapChain11(Renderer11 *renderer,
+ NativeWindow nativeWindow,
+ HANDLE shareHandle,
+ GLenum backBufferFormat,
+ GLenum depthBufferFormat,
+ EGLint orientation);
virtual ~SwapChain11();
EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight);
@@ -42,29 +46,45 @@ class SwapChain11 : public SwapChainD3D
EGLint getWidth() const { return mWidth; }
EGLint getHeight() const { return mHeight; }
+ void *getKeyedMutex() override { return mKeyedMutex; }
virtual void *getDevice();
- static SwapChain11 *makeSwapChain11(SwapChainD3D *swapChain);
-
private:
void release();
void initPassThroughResources();
- void releaseOffscreenTexture();
- EGLint resetOffscreenTexture(int backbufferWidth, int backbufferHeight);
+
+ void releaseOffscreenColorBuffer();
+ void releaseOffscreenDepthBuffer();
+ EGLint resetOffscreenBuffers(int backbufferWidth, int backbufferHeight);
+ EGLint resetOffscreenColorBuffer(int backbufferWidth, int backbufferHeight);
+ EGLint resetOffscreenDepthBuffer(int backbufferWidth, int backbufferHeight);
+
+ DXGI_FORMAT getSwapChainNativeFormat() const;
+
+ EGLint copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, EGLint height);
+ EGLint present(EGLint x, EGLint y, EGLint width, EGLint height);
Renderer11 *mRenderer;
- EGLint mHeight;
EGLint mWidth;
+ EGLint mHeight;
+ const EGLint mOrientation;
bool mAppCreatedShareHandle;
unsigned int mSwapInterval;
bool mPassThroughResourcesInit;
+ bool mFirstSwap;
DXGISwapChain *mSwapChain;
+#if defined(ANGLE_ENABLE_D3D11_1)
+ IDXGISwapChain1 *mSwapChain1;
+#endif
+ IDXGIKeyedMutex *mKeyedMutex;
ID3D11Texture2D *mBackBufferTexture;
ID3D11RenderTargetView *mBackBufferRTView;
+ ID3D11ShaderResourceView *mBackBufferSRView;
+ const bool mNeedsOffscreenTexture;
ID3D11Texture2D *mOffscreenTexture;
ID3D11RenderTargetView *mOffscreenRTView;
ID3D11ShaderResourceView *mOffscreenSRView;
@@ -78,6 +98,7 @@ class SwapChain11 : public SwapChainD3D
ID3D11InputLayout *mPassThroughIL;
ID3D11VertexShader *mPassThroughVS;
ID3D11PixelShader *mPassThroughPS;
+ ID3D11RasterizerState *mPassThroughRS;
SurfaceRenderTarget11 mColorRenderTarget;
SurfaceRenderTarget11 mDepthStencilRenderTarget;
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
index 103e90fed3..11b9f76464 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
@@ -13,22 +13,27 @@
#include "common/MemoryBuffer.h"
#include "common/utilities.h"
-#include "libANGLE/ImageIndex.h"
#include "libANGLE/formatutils.h"
-#include "libANGLE/renderer/d3d/TextureD3D.h"
+#include "libANGLE/ImageIndex.h"
#include "libANGLE/renderer/d3d/d3d11/Blit11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
#include "libANGLE/renderer/d3d/d3d11/Image11.h"
-#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
-#include "libANGLE/renderer/d3d/d3d11/SwapChain11.h"
-#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libANGLE/renderer/d3d/d3d11/SwapChain11.h"
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
+#include "libANGLE/renderer/d3d/EGLImageD3D.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
namespace rx
{
TextureStorage11::SwizzleCacheValue::SwizzleCacheValue()
- : swizzleRed(GL_NONE), swizzleGreen(GL_NONE), swizzleBlue(GL_NONE), swizzleAlpha(GL_NONE)
+ : swizzleRed(GL_INVALID_INDEX),
+ swizzleGreen(GL_INVALID_INDEX),
+ swizzleBlue(GL_INVALID_INDEX),
+ swizzleAlpha(GL_INVALID_INDEX)
{
}
@@ -60,8 +65,8 @@ bool TextureStorage11::SRVKey::operator<(const SRVKey &rhs) const
return std::tie(baseLevel, mipLevels, swizzle) < std::tie(rhs.baseLevel, rhs.mipLevels, rhs.swizzle);
}
-TextureStorage11::TextureStorage11(Renderer11 *renderer, UINT bindFlags)
- : mBindFlags(bindFlags),
+TextureStorage11::TextureStorage11(Renderer11 *renderer, UINT bindFlags, UINT miscFlags)
+ : mRenderer(renderer),
mTopLevel(0),
mMipLevels(0),
mInternalFormat(GL_NONE),
@@ -71,13 +76,13 @@ TextureStorage11::TextureStorage11(Renderer11 *renderer, UINT bindFlags)
mDepthStencilFormat(DXGI_FORMAT_UNKNOWN),
mTextureWidth(0),
mTextureHeight(0),
- mTextureDepth(0)
+ mTextureDepth(0),
+ mBindFlags(bindFlags),
+ mMiscFlags(miscFlags)
{
- mRenderer = Renderer11::makeRenderer11(renderer);
-
for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
{
- mLevelSRVs[i] = NULL;
+ mLevelSRVs[i] = nullptr;
}
}
@@ -95,17 +100,11 @@ TextureStorage11::~TextureStorage11()
mSrvCache.clear();
}
-TextureStorage11 *TextureStorage11::makeTextureStorage11(TextureStorage *storage)
-{
- ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11*, storage));
- return static_cast<TextureStorage11*>(storage);
-}
-
-DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, D3D_FEATURE_LEVEL featureLevel, bool renderTarget)
+DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, const Renderer11DeviceCaps &renderer11DeviceCaps, bool renderTarget)
{
UINT bindFlags = 0;
- const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat, featureLevel);
+ const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat, renderer11DeviceCaps);
if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN)
{
bindFlags |= D3D11_BIND_SHADER_RESOURCE;
@@ -122,11 +121,34 @@ DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, D3D_FEATURE_L
return bindFlags;
}
+DWORD TextureStorage11::GetTextureMiscFlags(GLenum internalFormat, const Renderer11DeviceCaps &renderer11DeviceCaps, bool renderTarget, int levels)
+{
+ UINT miscFlags = 0;
+
+ const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat, renderer11DeviceCaps);
+ if (renderTarget && levels > 1)
+ {
+ const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(formatInfo.texFormat);
+
+ if (dxgiFormatInfo.nativeMipmapSupport(renderer11DeviceCaps.featureLevel))
+ {
+ miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS;
+ }
+ }
+
+ return miscFlags;
+}
+
UINT TextureStorage11::getBindFlags() const
{
return mBindFlags;
}
+UINT TextureStorage11::getMiscFlags() const
+{
+ return mMiscFlags;
+}
+
int TextureStorage11::getTopLevel() const
{
return mTopLevel;
@@ -142,6 +164,11 @@ bool TextureStorage11::isManaged() const
return false;
}
+bool TextureStorage11::supportsNativeMipmapFunction() const
+{
+ return (mMiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS) != 0;
+}
+
int TextureStorage11::getLevelCount() const
{
return mMipLevels - mTopLevel;
@@ -171,16 +198,17 @@ UINT TextureStorage11::getSubresourceIndex(const gl::ImageIndex &index) const
return subresource;
}
-gl::Error TextureStorage11::getSRV(const gl::SamplerState &samplerState, ID3D11ShaderResourceView **outSRV)
+gl::Error TextureStorage11::getSRV(const gl::TextureState &textureState,
+ ID3D11ShaderResourceView **outSRV)
{
- bool swizzleRequired = samplerState.swizzleRequired();
- bool mipmapping = gl::IsMipmapFiltered(samplerState);
- unsigned int mipLevels = mipmapping ? (samplerState.maxLevel - samplerState.baseLevel + 1) : 1;
+ bool swizzleRequired = textureState.swizzleRequired();
+ bool mipmapping = gl::IsMipmapFiltered(textureState.samplerState);
+ unsigned int mipLevels = mipmapping ? (textureState.maxLevel - textureState.baseLevel + 1) : 1;
- // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level, which corresponds to GL level 0)
- mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - samplerState.baseLevel);
+ // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level, which corresponds to GL level 0)
+ mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - textureState.baseLevel);
- if (mRenderer->getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3)
+ if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
{
ASSERT(!swizzleRequired);
ASSERT(mipLevels == 1 || mipLevels == mMipLevels);
@@ -198,47 +226,47 @@ gl::Error TextureStorage11::getSRV(const gl::SamplerState &samplerState, ID3D11S
if (swizzleRequired)
{
- verifySwizzleExists(samplerState.swizzleRed, samplerState.swizzleGreen, samplerState.swizzleBlue, samplerState.swizzleAlpha);
+ verifySwizzleExists(textureState.swizzleRed, textureState.swizzleGreen,
+ textureState.swizzleBlue, textureState.swizzleAlpha);
}
- SRVKey key(samplerState.baseLevel, mipLevels, swizzleRequired);
- SRVCache::const_iterator iter = mSrvCache.find(key);
+ SRVKey key(textureState.baseLevel, mipLevels, swizzleRequired);
+ auto iter = mSrvCache.find(key);
if (iter != mSrvCache.end())
{
*outSRV = iter->second;
+ return gl::Error(GL_NO_ERROR);
}
- else
+
+ ID3D11Resource *texture = nullptr;
+ if (swizzleRequired)
{
- ID3D11Resource *texture = NULL;
- if (swizzleRequired)
- {
- gl::Error error = getSwizzleTexture(&texture);
- if (error.isError())
- {
- return error;
- }
- }
- else
+ gl::Error error = getSwizzleTexture(&texture);
+ if (error.isError())
{
- gl::Error error = getResource(&texture);
- if (error.isError())
- {
- return error;
- }
+ return error;
}
-
- ID3D11ShaderResourceView *srv = NULL;
- DXGI_FORMAT format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat);
- gl::Error error = createSRV(samplerState.baseLevel, mipLevels, format, texture, &srv);
+ }
+ else
+ {
+ gl::Error error = getResource(&texture);
if (error.isError())
{
return error;
}
+ }
- mSrvCache.insert(std::make_pair(key, srv));
- *outSRV = srv;
+ ID3D11ShaderResourceView *srv = nullptr;
+ DXGI_FORMAT format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat);
+ gl::Error error = createSRV(textureState.baseLevel, mipLevels, format, texture, &srv);
+ if (error.isError())
+ {
+ return error;
}
+ mSrvCache.insert(std::make_pair(key, srv));
+ *outSRV = srv;
+
return gl::Error(GL_NO_ERROR);
}
@@ -267,6 +295,56 @@ gl::Error TextureStorage11::getSRVLevel(int mipLevel, ID3D11ShaderResourceView *
return gl::Error(GL_NO_ERROR);
}
+gl::Error TextureStorage11::getSRVLevels(GLint baseLevel, GLint maxLevel, ID3D11ShaderResourceView **outSRV)
+{
+ unsigned int mipLevels = maxLevel - baseLevel + 1;
+
+ // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level, which corresponds to GL level 0)
+ mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - baseLevel);
+
+ if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
+ {
+ ASSERT(mipLevels == 1 || mipLevels == mMipLevels);
+ }
+
+ if (mRenderer->getWorkarounds().zeroMaxLodWorkaround)
+ {
+ // We must ensure that the level zero texture is in sync with mipped texture.
+ gl::Error error = useLevelZeroWorkaroundTexture(mipLevels == 1);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ SRVKey key(baseLevel, mipLevels, false);
+ auto iter = mSrvCache.find(key);
+ if (iter != mSrvCache.end())
+ {
+ *outSRV = iter->second;
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ ID3D11Resource *texture = nullptr;
+ gl::Error error = getResource(&texture);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ID3D11ShaderResourceView *srv = nullptr;
+ error = createSRV(baseLevel, mipLevels, mShaderResourceFormat, texture, &srv);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ mSrvCache[key] = srv;
+ *outSRV = srv;
+
+ return gl::Error(GL_NO_ERROR);
+}
+
gl::Error TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha)
{
SwizzleCacheValue swizzleTarget(swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha);
@@ -427,7 +505,7 @@ gl::Error TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, uns
// D3D11 can't perform partial CopySubresourceRegion on depth/stencil textures, so pSrcBox should be NULL.
D3D11_BOX srcBox;
D3D11_BOX *pSrcBox = NULL;
- if (mRenderer->getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3)
+ if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
{
// However, D3D10Level9 doesn't always perform CopySubresourceRegion correctly unless the source box
// is specified. This is okay, since we don't perform CopySubresourceRegion on depth/stencil
@@ -469,8 +547,8 @@ gl::Error TextureStorage11::generateMipmap(const gl::ImageIndex &sourceIndex, co
return error;
}
- ID3D11ShaderResourceView *sourceSRV = RenderTarget11::makeRenderTarget11(source)->getShaderResourceView();
- ID3D11RenderTargetView *destRTV = RenderTarget11::makeRenderTarget11(dest)->getRenderTargetView();
+ ID3D11ShaderResourceView *sourceSRV = GetAs<RenderTarget11>(source)->getShaderResourceView();
+ ID3D11RenderTargetView *destRTV = GetAs<RenderTarget11>(dest)->getRenderTargetView();
gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth());
gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth());
@@ -479,8 +557,9 @@ gl::Error TextureStorage11::generateMipmap(const gl::ImageIndex &sourceIndex, co
gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth());
Blit11 *blitter = mRenderer->getBlitter();
- return blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL,
- gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR);
+ return blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize,
+ NULL, gl::GetInternalFormatInfo(source->getInternalFormat()).format,
+ GL_LINEAR, false);
}
void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha)
@@ -492,6 +571,30 @@ void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGree
}
}
+void TextureStorage11::clearSRVCache()
+{
+ invalidateSwizzleCache();
+
+ auto iter = mSrvCache.begin();
+ while (iter != mSrvCache.end())
+ {
+ if (!iter->first.swizzle)
+ {
+ SafeRelease(iter->second);
+ iter = mSrvCache.erase(iter);
+ }
+ else
+ {
+ iter++;
+ }
+ }
+
+ for (size_t level = 0; level < ArraySize(mLevelSRVs); level++)
+ {
+ SafeRelease(mLevelSRVs[level]);
+ }
+}
+
gl::Error TextureStorage11::copyToStorage(TextureStorage *destStorage)
{
ASSERT(destStorage);
@@ -503,7 +606,7 @@ gl::Error TextureStorage11::copyToStorage(TextureStorage *destStorage)
return error;
}
- TextureStorage11 *dest11 = TextureStorage11::makeTextureStorage11(destStorage);
+ TextureStorage11 *dest11 = GetAs<TextureStorage11>(destStorage);
ID3D11Resource *destResource = NULL;
error = dest11->getResource(&destResource);
if (error.isError())
@@ -550,29 +653,43 @@ gl::Error TextureStorage11::setData(const gl::ImageIndex &index, ImageD3D *image
int height = destBox ? destBox->height : static_cast<int>(image->getHeight());
int depth = destBox ? destBox->depth : static_cast<int>(image->getDepth());
UINT srcRowPitch = internalFormatInfo.computeRowPitch(type, width, unpack.alignment, unpack.rowLength);
- UINT srcDepthPitch = internalFormatInfo.computeDepthPitch(type, width, height, unpack.alignment, unpack.rowLength);
+ UINT srcDepthPitch = internalFormatInfo.computeDepthPitch(type, width, height, unpack.alignment,
+ unpack.rowLength, unpack.imageHeight);
+ GLsizei srcSkipBytes = internalFormatInfo.computeSkipPixels(
+ srcRowPitch, srcDepthPitch, unpack.skipImages, unpack.skipRows, unpack.skipPixels);
- const d3d11::TextureFormat &d3d11Format = d3d11::GetTextureFormatInfo(image->getInternalFormat(), mRenderer->getFeatureLevel());
+ const d3d11::TextureFormat &d3d11Format = d3d11::GetTextureFormatInfo(image->getInternalFormat(), mRenderer->getRenderer11DeviceCaps());
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3d11Format.texFormat);
size_t outputPixelSize = dxgiFormatInfo.pixelBytes;
- UINT bufferRowPitch = outputPixelSize * width;
+ UINT bufferRowPitch = static_cast<unsigned int>(outputPixelSize) * width;
UINT bufferDepthPitch = bufferRowPitch * height;
size_t neededSize = bufferDepthPitch * depth;
- MemoryBuffer *conversionBuffer = NULL;
- error = mRenderer->getScratchMemoryBuffer(neededSize, &conversionBuffer);
- if (error.isError())
+ MemoryBuffer *conversionBuffer = nullptr;
+ const uint8_t *data = nullptr;
+
+ d3d11::LoadImageFunctionInfo loadFunctionInfo = d3d11Format.loadFunctions.at(type);
+ if (loadFunctionInfo.requiresConversion)
{
- return error;
- }
+ error = mRenderer->getScratchMemoryBuffer(neededSize, &conversionBuffer);
+ if (error.isError())
+ {
+ return error;
+ }
- // TODO: fast path
- LoadImageFunction loadFunction = d3d11Format.loadFunctions.at(type);
- loadFunction(width, height, depth,
- pixelData, srcRowPitch, srcDepthPitch,
- conversionBuffer->data(), bufferRowPitch, bufferDepthPitch);
+ loadFunctionInfo.loadFunction(width, height, depth, pixelData + srcSkipBytes, srcRowPitch,
+ srcDepthPitch, conversionBuffer->data(), bufferRowPitch,
+ bufferDepthPitch);
+ data = conversionBuffer->data();
+ }
+ else
+ {
+ data = pixelData + srcSkipBytes;
+ bufferRowPitch = srcRowPitch;
+ bufferDepthPitch = srcDepthPitch;
+ }
ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
@@ -588,27 +705,25 @@ gl::Error TextureStorage11::setData(const gl::ImageIndex &index, ImageD3D *image
destD3DBox.front = destBox->z;
destD3DBox.back = destBox->z + destBox->depth;
- immediateContext->UpdateSubresource(resource, destSubresource,
- &destD3DBox, conversionBuffer->data(),
+ immediateContext->UpdateSubresource(resource, destSubresource, &destD3DBox, data,
bufferRowPitch, bufferDepthPitch);
}
else
{
- immediateContext->UpdateSubresource(resource, destSubresource,
- NULL, conversionBuffer->data(),
- bufferRowPitch, bufferDepthPitch);
+ immediateContext->UpdateSubresource(resource, destSubresource, NULL, data, bufferRowPitch,
+ bufferDepthPitch);
}
return gl::Error(GL_NO_ERROR);
}
TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain)
- : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE),
+ : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, 0),
mTexture(swapchain->getOffscreenTexture()),
- mSwizzleTexture(NULL),
mLevelZeroTexture(NULL),
mLevelZeroRenderTarget(NULL),
- mUseLevelZeroTexture(false)
+ mUseLevelZeroTexture(false),
+ mSwizzleTexture(NULL)
{
mTexture->AddRef();
@@ -627,7 +742,7 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swap
mTextureHeight = texDesc.Height;
mTextureDepth = 1;
- mInternalFormat = swapchain->GetBackBufferInternalFormat();
+ mInternalFormat = swapchain->GetRenderTargetInternalFormat();
ID3D11ShaderResourceView *srv = swapchain->getRenderTargetShaderResource();
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
@@ -640,23 +755,23 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swap
mRenderTargetFormat = rtvDesc.Format;
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
- const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(dxgiFormatInfo.internalFormat, mRenderer->getFeatureLevel());
+ const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(dxgiFormatInfo.internalFormat, mRenderer->getRenderer11DeviceCaps());
mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
mDepthStencilFormat = DXGI_FORMAT_UNKNOWN;
-
- initializeSerials(1, 1);
}
TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly)
- : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderer->getFeatureLevel(), renderTarget)),
+ : TextureStorage11(renderer,
+ GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget),
+ GetTextureMiscFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget, levels)),
mTexture(NULL),
- mSwizzleTexture(NULL),
mLevelZeroTexture(NULL),
mLevelZeroRenderTarget(NULL),
- mUseLevelZeroTexture(false)
+ mUseLevelZeroTexture(false),
+ mSwizzleTexture(NULL)
{
for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
{
@@ -667,7 +782,7 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, GLenum internalfo
mInternalFormat = internalformat;
- const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, renderer->getFeatureLevel());
+ const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, renderer->getRenderer11DeviceCaps());
mTextureFormat = formatInfo.texFormat;
mShaderResourceFormat = formatInfo.srvFormat;
mDepthStencilFormat = formatInfo.dsvFormat;
@@ -688,8 +803,6 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, GLenum internalfo
ASSERT(mRenderer->getWorkarounds().zeroMaxLodWorkaround);
mUseLevelZeroTexture = true;
}
-
- initializeSerials(getLevelCount(), 1);
}
TextureStorage11_2D::~TextureStorage11_2D()
@@ -726,17 +839,11 @@ TextureStorage11_2D::~TextureStorage11_2D()
}
}
-TextureStorage11_2D *TextureStorage11_2D::makeTextureStorage11_2D(TextureStorage *storage)
-{
- ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_2D*, storage));
- return static_cast<TextureStorage11_2D*>(storage);
-}
-
gl::Error TextureStorage11_2D::copyToStorage(TextureStorage *destStorage)
{
ASSERT(destStorage);
- TextureStorage11_2D *dest11 = TextureStorage11_2D::makeTextureStorage11_2D(destStorage);
+ TextureStorage11_2D *dest11 = GetAs<TextureStorage11_2D>(destStorage);
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround)
{
@@ -989,7 +1096,7 @@ gl::Error TextureStorage11_2D::ensureTextureExists(int mipLevels)
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = getBindFlags();
desc.CPUAccessFlags = 0;
- desc.MiscFlags = 0;
+ desc.MiscFlags = getMiscFlags();
HRESULT result = device->CreateTexture2D(&desc, NULL, outputTexture);
@@ -1004,6 +1111,8 @@ gl::Error TextureStorage11_2D::ensureTextureExists(int mipLevels)
ASSERT(result == E_OUTOFMEMORY);
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D texture storage, result: 0x%X.", result);
}
+
+ d3d11::SetDebugName(*outputTexture, "TexStorage2D.Texture");
}
return gl::Error(GL_NO_ERROR);
@@ -1021,7 +1130,7 @@ gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, Rend
// On Feature Level 9_3, this is unlikely to be useful. The renderer can't create SRVs on the individual levels of the texture,
// so methods like generateMipmap can't do anything useful with non-zero-level RTVs.
// Therefore if level > 0 on 9_3 then there's almost certainly something wrong.
- ASSERT(!(mRenderer->getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3 && level > 0));
+ ASSERT(!(mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3 && level > 0));
if (!mRenderTarget[level])
{
@@ -1170,6 +1279,8 @@ gl::Error TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORM
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
}
+ d3d11::SetDebugName(*outSRV, "TexStorage2D.SRV");
+
return gl::Error(GL_NO_ERROR);
}
@@ -1201,6 +1312,8 @@ gl::Error TextureStorage11_2D::getSwizzleTexture(ID3D11Resource **outTexture)
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
}
+
+ d3d11::SetDebugName(mSwizzleTexture, "TexStorage2D.SwizzleTexture");
}
*outTexture = mSwizzleTexture;
@@ -1241,8 +1354,337 @@ gl::Error TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel, ID3D11Render
return gl::Error(GL_NO_ERROR);
}
+TextureStorage11_EGLImage::TextureStorage11_EGLImage(Renderer11 *renderer, EGLImageD3D *eglImage)
+ : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, 0),
+ mImage(eglImage),
+ mCurrentRenderTarget(0),
+ mSwizzleTexture(nullptr),
+ mSwizzleRenderTargets(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS, nullptr)
+{
+ RenderTargetD3D *renderTargetD3D = nullptr;
+ mImage->getRenderTarget(&renderTargetD3D);
+ RenderTarget11 *renderTarget11 = GetAs<RenderTarget11>(renderTargetD3D);
+ mCurrentRenderTarget = reinterpret_cast<uintptr_t>(renderTarget11);
+
+ mMipLevels = 1;
+ mTextureFormat = renderTarget11->getDXGIFormat();
+ mTextureWidth = renderTarget11->getWidth();
+ mTextureHeight = renderTarget11->getHeight();
+ mTextureDepth = 1;
+ mInternalFormat = renderTarget11->getInternalFormat();
+
+ ID3D11ShaderResourceView *srv = renderTarget11->getShaderResourceView();
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srv->GetDesc(&srvDesc);
+ mShaderResourceFormat = srvDesc.Format;
+
+ ID3D11RenderTargetView *rtv = renderTarget11->getRenderTargetView();
+ if (rtv != nullptr)
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtv->GetDesc(&rtvDesc);
+ mRenderTargetFormat = rtvDesc.Format;
+ }
+ else
+ {
+ mRenderTargetFormat = DXGI_FORMAT_UNKNOWN;
+ }
+
+ ID3D11DepthStencilView *dsv = renderTarget11->getDepthStencilView();
+ if (dsv != nullptr)
+ {
+ D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ dsv->GetDesc(&dsvDesc);
+ mDepthStencilFormat = dsvDesc.Format;
+ }
+ else
+ {
+ mDepthStencilFormat = DXGI_FORMAT_UNKNOWN;
+ }
+
+ const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
+ const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(
+ dxgiFormatInfo.internalFormat, mRenderer->getRenderer11DeviceCaps());
+ mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
+ mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
+ mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
+}
+
+TextureStorage11_EGLImage::~TextureStorage11_EGLImage()
+{
+ SafeRelease(mSwizzleTexture);
+ for (size_t i = 0; i < mSwizzleRenderTargets.size(); i++)
+ {
+ SafeRelease(mSwizzleRenderTargets[i]);
+ }
+}
+
+gl::Error TextureStorage11_EGLImage::getResource(ID3D11Resource **outResource)
+{
+ gl::Error error = checkForUpdatedRenderTarget();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ RenderTarget11 *renderTarget11 = nullptr;
+ error = getImageRenderTarget(&renderTarget11);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ *outResource = renderTarget11->getTexture();
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureStorage11_EGLImage::getSRV(const gl::TextureState &textureState,
+ ID3D11ShaderResourceView **outSRV)
+{
+ gl::Error error = checkForUpdatedRenderTarget();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return TextureStorage11::getSRV(textureState, outSRV);
+}
+
+gl::Error TextureStorage11_EGLImage::getMippedResource(ID3D11Resource **)
+{
+ // This shouldn't be called unless the zero max LOD workaround is active.
+ // EGL images are unavailable in this configuration.
+ UNREACHABLE();
+ return gl::Error(GL_INVALID_OPERATION);
+}
+
+gl::Error TextureStorage11_EGLImage::getRenderTarget(const gl::ImageIndex &index,
+ RenderTargetD3D **outRT)
+{
+ ASSERT(!index.hasLayer());
+ ASSERT(index.mipIndex == 0);
+ UNUSED_ASSERTION_VARIABLE(index);
+
+ gl::Error error = checkForUpdatedRenderTarget();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return mImage->getRenderTarget(outRT);
+}
+
+gl::Error TextureStorage11_EGLImage::copyToStorage(TextureStorage *destStorage)
+{
+ ID3D11Resource *sourceResouce = nullptr;
+ gl::Error error = getResource(&sourceResouce);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ASSERT(destStorage);
+ TextureStorage11_2D *dest11 = GetAs<TextureStorage11_2D>(destStorage);
+ ID3D11Resource *destResource = nullptr;
+ error = dest11->getResource(&destResource);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
+ immediateContext->CopyResource(destResource, sourceResouce);
+
+ dest11->invalidateSwizzleCache();
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+void TextureStorage11_EGLImage::associateImage(Image11 *, const gl::ImageIndex &)
+{
+}
+
+void TextureStorage11_EGLImage::disassociateImage(const gl::ImageIndex &, Image11 *)
+{
+}
+
+bool TextureStorage11_EGLImage::isAssociatedImageValid(const gl::ImageIndex &, Image11 *)
+{
+ return false;
+}
+
+gl::Error TextureStorage11_EGLImage::releaseAssociatedImage(const gl::ImageIndex &, Image11 *)
+{
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureStorage11_EGLImage::useLevelZeroWorkaroundTexture(bool)
+{
+ UNREACHABLE();
+ return gl::Error(GL_INVALID_OPERATION);
+}
+
+gl::Error TextureStorage11_EGLImage::getSwizzleTexture(ID3D11Resource **outTexture)
+{
+ ASSERT(outTexture);
+
+ if (!mSwizzleTexture)
+ {
+ ID3D11Device *device = mRenderer->getDevice();
+
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = mTextureWidth;
+ desc.Height = mTextureHeight;
+ desc.MipLevels = mMipLevels;
+ desc.ArraySize = 1;
+ desc.Format = mSwizzleTextureFormat;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
+
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY,
+ "Failed to create internal swizzle texture, result: 0x%X.", result);
+ }
+
+ d3d11::SetDebugName(mSwizzleTexture, "TexStorageEGLImage.SwizzleTexture");
+ }
+
+ *outTexture = mSwizzleTexture;
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureStorage11_EGLImage::getSwizzleRenderTarget(int mipLevel,
+ ID3D11RenderTargetView **outRTV)
+{
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+ ASSERT(outRTV);
+
+ if (!mSwizzleRenderTargets[mipLevel])
+ {
+ ID3D11Resource *swizzleTexture = NULL;
+ gl::Error error = getSwizzleTexture(&swizzleTexture);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ID3D11Device *device = mRenderer->getDevice();
+
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mSwizzleRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+ rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel;
+
+ HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc,
+ &mSwizzleRenderTargets[mipLevel]);
+
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY,
+ "Failed to create internal swizzle render target view, result: 0x%X.",
+ result);
+ }
+ }
+
+ *outRTV = mSwizzleRenderTargets[mipLevel];
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureStorage11_EGLImage::checkForUpdatedRenderTarget()
+{
+ RenderTarget11 *renderTarget11 = nullptr;
+ gl::Error error = getImageRenderTarget(&renderTarget11);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (mCurrentRenderTarget != reinterpret_cast<uintptr_t>(renderTarget11))
+ {
+ clearSRVCache();
+ mCurrentRenderTarget = reinterpret_cast<uintptr_t>(renderTarget11);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureStorage11_EGLImage::createSRV(int baseLevel,
+ int mipLevels,
+ DXGI_FORMAT format,
+ ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const
+{
+ ASSERT(baseLevel == 0);
+ ASSERT(mipLevels == 1);
+ ASSERT(outSRV);
+
+ // Create a new SRV only for the swizzle texture. Otherwise just return the Image's
+ // RenderTarget's SRV.
+ if (texture == mSwizzleTexture)
+ {
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = format;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+ srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel;
+ srvDesc.Texture2D.MipLevels = mipLevels;
+
+ ID3D11Device *device = mRenderer->getDevice();
+ HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
+
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY,
+ "Failed to create internal texture storage SRV, result: 0x%X.",
+ result);
+ }
+
+ d3d11::SetDebugName(*outSRV, "TexStorageEGLImage.SRV");
+ }
+ else
+ {
+ RenderTarget11 *renderTarget = nullptr;
+ gl::Error error = getImageRenderTarget(&renderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ASSERT(texture == renderTarget->getTexture());
+
+ *outSRV = renderTarget->getShaderResourceView();
+ (*outSRV)->AddRef();
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureStorage11_EGLImage::getImageRenderTarget(RenderTarget11 **outRT) const
+{
+ RenderTargetD3D *renderTargetD3D = nullptr;
+ gl::Error error = mImage->getRenderTarget(&renderTargetD3D);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ *outRT = GetAs<RenderTarget11>(renderTargetD3D);
+ return gl::Error(GL_NO_ERROR);
+}
+
TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer, GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly)
- : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderer->getFeatureLevel(), renderTarget))
+ : TextureStorage11(renderer,
+ GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget),
+ GetTextureMiscFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget, levels))
{
mTexture = NULL;
mSwizzleTexture = NULL;
@@ -1267,7 +1709,7 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer, GLenum intern
mInternalFormat = internalformat;
- const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, renderer->getFeatureLevel());
+ const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, renderer->getRenderer11DeviceCaps());
mTextureFormat = formatInfo.texFormat;
mShaderResourceFormat = formatInfo.srvFormat;
mDepthStencilFormat = formatInfo.dsvFormat;
@@ -1291,8 +1733,6 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer, GLenum intern
ASSERT(mRenderer->getWorkarounds().zeroMaxLodWorkaround);
mUseLevelZeroTexture = true;
}
-
- initializeSerials(getLevelCount() * CUBE_FACE_COUNT, CUBE_FACE_COUNT);
}
TextureStorage11_Cube::~TextureStorage11_Cube()
@@ -1334,12 +1774,6 @@ TextureStorage11_Cube::~TextureStorage11_Cube()
}
}
-TextureStorage11_Cube *TextureStorage11_Cube::makeTextureStorage11_Cube(TextureStorage *storage)
-{
- ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_Cube*, storage));
- return static_cast<TextureStorage11_Cube*>(storage);
-}
-
UINT TextureStorage11_Cube::getSubresourceIndex(const gl::ImageIndex &index) const
{
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround && mUseLevelZeroTexture && index.mipIndex == 0)
@@ -1363,7 +1797,7 @@ gl::Error TextureStorage11_Cube::copyToStorage(TextureStorage *destStorage)
{
ASSERT(destStorage);
- TextureStorage11_Cube *dest11 = TextureStorage11_Cube::makeTextureStorage11_Cube(destStorage);
+ TextureStorage11_Cube *dest11 = GetAs<TextureStorage11_Cube>(destStorage);
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround)
{
@@ -1643,7 +2077,7 @@ gl::Error TextureStorage11_Cube::ensureTextureExists(int mipLevels)
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = getBindFlags();
desc.CPUAccessFlags = 0;
- desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
+ desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE | getMiscFlags();
HRESULT result = device->CreateTexture2D(&desc, NULL, outputTexture);
@@ -1658,6 +2092,8 @@ gl::Error TextureStorage11_Cube::ensureTextureExists(int mipLevels)
ASSERT(result == E_OUTOFMEMORY);
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube texture storage, result: 0x%X.", result);
}
+
+ d3d11::SetDebugName(*outputTexture, "TexStorageCube.Texture");
}
return gl::Error(GL_NO_ERROR);
@@ -1721,7 +2157,7 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, Re
srvDesc.Texture2DArray.FirstArraySlice = faceIndex;
srvDesc.Texture2DArray.ArraySize = 1;
- if (mRenderer->getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3)
+ if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
{
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
}
@@ -1739,6 +2175,8 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, Re
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal shader resource view for texture storage, result: 0x%X.", result);
}
+ d3d11::SetDebugName(srv, "TexStorageCube.RenderTargetSRV");
+
if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
{
D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
@@ -1758,6 +2196,8 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, Re
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
}
+ d3d11::SetDebugName(rtv, "TexStorageCube.RenderTargetRTV");
+
mRenderTarget[faceIndex][level] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0);
// RenderTarget will take ownership of these resources
@@ -1784,6 +2224,8 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, Re
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal depth stencil view for texture storage, result: 0x%X.", result);
}
+ d3d11::SetDebugName(dsv, "TexStorageCube.RenderTargetDSV");
+
mRenderTarget[faceIndex][level] = new TextureRenderTarget11(dsv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0);
// RenderTarget will take ownership of these resources
@@ -1815,7 +2257,7 @@ gl::Error TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FO
{
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
- srvDesc.Texture2DArray.MipLevels = 1;
+ srvDesc.Texture2DArray.MipLevels = mipLevels;
srvDesc.Texture2DArray.FirstArraySlice = 0;
srvDesc.Texture2DArray.ArraySize = CUBE_FACE_COUNT;
}
@@ -1857,6 +2299,8 @@ gl::Error TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FO
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
}
+ d3d11::SetDebugName(*outSRV, "TexStorageCube.SRV");
+
return gl::Error(GL_NO_ERROR);
}
@@ -1888,6 +2332,8 @@ gl::Error TextureStorage11_Cube::getSwizzleTexture(ID3D11Resource **outTexture)
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
}
+
+ d3d11::SetDebugName(*outTexture, "TexStorageCube.SwizzleTexture");
}
*outTexture = mSwizzleTexture;
@@ -1932,7 +2378,9 @@ gl::Error TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel, ID3D11Rend
TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer, GLenum internalformat, bool renderTarget,
GLsizei width, GLsizei height, GLsizei depth, int levels)
- : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderer->getFeatureLevel(), renderTarget))
+ : TextureStorage11(renderer,
+ GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget),
+ GetTextureMiscFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget, levels))
{
mTexture = NULL;
mSwizzleTexture = NULL;
@@ -1946,7 +2394,7 @@ TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer, GLenum internalfo
mInternalFormat = internalformat;
- const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, renderer->getFeatureLevel());
+ const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, renderer->getRenderer11DeviceCaps());
mTextureFormat = formatInfo.texFormat;
mShaderResourceFormat = formatInfo.srvFormat;
mDepthStencilFormat = formatInfo.dsvFormat;
@@ -1962,8 +2410,6 @@ TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer, GLenum internalfo
mTextureWidth = width;
mTextureHeight = height;
mTextureDepth = depth;
-
- initializeSerials(getLevelCount() * depth, depth);
}
TextureStorage11_3D::~TextureStorage11_3D()
@@ -1999,12 +2445,6 @@ TextureStorage11_3D::~TextureStorage11_3D()
}
}
-TextureStorage11_3D *TextureStorage11_3D::makeTextureStorage11_3D(TextureStorage *storage)
-{
- ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_3D*, storage));
- return static_cast<TextureStorage11_3D*>(storage);
-}
-
void TextureStorage11_3D::associateImage(Image11* image, const gl::ImageIndex &index)
{
GLint level = index.mipIndex;
@@ -2101,7 +2541,7 @@ gl::Error TextureStorage11_3D::getResource(ID3D11Resource **outResource)
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = getBindFlags();
desc.CPUAccessFlags = 0;
- desc.MiscFlags = 0;
+ desc.MiscFlags = getMiscFlags();
HRESULT result = device->CreateTexture3D(&desc, NULL, &mTexture);
@@ -2116,6 +2556,8 @@ gl::Error TextureStorage11_3D::getResource(ID3D11Resource **outResource)
ASSERT(result == E_OUTOFMEMORY);
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 3D texture storage, result: 0x%X.", result);
}
+
+ d3d11::SetDebugName(mTexture, "TexStorage3D.Texture");
}
*outResource = mTexture;
@@ -2142,6 +2584,8 @@ gl::Error TextureStorage11_3D::createSRV(int baseLevel, int mipLevels, DXGI_FORM
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
}
+ d3d11::SetDebugName(*outSRV, "TexStorage3D.SRV");
+
return gl::Error(GL_NO_ERROR);
}
@@ -2189,6 +2633,8 @@ gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, Rend
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
}
+ d3d11::SetDebugName(rtv, "TexStorage3D.RTV");
+
mLevelRenderTargets[mipLevel] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel), 0);
// RenderTarget will take ownership of these resources
@@ -2236,6 +2682,8 @@ gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, Rend
}
ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(rtv, "TexStorage3D.LayerRTV");
+
mLevelLayerRenderTargets[key] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0);
// RenderTarget will take ownership of these resources
@@ -2274,6 +2722,8 @@ gl::Error TextureStorage11_3D::getSwizzleTexture(ID3D11Resource **outTexture)
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
}
+
+ d3d11::SetDebugName(mSwizzleTexture, "TexStorage3D.SwizzleTexture");
}
*outTexture = mSwizzleTexture;
@@ -2310,6 +2760,8 @@ gl::Error TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel, ID3D11Render
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result);
}
+
+ d3d11::SetDebugName(mSwizzleTexture, "TexStorage3D.SwizzleRTV");
}
*outRTV = mSwizzleRenderTargets[mipLevel];
@@ -2318,7 +2770,9 @@ gl::Error TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel, ID3D11Render
TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer11 *renderer, GLenum internalformat, bool renderTarget,
GLsizei width, GLsizei height, GLsizei depth, int levels)
- : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderer->getFeatureLevel(), renderTarget))
+ : TextureStorage11(renderer,
+ GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget),
+ GetTextureMiscFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget, levels))
{
mTexture = NULL;
mSwizzleTexture = NULL;
@@ -2330,7 +2784,7 @@ TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer11 *renderer, GLenum
mInternalFormat = internalformat;
- const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, renderer->getFeatureLevel());
+ const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, renderer->getRenderer11DeviceCaps());
mTextureFormat = formatInfo.texFormat;
mShaderResourceFormat = formatInfo.srvFormat;
mDepthStencilFormat = formatInfo.dsvFormat;
@@ -2346,8 +2800,6 @@ TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer11 *renderer, GLenum
mTextureWidth = width;
mTextureHeight = height;
mTextureDepth = depth;
-
- initializeSerials(getLevelCount() * depth, depth);
}
TextureStorage11_2DArray::~TextureStorage11_2DArray()
@@ -2383,12 +2835,6 @@ TextureStorage11_2DArray::~TextureStorage11_2DArray()
mRenderTargets.clear();
}
-TextureStorage11_2DArray *TextureStorage11_2DArray::makeTextureStorage11_2DArray(TextureStorage *storage)
-{
- ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_2DArray*, storage));
- return static_cast<TextureStorage11_2DArray*>(storage);
-}
-
void TextureStorage11_2DArray::associateImage(Image11* image, const gl::ImageIndex &index)
{
GLint level = index.mipIndex;
@@ -2486,7 +2932,7 @@ gl::Error TextureStorage11_2DArray::getResource(ID3D11Resource **outResource)
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = getBindFlags();
desc.CPUAccessFlags = 0;
- desc.MiscFlags = 0;
+ desc.MiscFlags = getMiscFlags();
HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
@@ -2501,6 +2947,8 @@ gl::Error TextureStorage11_2DArray::getResource(ID3D11Resource **outResource)
ASSERT(result == E_OUTOFMEMORY);
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D array texture storage, result: 0x%X.", result);
}
+
+ d3d11::SetDebugName(mTexture, "TexStorage2DArray.Texture");
}
*outResource = mTexture;
@@ -2527,6 +2975,8 @@ gl::Error TextureStorage11_2DArray::createSRV(int baseLevel, int mipLevels, DXGI
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
}
+ d3d11::SetDebugName(*outSRV, "TexStorage2DArray.SRV");
+
return gl::Error(GL_NO_ERROR);
}
@@ -2569,6 +3019,8 @@ gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index,
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal shader resource view for texture storage, result: 0x%X.", result);
}
+ d3d11::SetDebugName(srv, "TexStorage2DArray.RenderTargetSRV");
+
if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
{
D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
@@ -2588,6 +3040,8 @@ gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index,
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
}
+ d3d11::SetDebugName(rtv, "TexStorage2DArray.RenderTargetRTV");
+
mRenderTargets[key] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0);
// RenderTarget will take ownership of these resources
@@ -2631,6 +3085,8 @@ gl::Error TextureStorage11_2DArray::getSwizzleTexture(ID3D11Resource **outTextur
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
}
+
+ d3d11::SetDebugName(*outTexture, "TexStorage2DArray.SwizzleTexture");
}
*outTexture = mSwizzleTexture;
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h
index 456e2660f9..a88db2f0af 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h
@@ -23,25 +23,28 @@ struct ImageIndex;
namespace rx
{
+class EGLImageD3D;
class RenderTargetD3D;
class RenderTarget11;
class Renderer11;
class SwapChain11;
class Image11;
+struct Renderer11DeviceCaps;
class TextureStorage11 : public TextureStorage
{
public:
virtual ~TextureStorage11();
- static TextureStorage11 *makeTextureStorage11(TextureStorage *storage);
-
- static DWORD GetTextureBindFlags(GLenum internalFormat, D3D_FEATURE_LEVEL featureLevel, bool renderTarget);
+ static DWORD GetTextureBindFlags(GLenum internalFormat, const Renderer11DeviceCaps &renderer11DeviceCaps, bool renderTarget);
+ static DWORD GetTextureMiscFlags(GLenum internalFormat, const Renderer11DeviceCaps &renderer11DeviceCaps, bool renderTarget, int levels);
UINT getBindFlags() const;
+ UINT getMiscFlags() const;
virtual gl::Error getResource(ID3D11Resource **outResource) = 0;
- virtual gl::Error getSRV(const gl::SamplerState &samplerState, ID3D11ShaderResourceView **outSRV);
+ virtual gl::Error getSRV(const gl::TextureState &textureState,
+ ID3D11ShaderResourceView **outSRV);
virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) = 0;
virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex);
@@ -49,6 +52,7 @@ class TextureStorage11 : public TextureStorage
virtual int getTopLevel() const;
virtual bool isRenderTarget() const;
virtual bool isManaged() const;
+ bool supportsNativeMipmapFunction() const override;
virtual int getLevelCount() const;
virtual UINT getSubresourceIndex(const gl::ImageIndex &index) const;
@@ -71,8 +75,10 @@ class TextureStorage11 : public TextureStorage
virtual gl::Error setData(const gl::ImageIndex &index, ImageD3D *image, const gl::Box *destBox, GLenum type,
const gl::PixelUnpackState &unpack, const uint8_t *pixelData);
+ gl::Error getSRVLevels(GLint baseLevel, GLint maxLevel, ID3D11ShaderResourceView **outSRV);
+
protected:
- TextureStorage11(Renderer11 *renderer, UINT bindFlags);
+ TextureStorage11(Renderer11 *renderer, UINT bindFlags, UINT miscFlags);
int getLevelWidth(int mipLevel) const;
int getLevelHeight(int mipLevel) const;
int getLevelDepth(int mipLevel) const;
@@ -89,6 +95,9 @@ class TextureStorage11 : public TextureStorage
void verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha);
+ // Clear all cached non-swizzle SRVs and invalidate the swizzle cache.
+ void clearSRVCache();
+
Renderer11 *mRenderer;
int mTopLevel;
unsigned int mMipLevels;
@@ -122,6 +131,7 @@ class TextureStorage11 : public TextureStorage
private:
const UINT mBindFlags;
+ const UINT mMiscFlags;
struct SRVKey
{
@@ -146,8 +156,6 @@ class TextureStorage11_2D : public TextureStorage11
TextureStorage11_2D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly = false);
virtual ~TextureStorage11_2D();
- static TextureStorage11_2D *makeTextureStorage11_2D(TextureStorage *storage);
-
virtual gl::Error getResource(ID3D11Resource **outResource);
virtual gl::Error getMippedResource(ID3D11Resource **outResource);
virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT);
@@ -194,14 +202,58 @@ class TextureStorage11_2D : public TextureStorage11
Image11 *mAssociatedImages[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
};
+class TextureStorage11_EGLImage final : public TextureStorage11
+{
+ public:
+ TextureStorage11_EGLImage(Renderer11 *renderer, EGLImageD3D *eglImage);
+ ~TextureStorage11_EGLImage() override;
+
+ gl::Error getResource(ID3D11Resource **outResource) override;
+ gl::Error getSRV(const gl::TextureState &textureState,
+ ID3D11ShaderResourceView **outSRV) override;
+ gl::Error getMippedResource(ID3D11Resource **outResource) override;
+ gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) override;
+
+ gl::Error copyToStorage(TextureStorage *destStorage) override;
+
+ void associateImage(Image11 *image, const gl::ImageIndex &index) override;
+ void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
+ bool isAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
+ gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11 *incomingImage) override;
+
+ gl::Error useLevelZeroWorkaroundTexture(bool useLevelZeroTexture) override;
+
+ protected:
+ gl::Error getSwizzleTexture(ID3D11Resource **outTexture) override;
+ gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) override;
+
+ private:
+ // Check if the EGL image's render target has been updated due to orphaning and delete
+ // any SRVs and other resources based on the image's old render target.
+ gl::Error checkForUpdatedRenderTarget();
+
+ gl::Error createSRV(int baseLevel,
+ int mipLevels,
+ DXGI_FORMAT format,
+ ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const override;
+
+ gl::Error getImageRenderTarget(RenderTarget11 **outRT) const;
+
+ EGLImageD3D *mImage;
+ uintptr_t mCurrentRenderTarget;
+
+ // Swizzle-related variables
+ ID3D11Texture2D *mSwizzleTexture;
+ std::vector<ID3D11RenderTargetView *> mSwizzleRenderTargets;
+};
+
class TextureStorage11_Cube : public TextureStorage11
{
public:
TextureStorage11_Cube(Renderer11 *renderer, GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly);
virtual ~TextureStorage11_Cube();
- static TextureStorage11_Cube *makeTextureStorage11_Cube(TextureStorage *storage);
-
virtual UINT getSubresourceIndex(const gl::ImageIndex &index) const;
virtual gl::Error getResource(ID3D11Resource **outResource);
@@ -250,8 +302,6 @@ class TextureStorage11_3D : public TextureStorage11
GLsizei width, GLsizei height, GLsizei depth, int levels);
virtual ~TextureStorage11_3D();
- static TextureStorage11_3D *makeTextureStorage11_3D(TextureStorage *storage);
-
virtual gl::Error getResource(ID3D11Resource **outResource);
// Handles both layer and non-layer RTs
@@ -290,8 +340,6 @@ class TextureStorage11_2DArray : public TextureStorage11
GLsizei width, GLsizei height, GLsizei depth, int levels);
virtual ~TextureStorage11_2DArray();
- static TextureStorage11_2DArray *makeTextureStorage11_2DArray(TextureStorage *storage);
-
virtual gl::Error getResource(ID3D11Resource **outResource);
virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT);
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.h
index f232ad7e8e..4741e81601 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.h
@@ -31,7 +31,9 @@ class Trim11 : angle::NonCopyable
private:
Renderer11 *mRenderer;
+#if defined (ANGLE_ENABLE_WINDOWS_STORE)
EventRegistrationToken mApplicationSuspendedEventToken;
+#endif
void trim();
bool registerForRendererTrimRequest();
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h
index 78aad7d106..b397140e71 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h
@@ -19,20 +19,11 @@ class Renderer11;
class VertexArray11 : public VertexArrayImpl
{
public:
- VertexArray11(Renderer11 *renderer)
- : VertexArrayImpl(),
- mRenderer(renderer)
+ VertexArray11(const gl::VertexArray::Data &data)
+ : VertexArrayImpl(data)
{
}
- virtual ~VertexArray11() { }
-
- virtual void setElementArrayBuffer(const gl::Buffer *buffer) { }
- virtual void setAttribute(size_t idx, const gl::VertexAttribute &attr) { }
- virtual void setAttributeDivisor(size_t idx, GLuint divisor) { }
- virtual void enableAttribute(size_t idx, bool enabledState) { }
-
- private:
- Renderer11 *mRenderer;
+ virtual ~VertexArray11() {}
};
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp
index adc64cef5e..098cefcd53 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp
@@ -7,11 +7,14 @@
// VertexBuffer11.cpp: Defines the D3D11 VertexBuffer implementation.
#include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h"
-#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
-#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
-#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+
#include "libANGLE/Buffer.h"
#include "libANGLE/VertexAttribute.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
namespace rx
{
@@ -53,6 +56,15 @@ gl::Error VertexBuffer11::initialize(unsigned int size, bool dynamicUsage)
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal vertex buffer of size, %lu.", size);
}
+
+ if (dynamicUsage)
+ {
+ d3d11::SetDebugName(mBuffer, "VertexBuffer11 (dynamic)");
+ }
+ else
+ {
+ d3d11::SetDebugName(mBuffer, "VertexBuffer11 (static)");
+ }
}
mBufferSize = size;
@@ -61,12 +73,6 @@ gl::Error VertexBuffer11::initialize(unsigned int size, bool dynamicUsage)
return gl::Error(GL_NO_ERROR);
}
-VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer)
-{
- ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer11*, vetexBuffer));
- return static_cast<VertexBuffer11*>(vetexBuffer);
-}
-
gl::Error VertexBuffer11::mapResource()
{
if (mMappedResourceData == NULL)
@@ -98,16 +104,20 @@ void VertexBuffer11::hintUnmapResource()
}
}
-gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
- GLint start, GLsizei count, GLsizei instances, unsigned int offset)
+gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib,
+ GLenum currentValueType,
+ GLint start,
+ GLsizei count,
+ GLsizei instances,
+ unsigned int offset,
+ const uint8_t *sourceData)
{
if (!mBuffer)
{
return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized.");
}
- gl::Buffer *buffer = attrib.buffer.get();
- int inputStride = ComputeVertexAttributeStride(attrib);
+ int inputStride = static_cast<int>(ComputeVertexAttributeStride(attrib));
// This will map the resource if it isn't already mapped.
gl::Error error = mapResource();
@@ -118,36 +128,16 @@ gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attri
uint8_t *output = mMappedResourceData + offset;
- const uint8_t *input = NULL;
- if (attrib.enabled)
- {
- if (buffer)
- {
- BufferD3D *storage = GetImplAs<BufferD3D>(buffer);
- error = storage->getData(&input);
- if (error.isError())
- {
- return error;
- }
- input += static_cast<int>(attrib.offset);
- }
- else
- {
- input = static_cast<const uint8_t*>(attrib.pointer);
- }
- }
- else
- {
- input = reinterpret_cast<const uint8_t*>(currentValue.FloatValues);
- }
+ const uint8_t *input = sourceData;
if (instances == 0 || attrib.divisor == 0)
{
input += inputStride * start;
}
- gl::VertexFormat vertexFormat(attrib, currentValue.Type);
- const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat, mRenderer->getFeatureLevel());
+ gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib, currentValueType);
+ const D3D_FEATURE_LEVEL featureLevel = mRenderer->getRenderer11DeviceCaps().featureLevel;
+ const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormatType, featureLevel);
ASSERT(vertexFormatInfo.copyFunction != NULL);
vertexFormatInfo.copyFunction(input, inputStride, count, output);
@@ -170,8 +160,9 @@ gl::Error VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GL
elementCount = UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor);
}
- gl::VertexFormat vertexFormat(attrib);
- const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat, mRenderer->getFeatureLevel());
+ gl::VertexFormatType formatType = gl::GetVertexFormatType(attrib);
+ const D3D_FEATURE_LEVEL featureLevel = mRenderer->getRenderer11DeviceCaps().featureLevel;
+ const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(formatType, featureLevel);
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(vertexFormatInfo.nativeFormat);
unsigned int elementSize = dxgiFormatInfo.pixelBytes;
if (elementSize <= std::numeric_limits<unsigned int>::max() / elementCount)
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h
index 2450e8955c..773c4474e1 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h
@@ -25,10 +25,13 @@ class VertexBuffer11 : public VertexBuffer
virtual gl::Error initialize(unsigned int size, bool dynamicUsage);
- static VertexBuffer11 *makeVertexBuffer11(VertexBuffer *vetexBuffer);
-
- virtual gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
- GLint start, GLsizei count, GLsizei instances, unsigned int offset);
+ gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib,
+ GLenum currentValueType,
+ GLint start,
+ GLsizei count,
+ GLsizei instances,
+ unsigned int offset,
+ const uint8_t *sourceData) override;
virtual gl::Error getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances,
unsigned int *outSpaceRequired) const;
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/copyvertex.inl b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/copyvertex.inl
index 60678d7b9f..1ec21dee55 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/copyvertex.inl
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/copyvertex.inl
@@ -245,17 +245,17 @@ static inline void CopyPackedRGB(uint32_t data, uint8_t *output)
if (data & rgbSignMask)
{
- *intOutput = data | negativeMask;
+ *intOutput = static_cast<GLshort>(data | negativeMask);
}
else
{
- *intOutput = data;
+ *intOutput = static_cast<GLshort>(data);
}
}
else
{
GLushort *uintOutput = reinterpret_cast<GLushort*>(output);
- *uintOutput = data;
+ *uintOutput = static_cast<GLushort>(data);
}
}
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_data.json b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_data.json
new file mode 100644
index 0000000000..e81b4deea5
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_data.json
@@ -0,0 +1,1164 @@
+[
+ {
+ "DXGI_FORMAT_UNKNOWN":
+ {
+ "texture2D": "never",
+ "texture3D": "never",
+ "textureCube": "never",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R32G32B32A32_TYPELESS":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R32G32B32A32_FLOAT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0check10_1always",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R32G32B32A32_UINT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R32G32B32A32_SINT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R32G32B32_TYPELESS":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R32G32B32_FLOAT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "11_0check",
+ "renderTarget": "check",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R32G32B32_UINT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "check",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R32G32B32_SINT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "check",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R16G16B16A16_TYPELESS":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R16G16B16A16_FLOAT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R16G16B16A16_UNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R16G16B16A16_UINT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R16G16B16A16_SNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R16G16B16A16_SINT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R32G32_TYPELESS":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R32G32_FLOAT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0check10_1always",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R32G32_UINT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R32G32_SINT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R32G8X24_TYPELESS":
+ {
+ "texture2D": "always",
+ "texture3D": "never",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_D32_FLOAT_S8X24_UINT":
+ {
+ "texture2D": "always",
+ "texture3D": "never",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "check",
+ "depthStencil": "always"
+ },
+ "DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS":
+ {
+ "texture2D": "always",
+ "texture3D": "never",
+ "textureCube": "always",
+ "shaderSample": "10_0check10_1always",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_X32_TYPELESS_G8X24_UINT":
+ {
+ "texture2D": "always",
+ "texture3D": "never",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R10G10B10A2_TYPELESS":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R10G10B10A2_UNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R10G10B10A2_UINT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R11G11B10_FLOAT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R8G8B8A8_TYPELESS":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R8G8B8A8_UNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R8G8B8A8_UINT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R8G8B8A8_SNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R8G8B8A8_SINT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R16G16_TYPELESS":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R16G16_FLOAT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R16G16_UNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R16G16_UINT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R16G16_SNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R16G16_SINT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R32_TYPELESS":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_D32_FLOAT":
+ {
+ "texture2D": "always",
+ "texture3D": "never",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "check",
+ "depthStencil": "always"
+ },
+ "DXGI_FORMAT_R32_FLOAT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0check10_1always",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R32_UINT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R32_SINT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R24G8_TYPELESS":
+ {
+ "texture2D": "always",
+ "texture3D": "never",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_D24_UNORM_S8_UINT":
+ {
+ "texture2D": "always",
+ "texture3D": "never",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "check",
+ "depthStencil": "always"
+ },
+ "DXGI_FORMAT_R24_UNORM_X8_TYPELESS":
+ {
+ "texture2D": "always",
+ "texture3D": "never",
+ "textureCube": "always",
+ "shaderSample": "10_0check10_1always",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_X24_TYPELESS_G8_UINT":
+ {
+ "texture2D": "always",
+ "texture3D": "never",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R8G8_TYPELESS":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R8G8_UNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R8G8_UINT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R8G8_SNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R8G8_SINT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R16_TYPELESS":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R16_FLOAT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_D16_UNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "never",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "check",
+ "depthStencil": "always"
+ },
+ "DXGI_FORMAT_R16_UNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R16_UINT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R16_SNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R16_SINT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R8_TYPELESS":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R8_UNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R8_UINT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R8_SNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R8_SINT":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_A8_UNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R1_UNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "11_0",
+ "textureCube": "11_0",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R9G9B9E5_SHAREDEXP":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R8G8_B8G8_UNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_G8R8_G8B8_UNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_BC1_TYPELESS":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_BC1_UNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_BC1_UNORM_SRGB":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_BC2_TYPELESS":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_BC2_UNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_BC2_UNORM_SRGB":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_BC3_TYPELESS":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_BC3_UNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_BC3_UNORM_SRGB":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_BC4_TYPELESS":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_BC4_UNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_BC4_SNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_BC5_TYPELESS":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_BC5_UNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_BC5_SNORM":
+ {
+ "texture2D": "always",
+ "texture3D": "always",
+ "textureCube": "always",
+ "shaderSample": "10_0",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_B5G6R5_UNORM":
+ {
+ "texture2D": "dxgi1_2",
+ "texture3D": "dxgi1_2",
+ "textureCube": "dxgi1_2",
+ "shaderSample": "dxgi1_2",
+ "renderTarget": "dxgi1_2",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_B5G5R5A1_UNORM":
+ {
+ "texture2D": "dxgi1_2",
+ "texture3D": "dxgi1_2",
+ "textureCube": "dxgi1_2",
+ "shaderSample": "dxgi1_2",
+ "renderTarget": "check",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_B8G8R8A8_UNORM":
+ {
+ "texture2D": "check",
+ "texture3D": "check",
+ "textureCube": "check",
+ "shaderSample": "10_0check11_0always",
+ "renderTarget": "10_0check11_0always",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_B8G8R8X8_UNORM":
+ {
+ "texture2D": "check",
+ "texture3D": "check",
+ "textureCube": "check",
+ "shaderSample": "10_0check11_0always",
+ "renderTarget": "11_0",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM":
+ {
+ "texture2D": "check",
+ "texture3D": "check",
+ "textureCube": "never",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_B8G8R8A8_TYPELESS":
+ {
+ "texture2D": "check",
+ "texture3D": "check",
+ "textureCube": "check",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_B8G8R8A8_UNORM_SRGB":
+ {
+ "texture2D": "check",
+ "texture3D": "check",
+ "textureCube": "check",
+ "shaderSample": "10_0check11_0always",
+ "renderTarget": "11_0",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_B8G8R8X8_TYPELESS":
+ {
+ "texture2D": "check",
+ "texture3D": "check",
+ "textureCube": "check",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_B8G8R8X8_UNORM_SRGB":
+ {
+ "texture2D": "check",
+ "texture3D": "check",
+ "textureCube": "check",
+ "shaderSample": "10_0check11_0always",
+ "renderTarget": "11_0",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_BC6H_TYPELESS":
+ {
+ "texture2D": "11_0",
+ "texture3D": "11_0",
+ "textureCube": "11_0",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_BC6H_UF16":
+ {
+ "texture2D": "11_0",
+ "texture3D": "11_0",
+ "textureCube": "11_0",
+ "shaderSample": "11_0",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_BC6H_SF16":
+ {
+ "texture2D": "11_0",
+ "texture3D": "11_0",
+ "textureCube": "11_0",
+ "shaderSample": "11_0",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_BC7_TYPELESS":
+ {
+ "texture2D": "11_0",
+ "texture3D": "11_0",
+ "textureCube": "11_0",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_BC7_UNORM":
+ {
+ "texture2D": "11_0",
+ "texture3D": "11_0",
+ "textureCube": "11_0",
+ "shaderSample": "11_0",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_BC7_UNORM_SRGB":
+ {
+ "texture2D": "11_0",
+ "texture3D": "11_0",
+ "textureCube": "11_0",
+ "shaderSample": "11_0",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_AYUV":
+ {
+ "texture2D": "11_1",
+ "texture3D": "never",
+ "textureCube": "never",
+ "shaderSample": "11_1",
+ "renderTarget": "11_1",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_Y410":
+ {
+ "texture2D": "11_1",
+ "texture3D": "never",
+ "textureCube": "never",
+ "shaderSample": "11_1",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_Y416":
+ {
+ "texture2D": "11_1",
+ "texture3D": "never",
+ "textureCube": "never",
+ "shaderSample": "11_1",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_NV12":
+ {
+ "texture2D": "11_1",
+ "texture3D": "never",
+ "textureCube": "never",
+ "shaderSample": "11_1",
+ "renderTarget": "11_1",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_P010":
+ {
+ "texture2D": "11_1",
+ "texture3D": "never",
+ "textureCube": "never",
+ "shaderSample": "11_1",
+ "renderTarget": "11_1",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_P016":
+ {
+ "texture2D": "11_1",
+ "texture3D": "never",
+ "textureCube": "never",
+ "shaderSample": "11_1",
+ "renderTarget": "11_1",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_420_OPAQUE":
+ {
+ "texture2D": "11_1",
+ "texture3D": "never",
+ "textureCube": "never",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_YUY2":
+ {
+ "texture2D": "11_1",
+ "texture3D": "never",
+ "textureCube": "never",
+ "shaderSample": "11_1",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_Y210":
+ {
+ "texture2D": "11_1",
+ "texture3D": "never",
+ "textureCube": "never",
+ "shaderSample": "11_1",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_Y216":
+ {
+ "texture2D": "11_1",
+ "texture3D": "never",
+ "textureCube": "never",
+ "shaderSample": "11_1",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_NV11":
+ {
+ "texture2D": "11_1",
+ "texture3D": "never",
+ "textureCube": "never",
+ "shaderSample": "11_1",
+ "renderTarget": "11_1",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_AI44":
+ {
+ "texture2D": "11_1",
+ "texture3D": "never",
+ "textureCube": "never",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_IA44":
+ {
+ "texture2D": "11_1",
+ "texture3D": "never",
+ "textureCube": "never",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_P8":
+ {
+ "texture2D": "11_1",
+ "texture3D": "never",
+ "textureCube": "never",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_A8P8":
+ {
+ "texture2D": "11_1",
+ "texture3D": "never",
+ "textureCube": "never",
+ "shaderSample": "never",
+ "renderTarget": "never",
+ "multisampleRT": "never",
+ "depthStencil": "never"
+ },
+ "DXGI_FORMAT_B4G4R4A4_UNORM":
+ {
+ "texture2D": "dxgi1_2",
+ "texture3D": "dxgi1_2",
+ "textureCube": "dxgi1_2",
+ "shaderSample": "dxgi1_2",
+ "renderTarget": "check",
+ "multisampleRT": "check",
+ "depthStencil": "never"
+ }
+ }
+]
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.cpp
new file mode 100644
index 0000000000..cbc36445e6
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.cpp
@@ -0,0 +1,1846 @@
+// GENERATED FILE - DO NOT EDIT. See dxgi_support_data.json.
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// dxgi_support_table:
+// Queries for DXGI support of various texture formats. Depends on DXGI
+// version, D3D feature level, and is sometimes guaranteed or optional.
+//
+
+#include "libANGLE/renderer/d3d/d3d11/dxgi_support_table.h"
+
+#include "common/debug.h"
+
+namespace rx
+{
+
+namespace d3d11
+{
+
+#define F_2D D3D11_FORMAT_SUPPORT_TEXTURE2D
+#define F_3D D3D11_FORMAT_SUPPORT_TEXTURE3D
+#define F_CUBE D3D11_FORMAT_SUPPORT_TEXTURECUBE
+#define F_SAMPLE D3D11_FORMAT_SUPPORT_SHADER_SAMPLE
+#define F_RT D3D11_FORMAT_SUPPORT_RENDER_TARGET
+#define F_MS D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET
+#define F_DS D3D11_FORMAT_SUPPORT_DEPTH_STENCIL
+
+namespace
+{
+
+const DXGISupport &GetDefaultSupport()
+{
+ static UINT AllSupportFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D |
+ D3D11_FORMAT_SUPPORT_TEXTURE3D |
+ D3D11_FORMAT_SUPPORT_TEXTURECUBE |
+ D3D11_FORMAT_SUPPORT_SHADER_SAMPLE |
+ D3D11_FORMAT_SUPPORT_RENDER_TARGET |
+ D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET |
+ D3D11_FORMAT_SUPPORT_DEPTH_STENCIL;
+ static const DXGISupport defaultSupport(0, 0, AllSupportFlags);
+ return defaultSupport;
+}
+
+const DXGISupport &GetDXGISupport_10_0(DXGI_FORMAT dxgiFormat)
+{
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_420_OPAQUE:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_A8P8:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_A8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_AI44:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_AYUV:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B4G4R4A4_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_B5G5R5A1_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_B5G6R5_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ {
+ static const DXGISupport info(0, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_RT | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+ {
+ static const DXGISupport info(0, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_UNORM:
+ {
+ static const DXGISupport info(0, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
+ {
+ static const DXGISupport info(0, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_SF16:
+ {
+ static const DXGISupport info(0, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_UF16:
+ {
+ static const DXGISupport info(0, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_UNORM:
+ {
+ static const DXGISupport info(0, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_UNORM_SRGB:
+ {
+ static const DXGISupport info(0, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_D16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_G8R8_G8B8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_IA44:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_NV11:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_NV12:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P010:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P016:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P8:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
+ {
+ static const DXGISupport info(0, F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, F_2D | F_3D);
+ return info;
+ }
+ case DXGI_FORMAT_R11G11B10_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R1_UNORM:
+ {
+ static const DXGISupport info(F_2D, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R24G8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT, F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS, F_MS | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_SAMPLE, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_SAMPLE, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS, F_MS | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G8X24_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS, F_MS | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT, F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_R32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_B8G8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y210:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y216:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y410:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y416:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_YUY2:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+
+ default:
+ UNREACHABLE();
+ return GetDefaultSupport();
+ }
+}
+
+const DXGISupport &GetDXGISupport_10_1(DXGI_FORMAT dxgiFormat)
+{
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_420_OPAQUE:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_A8P8:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_A8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_AI44:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_AYUV:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B4G4R4A4_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_B5G5R5A1_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_B5G6R5_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ {
+ static const DXGISupport info(0, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_RT | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+ {
+ static const DXGISupport info(0, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_UNORM:
+ {
+ static const DXGISupport info(0, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
+ {
+ static const DXGISupport info(0, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_SF16:
+ {
+ static const DXGISupport info(0, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_UF16:
+ {
+ static const DXGISupport info(0, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_UNORM:
+ {
+ static const DXGISupport info(0, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_UNORM_SRGB:
+ {
+ static const DXGISupport info(0, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_D16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_G8R8_G8B8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_IA44:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_NV11:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_NV12:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P010:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P016:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P8:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
+ {
+ static const DXGISupport info(0, F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, F_2D | F_3D);
+ return info;
+ }
+ case DXGI_FORMAT_R11G11B10_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R1_UNORM:
+ {
+ static const DXGISupport info(F_2D, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R24G8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_SAMPLE, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_SAMPLE, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G8X24_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_B8G8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y210:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y216:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y410:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y416:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_YUY2:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+
+ default:
+ UNREACHABLE();
+ return GetDefaultSupport();
+ }
+}
+
+const DXGISupport &GetDXGISupport_11_0(DXGI_FORMAT dxgiFormat)
+{
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_420_OPAQUE:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_A8P8:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_A8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_AI44:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_AYUV:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B4G4R4A4_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_B5G5R5A1_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_B5G6R5_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ {
+ static const DXGISupport info(F_RT | F_SAMPLE, F_DS, F_2D | F_3D | F_CUBE | F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_RT | F_SAMPLE, F_DS, F_2D | F_3D | F_CUBE | F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_UNORM:
+ {
+ static const DXGISupport info(F_RT | F_SAMPLE, F_DS, F_2D | F_3D | F_CUBE | F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_RT | F_SAMPLE, F_DS, F_2D | F_3D | F_CUBE | F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_SF16:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_UF16:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_D16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_G8R8_G8B8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_IA44:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_NV11:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_NV12:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P010:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P016:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P8:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
+ {
+ static const DXGISupport info(0, F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, F_2D | F_3D);
+ return info;
+ }
+ case DXGI_FORMAT_R11G11B10_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R1_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R24G8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_SAMPLE, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_SAMPLE, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G8X24_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_B8G8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y210:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y216:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y410:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y416:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_YUY2:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+
+ default:
+ UNREACHABLE();
+ return GetDefaultSupport();
+ }
+}
+
+}
+
+#undef F_2D
+#undef F_3D
+#undef F_CUBE
+#undef F_SAMPLE
+#undef F_RT
+#undef F_MS
+#undef F_DS
+
+const DXGISupport &GetDXGISupport(DXGI_FORMAT dxgiFormat, D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_10_0:
+ return GetDXGISupport_10_0(dxgiFormat);
+ case D3D_FEATURE_LEVEL_10_1:
+ return GetDXGISupport_10_1(dxgiFormat);
+ case D3D_FEATURE_LEVEL_11_0:
+ return GetDXGISupport_11_0(dxgiFormat);
+ default:
+ return GetDefaultSupport();
+ }
+}
+
+} // namespace d3d11
+
+} // namespace rx
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.h
new file mode 100644
index 0000000000..1d8d68565e
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.h
@@ -0,0 +1,44 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// dxgi_support_table:
+// Queries for DXGI support of various texture formats. Depends on DXGI
+// version, D3D feature level, and is sometimes guaranteed or optional.
+//
+
+#include "common/platform.h"
+
+namespace rx
+{
+
+namespace d3d11
+{
+
+struct DXGISupport
+{
+ DXGISupport()
+ : alwaysSupportedFlags(0),
+ neverSupportedFlags(0),
+ optionallySupportedFlags(0)
+ {
+ }
+
+ DXGISupport(UINT alwaysSupportedIn, UINT neverSupportedIn, UINT optionallySupportedIn)
+ : alwaysSupportedFlags(alwaysSupportedIn),
+ neverSupportedFlags(neverSupportedIn),
+ optionallySupportedFlags(optionallySupportedIn)
+ {
+ }
+
+ UINT alwaysSupportedFlags;
+ UINT neverSupportedFlags;
+ UINT optionallySupportedFlags;
+};
+
+const DXGISupport &GetDXGISupport(DXGI_FORMAT dxgiFormat, D3D_FEATURE_LEVEL featureLevel);
+
+} // namespace d3d11
+
+} // namespace rx
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp
index 2f81d6d608..f073e9f46f 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp
@@ -10,11 +10,13 @@
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
#include "libANGLE/formatutils.h"
-#include "libANGLE/renderer/Renderer.h"
#include "libANGLE/renderer/d3d/copyimage.h"
+#include "libANGLE/renderer/d3d/d3d11/copyvertex.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/generatemip.h"
#include "libANGLE/renderer/d3d/loadimage.h"
-#include "libANGLE/renderer/d3d/d3d11/copyvertex.h"
+#include "libANGLE/renderer/Renderer.h"
namespace rx
{
@@ -99,6 +101,10 @@ static DXGIToESFormatMap BuildDXGIToESFormatMap()
AddDXGIToESEntry(&map, DXGI_FORMAT_BC2_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE);
AddDXGIToESEntry(&map, DXGI_FORMAT_BC3_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE);
+ AddDXGIToESEntry(&map, DXGI_FORMAT_B5G6R5_UNORM, GL_RGB565);
+ AddDXGIToESEntry(&map, DXGI_FORMAT_B5G5R5A1_UNORM, GL_RGB5_A1);
+ AddDXGIToESEntry(&map, DXGI_FORMAT_B4G4R4A4_UNORM, GL_RGBA4);
+
return map;
}
@@ -210,6 +216,10 @@ static ColorFormatInfoMap BuildColorFormatInfoMap()
InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, 9, 9, 9, 0, 5);
InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R11G11B10_FLOAT, 11, 11, 10, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_B5G6R5_UNORM, 5, 6, 5, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_B4G4R4A4_UNORM, 4, 4, 4, 4, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_B5G5R5A1_UNORM, 5, 5, 5, 1, 0);
+
return map;
}
@@ -278,8 +288,20 @@ DXGIFormat::DXGIFormat()
componentType(GL_NONE),
mipGenerationFunction(NULL),
colorReadFunction(NULL),
- fastCopyFunctions()
+ fastCopyFunctions(),
+ nativeMipmapSupport(NULL)
+{
+}
+
+static bool NeverSupported(D3D_FEATURE_LEVEL)
+{
+ return false;
+}
+
+template <D3D_FEATURE_LEVEL requiredFeatureLevel>
+static bool RequiresFeatureLevel(D3D_FEATURE_LEVEL featureLevel)
{
+ return featureLevel >= requiredFeatureLevel;
}
ColorCopyFunction DXGIFormat::getFastCopyFunction(GLenum format, GLenum type) const
@@ -289,7 +311,7 @@ ColorCopyFunction DXGIFormat::getFastCopyFunction(GLenum format, GLenum type) co
}
void AddDXGIFormat(DXGIFormatInfoMap *map, DXGI_FORMAT dxgiFormat, GLuint pixelBits, GLuint blockWidth, GLuint blockHeight,
- GLenum componentType, MipGenerationFunction mipFunc, ColorReadFunction readFunc)
+ GLenum componentType, MipGenerationFunction mipFunc, ColorReadFunction readFunc, NativeMipmapGenerationSupportFunction nativeMipmapSupport)
{
DXGIFormat info;
info.pixelBytes = pixelBits / 8;
@@ -301,11 +323,11 @@ void AddDXGIFormat(DXGIFormatInfoMap *map, DXGI_FORMAT dxgiFormat, GLuint pixelB
if (colorInfoIter != colorInfoMap.end())
{
const DXGIColorFormatInfo &colorInfo = colorInfoIter->second;
- info.redBits = colorInfo.redBits;
- info.greenBits = colorInfo.greenBits;
- info.blueBits = colorInfo.blueBits;
- info.alphaBits = colorInfo.alphaBits;
- info.sharedBits = colorInfo.sharedBits;
+ info.redBits = static_cast<GLuint>(colorInfo.redBits);
+ info.greenBits = static_cast<GLuint>(colorInfo.greenBits);
+ info.blueBits = static_cast<GLuint>(colorInfo.blueBits);
+ info.alphaBits = static_cast<GLuint>(colorInfo.alphaBits);
+ info.sharedBits = static_cast<GLuint>(colorInfo.sharedBits);
}
static const DepthStencilInfoMap dsInfoMap = BuildDepthStencilInfoMap();
@@ -335,6 +357,8 @@ void AddDXGIFormat(DXGIFormatInfoMap *map, DXGI_FORMAT dxgiFormat, GLuint pixelB
info.fastCopyFunctions.insert(std::make_pair(std::make_pair(i->second.destFormat, i->second.destType), i->second.copyFunction));
}
+ info.nativeMipmapSupport = nativeMipmapSupport;
+
map->insert(std::make_pair(dxgiFormat, info));
}
@@ -343,80 +367,86 @@ static DXGIFormatInfoMap BuildDXGIFormatInfoMap()
{
DXGIFormatInfoMap map;
- // | DXGI format |S |W |H |Component Type | Mip generation function | Color read function
- AddDXGIFormat(&map, DXGI_FORMAT_UNKNOWN, 0, 0, 0, GL_NONE, NULL, NULL);
-
- AddDXGIFormat(&map, DXGI_FORMAT_A8_UNORM, 8, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<A8>, ReadColor<A8, GLfloat>);
- AddDXGIFormat(&map, DXGI_FORMAT_R8_UNORM, 8, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R8>, ReadColor<R8, GLfloat>);
- AddDXGIFormat(&map, DXGI_FORMAT_R8G8_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R8G8>, ReadColor<R8G8, GLfloat>);
- AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UNORM, 32, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R8G8B8A8>, ReadColor<R8G8B8A8, GLfloat>);
- AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 32, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R8G8B8A8>, ReadColor<R8G8B8A8, GLfloat>);
- AddDXGIFormat(&map, DXGI_FORMAT_B8G8R8A8_UNORM, 32, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<B8G8R8A8>, ReadColor<B8G8R8A8, GLfloat>);
-
- AddDXGIFormat(&map, DXGI_FORMAT_R8_SNORM, 8, 1, 1, GL_SIGNED_NORMALIZED, GenerateMip<R8S>, ReadColor<R8S, GLfloat>);
- AddDXGIFormat(&map, DXGI_FORMAT_R8G8_SNORM, 16, 1, 1, GL_SIGNED_NORMALIZED, GenerateMip<R8G8S>, ReadColor<R8G8S, GLfloat>);
- AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_SNORM, 32, 1, 1, GL_SIGNED_NORMALIZED, GenerateMip<R8G8B8A8S>, ReadColor<R8G8B8A8S, GLfloat>);
-
- AddDXGIFormat(&map, DXGI_FORMAT_R8_UINT, 8, 1, 1, GL_UNSIGNED_INT, GenerateMip<R8>, ReadColor<R8, GLuint>);
- AddDXGIFormat(&map, DXGI_FORMAT_R16_UINT, 16, 1, 1, GL_UNSIGNED_INT, GenerateMip<R16>, ReadColor<R16, GLuint>);
- AddDXGIFormat(&map, DXGI_FORMAT_R32_UINT, 32, 1, 1, GL_UNSIGNED_INT, GenerateMip<R32>, ReadColor<R32, GLuint>);
- AddDXGIFormat(&map, DXGI_FORMAT_R8G8_UINT, 16, 1, 1, GL_UNSIGNED_INT, GenerateMip<R8G8>, ReadColor<R8G8, GLuint>);
- AddDXGIFormat(&map, DXGI_FORMAT_R16G16_UINT, 32, 1, 1, GL_UNSIGNED_INT, GenerateMip<R16G16>, ReadColor<R16G16, GLuint>);
- AddDXGIFormat(&map, DXGI_FORMAT_R32G32_UINT, 64, 1, 1, GL_UNSIGNED_INT, GenerateMip<R32G32>, ReadColor<R32G32, GLuint>);
- AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_UINT, 96, 1, 1, GL_UNSIGNED_INT, GenerateMip<R32G32B32>, ReadColor<R32G32B32, GLuint>);
- AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UINT, 32, 1, 1, GL_UNSIGNED_INT, GenerateMip<R8G8B8A8>, ReadColor<R8G8B8A8, GLuint>);
- AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_UINT, 64, 1, 1, GL_UNSIGNED_INT, GenerateMip<R16G16B16A16>, ReadColor<R16G16B16A16, GLuint>);
- AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_UINT, 128, 1, 1, GL_UNSIGNED_INT, GenerateMip<R32G32B32A32>, ReadColor<R32G32B32A32, GLuint>);
-
- AddDXGIFormat(&map, DXGI_FORMAT_R8_SINT, 8, 1, 1, GL_INT, GenerateMip<R8S>, ReadColor<R8S, GLint>);
- AddDXGIFormat(&map, DXGI_FORMAT_R16_SINT, 16, 1, 1, GL_INT, GenerateMip<R16S>, ReadColor<R16S, GLint>);
- AddDXGIFormat(&map, DXGI_FORMAT_R32_SINT, 32, 1, 1, GL_INT, GenerateMip<R32S>, ReadColor<R32S, GLint>);
- AddDXGIFormat(&map, DXGI_FORMAT_R8G8_SINT, 16, 1, 1, GL_INT, GenerateMip<R8G8S>, ReadColor<R8G8S, GLint>);
- AddDXGIFormat(&map, DXGI_FORMAT_R16G16_SINT, 32, 1, 1, GL_INT, GenerateMip<R16G16S>, ReadColor<R16G16S, GLint>);
- AddDXGIFormat(&map, DXGI_FORMAT_R32G32_SINT, 64, 1, 1, GL_INT, GenerateMip<R32G32S>, ReadColor<R32G32S, GLint>);
- AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_SINT, 96, 1, 1, GL_INT, GenerateMip<R32G32B32S>, ReadColor<R32G32B32S, GLint>);
- AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_SINT, 32, 1, 1, GL_INT, GenerateMip<R8G8B8A8S>, ReadColor<R8G8B8A8S, GLint>);
- AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_SINT, 64, 1, 1, GL_INT, GenerateMip<R16G16B16A16S>, ReadColor<R16G16B16A16S, GLint>);
- AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_SINT, 128, 1, 1, GL_INT, GenerateMip<R32G32B32A32S>, ReadColor<R32G32B32A32S, GLint>);
-
- AddDXGIFormat(&map, DXGI_FORMAT_R10G10B10A2_UNORM, 32, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R10G10B10A2>, ReadColor<R10G10B10A2, GLfloat>);
- AddDXGIFormat(&map, DXGI_FORMAT_R10G10B10A2_UINT, 32, 1, 1, GL_UNSIGNED_INT, GenerateMip<R10G10B10A2>, ReadColor<R10G10B10A2, GLuint>);
-
- AddDXGIFormat(&map, DXGI_FORMAT_R16_FLOAT, 16, 1, 1, GL_FLOAT, GenerateMip<R16F>, ReadColor<R16F, GLfloat>);
- AddDXGIFormat(&map, DXGI_FORMAT_R16G16_FLOAT, 32, 1, 1, GL_FLOAT, GenerateMip<R16G16F>, ReadColor<R16G16F, GLfloat>);
- AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_FLOAT, 64, 1, 1, GL_FLOAT, GenerateMip<R16G16B16A16F>, ReadColor<R16G16B16A16F, GLfloat>);
-
- AddDXGIFormat(&map, DXGI_FORMAT_R32_FLOAT, 32, 1, 1, GL_FLOAT, GenerateMip<R32F>, ReadColor<R32F, GLfloat>);
- AddDXGIFormat(&map, DXGI_FORMAT_R32G32_FLOAT, 64, 1, 1, GL_FLOAT, GenerateMip<R32G32F>, ReadColor<R32G32F, GLfloat>);
- AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_FLOAT, 96, 1, 1, GL_FLOAT, NULL, NULL);
- AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_FLOAT, 128, 1, 1, GL_FLOAT, GenerateMip<R32G32B32A32F>, ReadColor<R32G32B32A32F, GLfloat>);
-
- AddDXGIFormat(&map, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, 32, 1, 1, GL_FLOAT, GenerateMip<R9G9B9E5>, ReadColor<R9G9B9E5, GLfloat>);
- AddDXGIFormat(&map, DXGI_FORMAT_R11G11B10_FLOAT, 32, 1, 1, GL_FLOAT, GenerateMip<R11G11B10F>, ReadColor<R11G11B10F, GLfloat>);
-
- AddDXGIFormat(&map, DXGI_FORMAT_R16_TYPELESS, 16, 1, 1, GL_NONE, NULL, NULL);
- AddDXGIFormat(&map, DXGI_FORMAT_R16_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL);
- AddDXGIFormat(&map, DXGI_FORMAT_D16_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL);
- AddDXGIFormat(&map, DXGI_FORMAT_R24G8_TYPELESS, 32, 1, 1, GL_NONE, NULL, NULL);
- AddDXGIFormat(&map, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, 32, 1, 1, GL_NONE, NULL, NULL);
- AddDXGIFormat(&map, DXGI_FORMAT_D24_UNORM_S8_UINT, 32, 1, 1, GL_UNSIGNED_INT, NULL, NULL);
- AddDXGIFormat(&map, DXGI_FORMAT_R32G8X24_TYPELESS, 64, 1, 1, GL_NONE, NULL, NULL);
- AddDXGIFormat(&map, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, 64, 1, 1, GL_NONE, NULL, NULL);
- AddDXGIFormat(&map, DXGI_FORMAT_D32_FLOAT_S8X24_UINT, 64, 1, 1, GL_UNSIGNED_INT, NULL, NULL);
- AddDXGIFormat(&map, DXGI_FORMAT_R32_TYPELESS, 32, 1, 1, GL_NONE, NULL, NULL);
- AddDXGIFormat(&map, DXGI_FORMAT_D32_FLOAT, 32, 1, 1, GL_FLOAT, NULL, NULL);
-
- AddDXGIFormat(&map, DXGI_FORMAT_BC1_UNORM, 64, 4, 4, GL_UNSIGNED_NORMALIZED, NULL, NULL);
- AddDXGIFormat(&map, DXGI_FORMAT_BC2_UNORM, 128, 4, 4, GL_UNSIGNED_NORMALIZED, NULL, NULL);
- AddDXGIFormat(&map, DXGI_FORMAT_BC3_UNORM, 128, 4, 4, GL_UNSIGNED_NORMALIZED, NULL, NULL);
+ // | DXGI format |S |W |H |Component Type | Mip generation function | Color read function | Native mipmap function
+ AddDXGIFormat(&map, DXGI_FORMAT_UNKNOWN, 0, 0, 0, GL_NONE, NULL, NULL, NeverSupported);
+
+ AddDXGIFormat(&map, DXGI_FORMAT_A8_UNORM, 8, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<A8>, ReadColor<A8, GLfloat>, RequiresFeatureLevel<D3D_FEATURE_LEVEL_10_0>);
+ AddDXGIFormat(&map, DXGI_FORMAT_R8_UNORM, 8, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R8>, ReadColor<R8, GLfloat>, RequiresFeatureLevel<D3D_FEATURE_LEVEL_10_0>);
+ AddDXGIFormat(&map, DXGI_FORMAT_R8G8_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R8G8>, ReadColor<R8G8, GLfloat>, RequiresFeatureLevel<D3D_FEATURE_LEVEL_10_0>);
+ AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UNORM, 32, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R8G8B8A8>, ReadColor<R8G8B8A8, GLfloat>, RequiresFeatureLevel<D3D_FEATURE_LEVEL_9_1>);
+ AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 32, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R8G8B8A8>, ReadColor<R8G8B8A8, GLfloat>, RequiresFeatureLevel<D3D_FEATURE_LEVEL_9_1>);
+ AddDXGIFormat(&map, DXGI_FORMAT_B8G8R8A8_UNORM, 32, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<B8G8R8A8>, ReadColor<B8G8R8A8, GLfloat>, RequiresFeatureLevel<D3D_FEATURE_LEVEL_9_1>);
+
+ AddDXGIFormat(&map, DXGI_FORMAT_R8_SNORM, 8, 1, 1, GL_SIGNED_NORMALIZED, GenerateMip<R8S>, ReadColor<R8S, GLfloat> , RequiresFeatureLevel<D3D_FEATURE_LEVEL_10_0>);
+ AddDXGIFormat(&map, DXGI_FORMAT_R8G8_SNORM, 16, 1, 1, GL_SIGNED_NORMALIZED, GenerateMip<R8G8S>, ReadColor<R8G8S, GLfloat> , RequiresFeatureLevel<D3D_FEATURE_LEVEL_10_0>);
+ AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_SNORM, 32, 1, 1, GL_SIGNED_NORMALIZED, GenerateMip<R8G8B8A8S>, ReadColor<R8G8B8A8S, GLfloat>, RequiresFeatureLevel<D3D_FEATURE_LEVEL_10_0>);
+
+ AddDXGIFormat(&map, DXGI_FORMAT_R8_UINT, 8, 1, 1, GL_UNSIGNED_INT, GenerateMip<R8>, ReadColor<R8, GLuint>, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R16_UINT, 16, 1, 1, GL_UNSIGNED_INT, GenerateMip<R16>, ReadColor<R16, GLuint>, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R32_UINT, 32, 1, 1, GL_UNSIGNED_INT, GenerateMip<R32>, ReadColor<R32, GLuint>, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R8G8_UINT, 16, 1, 1, GL_UNSIGNED_INT, GenerateMip<R8G8>, ReadColor<R8G8, GLuint>, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R16G16_UINT, 32, 1, 1, GL_UNSIGNED_INT, GenerateMip<R16G16>, ReadColor<R16G16, GLuint>, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R32G32_UINT, 64, 1, 1, GL_UNSIGNED_INT, GenerateMip<R32G32>, ReadColor<R32G32, GLuint>, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_UINT, 96, 1, 1, GL_UNSIGNED_INT, GenerateMip<R32G32B32>, ReadColor<R32G32B32, GLuint>, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UINT, 32, 1, 1, GL_UNSIGNED_INT, GenerateMip<R8G8B8A8>, ReadColor<R8G8B8A8, GLuint>, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_UINT, 64, 1, 1, GL_UNSIGNED_INT, GenerateMip<R16G16B16A16>, ReadColor<R16G16B16A16, GLuint>, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_UINT, 128, 1, 1, GL_UNSIGNED_INT, GenerateMip<R32G32B32A32>, ReadColor<R32G32B32A32, GLuint>, NeverSupported);
+
+ AddDXGIFormat(&map, DXGI_FORMAT_R8_SINT, 8, 1, 1, GL_INT, GenerateMip<R8S>, ReadColor<R8S, GLint>, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R16_SINT, 16, 1, 1, GL_INT, GenerateMip<R16S>, ReadColor<R16S, GLint>, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R32_SINT, 32, 1, 1, GL_INT, GenerateMip<R32S>, ReadColor<R32S, GLint>, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R8G8_SINT, 16, 1, 1, GL_INT, GenerateMip<R8G8S>, ReadColor<R8G8S, GLint>, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R16G16_SINT, 32, 1, 1, GL_INT, GenerateMip<R16G16S>, ReadColor<R16G16S, GLint>, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R32G32_SINT, 64, 1, 1, GL_INT, GenerateMip<R32G32S>, ReadColor<R32G32S, GLint>, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_SINT, 96, 1, 1, GL_INT, GenerateMip<R32G32B32S>, ReadColor<R32G32B32S, GLint>, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_SINT, 32, 1, 1, GL_INT, GenerateMip<R8G8B8A8S>, ReadColor<R8G8B8A8S, GLint>, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_SINT, 64, 1, 1, GL_INT, GenerateMip<R16G16B16A16S>, ReadColor<R16G16B16A16S, GLint>, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_SINT, 128, 1, 1, GL_INT, GenerateMip<R32G32B32A32S>, ReadColor<R32G32B32A32S, GLint>, NeverSupported);
+
+ AddDXGIFormat(&map, DXGI_FORMAT_R10G10B10A2_UNORM, 32, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R10G10B10A2>, ReadColor<R10G10B10A2, GLfloat>, RequiresFeatureLevel<D3D_FEATURE_LEVEL_10_0>);
+ AddDXGIFormat(&map, DXGI_FORMAT_R10G10B10A2_UINT, 32, 1, 1, GL_UNSIGNED_INT, GenerateMip<R10G10B10A2>, ReadColor<R10G10B10A2, GLuint>, NeverSupported);
+
+ AddDXGIFormat(&map, DXGI_FORMAT_R16_FLOAT, 16, 1, 1, GL_FLOAT, GenerateMip<R16F>, ReadColor<R16F, GLfloat>, RequiresFeatureLevel<D3D_FEATURE_LEVEL_10_0>);
+ AddDXGIFormat(&map, DXGI_FORMAT_R16G16_FLOAT, 32, 1, 1, GL_FLOAT, GenerateMip<R16G16F>, ReadColor<R16G16F, GLfloat>, RequiresFeatureLevel<D3D_FEATURE_LEVEL_9_2>);
+ AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_FLOAT, 64, 1, 1, GL_FLOAT, GenerateMip<R16G16B16A16F>, ReadColor<R16G16B16A16F, GLfloat>, RequiresFeatureLevel<D3D_FEATURE_LEVEL_9_2>);
+
+ AddDXGIFormat(&map, DXGI_FORMAT_R32_FLOAT, 32, 1, 1, GL_FLOAT, GenerateMip<R32F>, ReadColor<R32F, GLfloat>, RequiresFeatureLevel<D3D_FEATURE_LEVEL_9_2>);
+ AddDXGIFormat(&map, DXGI_FORMAT_R32G32_FLOAT, 64, 1, 1, GL_FLOAT, GenerateMip<R32G32F>, ReadColor<R32G32F, GLfloat>, RequiresFeatureLevel<D3D_FEATURE_LEVEL_10_0>);
+ AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_FLOAT, 96, 1, 1, GL_FLOAT, NULL, NULL, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_FLOAT, 128, 1, 1, GL_FLOAT, GenerateMip<R32G32B32A32F>, ReadColor<R32G32B32A32F, GLfloat>, RequiresFeatureLevel<D3D_FEATURE_LEVEL_9_3>);
+
+ AddDXGIFormat(&map, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, 32, 1, 1, GL_FLOAT, GenerateMip<R9G9B9E5>, ReadColor<R9G9B9E5, GLfloat>, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R11G11B10_FLOAT, 32, 1, 1, GL_FLOAT, GenerateMip<R11G11B10F>, ReadColor<R11G11B10F, GLfloat>, RequiresFeatureLevel<D3D_FEATURE_LEVEL_10_0>);
+
+ AddDXGIFormat(&map, DXGI_FORMAT_R16_TYPELESS, 16, 1, 1, GL_NONE, NULL, NULL, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R16_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_D16_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R24G8_TYPELESS, 32, 1, 1, GL_NONE, NULL, NULL, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, 32, 1, 1, GL_NONE, NULL, NULL, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_D24_UNORM_S8_UINT, 32, 1, 1, GL_UNSIGNED_INT, NULL, NULL, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R32G8X24_TYPELESS, 64, 1, 1, GL_NONE, NULL, NULL, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, 64, 1, 1, GL_NONE, NULL, NULL, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_D32_FLOAT_S8X24_UINT, 64, 1, 1, GL_UNSIGNED_INT, NULL, NULL, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R32_TYPELESS, 32, 1, 1, GL_NONE, NULL, NULL, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_D32_FLOAT, 32, 1, 1, GL_FLOAT, NULL, NULL, NeverSupported);
+
+ AddDXGIFormat(&map, DXGI_FORMAT_BC1_UNORM, 64, 4, 4, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_BC2_UNORM, 128, 4, 4, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_BC3_UNORM, 128, 4, 4, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported);
+
+ // B5G6R5 in D3D11 is treated the same as R5G6B5 in D3D9, so reuse the R5G6B5 functions used by the D3D9 renderer.
+ // The same applies to B4G4R4A4 and B5G5R5A1 with A4R4G4B4 and A1R5G5B5 respectively.
+ AddDXGIFormat(&map, DXGI_FORMAT_B5G6R5_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R5G6B5>, ReadColor<R5G6B5, GLfloat>, RequiresFeatureLevel<D3D_FEATURE_LEVEL_9_1>);
+ AddDXGIFormat(&map, DXGI_FORMAT_B4G4R4A4_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<A4R4G4B4>, ReadColor<A4R4G4B4, GLfloat>, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_B5G5R5A1_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<A1R5G5B5>, ReadColor<A1R5G5B5, GLfloat>, NeverSupported);
// Useful formats for vertex buffers
- AddDXGIFormat(&map, DXGI_FORMAT_R16_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL);
- AddDXGIFormat(&map, DXGI_FORMAT_R16_SNORM, 16, 1, 1, GL_SIGNED_NORMALIZED, NULL, NULL);
- AddDXGIFormat(&map, DXGI_FORMAT_R16G16_UNORM, 32, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL);
- AddDXGIFormat(&map, DXGI_FORMAT_R16G16_SNORM, 32, 1, 1, GL_SIGNED_NORMALIZED, NULL, NULL);
- AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_UNORM, 64, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL);
- AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_SNORM, 64, 1, 1, GL_SIGNED_NORMALIZED, NULL, NULL);
+ AddDXGIFormat(&map, DXGI_FORMAT_R16_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R16_SNORM, 16, 1, 1, GL_SIGNED_NORMALIZED, NULL, NULL, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R16G16_UNORM, 32, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R16G16_SNORM, 32, 1, 1, GL_SIGNED_NORMALIZED, NULL, NULL, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_UNORM, 64, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported);
+ AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_SNORM, 64, 1, 1, GL_SIGNED_NORMALIZED, NULL, NULL, NeverSupported);
return map;
}
@@ -436,613 +466,8 @@ const DXGIFormat &GetDXGIFormatInfo(DXGI_FORMAT format)
}
}
-struct SwizzleSizeType
-{
- size_t maxComponentSize;
- GLenum componentType;
-
- SwizzleSizeType()
- : maxComponentSize(0), componentType(GL_NONE)
- { }
-
- SwizzleSizeType(size_t maxComponentSize, GLenum componentType)
- : maxComponentSize(maxComponentSize), componentType(componentType)
- { }
-
- bool operator<(const SwizzleSizeType& other) const
- {
- return (maxComponentSize != other.maxComponentSize) ? (maxComponentSize < other.maxComponentSize)
- : (componentType < other.componentType);
- }
-};
-
-struct SwizzleFormatInfo
-{
- DXGI_FORMAT mTexFormat;
- DXGI_FORMAT mSRVFormat;
- DXGI_FORMAT mRTVFormat;
-
- SwizzleFormatInfo()
- : mTexFormat(DXGI_FORMAT_UNKNOWN), mSRVFormat(DXGI_FORMAT_UNKNOWN), mRTVFormat(DXGI_FORMAT_UNKNOWN)
- { }
-
- SwizzleFormatInfo(DXGI_FORMAT texFormat, DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat)
- : mTexFormat(texFormat), mSRVFormat(srvFormat), mRTVFormat(rtvFormat)
- { }
-};
-
-typedef std::map<SwizzleSizeType, SwizzleFormatInfo> SwizzleInfoMap;
-typedef std::pair<SwizzleSizeType, SwizzleFormatInfo> SwizzleInfoPair;
-
-static SwizzleInfoMap BuildSwizzleInfoMap()
-{
- SwizzleInfoMap map;
-
- map.insert(SwizzleInfoPair(SwizzleSizeType( 8, GL_UNSIGNED_NORMALIZED), SwizzleFormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM )));
- map.insert(SwizzleInfoPair(SwizzleSizeType(16, GL_UNSIGNED_NORMALIZED), SwizzleFormatInfo(DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM)));
- map.insert(SwizzleInfoPair(SwizzleSizeType(24, GL_UNSIGNED_NORMALIZED), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT)));
- map.insert(SwizzleInfoPair(SwizzleSizeType(32, GL_UNSIGNED_NORMALIZED), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT)));
-
- map.insert(SwizzleInfoPair(SwizzleSizeType( 8, GL_SIGNED_NORMALIZED ), SwizzleFormatInfo(DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM )));
-
- map.insert(SwizzleInfoPair(SwizzleSizeType(16, GL_FLOAT ), SwizzleFormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT)));
- map.insert(SwizzleInfoPair(SwizzleSizeType(32, GL_FLOAT ), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT)));
-
- map.insert(SwizzleInfoPair(SwizzleSizeType( 8, GL_UNSIGNED_INT ), SwizzleFormatInfo(DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT )));
- map.insert(SwizzleInfoPair(SwizzleSizeType(16, GL_UNSIGNED_INT ), SwizzleFormatInfo(DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT )));
- map.insert(SwizzleInfoPair(SwizzleSizeType(32, GL_UNSIGNED_INT ), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT )));
-
- map.insert(SwizzleInfoPair(SwizzleSizeType( 8, GL_INT ), SwizzleFormatInfo(DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT )));
- map.insert(SwizzleInfoPair(SwizzleSizeType(16, GL_INT ), SwizzleFormatInfo(DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT )));
- map.insert(SwizzleInfoPair(SwizzleSizeType(32, GL_INT ), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT )));
-
- return map;
-}
-
-typedef std::pair<GLint, InitializeTextureDataFunction> InternalFormatInitializerPair;
-typedef std::map<GLint, InitializeTextureDataFunction> InternalFormatInitializerMap;
-
-static InternalFormatInitializerMap BuildInternalFormatInitializerMap()
-{
- InternalFormatInitializerMap map;
-
- map.insert(InternalFormatInitializerPair(GL_RGB8, Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF> ));
- map.insert(InternalFormatInitializerPair(GL_RGB565, Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF> ));
- map.insert(InternalFormatInitializerPair(GL_SRGB8, Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF> ));
- map.insert(InternalFormatInitializerPair(GL_RGB16F, Initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>));
- map.insert(InternalFormatInitializerPair(GL_RGB32F, Initialize4ComponentData<GLfloat, 0x00000000, 0x00000000, 0x00000000, gl::Float32One>));
- map.insert(InternalFormatInitializerPair(GL_RGB8UI, Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0x01> ));
- map.insert(InternalFormatInitializerPair(GL_RGB8I, Initialize4ComponentData<GLbyte, 0x00, 0x00, 0x00, 0x01> ));
- map.insert(InternalFormatInitializerPair(GL_RGB16UI, Initialize4ComponentData<GLushort, 0x0000, 0x0000, 0x0000, 0x0001> ));
- map.insert(InternalFormatInitializerPair(GL_RGB16I, Initialize4ComponentData<GLshort, 0x0000, 0x0000, 0x0000, 0x0001> ));
- map.insert(InternalFormatInitializerPair(GL_RGB32UI, Initialize4ComponentData<GLuint, 0x00000000, 0x00000000, 0x00000000, 0x00000001> ));
- map.insert(InternalFormatInitializerPair(GL_RGB32I, Initialize4ComponentData<GLint, 0x00000000, 0x00000000, 0x00000000, 0x00000001> ));
-
- return map;
-}
-
-// ES3 image loading functions vary based on the internal format and data type given,
-// this map type determines the loading function from the internal format and type supplied
-// to glTex*Image*D and the destination DXGI_FORMAT. Source formats and types are taken from
-// Tables 3.2 and 3.3 of the ES 3 spec.
-typedef std::pair<GLenum, LoadImageFunction> TypeLoadFunctionPair;
-typedef std::map<GLenum, std::vector<TypeLoadFunctionPair> > D3D11LoadFunctionMap;
-
-static void UnimplementedLoadFunction(size_t width, size_t height, size_t depth,
- const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
- uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
-{
- UNIMPLEMENTED();
-}
-
-static void UnreachableLoadFunction(size_t width, size_t height, size_t depth,
- const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
- uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
-{
- UNREACHABLE();
-}
-
-// A helper function to insert data into the D3D11LoadFunctionMap with fewer characters.
-static inline void InsertLoadFunction(D3D11LoadFunctionMap *map, GLenum internalFormat, GLenum type,
- LoadImageFunction loadFunc)
-{
- (*map)[internalFormat].push_back(TypeLoadFunctionPair(type, loadFunc));
-}
-
-D3D11LoadFunctionMap BuildD3D11_FL9_3_LoadFunctionMap()
-{
- D3D11LoadFunctionMap map;
-
- // From GL_EXT_texture_storage. Also used by GL_ALPHA8
- // On feature level 9_3, A8_UNORM doesn't support mipmaps, so we must use RGBA8 instead
- InsertLoadFunction(&map, GL_ALPHA8_EXT, GL_UNSIGNED_BYTE, LoadA8ToRGBA8);
-
- return map;
-}
-
-D3D11LoadFunctionMap BuildD3D11_FL10_0Plus_LoadFunctionMap()
-{
- D3D11LoadFunctionMap map;
-
- // From GL_EXT_texture_storage. Also used by GL_ALPHA8
- InsertLoadFunction(&map, GL_ALPHA8_EXT, GL_UNSIGNED_BYTE, LoadToNative<GLubyte, 1>);
-
- return map;
-}
-
-D3D11LoadFunctionMap BuildBaseD3D11LoadFunctionMap()
-{
- D3D11LoadFunctionMap map;
-
- // | Internal format | Type | Load function |
- InsertLoadFunction(&map, GL_RGBA8, GL_UNSIGNED_BYTE, LoadToNative<GLubyte, 4> );
- InsertLoadFunction(&map, GL_RGB5_A1, GL_UNSIGNED_BYTE, LoadToNative<GLubyte, 4> );
- InsertLoadFunction(&map, GL_RGBA4, GL_UNSIGNED_BYTE, LoadToNative<GLubyte, 4> );
- InsertLoadFunction(&map, GL_SRGB8_ALPHA8, GL_UNSIGNED_BYTE, LoadToNative<GLubyte, 4> );
- InsertLoadFunction(&map, GL_RGBA8_SNORM, GL_BYTE, LoadToNative<GLbyte, 4> );
- InsertLoadFunction(&map, GL_RGBA4, GL_UNSIGNED_SHORT_4_4_4_4, LoadRGBA4ToRGBA8 );
- InsertLoadFunction(&map, GL_RGB10_A2, GL_UNSIGNED_INT_2_10_10_10_REV, LoadToNative<GLuint, 1> );
- InsertLoadFunction(&map, GL_RGB5_A1, GL_UNSIGNED_SHORT_5_5_5_1, LoadRGB5A1ToRGBA8 );
- InsertLoadFunction(&map, GL_RGB5_A1, GL_UNSIGNED_INT_2_10_10_10_REV, LoadRGB10A2ToRGBA8 );
- InsertLoadFunction(&map, GL_RGBA16F, GL_HALF_FLOAT, LoadToNative<GLhalf, 4> );
- InsertLoadFunction(&map, GL_RGBA16F, GL_HALF_FLOAT_OES, LoadToNative<GLhalf, 4> );
- InsertLoadFunction(&map, GL_RGBA32F, GL_FLOAT, LoadToNative<GLfloat, 4> );
- InsertLoadFunction(&map, GL_RGBA16F, GL_FLOAT, Load32FTo16F<4> );
- InsertLoadFunction(&map, GL_RGBA8UI, GL_UNSIGNED_BYTE, LoadToNative<GLubyte, 4> );
- InsertLoadFunction(&map, GL_RGBA8I, GL_BYTE, LoadToNative<GLbyte, 4> );
- InsertLoadFunction(&map, GL_RGBA16UI, GL_UNSIGNED_SHORT, LoadToNative<GLushort, 4> );
- InsertLoadFunction(&map, GL_RGBA16I, GL_SHORT, LoadToNative<GLshort, 4> );
- InsertLoadFunction(&map, GL_RGBA32UI, GL_UNSIGNED_INT, LoadToNative<GLuint, 4> );
- InsertLoadFunction(&map, GL_RGBA32I, GL_INT, LoadToNative<GLint, 4> );
- InsertLoadFunction(&map, GL_RGB10_A2UI, GL_UNSIGNED_INT_2_10_10_10_REV, LoadToNative<GLuint, 1> );
- InsertLoadFunction(&map, GL_RGB8, GL_UNSIGNED_BYTE, LoadToNative3To4<GLubyte, 0xFF> );
- InsertLoadFunction(&map, GL_RGB565, GL_UNSIGNED_BYTE, LoadToNative3To4<GLubyte, 0xFF> );
- InsertLoadFunction(&map, GL_SRGB8, GL_UNSIGNED_BYTE, LoadToNative3To4<GLubyte, 0xFF> );
- InsertLoadFunction(&map, GL_RGB8_SNORM, GL_BYTE, LoadToNative3To4<GLbyte, 0x7F> );
- InsertLoadFunction(&map, GL_RGB565, GL_UNSIGNED_SHORT_5_6_5, LoadR5G6B5ToRGBA8 );
- InsertLoadFunction(&map, GL_R11F_G11F_B10F, GL_UNSIGNED_INT_10F_11F_11F_REV, LoadToNative<GLuint, 1> );
- InsertLoadFunction(&map, GL_RGB9_E5, GL_UNSIGNED_INT_5_9_9_9_REV, LoadToNative<GLuint, 1> );
- InsertLoadFunction(&map, GL_RGB16F, GL_HALF_FLOAT, LoadToNative3To4<GLhalf, gl::Float16One>);
- InsertLoadFunction(&map, GL_RGB16F, GL_HALF_FLOAT_OES, LoadToNative3To4<GLhalf, gl::Float16One>);
- InsertLoadFunction(&map, GL_R11F_G11F_B10F, GL_HALF_FLOAT, LoadRGB16FToRG11B10F );
- InsertLoadFunction(&map, GL_R11F_G11F_B10F, GL_HALF_FLOAT_OES, LoadRGB16FToRG11B10F );
- InsertLoadFunction(&map, GL_RGB9_E5, GL_HALF_FLOAT, LoadRGB16FToRGB9E5 );
- InsertLoadFunction(&map, GL_RGB9_E5, GL_HALF_FLOAT_OES, LoadRGB16FToRGB9E5 );
- InsertLoadFunction(&map, GL_RGB32F, GL_FLOAT, LoadToNative3To4<GLfloat, gl::Float32One>);
- InsertLoadFunction(&map, GL_RGB16F, GL_FLOAT, LoadRGB32FToRGBA16F );
- InsertLoadFunction(&map, GL_R11F_G11F_B10F, GL_FLOAT, LoadRGB32FToRG11B10F );
- InsertLoadFunction(&map, GL_RGB9_E5, GL_FLOAT, LoadRGB32FToRGB9E5 );
- InsertLoadFunction(&map, GL_RGB8UI, GL_UNSIGNED_BYTE, LoadToNative3To4<GLubyte, 0x01> );
- InsertLoadFunction(&map, GL_RGB8I, GL_BYTE, LoadToNative3To4<GLbyte, 0x01> );
- InsertLoadFunction(&map, GL_RGB16UI, GL_UNSIGNED_SHORT, LoadToNative3To4<GLushort, 0x0001> );
- InsertLoadFunction(&map, GL_RGB16I, GL_SHORT, LoadToNative3To4<GLshort, 0x0001> );
- InsertLoadFunction(&map, GL_RGB32UI, GL_UNSIGNED_INT, LoadToNative3To4<GLuint, 0x00000001> );
- InsertLoadFunction(&map, GL_RGB32I, GL_INT, LoadToNative3To4<GLint, 0x00000001> );
- InsertLoadFunction(&map, GL_RG8, GL_UNSIGNED_BYTE, LoadToNative<GLubyte, 2> );
- InsertLoadFunction(&map, GL_RG8_SNORM, GL_BYTE, LoadToNative<GLbyte, 2> );
- InsertLoadFunction(&map, GL_RG16F, GL_HALF_FLOAT, LoadToNative<GLhalf, 2> );
- InsertLoadFunction(&map, GL_RG16F, GL_HALF_FLOAT_OES, LoadToNative<GLhalf, 2> );
- InsertLoadFunction(&map, GL_RG32F, GL_FLOAT, LoadToNative<GLfloat, 2> );
- InsertLoadFunction(&map, GL_RG16F, GL_FLOAT, Load32FTo16F<2> );
- InsertLoadFunction(&map, GL_RG8UI, GL_UNSIGNED_BYTE, LoadToNative<GLubyte, 2> );
- InsertLoadFunction(&map, GL_RG8I, GL_BYTE, LoadToNative<GLbyte, 2> );
- InsertLoadFunction(&map, GL_RG16UI, GL_UNSIGNED_SHORT, LoadToNative<GLushort, 2> );
- InsertLoadFunction(&map, GL_RG16I, GL_SHORT, LoadToNative<GLshort, 2> );
- InsertLoadFunction(&map, GL_RG32UI, GL_UNSIGNED_INT, LoadToNative<GLuint, 2> );
- InsertLoadFunction(&map, GL_RG32I, GL_INT, LoadToNative<GLint, 2> );
- InsertLoadFunction(&map, GL_R8, GL_UNSIGNED_BYTE, LoadToNative<GLubyte, 1> );
- InsertLoadFunction(&map, GL_R8_SNORM, GL_BYTE, LoadToNative<GLbyte, 1> );
- InsertLoadFunction(&map, GL_R16F, GL_HALF_FLOAT, LoadToNative<GLhalf, 1> );
- InsertLoadFunction(&map, GL_R16F, GL_HALF_FLOAT_OES, LoadToNative<GLhalf, 1> );
- InsertLoadFunction(&map, GL_R32F, GL_FLOAT, LoadToNative<GLfloat, 1> );
- InsertLoadFunction(&map, GL_R16F, GL_FLOAT, Load32FTo16F<1> );
- InsertLoadFunction(&map, GL_R8UI, GL_UNSIGNED_BYTE, LoadToNative<GLubyte, 1> );
- InsertLoadFunction(&map, GL_R8I, GL_BYTE, LoadToNative<GLbyte, 1> );
- InsertLoadFunction(&map, GL_R16UI, GL_UNSIGNED_SHORT, LoadToNative<GLushort, 1> );
- InsertLoadFunction(&map, GL_R16I, GL_SHORT, LoadToNative<GLshort, 1> );
- InsertLoadFunction(&map, GL_R32UI, GL_UNSIGNED_INT, LoadToNative<GLuint, 1> );
- InsertLoadFunction(&map, GL_R32I, GL_INT, LoadToNative<GLint, 1> );
- InsertLoadFunction(&map, GL_DEPTH_COMPONENT16, GL_UNSIGNED_SHORT, LoadToNative<GLushort, 1> );
- InsertLoadFunction(&map, GL_DEPTH_COMPONENT24, GL_UNSIGNED_INT, LoadR32ToR24G8 );
- InsertLoadFunction(&map, GL_DEPTH_COMPONENT16, GL_UNSIGNED_INT, LoadR32ToR16 );
- InsertLoadFunction(&map, GL_DEPTH_COMPONENT32F, GL_FLOAT, LoadToNative<GLfloat, 1> );
- InsertLoadFunction(&map, GL_DEPTH24_STENCIL8, GL_UNSIGNED_INT_24_8, LoadR32ToR24G8 );
- InsertLoadFunction(&map, GL_DEPTH32F_STENCIL8, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, LoadToNative<GLuint, 2> );
-
- // Unsized formats
- // Load functions are unreachable because they are converted to sized internal formats based on
- // the format and type before loading takes place.
- InsertLoadFunction(&map, GL_RGBA, GL_UNSIGNED_BYTE, UnreachableLoadFunction );
- InsertLoadFunction(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, UnreachableLoadFunction );
- InsertLoadFunction(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, UnreachableLoadFunction );
- InsertLoadFunction(&map, GL_RGB, GL_UNSIGNED_BYTE, UnreachableLoadFunction );
- InsertLoadFunction(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, UnreachableLoadFunction );
- InsertLoadFunction(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, UnreachableLoadFunction );
- InsertLoadFunction(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, UnreachableLoadFunction );
- InsertLoadFunction(&map, GL_ALPHA, GL_UNSIGNED_BYTE, UnreachableLoadFunction );
-
- // From GL_OES_texture_float
- InsertLoadFunction(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, LoadLA32FToRGBA32F );
- InsertLoadFunction(&map, GL_LUMINANCE, GL_FLOAT, LoadL32FToRGBA32F );
- InsertLoadFunction(&map, GL_ALPHA, GL_FLOAT, LoadA32FToRGBA32F );
-
- // From GL_OES_texture_half_float
- InsertLoadFunction(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, LoadLA16FToRGBA16F );
- InsertLoadFunction(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, LoadLA16FToRGBA16F );
- InsertLoadFunction(&map, GL_LUMINANCE, GL_HALF_FLOAT, LoadL16FToRGBA16F );
- InsertLoadFunction(&map, GL_LUMINANCE, GL_HALF_FLOAT_OES, LoadL16FToRGBA16F );
- InsertLoadFunction(&map, GL_ALPHA, GL_HALF_FLOAT, LoadA16FToRGBA16F );
- InsertLoadFunction(&map, GL_ALPHA, GL_HALF_FLOAT_OES, LoadA16FToRGBA16F );
-
- // From GL_EXT_texture_storage
- // GL_ALPHA8_EXT GL_UNSIGNED_BYTE is in the feature-level-specific load function maps, due to differences between 9_3 and 10_0+
- InsertLoadFunction(&map, GL_LUMINANCE8_EXT, GL_UNSIGNED_BYTE, LoadL8ToRGBA8 );
- InsertLoadFunction(&map, GL_LUMINANCE8_ALPHA8_EXT, GL_UNSIGNED_BYTE, LoadLA8ToRGBA8 );
- InsertLoadFunction(&map, GL_ALPHA32F_EXT, GL_FLOAT, LoadA32FToRGBA32F );
- InsertLoadFunction(&map, GL_LUMINANCE32F_EXT, GL_FLOAT, LoadL32FToRGBA32F );
- InsertLoadFunction(&map, GL_LUMINANCE_ALPHA32F_EXT, GL_FLOAT, LoadLA32FToRGBA32F );
- InsertLoadFunction(&map, GL_ALPHA16F_EXT, GL_HALF_FLOAT, LoadA16FToRGBA16F );
- InsertLoadFunction(&map, GL_ALPHA16F_EXT, GL_HALF_FLOAT_OES, LoadA16FToRGBA16F );
- InsertLoadFunction(&map, GL_LUMINANCE16F_EXT, GL_HALF_FLOAT, LoadL16FToRGBA16F );
- InsertLoadFunction(&map, GL_LUMINANCE16F_EXT, GL_HALF_FLOAT_OES, LoadL16FToRGBA16F );
- InsertLoadFunction(&map, GL_LUMINANCE_ALPHA16F_EXT, GL_HALF_FLOAT, LoadLA16FToRGBA16F );
- InsertLoadFunction(&map, GL_LUMINANCE_ALPHA16F_EXT, GL_HALF_FLOAT_OES, LoadLA16FToRGBA16F );
-
- // From GL_ANGLE_depth_texture
- InsertLoadFunction(&map, GL_DEPTH_COMPONENT32_OES, GL_UNSIGNED_INT, LoadR32ToR24G8 );
-
- // From GL_EXT_texture_format_BGRA8888
- InsertLoadFunction(&map, GL_BGRA8_EXT, GL_UNSIGNED_BYTE, LoadToNative<GLubyte, 4> );
- InsertLoadFunction(&map, GL_BGRA4_ANGLEX, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, LoadRGBA4ToRGBA8 );
- InsertLoadFunction(&map, GL_BGRA4_ANGLEX, GL_UNSIGNED_BYTE, LoadToNative<GLubyte, 4> );
- InsertLoadFunction(&map, GL_BGR5_A1_ANGLEX, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, LoadRGB5A1ToRGBA8 );
- InsertLoadFunction(&map, GL_BGR5_A1_ANGLEX, GL_UNSIGNED_BYTE, LoadToNative<GLubyte, 4> );
-
- // Compressed formats
- // From ES 3.0.1 spec, table 3.16
- // | Internal format | Type | Load function |
- InsertLoadFunction(&map, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
- InsertLoadFunction(&map, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
- InsertLoadFunction(&map, GL_COMPRESSED_SIGNED_R11_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
- InsertLoadFunction(&map, GL_COMPRESSED_RG11_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
- InsertLoadFunction(&map, GL_COMPRESSED_SIGNED_RG11_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
- InsertLoadFunction(&map, GL_COMPRESSED_RGB8_ETC2, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
- InsertLoadFunction(&map, GL_COMPRESSED_SRGB8_ETC2, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
- InsertLoadFunction(&map, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
- InsertLoadFunction(&map, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
- InsertLoadFunction(&map, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
- InsertLoadFunction(&map, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
-
- // From GL_EXT_texture_compression_dxt1
- InsertLoadFunction(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4, 8>);
- InsertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4, 8>);
-
- // From GL_ANGLE_texture_compression_dxt3
- InsertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4, 16>);
-
- // From GL_ANGLE_texture_compression_dxt5
- InsertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4, 16>);
-
- return map;
-}
-
-// For sized GL internal formats, there is only one corresponding D3D11 format. This map type allows
-// querying for the DXGI texture formats to use for textures, SRVs, RTVs and DSVs given a GL internal
-// format.
-typedef std::map<GLenum, TextureFormat> D3D11ES3FormatMap;
-
-TextureFormat::TextureFormat()
- : texFormat(DXGI_FORMAT_UNKNOWN),
- srvFormat(DXGI_FORMAT_UNKNOWN),
- rtvFormat(DXGI_FORMAT_UNKNOWN),
- dsvFormat(DXGI_FORMAT_UNKNOWN),
- renderFormat(DXGI_FORMAT_UNKNOWN),
- swizzleTexFormat(DXGI_FORMAT_UNKNOWN),
- swizzleSRVFormat(DXGI_FORMAT_UNKNOWN),
- swizzleRTVFormat(DXGI_FORMAT_UNKNOWN),
- dataInitializerFunction(NULL),
- loadFunctions()
-{
-}
-
-static inline void InsertD3D11FormatInfoBase(D3D11ES3FormatMap *formatMap, const D3D11LoadFunctionMap &flLoadFunctions, GLenum internalFormat, DXGI_FORMAT texFormat,
- DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat, DXGI_FORMAT dsvFormat)
-{
- TextureFormat info;
- info.texFormat = texFormat;
- info.srvFormat = srvFormat;
- info.rtvFormat = rtvFormat;
- info.dsvFormat = dsvFormat;
-
- // Given a GL internal format, the renderFormat is the DSV format if it is depth- or stencil-renderable,
- // the RTV format if it is color-renderable, and the (nonrenderable) texture format otherwise.
- if (dsvFormat != DXGI_FORMAT_UNKNOWN)
- {
- info.renderFormat = dsvFormat;
- }
- else if (rtvFormat != DXGI_FORMAT_UNKNOWN)
- {
- info.renderFormat = rtvFormat;
- }
- else if (texFormat != DXGI_FORMAT_UNKNOWN)
- {
- info.renderFormat = texFormat;
- }
- else
- {
- info.renderFormat = DXGI_FORMAT_UNKNOWN;
- }
-
- // Compute the swizzle formats
- const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
- if (internalFormat != GL_NONE && formatInfo.pixelBytes > 0)
- {
- if (formatInfo.componentCount != 4 || texFormat == DXGI_FORMAT_UNKNOWN ||
- srvFormat == DXGI_FORMAT_UNKNOWN || rtvFormat == DXGI_FORMAT_UNKNOWN)
- {
- // Get the maximum sized component
- unsigned int maxBits = 1;
- if (formatInfo.compressed)
- {
- unsigned int compressedBitsPerBlock = formatInfo.pixelBytes * 8;
- unsigned int blockSize = formatInfo.compressedBlockWidth * formatInfo.compressedBlockHeight;
- maxBits = std::max(compressedBitsPerBlock / blockSize, maxBits);
- }
- else
- {
- maxBits = std::max(maxBits, formatInfo.alphaBits);
- maxBits = std::max(maxBits, formatInfo.redBits);
- maxBits = std::max(maxBits, formatInfo.greenBits);
- maxBits = std::max(maxBits, formatInfo.blueBits);
- maxBits = std::max(maxBits, formatInfo.luminanceBits);
- maxBits = std::max(maxBits, formatInfo.depthBits);
- }
-
- maxBits = roundUp(maxBits, 8U);
-
- static const SwizzleInfoMap swizzleMap = BuildSwizzleInfoMap();
- SwizzleInfoMap::const_iterator swizzleIter = swizzleMap.find(SwizzleSizeType(maxBits, formatInfo.componentType));
- ASSERT(swizzleIter != swizzleMap.end());
-
- const SwizzleFormatInfo &swizzleInfo = swizzleIter->second;
- info.swizzleTexFormat = swizzleInfo.mTexFormat;
- info.swizzleSRVFormat = swizzleInfo.mSRVFormat;
- info.swizzleRTVFormat = swizzleInfo.mRTVFormat;
- }
- else
- {
- // The original texture format is suitable for swizzle operations
- info.swizzleTexFormat = texFormat;
- info.swizzleSRVFormat = srvFormat;
- info.swizzleRTVFormat = rtvFormat;
- }
- }
- else
- {
- // Not possible to swizzle with this texture format since it is either unsized or GL_NONE
- info.swizzleTexFormat = DXGI_FORMAT_UNKNOWN;
- info.swizzleSRVFormat = DXGI_FORMAT_UNKNOWN;
- info.swizzleRTVFormat = DXGI_FORMAT_UNKNOWN;
- }
-
- // Check if there is an initialization function for this texture format
- static const InternalFormatInitializerMap initializerMap = BuildInternalFormatInitializerMap();
- InternalFormatInitializerMap::const_iterator initializerIter = initializerMap.find(internalFormat);
- info.dataInitializerFunction = (initializerIter != initializerMap.end()) ? initializerIter->second : NULL;
-
- // Gather all the load functions for this internal format from the base list
- static const D3D11LoadFunctionMap loadFunctions = BuildBaseD3D11LoadFunctionMap();
- D3D11LoadFunctionMap::const_iterator loadFunctionIter = loadFunctions.find(internalFormat);
- if (loadFunctionIter != loadFunctions.end())
- {
- const std::vector<TypeLoadFunctionPair> &loadFunctionVector = loadFunctionIter->second;
- for (size_t i = 0; i < loadFunctionVector.size(); i++)
- {
- GLenum type = loadFunctionVector[i].first;
- LoadImageFunction function = loadFunctionVector[i].second;
- info.loadFunctions.insert(std::make_pair(type, function));
- }
- }
-
- // Gather load functions for this internal format from the feature-level-specific list
- D3D11LoadFunctionMap::const_iterator flLoadFunctionIter = flLoadFunctions.find(internalFormat);
- if (flLoadFunctionIter != flLoadFunctions.end())
- {
- const std::vector<TypeLoadFunctionPair> &flLoadFunctionVector = flLoadFunctionIter->second;
- for (size_t i = 0; i < flLoadFunctionVector.size(); i++)
- {
- GLenum type = flLoadFunctionVector[i].first;
- LoadImageFunction function = flLoadFunctionVector[i].second;
- info.loadFunctions.insert(std::make_pair(type, function));
- }
- }
-
- formatMap->insert(std::make_pair(internalFormat, info));
-}
-
-static inline void InsertD3D11_FL9_3_FormatInfo(D3D11ES3FormatMap *map, GLenum internalFormat, DXGI_FORMAT texFormat,
- DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat, DXGI_FORMAT dsvFormat)
-{
- static const D3D11LoadFunctionMap flLoadFunctions = BuildD3D11_FL9_3_LoadFunctionMap();
- InsertD3D11FormatInfoBase(map, flLoadFunctions, internalFormat, texFormat, srvFormat, rtvFormat, dsvFormat);
-}
-
-static inline void InsertD3D11FormatInfo(D3D11ES3FormatMap *map, GLenum internalFormat, DXGI_FORMAT texFormat,
- DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat, DXGI_FORMAT dsvFormat)
-{
- static const D3D11LoadFunctionMap flLoadFunctions = BuildD3D11_FL10_0Plus_LoadFunctionMap();
- InsertD3D11FormatInfoBase(map, flLoadFunctions, internalFormat, texFormat, srvFormat, rtvFormat, dsvFormat);
-}
-
-static D3D11ES3FormatMap BuildD3D11_FL9_3FormatOverrideMap()
-{
- // D3D11 Feature Level 9_3 doesn't support as many texture formats as Feature Level 10_0+.
- // In particular, it doesn't support:
- // - mipmaps on DXGI_FORMAT_A8_NORM
- // - *_TYPELESS formats
- // - DXGI_FORMAT_D32_FLOAT_S8X24_UINT or DXGI_FORMAT_D32_FLOAT
-
- D3D11ES3FormatMap map;
-
- // | GL internal format | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format
- InsertD3D11_FL9_3_FormatInfo(&map, GL_ALPHA, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN);
- InsertD3D11_FL9_3_FormatInfo(&map, GL_ALPHA8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN);
- InsertD3D11_FL9_3_FormatInfo(&map, GL_DEPTH_COMPONENT16, DXGI_FORMAT_D16_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D16_UNORM);
- InsertD3D11_FL9_3_FormatInfo(&map, GL_DEPTH_COMPONENT24, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT);
- InsertD3D11_FL9_3_FormatInfo(&map, GL_DEPTH_COMPONENT32F, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
- InsertD3D11_FL9_3_FormatInfo(&map, GL_DEPTH24_STENCIL8, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT);
- InsertD3D11_FL9_3_FormatInfo(&map, GL_DEPTH32F_STENCIL8, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
- InsertD3D11_FL9_3_FormatInfo(&map, GL_STENCIL_INDEX8, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT);
-
- return map;
-}
-
-static D3D11ES3FormatMap BuildD3D11FormatMap()
-{
- D3D11ES3FormatMap map;
-
- // | GL internal format | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format |
- InsertD3D11FormatInfo(&map, GL_NONE, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_R8, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_R8_SNORM, DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RG8, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RG8_SNORM, DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGB8, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGB8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGB565, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGBA4, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGB5_A1, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGBA8, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGBA8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGB10_A2, DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGB10_A2UI, DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_SRGB8, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_SRGB8_ALPHA8, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_R16F, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RG16F, DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGB16F, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGBA16F, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_R32F, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RG32F, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGB32F, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGBA32F, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_R11F_G11F_B10F, DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGB9_E5, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_R8I, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_R8UI, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_R16I, DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_SINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_R16UI, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_R32I, DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_SINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_R32UI, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RG8I, DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RG8UI, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RG16I, DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RG16UI, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RG32I, DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RG32UI, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGB8I, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGB8UI, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGB16I, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGB16UI, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGB32I, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGB32UI, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGBA8I, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGBA8UI, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGBA16I, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGBA16UI, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGBA32I, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGBA32UI, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_UNKNOWN);
-
- // Unsized formats, TODO: Are types of float and half float allowed for the unsized types? Would it change the DXGI format?
- InsertD3D11FormatInfo(&map, GL_ALPHA, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_LUMINANCE, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_LUMINANCE_ALPHA, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGB, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_RGBA, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_BGRA_EXT, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN);
-
- // From GL_EXT_texture_storage
- // | GL internal format | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format |
- InsertD3D11FormatInfo(&map, GL_ALPHA8_EXT, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN );
- InsertD3D11FormatInfo(&map, GL_LUMINANCE8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN );
- InsertD3D11FormatInfo(&map, GL_ALPHA32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN );
- InsertD3D11FormatInfo(&map, GL_LUMINANCE32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN );
- InsertD3D11FormatInfo(&map, GL_ALPHA16F_EXT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN );
- InsertD3D11FormatInfo(&map, GL_LUMINANCE16F_EXT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN );
- InsertD3D11FormatInfo(&map, GL_LUMINANCE8_ALPHA8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN );
- InsertD3D11FormatInfo(&map, GL_LUMINANCE_ALPHA32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN );
- InsertD3D11FormatInfo(&map, GL_LUMINANCE_ALPHA16F_EXT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN );
- InsertD3D11FormatInfo(&map, GL_BGRA8_EXT, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN );
- InsertD3D11FormatInfo(&map, GL_BGRA4_ANGLEX, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN );
- InsertD3D11FormatInfo(&map, GL_BGR5_A1_ANGLEX, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN );
-
- // Depth stencil formats
- InsertD3D11FormatInfo(&map, GL_DEPTH_COMPONENT16, DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D16_UNORM );
- InsertD3D11FormatInfo(&map, GL_DEPTH_COMPONENT24, DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT );
- InsertD3D11FormatInfo(&map, GL_DEPTH_COMPONENT32F, DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D32_FLOAT );
- InsertD3D11FormatInfo(&map, GL_DEPTH24_STENCIL8, DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT );
- InsertD3D11FormatInfo(&map, GL_DEPTH32F_STENCIL8, DXGI_FORMAT_R32G8X24_TYPELESS, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D32_FLOAT_S8X24_UINT);
- InsertD3D11FormatInfo(&map, GL_STENCIL_INDEX8, DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_X24_TYPELESS_G8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT );
-
- // From GL_ANGLE_depth_texture
- // Since D3D11 doesn't have a D32_UNORM format, use D24S8 which has comparable precision and matches the ES3 format.
- InsertD3D11FormatInfo(&map, GL_DEPTH_COMPONENT32_OES, DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT);
-
- // Compressed formats, From ES 3.0.1 spec, table 3.16
- // | GL internal format | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format |
- InsertD3D11FormatInfo(&map, GL_COMPRESSED_R11_EAC, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_COMPRESSED_SIGNED_R11_EAC, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_COMPRESSED_RG11_EAC, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_COMPRESSED_SIGNED_RG11_EAC, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGB8_ETC2, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_COMPRESSED_SRGB8_ETC2, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGBA8_ETC2_EAC, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
-
- // From GL_EXT_texture_compression_dxt1
- InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
- InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
-
- // From GL_ANGLE_texture_compression_dxt3
- InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
-
- // From GL_ANGLE_texture_compression_dxt5
- InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
-
- return map;
-}
-
-const TextureFormat &GetTextureFormatInfo(GLenum internalFormat, D3D_FEATURE_LEVEL featureLevel)
-{
- static const D3D11ES3FormatMap formatMap = BuildD3D11FormatMap();
- static const D3D11ES3FormatMap formatMapFL9_3Override = BuildD3D11_FL9_3FormatOverrideMap();
-
- if (featureLevel == D3D_FEATURE_LEVEL_9_3)
- {
- // First see if the internalFormat has a special map for FL9_3
- D3D11ES3FormatMap::const_iterator fl9_3Iter = formatMapFL9_3Override.find(internalFormat);
- if (fl9_3Iter != formatMapFL9_3Override.end())
- {
- return fl9_3Iter->second;
- }
- }
-
- D3D11ES3FormatMap::const_iterator iter = formatMap.find(internalFormat);
- if (iter != formatMap.end())
- {
- return iter->second;
- }
- else
- {
- static const TextureFormat defaultInfo;
- return defaultInfo;
- }
-}
-
-typedef std::map<gl::VertexFormat, VertexFormat> D3D11VertexFormatInfoMap;
-typedef std::pair<gl::VertexFormat, VertexFormat> D3D11VertexFormatPair;
+typedef std::map<gl::VertexFormatType, VertexFormat> D3D11VertexFormatInfoMap;
+typedef std::pair<gl::VertexFormatType, VertexFormat> D3D11VertexFormatPair;
VertexFormat::VertexFormat()
: conversionType(VERTEX_CONVERT_NONE),
@@ -1051,30 +476,31 @@ VertexFormat::VertexFormat()
{
}
-static void AddVertexFormatInfo(D3D11VertexFormatInfoMap *map, GLenum inputType, GLboolean normalized, GLuint componentCount,
- VertexConversionType conversionType, DXGI_FORMAT nativeFormat, VertexCopyFunction copyFunction)
+VertexFormat::VertexFormat(VertexConversionType conversionTypeIn,
+ DXGI_FORMAT nativeFormatIn,
+ VertexCopyFunction copyFunctionIn)
+ : conversionType(conversionTypeIn),
+ nativeFormat(nativeFormatIn),
+ copyFunction(copyFunctionIn)
{
- gl::VertexFormat inputFormat(inputType, normalized, componentCount, false);
-
- VertexFormat info;
- info.conversionType = conversionType;
- info.nativeFormat = nativeFormat;
- info.copyFunction = copyFunction;
-
- map->insert(D3D11VertexFormatPair(inputFormat, info));
}
-static void AddIntegerVertexFormatInfo(D3D11VertexFormatInfoMap *map, GLenum inputType, GLuint componentCount,
- VertexConversionType conversionType, DXGI_FORMAT nativeFormat, VertexCopyFunction copyFunction)
+static void AddVertexFormatInfo(D3D11VertexFormatInfoMap *map,
+ GLenum inputType,
+ GLboolean normalized,
+ GLuint componentCount,
+ VertexConversionType conversionType,
+ DXGI_FORMAT nativeFormat,
+ VertexCopyFunction copyFunction)
{
- gl::VertexFormat inputFormat(inputType, GL_FALSE, componentCount, true);
+ gl::VertexFormatType formatType = gl::GetVertexFormatType(inputType, normalized, componentCount, false);
VertexFormat info;
info.conversionType = conversionType;
info.nativeFormat = nativeFormat;
info.copyFunction = copyFunction;
- map->insert(D3D11VertexFormatPair(inputFormat, info));
+ map->insert(D3D11VertexFormatPair(formatType, info));
}
static D3D11VertexFormatInfoMap BuildD3D11_FL9_3VertexFormatInfoOverrideMap()
@@ -1139,187 +565,536 @@ static D3D11VertexFormatInfoMap BuildD3D11_FL9_3VertexFormatInfoOverrideMap()
return map;
}
-static D3D11VertexFormatInfoMap BuildD3D11VertexFormatInfoMap()
+const VertexFormat &GetVertexFormatInfo(gl::VertexFormatType vertexFormatType, D3D_FEATURE_LEVEL featureLevel)
{
- D3D11VertexFormatInfoMap map;
+ if (featureLevel == D3D_FEATURE_LEVEL_9_3)
+ {
+ static const D3D11VertexFormatInfoMap vertexFormatMapFL9_3Override =
+ BuildD3D11_FL9_3VertexFormatInfoOverrideMap();
- // TODO: column legend
+ // First see if the format has a special mapping for FL9_3
+ auto iter = vertexFormatMapFL9_3Override.find(vertexFormatType);
+ if (iter != vertexFormatMapFL9_3Override.end())
+ {
+ return iter->second;
+ }
+ }
- //
- // Float formats
- //
+ switch (vertexFormatType)
+ {
+ //
+ // Float formats
+ //
- // GL_BYTE -- un-normalized
- AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_SINT, &CopyNativeVertexData<GLbyte, 1, 1, 0>);
- AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_SINT, &CopyNativeVertexData<GLbyte, 2, 2, 0>);
- AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<GLbyte, 3, 4, 1>);
- AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<GLbyte, 4, 4, 0>);
+ // GL_BYTE -- un-normalized
+ case gl::VERTEX_FORMAT_SBYTE1:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_SINT, &CopyNativeVertexData<GLbyte, 1, 1, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SBYTE2:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_SINT, &CopyNativeVertexData<GLbyte, 2, 2, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SBYTE3:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<GLbyte, 3, 4, 1>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SBYTE4:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<GLbyte, 4, 4, 0>);
+ return info;
+ }
- // GL_BYTE -- normalized
- AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SNORM, &CopyNativeVertexData<GLbyte, 1, 1, 0>);
- AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SNORM, &CopyNativeVertexData<GLbyte, 2, 2, 0>);
- AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SNORM, &CopyNativeVertexData<GLbyte, 3, 4, INT8_MAX>);
- AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SNORM, &CopyNativeVertexData<GLbyte, 4, 4, 0>);
+ // GL_BYTE -- normalized
+ case gl::VERTEX_FORMAT_SBYTE1_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SNORM, &CopyNativeVertexData<GLbyte, 1, 1, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SBYTE2_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SNORM, &CopyNativeVertexData<GLbyte, 2, 2, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SBYTE3_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SNORM, &CopyNativeVertexData<GLbyte, 3, 4, INT8_MAX>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SBYTE4_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SNORM, &CopyNativeVertexData<GLbyte, 4, 4, 0>);
+ return info;
+ }
- // GL_UNSIGNED_BYTE -- un-normalized
- AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_UINT, &CopyNativeVertexData<GLubyte, 1, 1, 0>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_UINT, &CopyNativeVertexData<GLubyte, 2, 2, 0>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 3, 4, 1>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 4, 4, 0>);
+ // GL_UNSIGNED_BYTE -- un-normalized
+ case gl::VERTEX_FORMAT_UBYTE1:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_UINT, &CopyNativeVertexData<GLubyte, 1, 1, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_UBYTE2:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_UINT, &CopyNativeVertexData<GLubyte, 2, 2, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_UBYTE3:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 3, 4, 1>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_UBYTE4:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 4, 4, 0>);
+ return info;
+ }
- // GL_UNSIGNED_BYTE -- normalized
- AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UNORM, &CopyNativeVertexData<GLubyte, 1, 1, 0>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UNORM, &CopyNativeVertexData<GLubyte, 2, 2, 0>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM, &CopyNativeVertexData<GLubyte, 3, 4, UINT8_MAX>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UNORM, &CopyNativeVertexData<GLubyte, 4, 4, 0>);
+ // GL_UNSIGNED_BYTE -- normalized
+ case gl::VERTEX_FORMAT_UBYTE1_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UNORM, &CopyNativeVertexData<GLubyte, 1, 1, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_UBYTE2_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UNORM, &CopyNativeVertexData<GLubyte, 2, 2, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_UBYTE3_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM, &CopyNativeVertexData<GLubyte, 3, 4, UINT8_MAX>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_UBYTE4_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UNORM, &CopyNativeVertexData<GLubyte, 4, 4, 0>);
+ return info;
+ }
- // GL_SHORT -- un-normalized
- AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_SINT, &CopyNativeVertexData<GLshort, 1, 1, 0>);
- AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_SINT, &CopyNativeVertexData<GLshort, 2, 2, 0>);
- AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 3, 4, 1>);
- AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 4, 4, 0>);
+ // GL_SHORT -- un-normalized
+ case gl::VERTEX_FORMAT_SSHORT1:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_SINT, &CopyNativeVertexData<GLshort, 1, 1, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SSHORT2:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_SINT, &CopyNativeVertexData<GLshort, 2, 2, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SSHORT3:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 3, 4, 1>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SSHORT4:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 4, 4, 0>);
+ return info;
+ }
- // GL_SHORT -- normalized
- AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SNORM, &CopyNativeVertexData<GLshort, 1, 1, 0>);
- AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SNORM, &CopyNativeVertexData<GLshort, 2, 2, 0>);
- AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM, &CopyNativeVertexData<GLshort, 3, 4, INT16_MAX>);
- AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SNORM, &CopyNativeVertexData<GLshort, 4, 4, 0>);
+ // GL_SHORT -- normalized
+ case gl::VERTEX_FORMAT_SSHORT1_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SNORM, &CopyNativeVertexData<GLshort, 1, 1, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SSHORT2_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SNORM, &CopyNativeVertexData<GLshort, 2, 2, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SSHORT3_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM, &CopyNativeVertexData<GLshort, 3, 4, INT16_MAX>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SSHORT4_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SNORM, &CopyNativeVertexData<GLshort, 4, 4, 0>);
+ return info;
+ }
- // GL_UNSIGNED_SHORT -- un-normalized
- AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_UINT, &CopyNativeVertexData<GLushort, 1, 1, 0>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_UINT, &CopyNativeVertexData<GLushort, 2, 2, 0>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 3, 4, 1>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 4, 4, 0>);
+ // GL_UNSIGNED_SHORT -- un-normalized
+ case gl::VERTEX_FORMAT_USHORT1:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_UINT, &CopyNativeVertexData<GLushort, 1, 1, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_USHORT2:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_UINT, &CopyNativeVertexData<GLushort, 2, 2, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_USHORT3:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 3, 4, 1>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_USHORT4:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 4, 4, 0>);
+ return info;
+ }
- // GL_UNSIGNED_SHORT -- normalized
- AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UNORM, &CopyNativeVertexData<GLushort, 1, 1, 0>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UNORM, &CopyNativeVertexData<GLushort, 2, 2, 0>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UNORM, &CopyNativeVertexData<GLushort, 3, 4, UINT16_MAX>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UNORM, &CopyNativeVertexData<GLushort, 4, 4, 0>);
-
- // GL_INT -- un-normalized
- AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData<GLint, 1, 1, 0>);
- AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData<GLint, 2, 2, 0>);
- AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 3, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData<GLint, 3, 3, 0>);
- AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData<GLint, 4, 4, 0>);
-
- // GL_INT -- normalized
- AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, &CopyTo32FVertexData<GLint, 1, 1, true>);
- AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData<GLint, 2, 2, true>);
- AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &CopyTo32FVertexData<GLint, 3, 3, true>);
- AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData<GLint, 4, 4, true>);
-
- // GL_UNSIGNED_INT -- un-normalized
- AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_UINT, &CopyNativeVertexData<GLuint, 1, 1, 0>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_UINT, &CopyNativeVertexData<GLuint, 2, 2, 0>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 3, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_UINT, &CopyNativeVertexData<GLuint, 3, 3, 0>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_UINT, &CopyNativeVertexData<GLuint, 4, 4, 0>);
-
- // GL_UNSIGNED_INT -- normalized
- AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, &CopyTo32FVertexData<GLuint, 1, 1, true>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData<GLuint, 2, 2, true>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &CopyTo32FVertexData<GLuint, 3, 3, true>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData<GLuint, 4, 4, true>);
+ // GL_UNSIGNED_SHORT -- normalized
+ case gl::VERTEX_FORMAT_USHORT1_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UNORM, &CopyNativeVertexData<GLushort, 1, 1, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_USHORT2_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UNORM, &CopyNativeVertexData<GLushort, 2, 2, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_USHORT3_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UNORM, &CopyNativeVertexData<GLushort, 3, 4, UINT16_MAX>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_USHORT4_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UNORM, &CopyNativeVertexData<GLushort, 4, 4, 0>);
+ return info;
+ }
- // GL_FIXED
- AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, &Copy32FixedTo32FVertexData<1, 1>);
- AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &Copy32FixedTo32FVertexData<2, 2>);
- AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &Copy32FixedTo32FVertexData<3, 3>);
- AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &Copy32FixedTo32FVertexData<4, 4>);
+ // GL_INT -- un-normalized
+ case gl::VERTEX_FORMAT_SINT1:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData<GLint, 1, 1, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SINT2:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData<GLint, 2, 2, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SINT3:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData<GLint, 3, 3, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SINT4:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData<GLint, 4, 4, 0>);
+ return info;
+ }
- // GL_HALF_FLOAT
- AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_FLOAT, &CopyNativeVertexData<GLhalf, 1, 1, 0>);
- AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_FLOAT, &CopyNativeVertexData<GLhalf, 2, 2, 0>);
- AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_FLOAT, &CopyNativeVertexData<GLhalf, 3, 4, gl::Float16One>);
- AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_FLOAT, &CopyNativeVertexData<GLhalf, 4, 4, 0>);
+ // GL_INT -- normalized
+ case gl::VERTEX_FORMAT_SINT1_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, &CopyTo32FVertexData<GLint, 1, 1, true>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SINT2_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData<GLint, 2, 2, true>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SINT3_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &CopyTo32FVertexData<GLint, 3, 3, true>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SINT4_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData<GLint, 4, 4, true>);
+ return info;
+ }
- // GL_FLOAT
- AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, &CopyNativeVertexData<GLfloat, 1, 1, 0>);
- AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, &CopyNativeVertexData<GLfloat, 2, 2, 0>);
- AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_FLOAT, &CopyNativeVertexData<GLfloat, 3, 3, 0>);
- AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyNativeVertexData<GLfloat, 4, 4, 0>);
-
- // GL_INT_2_10_10_10_REV
- AddVertexFormatInfo(&map, GL_INT_2_10_10_10_REV, GL_FALSE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyXYZ10W2ToXYZW32FVertexData<true, false, true>);
- AddVertexFormatInfo(&map, GL_INT_2_10_10_10_REV, GL_TRUE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyXYZ10W2ToXYZW32FVertexData<true, true, true>);
-
- // GL_UNSIGNED_INT_2_10_10_10_REV
- AddVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyXYZ10W2ToXYZW32FVertexData<false, false, true>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UNORM, &CopyNativeVertexData<GLuint, 1, 1, 0>);
-
- //
- // Integer Formats
- //
-
- // GL_BYTE
- AddIntegerVertexFormatInfo(&map, GL_BYTE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SINT, &CopyNativeVertexData<GLbyte, 1, 1, 0>);
- AddIntegerVertexFormatInfo(&map, GL_BYTE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SINT, &CopyNativeVertexData<GLbyte, 2, 2, 0>);
- AddIntegerVertexFormatInfo(&map, GL_BYTE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<GLbyte, 3, 4, 1>);
- AddIntegerVertexFormatInfo(&map, GL_BYTE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<GLbyte, 4, 4, 0>);
-
- // GL_UNSIGNED_BYTE
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UINT, &CopyNativeVertexData<GLubyte, 1, 1, 0>);
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UINT, &CopyNativeVertexData<GLubyte, 2, 2, 0>);
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 3, 4, 1>);
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 4, 4, 0>);
-
- // GL_SHORT
- AddIntegerVertexFormatInfo(&map, GL_SHORT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SINT, &CopyNativeVertexData<GLshort, 1, 1, 0>);
- AddIntegerVertexFormatInfo(&map, GL_SHORT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SINT, &CopyNativeVertexData<GLshort, 2, 2, 0>);
- AddIntegerVertexFormatInfo(&map, GL_SHORT, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 3, 4, 1>);
- AddIntegerVertexFormatInfo(&map, GL_SHORT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 4, 4, 0>);
-
- // GL_UNSIGNED_SHORT
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UINT, &CopyNativeVertexData<GLushort, 1, 1, 0>);
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UINT, &CopyNativeVertexData<GLushort, 2, 2, 0>);
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 3, 4, 1>);
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 4, 4, 0>);
-
- // GL_INT
- AddIntegerVertexFormatInfo(&map, GL_INT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData<GLint, 1, 1, 0>);
- AddIntegerVertexFormatInfo(&map, GL_INT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData<GLint, 2, 2, 0>);
- AddIntegerVertexFormatInfo(&map, GL_INT, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData<GLint, 3, 3, 0>);
- AddIntegerVertexFormatInfo(&map, GL_INT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData<GLint, 4, 4, 0>);
-
- // GL_UNSIGNED_INT
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData<GLuint, 1, 1, 0>);
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData<GLuint, 2, 2, 0>);
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData<GLuint, 3, 3, 0>);
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData<GLuint, 4, 4, 0>);
-
- // GL_INT_2_10_10_10_REV
- AddIntegerVertexFormatInfo(&map, GL_INT_2_10_10_10_REV, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyXYZ10W2ToXYZW32FVertexData<true, true, false>);
-
- // GL_UNSIGNED_INT_2_10_10_10_REV
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UINT, &CopyNativeVertexData<GLuint, 1, 1, 0>);
+ // GL_UNSIGNED_INT -- un-normalized
+ case gl::VERTEX_FORMAT_UINT1:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_UINT, &CopyNativeVertexData<GLuint, 1, 1, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_UINT2:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_UINT, &CopyNativeVertexData<GLuint, 2, 2, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_UINT3:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_UINT, &CopyNativeVertexData<GLuint, 3, 3, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_UINT4:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_UINT, &CopyNativeVertexData<GLuint, 4, 4, 0>);
+ return info;
+ }
- return map;
-}
+ // GL_UNSIGNED_INT -- normalized
+ case gl::VERTEX_FORMAT_UINT1_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, &CopyTo32FVertexData<GLuint, 1, 1, true>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_UINT2_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData<GLuint, 2, 2, true>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_UINT3_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &CopyTo32FVertexData<GLuint, 3, 3, true>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_UINT4_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData<GLuint, 4, 4, true>);
+ return info;
+ }
-const VertexFormat &GetVertexFormatInfo(const gl::VertexFormat &vertexFormat, D3D_FEATURE_LEVEL featureLevel)
-{
- static const D3D11VertexFormatInfoMap vertexFormatMap = BuildD3D11VertexFormatInfoMap();
- static const D3D11VertexFormatInfoMap vertexFormatMapFL9_3Override = BuildD3D11_FL9_3VertexFormatInfoOverrideMap();
+ // GL_FIXED
+ case gl::VERTEX_FORMAT_FIXED1:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, &Copy32FixedTo32FVertexData<1, 1>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_FIXED2:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &Copy32FixedTo32FVertexData<2, 2>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_FIXED3:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &Copy32FixedTo32FVertexData<3, 3>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_FIXED4:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &Copy32FixedTo32FVertexData<4, 4>);
+ return info;
+ }
- if (featureLevel == D3D_FEATURE_LEVEL_9_3)
- {
- // First see if the format has a special mapping for FL9_3
- D3D11VertexFormatInfoMap::const_iterator iter = vertexFormatMapFL9_3Override.find(vertexFormat);
- if (iter != vertexFormatMapFL9_3Override.end())
+ // GL_HALF_FLOAT
+ case gl::VERTEX_FORMAT_HALF1:
{
- return iter->second;
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_FLOAT, &CopyNativeVertexData<GLhalf, 1, 1, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_HALF2:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_FLOAT, &CopyNativeVertexData<GLhalf, 2, 2, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_HALF3:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_FLOAT, &CopyNativeVertexData<GLhalf, 3, 4, gl::Float16One>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_HALF4:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_FLOAT, &CopyNativeVertexData<GLhalf, 4, 4, 0>);
+ return info;
}
- }
- D3D11VertexFormatInfoMap::const_iterator iter = vertexFormatMap.find(vertexFormat);
- if (iter != vertexFormatMap.end())
- {
- return iter->second;
- }
- else
- {
- static const VertexFormat defaultInfo;
- return defaultInfo;
+ // GL_FLOAT
+ case gl::VERTEX_FORMAT_FLOAT1:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, &CopyNativeVertexData<GLfloat, 1, 1, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_FLOAT2:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, &CopyNativeVertexData<GLfloat, 2, 2, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_FLOAT3:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_FLOAT, &CopyNativeVertexData<GLfloat, 3, 3, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_FLOAT4:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyNativeVertexData<GLfloat, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_INT_2_10_10_10_REV
+ case gl::VERTEX_FORMAT_SINT210:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyXYZ10W2ToXYZW32FVertexData<true, false, true>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SINT210_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyXYZ10W2ToXYZW32FVertexData<true, true, true>);
+ return info;
+ }
+
+ // GL_UNSIGNED_INT_2_10_10_10_REV
+ case gl::VERTEX_FORMAT_UINT210:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyXYZ10W2ToXYZW32FVertexData<false, false, true>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_UINT210_NORM:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UNORM, &CopyNativeVertexData<GLuint, 1, 1, 0>);
+ return info;
+ }
+
+ //
+ // Integer Formats
+ //
+
+ // GL_BYTE
+ case gl::VERTEX_FORMAT_SBYTE1_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SINT, &CopyNativeVertexData<GLbyte, 1, 1, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SBYTE2_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SINT, &CopyNativeVertexData<GLbyte, 2, 2, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SBYTE3_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<GLbyte, 3, 4, 1>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SBYTE4_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<GLbyte, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_UNSIGNED_BYTE
+ case gl::VERTEX_FORMAT_UBYTE1_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UINT, &CopyNativeVertexData<GLubyte, 1, 1, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_UBYTE2_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UINT, &CopyNativeVertexData<GLubyte, 2, 2, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_UBYTE3_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 3, 4, 1>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_UBYTE4_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_SHORT
+ case gl::VERTEX_FORMAT_SSHORT1_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SINT, &CopyNativeVertexData<GLshort, 1, 1, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SSHORT2_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SINT, &CopyNativeVertexData<GLshort, 2, 2, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SSHORT3_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 3, 4, 1>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SSHORT4_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_UNSIGNED_SHORT
+ case gl::VERTEX_FORMAT_USHORT1_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UINT, &CopyNativeVertexData<GLushort, 1, 1, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_USHORT2_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UINT, &CopyNativeVertexData<GLushort, 2, 2, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_USHORT3_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 3, 4, 1>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_USHORT4_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_INT
+ case gl::VERTEX_FORMAT_SINT1_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData<GLint, 1, 1, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SINT2_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData<GLint, 2, 2, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SINT3_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData<GLint, 3, 3, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_SINT4_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData<GLint, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_UNSIGNED_INT
+ case gl::VERTEX_FORMAT_UINT1_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData<GLuint, 1, 1, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_UINT2_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData<GLuint, 2, 2, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_UINT3_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData<GLuint, 3, 3, 0>);
+ return info;
+ }
+ case gl::VERTEX_FORMAT_UINT4_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData<GLuint, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_INT_2_10_10_10_REV
+ case gl::VERTEX_FORMAT_SINT210_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyXYZ10W2ToXYZW32FVertexData<true, true, false>);
+ return info;
+ }
+
+ // GL_UNSIGNED_INT_2_10_10_10_REV
+ case gl::VERTEX_FORMAT_UINT210_INT:
+ {
+ static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UINT, &CopyNativeVertexData<GLuint, 1, 1, 0>);
+ return info;
+ }
+
+ default:
+ {
+ static const VertexFormat info;
+ return info;
+ }
}
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.h
index 33fe29dc39..7b97527140 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.h
@@ -10,20 +10,22 @@
#ifndef LIBANGLE_RENDERER_D3D_D3D11_FORMATUTILS11_H_
#define LIBANGLE_RENDERER_D3D_D3D11_FORMATUTILS11_H_
-#include "libANGLE/renderer/d3d/formatutilsD3D.h"
-#include "libANGLE/angletypes.h"
+#include <map>
#include "common/platform.h"
-
-#include <map>
+#include "libANGLE/angletypes.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/formatutilsD3D.h"
namespace rx
{
+struct Renderer11DeviceCaps;
namespace d3d11
{
typedef std::map<std::pair<GLenum, GLenum>, ColorCopyFunction> FastCopyFunctionMap;
+typedef bool (*NativeMipmapGenerationSupportFunction)(D3D_FEATURE_LEVEL);
struct DXGIFormat
{
@@ -51,43 +53,29 @@ struct DXGIFormat
ColorReadFunction colorReadFunction;
FastCopyFunctionMap fastCopyFunctions;
- ColorCopyFunction getFastCopyFunction(GLenum format, GLenum type) const;
-};
-const DXGIFormat &GetDXGIFormatInfo(DXGI_FORMAT format);
-
-struct TextureFormat
-{
- TextureFormat();
- DXGI_FORMAT texFormat;
- DXGI_FORMAT srvFormat;
- DXGI_FORMAT rtvFormat;
- DXGI_FORMAT dsvFormat;
- DXGI_FORMAT renderFormat;
+ NativeMipmapGenerationSupportFunction nativeMipmapSupport;
- DXGI_FORMAT swizzleTexFormat;
- DXGI_FORMAT swizzleSRVFormat;
- DXGI_FORMAT swizzleRTVFormat;
-
- InitializeTextureDataFunction dataInitializerFunction;
-
- typedef std::map<GLenum, LoadImageFunction> LoadFunctionMap;
- LoadFunctionMap loadFunctions;
+ ColorCopyFunction getFastCopyFunction(GLenum format, GLenum type) const;
};
-const TextureFormat &GetTextureFormatInfo(GLenum internalFormat, D3D_FEATURE_LEVEL featureLevel);
+const DXGIFormat &GetDXGIFormatInfo(DXGI_FORMAT format);
struct VertexFormat
{
VertexFormat();
+ VertexFormat(VertexConversionType conversionType,
+ DXGI_FORMAT nativeFormat,
+ VertexCopyFunction copyFunction);
VertexConversionType conversionType;
DXGI_FORMAT nativeFormat;
VertexCopyFunction copyFunction;
};
-const VertexFormat &GetVertexFormatInfo(const gl::VertexFormat &vertexFormat, D3D_FEATURE_LEVEL featureLevel);
+const VertexFormat &GetVertexFormatInfo(gl::VertexFormatType vertexFormatType,
+ D3D_FEATURE_LEVEL featureLevel);
-}
+} // namespace d3d11
-}
+} // namespace rx
#endif // LIBANGLE_RENDERER_D3D_D3D11_FORMATUTILS11_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/gen_load_functions_table.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/gen_load_functions_table.cpp
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/gen_load_functions_table.cpp
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.cpp
new file mode 100644
index 0000000000..adb20a5e60
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.cpp
@@ -0,0 +1,170 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// internal_format_initializer_table:
+// Contains table to go from internal format and dxgi format to initializer function
+// for TextureFormat
+//
+
+#include "libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.h"
+#include "libANGLE/renderer/d3d/loadimage.h"
+
+namespace rx
+{
+
+namespace d3d11
+{
+
+// TODO: This should be generated by a JSON file
+InitializeTextureDataFunction GetInternalFormatInitializer(GLenum internalFormat,
+ DXGI_FORMAT dxgiFormat)
+{
+ switch (internalFormat)
+ {
+ case GL_RGB8:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ {
+ return Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB565:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ {
+ return Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_SRGB8:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ {
+ return Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB16F:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ {
+ return Initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB32F:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ {
+ return Initialize4ComponentData<GLfloat, 0x00000000, 0x00000000, 0x00000000,
+ gl::Float32One>;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB8UI:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UINT:
+ {
+ return Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0x01>;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB8I:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8B8A8_SINT:
+ {
+ return Initialize4ComponentData<GLbyte, 0x00, 0x00, 0x00, 0x01>;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB16UI:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R16G16B16A16_UINT:
+ {
+ return Initialize4ComponentData<GLushort, 0x0000, 0x0000, 0x0000, 0x0001>;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB16I:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R16G16B16A16_SINT:
+ {
+ return Initialize4ComponentData<GLshort, 0x0000, 0x0000, 0x0000, 0x0001>;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB32UI:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R32G32B32A32_UINT:
+ {
+ return Initialize4ComponentData<GLuint, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000001>;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB32I:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R32G32B32A32_SINT:
+ {
+ return Initialize4ComponentData<GLint, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000001>;
+ }
+ default:
+ break;
+ }
+ }
+ default:
+ {
+ return nullptr;
+ }
+ }
+}
+
+} // namespace d3d11
+
+} // namespace rx
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.h
new file mode 100644
index 0000000000..2d538e1d82
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.h
@@ -0,0 +1,31 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// internal_format_initializer_table:
+// Contains table to go from internal format and dxgi format to initializer function
+// for TextureFormat
+//
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_INTERNALFORMATINITIALIZERTABLE_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_INTERNALFORMATINITIALIZERTABLE_H_
+
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+
+#include <map>
+
+namespace rx
+{
+
+namespace d3d11
+{
+
+InitializeTextureDataFunction GetInternalFormatInitializer(GLenum internalFormat,
+ DXGI_FORMAT dxgiFormat);
+
+} // namespace d3d11
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_INTERNALFORMATINITIALIZERTABLE_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_data.json b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_data.json
new file mode 100644
index 0000000000..c85393e06b
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_data.json
@@ -0,0 +1,1116 @@
+{
+ "GL_RG8_SNORM": {
+ "GL_BYTE": [
+ {
+ "loadFunction": "LoadToNative<GLbyte,2>",
+ "dxgiFormat": "DXGI_FORMAT_R8G8_SNORM",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_SRGB8": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadToNative3To4<GLubyte,0xFF>",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RGBA8I": {
+ "GL_BYTE": [
+ {
+ "loadFunction": "LoadToNative<GLbyte,4>",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_SINT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_R8_SNORM": {
+ "GL_BYTE": [
+ {
+ "loadFunction": "LoadToNative<GLbyte,1>",
+ "dxgiFormat": "DXGI_FORMAT_R8_SNORM",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_RGBA8_SNORM": {
+ "GL_BYTE": [
+ {
+ "loadFunction": "LoadToNative<GLbyte,4>",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_SNORM",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_R16I": {
+ "GL_SHORT": [
+ {
+ "loadFunction": "LoadToNative<GLshort,1>",
+ "dxgiFormat": "DXGI_FORMAT_R16_SINT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadETC2SRGBA8ToSRGBA8",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadETC2RGB8A1ToRGBA8",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RGB32UI": {
+ "GL_UNSIGNED_INT": [
+ {
+ "loadFunction": "LoadToNative3To4<GLuint,0x00000001>",
+ "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_UINT",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_ALPHA32F_EXT": {
+ "GL_FLOAT": [
+ {
+ "loadFunction": "LoadA32FToRGBA32F",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_R16UI": {
+ "GL_UNSIGNED_SHORT": [
+ {
+ "loadFunction": "LoadToNative<GLushort,1>",
+ "dxgiFormat": "DXGI_FORMAT_R16_UINT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_RGB9_E5": {
+ "GL_HALF_FLOAT": [
+ {
+ "loadFunction": "LoadRGB16FToRGB9E5",
+ "dxgiFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_UNSIGNED_INT_5_9_9_9_REV": [
+ {
+ "loadFunction": "LoadToNative<GLuint,1>",
+ "dxgiFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP",
+ "requiresConversion": "false"
+ }
+ ],
+ "GL_FLOAT": [
+ {
+ "loadFunction": "LoadRGB32FToRGB9E5",
+ "dxgiFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_HALF_FLOAT_OES": [
+ {
+ "loadFunction": "LoadRGB16FToRGB9E5",
+ "dxgiFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_COMPRESSED_R11_EAC": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadEACR11ToR8",
+ "dxgiFormat": "DXGI_FORMAT_R8_UNORM",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RGBA32UI": {
+ "GL_UNSIGNED_INT": [
+ {
+ "loadFunction": "LoadToNative<GLuint,4>",
+ "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_UINT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_RG8UI": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadToNative<GLubyte,2>",
+ "dxgiFormat": "DXGI_FORMAT_R8G8_UINT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_LUMINANCE32F_EXT": {
+ "GL_FLOAT": [
+ {
+ "loadFunction": "LoadL32FToRGBA32F",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadETC2SRGB8A1ToRGBA8",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_R16F": {
+ "GL_HALF_FLOAT": [
+ {
+ "loadFunction": "LoadToNative<GLhalf,1>",
+ "dxgiFormat": "DXGI_FORMAT_R16_FLOAT",
+ "requiresConversion": "false"
+ }
+ ],
+ "GL_FLOAT": [
+ {
+ "loadFunction": "Load32FTo16F<1>",
+ "dxgiFormat": "DXGI_FORMAT_R16_FLOAT",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_HALF_FLOAT_OES": [
+ {
+ "loadFunction": "LoadToNative<GLhalf,1>",
+ "dxgiFormat": "DXGI_FORMAT_R16_FLOAT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_RGBA8UI": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadToNative<GLubyte,4>",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UINT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_BGRA4_ANGLEX": {
+ "GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT": [
+ {
+ "loadFunction": "LoadRGBA4ToRGBA8",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadToNative<GLubyte,4>",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_RGBA16F": {
+ "GL_HALF_FLOAT": [
+ {
+ "loadFunction": "LoadToNative<GLhalf,4>",
+ "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "requiresConversion": "false"
+ }
+ ],
+ "GL_FLOAT": [
+ {
+ "loadFunction": "Load32FTo16F<4>",
+ "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_HALF_FLOAT_OES": [
+ {
+ "loadFunction": "LoadToNative<GLhalf,4>",
+ "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_LUMINANCE8_EXT": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadL8ToRGBA8",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadCompressedToNative<4,4,16>",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RGB": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "UnreachableLoadFunction",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_UNSIGNED_SHORT_5_6_5": [
+ {
+ "loadFunction": "UnreachableLoadFunction",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RGB5_A1": {
+ "GL_UNSIGNED_INT_2_10_10_10_REV": [
+ {
+ "loadFunction": "LoadRGB10A2ToRGBA8",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadToNative<GLubyte,4>",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "requiresConversion": "false"
+ }
+ ],
+ "GL_UNSIGNED_SHORT_5_5_5_1": [
+ {
+ "loadFunction": "LoadRGB5A1ToRGBA8",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "requiresConversion": "true"
+ },
+ {
+ "loadFunction": "LoadRGB5A1ToA1RGB5",
+ "dxgiFormat": "DXGI_FORMAT_B5G5R5A1_UNORM",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RGB16UI": {
+ "GL_UNSIGNED_SHORT": [
+ {
+ "loadFunction": "LoadToNative3To4<GLushort,0x0001>",
+ "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_UINT",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_BGRA_EXT": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "UnreachableLoadFunction",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_COMPRESSED_RGB8_ETC2": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadETC2RGB8ToRGBA8",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RGBA32F": {
+ "GL_FLOAT": [
+ {
+ "loadFunction": "LoadToNative<GLfloat,4>",
+ "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_RGBA32I": {
+ "GL_INT": [
+ {
+ "loadFunction": "LoadToNative<GLint,4>",
+ "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_SINT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_LUMINANCE8_ALPHA8_EXT": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadLA8ToRGBA8",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RG8": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadToNative<GLubyte,2>",
+ "dxgiFormat": "DXGI_FORMAT_R8G8_UNORM",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_RGB10_A2": {
+ "GL_UNSIGNED_INT_2_10_10_10_REV": [
+ {
+ "loadFunction": "LoadToNative<GLuint,1>",
+ "dxgiFormat": "DXGI_FORMAT_R10G10B10A2_UNORM",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_COMPRESSED_SIGNED_RG11_EAC": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadEACRG11SToRG8",
+ "dxgiFormat": "DXGI_FORMAT_R8G8_SNORM",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_DEPTH_COMPONENT16": {
+ "GL_UNSIGNED_INT": [
+ {
+ "loadFunction": "LoadR32ToR16",
+ "dxgiFormat": "DXGI_FORMAT_R16_TYPELESS",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_UNSIGNED_SHORT": [
+ {
+ "loadFunction": "LoadToNative<GLushort,1>",
+ "dxgiFormat": "DXGI_FORMAT_R16_TYPELESS",
+ "requiresConversion": "false"
+ },
+ {
+ "loadFunction": "LoadToNative<GLushort,1>",
+ "dxgiFormat": "DXGI_FORMAT_D16_UNORM",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_RGB32I": {
+ "GL_INT": [
+ {
+ "loadFunction": "LoadToNative3To4<GLint,0x00000001>",
+ "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_SINT",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_R8": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadToNative<GLubyte,1>",
+ "dxgiFormat": "DXGI_FORMAT_R8_UNORM",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_RGB32F": {
+ "GL_FLOAT": [
+ {
+ "loadFunction": "LoadToNative3To4<GLfloat,gl::Float32One>",
+ "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_R11F_G11F_B10F": {
+ "GL_UNSIGNED_INT_10F_11F_11F_REV": [
+ {
+ "loadFunction": "LoadToNative<GLuint,1>",
+ "dxgiFormat": "DXGI_FORMAT_R11G11B10_FLOAT",
+ "requiresConversion": "false"
+ }
+ ],
+ "GL_HALF_FLOAT": [
+ {
+ "loadFunction": "LoadRGB16FToRG11B10F",
+ "dxgiFormat": "DXGI_FORMAT_R11G11B10_FLOAT",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_FLOAT": [
+ {
+ "loadFunction": "LoadRGB32FToRG11B10F",
+ "dxgiFormat": "DXGI_FORMAT_R11G11B10_FLOAT",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_HALF_FLOAT_OES": [
+ {
+ "loadFunction": "LoadRGB16FToRG11B10F",
+ "dxgiFormat": "DXGI_FORMAT_R11G11B10_FLOAT",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RGB8": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadToNative3To4<GLubyte,0xFF>",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_LUMINANCE_ALPHA": {
+ "GL_HALF_FLOAT": [
+ {
+ "loadFunction": "LoadLA16FToRGBA16F",
+ "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "UnreachableLoadFunction",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_FLOAT": [
+ {
+ "loadFunction": "LoadLA32FToRGBA32F",
+ "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_HALF_FLOAT_OES": [
+ {
+ "loadFunction": "LoadLA16FToRGBA16F",
+ "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RGBA16I": {
+ "GL_SHORT": [
+ {
+ "loadFunction": "LoadToNative<GLshort,4>",
+ "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_SINT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_R8I": {
+ "GL_BYTE": [
+ {
+ "loadFunction": "LoadToNative<GLbyte,1>",
+ "dxgiFormat": "DXGI_FORMAT_R8_SINT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_RGB8_SNORM": {
+ "GL_BYTE": [
+ {
+ "loadFunction": "LoadToNative3To4<GLbyte,0x7F>",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_SNORM",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RG32F": {
+ "GL_FLOAT": [
+ {
+ "loadFunction": "LoadToNative<GLfloat,2>",
+ "dxgiFormat": "DXGI_FORMAT_R32G32_FLOAT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_DEPTH_COMPONENT32F": {
+ "GL_FLOAT": [
+ {
+ "loadFunction": "LoadToNative<GLfloat,1>",
+ "dxgiFormat": "DXGI_FORMAT_R32_TYPELESS",
+ "requiresConversion": "false"
+ },
+ {
+ "loadFunction": "UnimplementedLoadFunction",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RG32I": {
+ "GL_INT": [
+ {
+ "loadFunction": "LoadToNative<GLint,2>",
+ "dxgiFormat": "DXGI_FORMAT_R32G32_SINT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_ALPHA8_EXT": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadToNative<GLubyte,1>",
+ "dxgiFormat": "DXGI_FORMAT_A8_UNORM",
+ "requiresConversion": "false"
+ },
+ {
+ "loadFunction": "LoadA8ToRGBA8",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RG32UI": {
+ "GL_UNSIGNED_INT": [
+ {
+ "loadFunction": "LoadToNative<GLuint,2>",
+ "dxgiFormat": "DXGI_FORMAT_R32G32_UINT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_RGBA16UI": {
+ "GL_UNSIGNED_SHORT": [
+ {
+ "loadFunction": "LoadToNative<GLushort,4>",
+ "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_UINT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_COMPRESSED_RGBA8_ETC2_EAC": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadETC2RGBA8ToRGBA8",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RGB8I": {
+ "GL_BYTE": [
+ {
+ "loadFunction": "LoadToNative3To4<GLbyte,0x01>",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_SINT",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_COMPRESSED_SRGB8_ETC2": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadETC2SRGB8ToRGBA8",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_DEPTH32F_STENCIL8": {
+ "GL_FLOAT_32_UNSIGNED_INT_24_8_REV": [
+ {
+ "loadFunction": "LoadToNative<GLuint,2>",
+ "dxgiFormat": "DXGI_FORMAT_R32G8X24_TYPELESS",
+ "requiresConversion": "false"
+ },
+ {
+ "loadFunction": "UnimplementedLoadFunction",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RG8I": {
+ "GL_BYTE": [
+ {
+ "loadFunction": "LoadToNative<GLbyte,2>",
+ "dxgiFormat": "DXGI_FORMAT_R8G8_SINT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_R32UI": {
+ "GL_UNSIGNED_INT": [
+ {
+ "loadFunction": "LoadToNative<GLuint,1>",
+ "dxgiFormat": "DXGI_FORMAT_R32_UINT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_BGR5_A1_ANGLEX": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadToNative<GLubyte,4>",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "false"
+ }
+ ],
+ "GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT": [
+ {
+ "loadFunction": "LoadRGB5A1ToRGBA8",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_COMPRESSED_RG11_EAC": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadEACRG11ToRG8",
+ "dxgiFormat": "DXGI_FORMAT_R8G8_UNORM",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_SRGB8_ALPHA8": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadToNative<GLubyte,4>",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_LUMINANCE_ALPHA16F_EXT": {
+ "GL_HALF_FLOAT": [
+ {
+ "loadFunction": "LoadLA16FToRGBA16F",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_HALF_FLOAT_OES": [
+ {
+ "loadFunction": "LoadLA16FToRGBA16F",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RGBA": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "UnreachableLoadFunction",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_UNSIGNED_SHORT_4_4_4_4": [
+ {
+ "loadFunction": "UnreachableLoadFunction",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_UNSIGNED_SHORT_5_5_5_1": [
+ {
+ "loadFunction": "UnreachableLoadFunction",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_DEPTH24_STENCIL8": {
+ "GL_UNSIGNED_INT_24_8": [
+ {
+ "loadFunction": "LoadR32ToR24G8",
+ "dxgiFormat": "DXGI_FORMAT_R24G8_TYPELESS",
+ "requiresConversion": "true"
+ },
+ {
+ "loadFunction": "LoadR32ToR24G8",
+ "dxgiFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RGB16I": {
+ "GL_SHORT": [
+ {
+ "loadFunction": "LoadToNative3To4<GLshort,0x0001>",
+ "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_SINT",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_R8UI": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadToNative<GLubyte,1>",
+ "dxgiFormat": "DXGI_FORMAT_R8_UINT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_ALPHA": {
+ "GL_HALF_FLOAT": [
+ {
+ "loadFunction": "LoadA16FToRGBA16F",
+ "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "UnreachableLoadFunction",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_FLOAT": [
+ {
+ "loadFunction": "LoadA32FToRGBA32F",
+ "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_HALF_FLOAT_OES": [
+ {
+ "loadFunction": "LoadA16FToRGBA16F",
+ "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RGB16F": {
+ "GL_HALF_FLOAT": [
+ {
+ "loadFunction": "LoadToNative3To4<GLhalf,gl::Float16One>",
+ "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_FLOAT": [
+ {
+ "loadFunction": "LoadRGB32FToRGBA16F",
+ "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_HALF_FLOAT_OES": [
+ {
+ "loadFunction": "LoadToNative3To4<GLhalf,gl::Float16One>",
+ "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_COMPRESSED_SIGNED_R11_EAC": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadEACR11SToR8",
+ "dxgiFormat": "DXGI_FORMAT_R8_SNORM",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_COMPRESSED_RGB_S3TC_DXT1_EXT": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadCompressedToNative<4,4,8>",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadCompressedToNative<4,4,8>",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_STENCIL_INDEX8": {
+ "DXGI_FORMAT_R24G8_TYPELESS": [
+ {
+ "loadFunction": "UnimplementedLoadFunction",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ],
+ "DXGI_FORMAT_D24_UNORM_S8_UINT": [
+ {
+ "loadFunction": "UnimplementedLoadFunction",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_LUMINANCE_ALPHA32F_EXT": {
+ "GL_FLOAT": [
+ {
+ "loadFunction": "LoadLA32FToRGBA32F",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RGB8UI": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadToNative3To4<GLubyte,0x01>",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UINT",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_DEPTH_COMPONENT24": {
+ "GL_UNSIGNED_INT": [
+ {
+ "loadFunction": "LoadR32ToR24G8",
+ "dxgiFormat": "DXGI_FORMAT_R24G8_TYPELESS",
+ "requiresConversion": "true"
+ },
+ {
+ "loadFunction": "LoadR32ToR24G8",
+ "dxgiFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_R32I": {
+ "GL_INT": [
+ {
+ "loadFunction": "LoadToNative<GLint,1>",
+ "dxgiFormat": "DXGI_FORMAT_R32_SINT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_DEPTH_COMPONENT32_OES": {
+ "GL_UNSIGNED_INT": [
+ {
+ "loadFunction": "LoadR32ToR24G8",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_R32F": {
+ "GL_FLOAT": [
+ {
+ "loadFunction": "LoadToNative<GLfloat,1>",
+ "dxgiFormat": "DXGI_FORMAT_R32_FLOAT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_RG16F": {
+ "GL_HALF_FLOAT": [
+ {
+ "loadFunction": "LoadToNative<GLhalf,2>",
+ "dxgiFormat": "DXGI_FORMAT_R16G16_FLOAT",
+ "requiresConversion": "false"
+ }
+ ],
+ "GL_FLOAT": [
+ {
+ "loadFunction": "Load32FTo16F<2>",
+ "dxgiFormat": "DXGI_FORMAT_R16G16_FLOAT",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_HALF_FLOAT_OES": [
+ {
+ "loadFunction": "LoadToNative<GLhalf,2>",
+ "dxgiFormat": "DXGI_FORMAT_R16G16_FLOAT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_RGB565": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadToNative3To4<GLubyte,0xFF>",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_UNSIGNED_SHORT_5_6_5": [
+ {
+ "loadFunction": "LoadR5G6B5ToRGBA8",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "requiresConversion": "true"
+ },
+ {
+ "loadFunction": "LoadToNative<GLushort,1>",
+ "dxgiFormat": "DXGI_FORMAT_B5G6R5_UNORM",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_LUMINANCE16F_EXT": {
+ "GL_HALF_FLOAT": [
+ {
+ "loadFunction": "LoadL16FToRGBA16F",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_HALF_FLOAT_OES": [
+ {
+ "loadFunction": "LoadL16FToRGBA16F",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RG16UI": {
+ "GL_UNSIGNED_SHORT": [
+ {
+ "loadFunction": "LoadToNative<GLushort,2>",
+ "dxgiFormat": "DXGI_FORMAT_R16G16_UINT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadCompressedToNative<4,4,16>",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RG16I": {
+ "GL_SHORT": [
+ {
+ "loadFunction": "LoadToNative<GLshort,2>",
+ "dxgiFormat": "DXGI_FORMAT_R16G16_SINT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_BGRA8_EXT": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadToNative<GLubyte,4>",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_ALPHA16F_EXT": {
+ "GL_HALF_FLOAT": [
+ {
+ "loadFunction": "LoadA16FToRGBA16F",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_HALF_FLOAT_OES": [
+ {
+ "loadFunction": "LoadA16FToRGBA16F",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RGBA4": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadToNative<GLubyte,4>",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "requiresConversion": "false"
+ }
+ ],
+ "GL_UNSIGNED_SHORT_4_4_4_4": [
+ {
+ "loadFunction": "LoadRGBA4ToRGBA8",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "requiresConversion": "true"
+ },
+ {
+ "loadFunction": "LoadRGBA4ToARGB4",
+ "dxgiFormat": "DXGI_FORMAT_B4G4R4A4_UNORM",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RGBA8": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadToNative<GLubyte,4>",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_LUMINANCE": {
+ "GL_HALF_FLOAT": [
+ {
+ "loadFunction": "LoadL16FToRGBA16F",
+ "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "UnreachableLoadFunction",
+ "dxgiFormat": "DXGI_FORMAT_UNKNOWN",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_FLOAT": [
+ {
+ "loadFunction": "LoadL32FToRGBA32F",
+ "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
+ "requiresConversion": "true"
+ }
+ ],
+ "GL_HALF_FLOAT_OES": [
+ {
+ "loadFunction": "LoadL16FToRGBA16F",
+ "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_RGB10_A2UI": {
+ "GL_UNSIGNED_INT_2_10_10_10_REV": [
+ {
+ "loadFunction": "LoadToNative<GLuint,1>",
+ "dxgiFormat": "DXGI_FORMAT_R10G10B10A2_UINT",
+ "requiresConversion": "false"
+ }
+ ]
+ },
+ "GL_ETC1_RGB8_OES": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadETC1RGB8ToRGBA8",
+ "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "requiresConversion": "true"
+ }
+ ]
+ },
+ "GL_ETC1_RGB8_LOSSY_DECODE_ANGLE": {
+ "GL_UNSIGNED_BYTE": [
+ {
+ "loadFunction": "LoadETC1RGB8ToBC1",
+ "dxgiFormat": "DXGI_FORMAT_BC1_UNORM",
+ "requiresConversion": "true"
+ }
+ ]
+ }
+} \ No newline at end of file
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table.h
new file mode 100644
index 0000000000..b17062f68d
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table.h
@@ -0,0 +1,31 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// load_functions_table:
+// Contains load functions table depending on internal format and dxgi format
+//
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_LOADFUNCTIONSTABLE_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_LOADFUNCTIONSTABLE_H_
+
+#include <map>
+
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
+
+namespace rx
+{
+
+namespace d3d11
+{
+
+const std::map<GLenum, LoadImageFunctionInfo> &GetLoadFunctionsMap(GLenum internalFormat,
+ DXGI_FORMAT dxgiFormat);
+
+} // namespace d3d11
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_LOADFUNCTIONSTABLE_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp
new file mode 100644
index 0000000000..acb48b9573
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp
@@ -0,0 +1,2098 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_load_functions_table.py using data from load_functions_data.json
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// load_functions_table:
+// Contains the GetLoadFunctionsMap for texture_format_util.h
+//
+
+#include "libANGLE/renderer/d3d/d3d11/load_functions_table.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
+#include "libANGLE/renderer/d3d/loadimage.h"
+#include "libANGLE/renderer/d3d/loadimage_etc.h"
+
+namespace rx
+{
+
+namespace d3d11
+{
+
+namespace
+{
+
+// ES3 image loading functions vary based on:
+// - the GL internal format (supplied to glTex*Image*D)
+// - the GL data type given (supplied to glTex*Image*D)
+// - the target DXGI_FORMAT that the image will be loaded into (which is chosen based on the D3D
+// device's capabilities)
+// This map type determines which loading function to use, based on these three parameters.
+// Source formats and types are taken from Tables 3.2 and 3.3 of the ES 3 spec.
+void UnimplementedLoadFunction(size_t width,
+ size_t height,
+ size_t depth,
+ const uint8_t *input,
+ size_t inputRowPitch,
+ size_t inputDepthPitch,
+ uint8_t *output,
+ size_t outputRowPitch,
+ size_t outputDepthPitch)
+{
+ UNIMPLEMENTED();
+}
+
+void UnreachableLoadFunction(size_t width,
+ size_t height,
+ size_t depth,
+ const uint8_t *input,
+ size_t inputRowPitch,
+ size_t inputDepthPitch,
+ uint8_t *output,
+ size_t outputRowPitch,
+ size_t outputDepthPitch)
+{
+ UNREACHABLE();
+}
+
+} // namespace
+
+// TODO we can replace these maps with more generated code
+const std::map<GLenum, LoadImageFunctionInfo> &GetLoadFunctionsMap(GLenum internalFormat,
+ DXGI_FORMAT dxgiFormat)
+{
+ // clang-format off
+ switch (internalFormat)
+ {
+ case GL_ALPHA:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadA16FToRGBA16F, true);
+ loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadA16FToRGBA16F, true);
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadA32FToRGBA32F, true);
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_ALPHA16F_EXT:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadA16FToRGBA16F, true);
+ loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadA16FToRGBA16F, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadA16FToRGBA16F, true);
+ loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadA16FToRGBA16F, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_ALPHA32F_EXT:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadA32FToRGBA32F, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadA32FToRGBA32F, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_ALPHA8_EXT:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_A8_UNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative<GLubyte,1>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadA8ToRGBA8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_BGR5_A1_ANGLEX:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT] = LoadImageFunctionInfo(LoadRGB5A1ToRGBA8, true);
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative<GLubyte,4>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative<GLubyte,4>, true);
+ loadMap[GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT] = LoadImageFunctionInfo(LoadRGB5A1ToRGBA8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_BGRA4_ANGLEX:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT] = LoadImageFunctionInfo(LoadRGBA4ToRGBA8, true);
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative<GLubyte,4>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative<GLubyte,4>, true);
+ loadMap[GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT] = LoadImageFunctionInfo(LoadRGBA4ToRGBA8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_BGRA8_EXT:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative<GLubyte,4>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative<GLubyte,4>, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_BGRA_EXT:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_COMPRESSED_R11_EAC:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8_UNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadEACR11ToR8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_COMPRESSED_RG11_EAC:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8_UNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadEACRG11ToRG8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_COMPRESSED_RGB8_ETC2:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC2RGB8ToRGBA8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC2RGB8A1ToRGBA8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_COMPRESSED_RGBA8_ETC2_EAC:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC2RGBA8ToRGBA8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,8>, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,8>, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,16>, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,16>, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,16>, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,16>, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,8>, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,8>, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_COMPRESSED_SIGNED_R11_EAC:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8_SNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadEACR11SToR8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_COMPRESSED_SIGNED_RG11_EAC:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8_SNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadEACRG11SToRG8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC2SRGBA8ToSRGBA8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_COMPRESSED_SRGB8_ETC2:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC2SRGB8ToRGBA8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC2SRGB8A1ToRGBA8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_DEPTH24_STENCIL8:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_INT_24_8] = LoadImageFunctionInfo(LoadR32ToR24G8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ case DXGI_FORMAT_R24G8_TYPELESS:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_INT_24_8] = LoadImageFunctionInfo(LoadR32ToR24G8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_DEPTH32F_STENCIL8:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R32G8X24_TYPELESS:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_FLOAT_32_UNSIGNED_INT_24_8_REV] = LoadImageFunctionInfo(LoadToNative<GLuint,2>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_FLOAT_32_UNSIGNED_INT_24_8_REV] = LoadImageFunctionInfo(UnimplementedLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_FLOAT_32_UNSIGNED_INT_24_8_REV] = LoadImageFunctionInfo(UnimplementedLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_DEPTH_COMPONENT16:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_D16_UNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_SHORT] = LoadImageFunctionInfo(LoadToNative<GLushort,1>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ case DXGI_FORMAT_R16_TYPELESS:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadR32ToR16, true);
+ loadMap[GL_UNSIGNED_SHORT] = LoadImageFunctionInfo(LoadToNative<GLushort,1>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_DEPTH_COMPONENT24:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadR32ToR24G8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ case DXGI_FORMAT_R24G8_TYPELESS:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadR32ToR24G8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_DEPTH_COMPONENT32F:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R32_TYPELESS:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadToNative<GLfloat,1>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_FLOAT] = LoadImageFunctionInfo(UnimplementedLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_FLOAT] = LoadImageFunctionInfo(UnimplementedLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_DEPTH_COMPONENT32_OES:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadR32ToR24G8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadR32ToR24G8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_BC1_UNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC1RGB8ToBC1, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_ETC1_RGB8_OES:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC1RGB8ToRGBA8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_LUMINANCE:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadL16FToRGBA16F, true);
+ loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadL16FToRGBA16F, true);
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadL32FToRGBA32F, true);
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_LUMINANCE16F_EXT:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadL16FToRGBA16F, true);
+ loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadL16FToRGBA16F, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadL16FToRGBA16F, true);
+ loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadL16FToRGBA16F, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_LUMINANCE32F_EXT:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadL32FToRGBA32F, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadL32FToRGBA32F, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_LUMINANCE8_ALPHA8_EXT:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadLA8ToRGBA8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadLA8ToRGBA8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_LUMINANCE8_EXT:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadL8ToRGBA8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadL8ToRGBA8, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_LUMINANCE_ALPHA:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadLA16FToRGBA16F, true);
+ loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadLA16FToRGBA16F, true);
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadLA32FToRGBA32F, true);
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_LUMINANCE_ALPHA16F_EXT:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadLA16FToRGBA16F, true);
+ loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadLA16FToRGBA16F, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadLA16FToRGBA16F, true);
+ loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadLA16FToRGBA16F, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_LUMINANCE_ALPHA32F_EXT:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadLA32FToRGBA32F, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadLA32FToRGBA32F, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_R11F_G11F_B10F:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R11G11B10_FLOAT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadRGB16FToRG11B10F, true);
+ loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadRGB16FToRG11B10F, true);
+ loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadRGB32FToRG11B10F, true);
+ loadMap[GL_UNSIGNED_INT_10F_11F_11F_REV] = LoadImageFunctionInfo(LoadToNative<GLuint,1>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_R16F:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R16_FLOAT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_FLOAT] = LoadImageFunctionInfo(Load32FTo16F<1>, true);
+ loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadToNative<GLhalf,1>, false);
+ loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadToNative<GLhalf,1>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_R16I:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R16_SINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_SHORT] = LoadImageFunctionInfo(LoadToNative<GLshort,1>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_R16UI:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R16_UINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_SHORT] = LoadImageFunctionInfo(LoadToNative<GLushort,1>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_R32F:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R32_FLOAT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadToNative<GLfloat,1>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_R32I:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R32_SINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_INT] = LoadImageFunctionInfo(LoadToNative<GLint,1>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_R32UI:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R32_UINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadToNative<GLuint,1>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_R8:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8_UNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative<GLubyte,1>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_R8I:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8_SINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative<GLbyte,1>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_R8UI:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8_UINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative<GLubyte,1>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_R8_SNORM:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8_SNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative<GLbyte,1>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RG16F:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R16G16_FLOAT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_FLOAT] = LoadImageFunctionInfo(Load32FTo16F<2>, true);
+ loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadToNative<GLhalf,2>, false);
+ loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadToNative<GLhalf,2>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RG16I:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R16G16_SINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_SHORT] = LoadImageFunctionInfo(LoadToNative<GLshort,2>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RG16UI:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R16G16_UINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_SHORT] = LoadImageFunctionInfo(LoadToNative<GLushort,2>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RG32F:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R32G32_FLOAT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadToNative<GLfloat,2>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RG32I:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R32G32_SINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_INT] = LoadImageFunctionInfo(LoadToNative<GLint,2>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RG32UI:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R32G32_UINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadToNative<GLuint,2>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RG8:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8_UNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative<GLubyte,2>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RG8I:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8_SINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative<GLbyte,2>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RG8UI:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8_UINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative<GLubyte,2>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RG8_SNORM:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8_SNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative<GLbyte,2>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ loadMap[GL_UNSIGNED_SHORT_5_6_5] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ loadMap[GL_UNSIGNED_SHORT_5_6_5] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_RGB10_A2:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_INT_2_10_10_10_REV] = LoadImageFunctionInfo(LoadToNative<GLuint,1>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB10_A2UI:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R10G10B10A2_UINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_INT_2_10_10_10_REV] = LoadImageFunctionInfo(LoadToNative<GLuint,1>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB16F:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadRGB32FToRGBA16F, true);
+ loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadToNative3To4<GLhalf,gl::Float16One>, true);
+ loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadToNative3To4<GLhalf,gl::Float16One>, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB16I:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R16G16B16A16_SINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_SHORT] = LoadImageFunctionInfo(LoadToNative3To4<GLshort,0x0001>, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB16UI:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R16G16B16A16_UINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_SHORT] = LoadImageFunctionInfo(LoadToNative3To4<GLushort,0x0001>, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB32F:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadToNative3To4<GLfloat,gl::Float32One>, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB32I:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R32G32B32A32_SINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_INT] = LoadImageFunctionInfo(LoadToNative3To4<GLint,0x00000001>, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB32UI:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R32G32B32A32_UINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadToNative3To4<GLuint,0x00000001>, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB565:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_B5G6R5_UNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_SHORT_5_6_5] = LoadImageFunctionInfo(LoadToNative<GLushort,1>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_SHORT_5_6_5] = LoadImageFunctionInfo(LoadR5G6B5ToRGBA8, true);
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative3To4<GLubyte,0xFF>, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB5_A1:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_B5G5R5A1_UNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_SHORT_5_5_5_1] = LoadImageFunctionInfo(LoadRGB5A1ToA1RGB5, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_INT_2_10_10_10_REV] = LoadImageFunctionInfo(LoadRGB10A2ToRGBA8, true);
+ loadMap[GL_UNSIGNED_SHORT_5_5_5_1] = LoadImageFunctionInfo(LoadRGB5A1ToRGBA8, true);
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative<GLubyte,4>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB8:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative3To4<GLubyte,0xFF>, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB8I:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8B8A8_SINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative3To4<GLbyte,0x01>, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB8UI:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative3To4<GLubyte,0x01>, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB8_SNORM:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8B8A8_SNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative3To4<GLbyte,0x7F>, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGB9_E5:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadRGB16FToRGB9E5, true);
+ loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadRGB16FToRGB9E5, true);
+ loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadRGB32FToRGB9E5, true);
+ loadMap[GL_UNSIGNED_INT_5_9_9_9_REV] = LoadImageFunctionInfo(LoadToNative<GLuint,1>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGBA:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ loadMap[GL_UNSIGNED_SHORT_4_4_4_4] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ loadMap[GL_UNSIGNED_SHORT_5_5_5_1] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ loadMap[GL_UNSIGNED_SHORT_4_4_4_4] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ loadMap[GL_UNSIGNED_SHORT_5_5_5_1] = LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+ case GL_RGBA16F:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_FLOAT] = LoadImageFunctionInfo(Load32FTo16F<4>, true);
+ loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadToNative<GLhalf,4>, false);
+ loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadToNative<GLhalf,4>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGBA16I:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R16G16B16A16_SINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_SHORT] = LoadImageFunctionInfo(LoadToNative<GLshort,4>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGBA16UI:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R16G16B16A16_UINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_SHORT] = LoadImageFunctionInfo(LoadToNative<GLushort,4>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGBA32F:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadToNative<GLfloat,4>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGBA32I:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R32G32B32A32_SINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_INT] = LoadImageFunctionInfo(LoadToNative<GLint,4>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGBA32UI:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R32G32B32A32_UINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadToNative<GLuint,4>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGBA4:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_B4G4R4A4_UNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_SHORT_4_4_4_4] = LoadImageFunctionInfo(LoadRGBA4ToARGB4, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_SHORT_4_4_4_4] = LoadImageFunctionInfo(LoadRGBA4ToRGBA8, true);
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative<GLubyte,4>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGBA8:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative<GLubyte,4>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGBA8I:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8B8A8_SINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative<GLbyte,4>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGBA8UI:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UINT:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative<GLubyte,4>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_RGBA8_SNORM:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8B8A8_SNORM:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative<GLbyte,4>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_SRGB8:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative3To4<GLubyte,0xFF>, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_SRGB8_ALPHA8:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative<GLubyte,4>, false);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_STENCIL_INDEX8:
+ {
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[DXGI_FORMAT_D24_UNORM_S8_UINT] = LoadImageFunctionInfo(UnimplementedLoadFunction, true);
+ loadMap[DXGI_FORMAT_R24G8_TYPELESS] = LoadImageFunctionInfo(UnimplementedLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ default:
+ {
+ static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {
+ std::map<GLenum, LoadImageFunctionInfo> loadMap;
+ loadMap[DXGI_FORMAT_D24_UNORM_S8_UINT] = LoadImageFunctionInfo(UnimplementedLoadFunction, true);
+ loadMap[DXGI_FORMAT_R24G8_TYPELESS] = LoadImageFunctionInfo(UnimplementedLoadFunction, true);
+ return loadMap;
+ }();
+
+ return loadFunctionsMap;
+ }
+ }
+ }
+
+ default:
+ {
+ static std::map<GLenum, LoadImageFunctionInfo> emptyLoadFunctionsMap;
+ return emptyLoadFunctionsMap;
+ }
+ }
+ // clang-format on
+
+} // GetLoadFunctionsMap
+
+} // namespace d3d11
+
+} // namespace rx
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
index 63085f497f..a1175db9af 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
@@ -8,17 +8,20 @@
// specific to the D3D11 renderer.
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+#include <algorithm>
+
+#include "common/debug.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/renderer/d3d/d3d11/dxgi_support_table.h"
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
#include "libANGLE/renderer/d3d/FramebufferD3D.h"
-#include "libANGLE/renderer/Workarounds.h"
-#include "libANGLE/formatutils.h"
-#include "libANGLE/Program.h"
-#include "libANGLE/Framebuffer.h"
-
-#include "common/debug.h"
-
-#include <algorithm>
+#include "libANGLE/renderer/d3d/WorkaroundsD3D.h"
#ifndef D3D_FL9_1_DEFAULT_MAX_ANISOTROPY
# define D3D_FL9_1_DEFAULT_MAX_ANISOTROPY 2
@@ -300,23 +303,111 @@ D3D11_QUERY ConvertQueryType(GLenum queryType)
case GL_ANY_SAMPLES_PASSED_EXT:
case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: return D3D11_QUERY_OCCLUSION;
case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: return D3D11_QUERY_SO_STATISTICS;
+ case GL_TIME_ELAPSED_EXT:
+ // Two internal queries are also created for begin/end timestamps
+ return D3D11_QUERY_TIMESTAMP_DISJOINT;
default: UNREACHABLE(); return D3D11_QUERY_EVENT;
}
}
-}
-
+} // namespace gl_d3d11
namespace d3d11_gl
{
+namespace
+{
+
+// Helper functor for querying DXGI support. Saves passing the parameters repeatedly.
+class DXGISupportHelper : angle::NonCopyable
+{
+ public:
+ DXGISupportHelper(ID3D11Device *device, D3D_FEATURE_LEVEL featureLevel)
+ : mDevice(device),
+ mFeatureLevel(featureLevel)
+ {
+ }
+
+ bool query(DXGI_FORMAT dxgiFormat, UINT supportMask)
+ {
+ if (dxgiFormat == DXGI_FORMAT_UNKNOWN)
+ return false;
+
+ auto dxgiSupport = d3d11::GetDXGISupport(dxgiFormat, mFeatureLevel);
+
+ UINT supportedBits = dxgiSupport.alwaysSupportedFlags;
+
+ if ((dxgiSupport.optionallySupportedFlags & supportMask) != 0)
+ {
+ UINT formatSupport;
+ if (SUCCEEDED(mDevice->CheckFormatSupport(dxgiFormat, &formatSupport)))
+ {
+ supportedBits |= (formatSupport & supportMask);
+ }
+ else
+ {
+ // TODO(jmadill): find out why we fail this call sometimes in FL9_3
+ // ERR("Error checking format support for format 0x%x", dxgiFormat);
+ }
+ }
+
+ return ((supportedBits & supportMask) == supportMask);
+ }
+
+ private:
+ ID3D11Device *mDevice;
+ D3D_FEATURE_LEVEL mFeatureLevel;
+};
+
+} // anonymous namespace
+
+unsigned int GetReservedVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return 0;
+
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 3; // dx_ViewAdjust, dx_ViewCoords and dx_ViewScale
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+unsigned int GetReservedFragmentUniformVectors(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return 0;
+
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 3;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
GLint GetMaximumClientVersion(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return 3;
@@ -329,52 +420,52 @@ GLint GetMaximumClientVersion(D3D_FEATURE_LEVEL featureLevel)
}
}
-static gl::TextureCaps GenerateTextureFormatCaps(GLint maxClientVersion, GLenum internalFormat, ID3D11Device *device)
+static gl::TextureCaps GenerateTextureFormatCaps(GLint maxClientVersion, GLenum internalFormat, ID3D11Device *device, const Renderer11DeviceCaps &renderer11DeviceCaps)
{
gl::TextureCaps textureCaps;
- const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat, device->GetFeatureLevel());
+ DXGISupportHelper support(device, renderer11DeviceCaps.featureLevel);
+ const d3d11::TextureFormat &formatInfo =
+ d3d11::GetTextureFormatInfo(internalFormat, renderer11DeviceCaps);
+
+ const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
- UINT formatSupport;
- if (SUCCEEDED(device->CheckFormatSupport(formatInfo.texFormat, &formatSupport)))
+ UINT texSupportMask = D3D11_FORMAT_SUPPORT_TEXTURE2D;
+ if (internalFormatInfo.depthBits == 0 && internalFormatInfo.stencilBits == 0)
{
- const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
- if (internalFormatInfo.depthBits > 0 || internalFormatInfo.stencilBits > 0)
+ texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURECUBE;
+ if (maxClientVersion > 2)
{
- textureCaps.texturable = ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0);
- }
- else
- {
- UINT formatSupportMask = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURECUBE;
- if (maxClientVersion > 2)
- {
- formatSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURE3D;
- }
- textureCaps.texturable = ((formatSupport & formatSupportMask) == formatSupportMask);
+ texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURE3D;
}
}
- if (SUCCEEDED(device->CheckFormatSupport(formatInfo.renderFormat, &formatSupport)) &&
- ((formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET) != 0))
+ textureCaps.texturable = support.query(formatInfo.texFormat, texSupportMask);
+ textureCaps.filterable = support.query(formatInfo.srvFormat, D3D11_FORMAT_SUPPORT_SHADER_SAMPLE);
+ textureCaps.renderable = (support.query(formatInfo.rtvFormat, D3D11_FORMAT_SUPPORT_RENDER_TARGET)) ||
+ (support.query(formatInfo.dsvFormat, D3D11_FORMAT_SUPPORT_DEPTH_STENCIL));
+
+ if (support.query(formatInfo.renderFormat, D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET))
{
- for (size_t sampleCount = 1; sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount++)
+ // Assume 1x
+ textureCaps.sampleCounts.insert(1);
+
+ for (unsigned int sampleCount = 2; sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT;
+ sampleCount *= 2)
{
UINT qualityCount = 0;
- if (SUCCEEDED(device->CheckMultisampleQualityLevels(formatInfo.renderFormat, sampleCount, &qualityCount)) &&
- qualityCount > 0)
+ if (SUCCEEDED(device->CheckMultisampleQualityLevels(formatInfo.renderFormat, sampleCount, &qualityCount)))
{
+ // Assume we always support lower sample counts
+ if (qualityCount == 0)
+ {
+ break;
+ }
textureCaps.sampleCounts.insert(sampleCount);
}
}
}
- textureCaps.filterable = SUCCEEDED(device->CheckFormatSupport(formatInfo.srvFormat, &formatSupport)) &&
- ((formatSupport & D3D11_FORMAT_SUPPORT_SHADER_SAMPLE)) != 0;
- textureCaps.renderable = (SUCCEEDED(device->CheckFormatSupport(formatInfo.rtvFormat, &formatSupport)) &&
- ((formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET)) != 0) ||
- (SUCCEEDED(device->CheckFormatSupport(formatInfo.dsvFormat, &formatSupport)) &&
- ((formatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL) != 0));
-
return textureCaps;
}
@@ -382,9 +473,7 @@ static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return true;
@@ -402,9 +491,7 @@ static float GetMaximumAnisotropy(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_MAX_MAXANISOTROPY;
case D3D_FEATURE_LEVEL_10_1:
@@ -424,9 +511,7 @@ static bool GetOcclusionQuerySupport(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return true;
@@ -446,9 +531,7 @@ static bool GetEventQuerySupport(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0:
@@ -466,9 +549,7 @@ static bool GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return true;
@@ -491,9 +572,7 @@ static bool GetFramebufferMultisampleSupport(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return true;
@@ -510,9 +589,7 @@ static bool GetFramebufferBlitSupport(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return true;
@@ -535,9 +612,7 @@ static bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0:
@@ -553,9 +628,7 @@ static bool GetShaderTextureLODSupport(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return true;
@@ -574,9 +647,7 @@ static size_t GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;
case D3D_FEATURE_LEVEL_10_1:
@@ -594,9 +665,7 @@ static size_t GetMaximum2DTextureSize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
case D3D_FEATURE_LEVEL_10_1:
@@ -654,9 +723,7 @@ static size_t GetMaximum3DTextureSize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
case D3D_FEATURE_LEVEL_10_1:
@@ -674,9 +741,7 @@ static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_VIEWPORT_BOUNDS_MAX;
case D3D_FEATURE_LEVEL_10_1:
@@ -700,9 +765,7 @@ static size_t GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return std::numeric_limits<GLint>::max();
@@ -724,9 +787,7 @@ static size_t GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return std::numeric_limits<GLint>::max();
@@ -743,9 +804,7 @@ static size_t GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_STANDARD_VERTEX_ELEMENT_COUNT;
case D3D_FEATURE_LEVEL_10_1: return D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT;
@@ -765,9 +824,7 @@ static size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel)
// TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
case D3D_FEATURE_LEVEL_10_1:
@@ -776,7 +833,8 @@ static size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel)
// From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::VSSetConstantBuffers
case D3D_FEATURE_LEVEL_9_3:
case D3D_FEATURE_LEVEL_9_2:
- case D3D_FEATURE_LEVEL_9_1: return 255;
+ case D3D_FEATURE_LEVEL_9_1:
+ return 255 - d3d11_gl::GetReservedVertexUniformVectors(featureLevel);
default: UNREACHABLE(); return 0;
}
@@ -792,9 +850,7 @@ static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers();
case D3D_FEATURE_LEVEL_10_1:
@@ -822,9 +878,7 @@ static size_t GetReservedVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)
// We must reserve one output vector for dx_Position.
// We also reserve one for gl_Position, which we unconditionally output on Feature Levels 10_0+,
// even if it's unused in the shader (e.g. for transform feedback). TODO: This could be improved.
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return 2;
@@ -846,9 +900,7 @@ static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
case D3D_FEATURE_LEVEL_10_1: return D3D10_1_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
@@ -867,9 +919,7 @@ static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
case D3D_FEATURE_LEVEL_10_1:
@@ -891,9 +941,7 @@ static size_t GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel)
// TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
case D3D_FEATURE_LEVEL_10_1:
@@ -902,7 +950,8 @@ static size_t GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel)
// From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::PSSetConstantBuffers
case D3D_FEATURE_LEVEL_9_3:
case D3D_FEATURE_LEVEL_9_2:
- case D3D_FEATURE_LEVEL_9_1: return 32;
+ case D3D_FEATURE_LEVEL_9_1:
+ return 32 - d3d11_gl::GetReservedFragmentUniformVectors(featureLevel);
default: UNREACHABLE(); return 0;
}
@@ -918,9 +967,7 @@ static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers();
case D3D_FEATURE_LEVEL_10_1:
@@ -939,9 +986,7 @@ static size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
case D3D_FEATURE_LEVEL_10_1:
@@ -960,9 +1005,7 @@ static size_t GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
case D3D_FEATURE_LEVEL_10_1:
@@ -981,9 +1024,7 @@ static int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE;
case D3D_FEATURE_LEVEL_10_1:
@@ -1002,9 +1043,7 @@ static int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE;
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE;
@@ -1027,9 +1066,7 @@ static size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent;
case D3D_FEATURE_LEVEL_10_1:
@@ -1048,9 +1085,7 @@ static size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_SO_BUFFER_SLOT_COUNT;
case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SO_BUFFER_SLOT_COUNT;
@@ -1068,9 +1103,7 @@ static size_t GetMaximumStreamOutputInterleavedComponents(D3D_FEATURE_LEVEL feat
{
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
@@ -1088,9 +1121,7 @@ static size_t GetMaximumStreamOutputSeparateComponents(D3D_FEATURE_LEVEL feature
{
switch (featureLevel)
{
-#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
-#endif
case D3D_FEATURE_LEVEL_11_0: return GetMaximumStreamOutputInterleavedComponents(featureLevel) /
GetMaximumStreamOutputBuffers(featureLevel);
@@ -1107,15 +1138,15 @@ static size_t GetMaximumStreamOutputSeparateComponents(D3D_FEATURE_LEVEL feature
}
}
-void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions)
+void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, const Renderer11DeviceCaps &renderer11DeviceCaps, gl::Caps *caps,
+ gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions, gl::Limitations *limitations)
{
- D3D_FEATURE_LEVEL featureLevel = device->GetFeatureLevel();
-
GLuint maxSamples = 0;
+ D3D_FEATURE_LEVEL featureLevel = renderer11DeviceCaps.featureLevel;
const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
for (gl::FormatSet::const_iterator internalFormat = allFormats.begin(); internalFormat != allFormats.end(); ++internalFormat)
{
- gl::TextureCaps textureCaps = GenerateTextureFormatCaps(GetMaximumClientVersion(featureLevel), *internalFormat, device);
+ gl::TextureCaps textureCaps = GenerateTextureFormatCaps(GetMaximumClientVersion(featureLevel), *internalFormat, device, renderer11DeviceCaps);
textureCapsMap->insert(*internalFormat, textureCaps);
maxSamples = std::max(maxSamples, textureCaps.getMaxSamples());
@@ -1127,11 +1158,12 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, gl::
}
// GL core feature limits
- caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());
- caps->max3DTextureSize = GetMaximum3DTextureSize(featureLevel);
- caps->max2DTextureSize = GetMaximum2DTextureSize(featureLevel);
- caps->maxCubeMapTextureSize = GetMaximumCubeMapTextureSize(featureLevel);
- caps->maxArrayTextureLayers = GetMaximum2DTextureArraySize(featureLevel);
+ // Reserve MAX_UINT for D3D11's primitive restart.
+ caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max() - 1);
+ caps->max3DTextureSize = static_cast<GLuint>(GetMaximum3DTextureSize(featureLevel));
+ caps->max2DTextureSize = static_cast<GLuint>(GetMaximum2DTextureSize(featureLevel));
+ caps->maxCubeMapTextureSize = static_cast<GLuint>(GetMaximumCubeMapTextureSize(featureLevel));
+ caps->maxArrayTextureLayers = static_cast<GLuint>(GetMaximum2DTextureArraySize(featureLevel));
// Unimplemented, set to minimum required
caps->maxLODBias = 2.0f;
@@ -1141,11 +1173,12 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, gl::
// Maximum draw buffers and color attachments are the same, max color attachments could eventually be
// increased to 16
- caps->maxDrawBuffers = GetMaximumSimultaneousRenderTargets(featureLevel);
- caps->maxColorAttachments = GetMaximumSimultaneousRenderTargets(featureLevel);
+ caps->maxDrawBuffers = static_cast<GLuint>(GetMaximumSimultaneousRenderTargets(featureLevel));
+ caps->maxColorAttachments =
+ static_cast<GLuint>(GetMaximumSimultaneousRenderTargets(featureLevel));
// D3D11 has the same limit for viewport width and height
- caps->maxViewportWidth = GetMaximumViewportSize(featureLevel);
+ caps->maxViewportWidth = static_cast<GLuint>(GetMaximumViewportSize(featureLevel));
caps->maxViewportHeight = caps->maxViewportWidth;
// Choose a reasonable maximum, enforced in the shader.
@@ -1157,8 +1190,8 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, gl::
caps->maxAliasedLineWidth = 1.0f;
// Primitive count limits
- caps->maxElementsIndices = GetMaximumDrawIndexedIndexCount(featureLevel);
- caps->maxElementsVertices = GetMaximumDrawVertexCount(featureLevel);
+ caps->maxElementsIndices = static_cast<GLuint>(GetMaximumDrawIndexedIndexCount(featureLevel));
+ caps->maxElementsVertices = static_cast<GLuint>(GetMaximumDrawVertexCount(featureLevel));
// Program and shader binary formats (no supported shader binary formats)
caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE);
@@ -1182,19 +1215,27 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, gl::
caps->maxServerWaitTimeout = 0;
// Vertex shader limits
- caps->maxVertexAttributes = GetMaximumVertexInputSlots(featureLevel);
- caps->maxVertexUniformComponents = GetMaximumVertexUniformVectors(featureLevel) * 4;
- caps->maxVertexUniformVectors = GetMaximumVertexUniformVectors(featureLevel);
- caps->maxVertexUniformBlocks = GetMaximumVertexUniformBlocks(featureLevel);
- caps->maxVertexOutputComponents = GetMaximumVertexOutputVectors(featureLevel) * 4;
- caps->maxVertexTextureImageUnits = GetMaximumVertexTextureUnits(featureLevel);
+ caps->maxVertexAttributes = static_cast<GLuint>(GetMaximumVertexInputSlots(featureLevel));
+ caps->maxVertexUniformComponents =
+ static_cast<GLuint>(GetMaximumVertexUniformVectors(featureLevel)) * 4;
+ caps->maxVertexUniformVectors =
+ static_cast<GLuint>(GetMaximumVertexUniformVectors(featureLevel));
+ caps->maxVertexUniformBlocks = static_cast<GLuint>(GetMaximumVertexUniformBlocks(featureLevel));
+ caps->maxVertexOutputComponents =
+ static_cast<GLuint>(GetMaximumVertexOutputVectors(featureLevel)) * 4;
+ caps->maxVertexTextureImageUnits =
+ static_cast<GLuint>(GetMaximumVertexTextureUnits(featureLevel));
// Fragment shader limits
- caps->maxFragmentUniformComponents = GetMaximumPixelUniformVectors(featureLevel) * 4;
- caps->maxFragmentUniformVectors = GetMaximumPixelUniformVectors(featureLevel);
- caps->maxFragmentUniformBlocks = GetMaximumPixelUniformBlocks(featureLevel);
- caps->maxFragmentInputComponents = GetMaximumPixelInputVectors(featureLevel) * 4;
- caps->maxTextureImageUnits = GetMaximumPixelTextureUnits(featureLevel);
+ caps->maxFragmentUniformComponents =
+ static_cast<GLuint>(GetMaximumPixelUniformVectors(featureLevel)) * 4;
+ caps->maxFragmentUniformVectors =
+ static_cast<GLuint>(GetMaximumPixelUniformVectors(featureLevel));
+ caps->maxFragmentUniformBlocks =
+ static_cast<GLuint>(GetMaximumPixelUniformBlocks(featureLevel));
+ caps->maxFragmentInputComponents =
+ static_cast<GLuint>(GetMaximumPixelInputVectors(featureLevel)) * 4;
+ caps->maxTextureImageUnits = static_cast<GLuint>(GetMaximumPixelTextureUnits(featureLevel));
caps->minProgramTexelOffset = GetMinimumTexelOffset(featureLevel);
caps->maxProgramTexelOffset = GetMaximumTexelOffset(featureLevel);
@@ -1202,45 +1243,36 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, gl::
caps->maxUniformBufferBindings = caps->maxVertexUniformBlocks + caps->maxFragmentUniformBlocks;
caps->maxUniformBlockSize = GetMaximumConstantBufferSize(featureLevel);
- // Setting a large alignment forces uniform buffers to bind with zero offset
- caps->uniformBufferOffsetAlignment = static_cast<GLuint>(std::numeric_limits<GLint>::max());
-#if defined(ANGLE_ENABLE_D3D11_1)
- ID3D11DeviceContext1 *deviceContext1 = d3d11::DynamicCastComObject<ID3D11DeviceContext1>(deviceContext);
-
- if (deviceContext1)
- {
- D3D11_FEATURE_DATA_D3D11_OPTIONS d3d11Options;
- device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &d3d11Options, sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS));
-
- if (d3d11Options.ConstantBufferOffsetting)
- {
- // With DirectX 11.1, constant buffer offset and size must be a multiple of 16 constants of 16 bytes each.
- // https://msdn.microsoft.com/en-us/library/windows/desktop/hh404649%28v=vs.85%29.aspx
- caps->uniformBufferOffsetAlignment = 256;
- }
-
- SafeRelease(deviceContext1);
- }
-#endif
+ // With DirectX 11.1, constant buffer offset and size must be a multiple of 16 constants of 16 bytes each.
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/hh404649%28v=vs.85%29.aspx
+ // With DirectX 11.0, we emulate UBO offsets using copies of ranges of the UBO however
+ // we still keep the same alignment as 11.1 for consistency.
+ caps->uniformBufferOffsetAlignment = 256;
caps->maxCombinedUniformBlocks = caps->maxVertexUniformBlocks + caps->maxFragmentUniformBlocks;
caps->maxCombinedVertexUniformComponents = (static_cast<GLint64>(caps->maxVertexUniformBlocks) * static_cast<GLint64>(caps->maxUniformBlockSize / 4)) +
static_cast<GLint64>(caps->maxVertexUniformComponents);
caps->maxCombinedFragmentUniformComponents = (static_cast<GLint64>(caps->maxFragmentUniformBlocks) * static_cast<GLint64>(caps->maxUniformBlockSize / 4)) +
static_cast<GLint64>(caps->maxFragmentUniformComponents);
- caps->maxVaryingComponents = GetMaximumVertexOutputVectors(featureLevel) * 4;
- caps->maxVaryingVectors = GetMaximumVertexOutputVectors(featureLevel);
+ caps->maxVaryingComponents =
+ static_cast<GLuint>(GetMaximumVertexOutputVectors(featureLevel)) * 4;
+ caps->maxVaryingVectors = static_cast<GLuint>(GetMaximumVertexOutputVectors(featureLevel));
caps->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxTextureImageUnits;
// Transform feedback limits
- caps->maxTransformFeedbackInterleavedComponents = GetMaximumStreamOutputInterleavedComponents(featureLevel);
- caps->maxTransformFeedbackSeparateAttributes = GetMaximumStreamOutputBuffers(featureLevel);
- caps->maxTransformFeedbackSeparateComponents = GetMaximumStreamOutputSeparateComponents(featureLevel);
+ caps->maxTransformFeedbackInterleavedComponents =
+ static_cast<GLuint>(GetMaximumStreamOutputInterleavedComponents(featureLevel));
+ caps->maxTransformFeedbackSeparateAttributes =
+ static_cast<GLuint>(GetMaximumStreamOutputBuffers(featureLevel));
+ caps->maxTransformFeedbackSeparateComponents =
+ static_cast<GLuint>(GetMaximumStreamOutputSeparateComponents(featureLevel));
+
+ // Multisample limits
+ caps->maxSamples = maxSamples;
// GL extension support
extensions->setTextureExtensionSupport(*textureCapsMap);
extensions->elementIndexUint = true;
- extensions->packedDepthStencil = true;
extensions->getProgramBinary = true;
extensions->rgb8rgba8 = true;
extensions->readFormatBGRA = true;
@@ -1255,25 +1287,136 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, gl::
extensions->occlusionQueryBoolean = GetOcclusionQuerySupport(featureLevel);
extensions->fence = GetEventQuerySupport(featureLevel);
extensions->timerQuery = false; // Unimplemented
+ extensions->disjointTimerQuery = true;
+ extensions->queryCounterBitsTimeElapsed = 64;
+ extensions->queryCounterBitsTimestamp =
+ 0; // Timestamps cannot be supported due to D3D11 limitations
extensions->robustness = true;
extensions->blendMinMax = true;
extensions->framebufferBlit = GetFramebufferBlitSupport(featureLevel);
extensions->framebufferMultisample = GetFramebufferMultisampleSupport(featureLevel);
- extensions->maxSamples = maxSamples;
extensions->instancedArrays = GetInstancingSupport(featureLevel);
extensions->packReverseRowOrder = true;
extensions->standardDerivatives = GetDerivativeInstructionSupport(featureLevel);
extensions->shaderTextureLOD = GetShaderTextureLODSupport(featureLevel);
extensions->fragDepth = true;
extensions->textureUsage = true; // This could be false since it has no effect in D3D11
+ extensions->discardFramebuffer = true;
extensions->translatedShaderSource = true;
+ extensions->fboRenderMipmap = false;
+ extensions->debugMarker = true;
+ extensions->eglImage = true;
+ extensions->unpackSubimage = true;
+ extensions->packSubimage = true;
+ extensions->vertexArrayObject = true;
+ extensions->noError = true;
+ extensions->lossyETCDecode = true;
+
+ // D3D11 Feature Level 10_0+ uses SV_IsFrontFace in HLSL to emulate gl_FrontFacing.
+ // D3D11 Feature Level 9_3 doesn't support SV_IsFrontFace, and has no equivalent, so can't support gl_FrontFacing.
+ limitations->noFrontFacingSupport = (renderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3);
+
+ // D3D11 Feature Level 9_3 doesn't support alpha-to-coverage
+ limitations->noSampleAlphaToCoverageSupport = (renderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3);
+
+ // D3D11 Feature Levels 9_3 and below do not support non-constant loop indexing and require
+ // additional
+ // pre-validation of the shader at compile time to produce a better error message.
+ limitations->shadersRequireIndexedLoopValidation =
+ (renderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3);
+
+ // D3D11 has no concept of separate masks and refs for front and back faces in the depth stencil
+ // state.
+ limitations->noSeparateStencilRefsAndMasks = true;
+
+ // D3D11 cannot support constant color and alpha blend funcs together
+ limitations->noSimultaneousConstantColorAndAlphaBlendFunc = true;
+
+#ifdef ANGLE_ENABLE_WINDOWS_STORE
+ // Setting a non-zero divisor on attribute zero doesn't work on certain Windows Phone 8-era devices.
+ // We should prevent developers from doing this on ALL Windows Store devices. This will maintain consistency across all Windows devices.
+ // We allow non-zero divisors on attribute zero if the Client Version >= 3, since devices affected by this issue don't support ES3+.
+ limitations->attributeZeroRequiresZeroDivisorInEXT = true;
+#endif
}
-}
+} // namespace d3d11_gl
namespace d3d11
{
+ANGLED3D11DeviceType GetDeviceType(ID3D11Device *device)
+{
+ // Note that this function returns an ANGLED3D11DeviceType rather than a D3D_DRIVER_TYPE value,
+ // since it is difficult to tell Software and Reference devices apart
+
+ IDXGIDevice *dxgiDevice = nullptr;
+ IDXGIAdapter *dxgiAdapter = nullptr;
+#if defined(ANGLE_ENABLE_D3D11_1)
+ IDXGIAdapter2 *dxgiAdapter2 = nullptr;
+#endif
+
+ ANGLED3D11DeviceType retDeviceType = ANGLE_D3D11_DEVICE_TYPE_UNKNOWN;
+
+ HRESULT hr = device->QueryInterface(__uuidof(IDXGIDevice), (void **)&dxgiDevice);
+ if (SUCCEEDED(hr))
+ {
+ hr = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&dxgiAdapter);
+ if (SUCCEEDED(hr))
+ {
+ std::wstring adapterString;
+#if defined(ANGLE_ENABLE_D3D11_1)
+ HRESULT adapter2hr =
+ dxgiAdapter->QueryInterface(__uuidof(dxgiAdapter2), (void **)&dxgiAdapter2);
+ if (SUCCEEDED(adapter2hr))
+ {
+ // On D3D_FEATURE_LEVEL_9_*, IDXGIAdapter::GetDesc returns "Software Adapter"
+ // for the description string. Try to use IDXGIAdapter2::GetDesc2 to get the
+ // actual hardware values if possible.
+ DXGI_ADAPTER_DESC2 adapterDesc2;
+ dxgiAdapter2->GetDesc2(&adapterDesc2);
+ adapterString = std::wstring(adapterDesc2.Description);
+ }
+ else
+#endif
+ {
+ DXGI_ADAPTER_DESC adapterDesc;
+ dxgiAdapter->GetDesc(&adapterDesc);
+ adapterString = std::wstring(adapterDesc.Description);
+ }
+
+ // Both Reference and Software adapters will be 'Software Adapter'
+ const bool isSoftwareDevice =
+ (adapterString.find(std::wstring(L"Software Adapter")) != std::string::npos);
+ const bool isNullDevice = (adapterString == L"");
+ const bool isWARPDevice =
+ (adapterString.find(std::wstring(L"Basic Render")) != std::string::npos);
+
+ if (isSoftwareDevice || isNullDevice)
+ {
+ ASSERT(!isWARPDevice);
+ retDeviceType = ANGLE_D3D11_DEVICE_TYPE_SOFTWARE_REF_OR_NULL;
+ }
+ else if (isWARPDevice)
+ {
+ retDeviceType = ANGLE_D3D11_DEVICE_TYPE_WARP;
+ }
+ else
+ {
+ retDeviceType = ANGLE_D3D11_DEVICE_TYPE_HARDWARE;
+ }
+ }
+ }
+
+ SafeRelease(dxgiDevice);
+ SafeRelease(dxgiAdapter);
+#if defined(ANGLE_ENABLE_D3D11_1)
+ SafeRelease(dxgiAdapter2);
+#endif
+
+ return retDeviceType;
+}
+
void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset)
{
const DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format);
@@ -1293,11 +1436,16 @@ void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsi
*levelOffset = upsampleCount;
}
-void GenerateInitialTextureData(GLint internalFormat, D3D_FEATURE_LEVEL featureLevel, GLuint width, GLuint height, GLuint depth,
- GLuint mipLevels, std::vector<D3D11_SUBRESOURCE_DATA> *outSubresourceData,
- std::vector< std::vector<BYTE> > *outData)
+void GenerateInitialTextureData(GLint internalFormat,
+ const Renderer11DeviceCaps &renderer11DeviceCaps,
+ GLuint width,
+ GLuint height,
+ GLuint depth,
+ GLuint mipLevels,
+ std::vector<D3D11_SUBRESOURCE_DATA> *outSubresourceData,
+ std::vector<std::vector<BYTE>> *outData)
{
- const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(internalFormat, featureLevel);
+ const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(internalFormat, renderer11DeviceCaps);
ASSERT(d3dFormatInfo.dataInitializerFunction != NULL);
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3dFormatInfo.texFormat);
@@ -1323,6 +1471,11 @@ void GenerateInitialTextureData(GLint internalFormat, D3D_FEATURE_LEVEL featureL
}
}
+UINT GetPrimitiveRestartIndex()
+{
+ return std::numeric_limits<UINT>::max();
+}
+
void SetPositionTexCoordVertex(PositionTexCoordVertex* vertex, float x, float y, float u, float v)
{
vertex->x = x;
@@ -1345,27 +1498,94 @@ void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex* vertex, flo
HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name)
{
#if defined(_DEBUG)
- return resource->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(name), name);
+ UINT existingDataSize = 0;
+ resource->GetPrivateData(WKPDID_D3DDebugObjectName, &existingDataSize, nullptr);
+ // Don't check the HRESULT- if it failed then that probably just means that no private data
+ // exists yet
+
+ if (existingDataSize > 0)
+ {
+ // In some cases, ANGLE will try to apply two names to one object, which causes
+ // a D3D SDK Layers warning. This can occur if, for example, you 'create' two objects
+ // (e.g.Rasterizer States) with identical DESCs on the same device. D3D11 will optimize
+ // these calls and return the same object both times.
+ static const char *multipleNamesUsed = "Multiple names set by ANGLE";
+
+ // Remove the existing name
+ HRESULT hr = resource->SetPrivateData(WKPDID_D3DDebugObjectName, 0, nullptr);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+
+ // Apply the new name
+ return resource->SetPrivateData(WKPDID_D3DDebugObjectName,
+ static_cast<unsigned int>(strlen(multipleNamesUsed)),
+ multipleNamesUsed);
+ }
+ else
+ {
+ return resource->SetPrivateData(WKPDID_D3DDebugObjectName,
+ static_cast<unsigned int>(strlen(name)), name);
+ }
#else
return S_OK;
#endif
}
-gl::Error GetAttachmentRenderTarget(const gl::FramebufferAttachment *attachment, RenderTarget11 **outRT)
+LazyInputLayout::LazyInputLayout(const D3D11_INPUT_ELEMENT_DESC *inputDesc,
+ size_t inputDescLen,
+ const BYTE *byteCode,
+ size_t byteCodeLen,
+ const char *debugName)
+ : mInputDesc(inputDescLen),
+ mByteCodeLen(byteCodeLen),
+ mByteCode(byteCode),
+ mDebugName(debugName)
+{
+ memcpy(&mInputDesc[0], inputDesc, sizeof(D3D11_INPUT_ELEMENT_DESC) * inputDescLen);
+}
+
+ID3D11InputLayout *LazyInputLayout::resolve(ID3D11Device *device)
+{
+ checkAssociatedDevice(device);
+
+ if (mResource == nullptr)
+ {
+ HRESULT result =
+ device->CreateInputLayout(&mInputDesc[0], static_cast<UINT>(mInputDesc.size()),
+ mByteCode, mByteCodeLen, &mResource);
+ ASSERT(SUCCEEDED(result));
+ UNUSED_ASSERTION_VARIABLE(result);
+ d3d11::SetDebugName(mResource, mDebugName);
+ }
+
+ return mResource;
+}
+
+LazyBlendState::LazyBlendState(const D3D11_BLEND_DESC &desc, const char *debugName)
+ : mDesc(desc), mDebugName(debugName)
+{
+}
+
+ID3D11BlendState *LazyBlendState::resolve(ID3D11Device *device)
{
- RenderTargetD3D *renderTarget = NULL;
- gl::Error error = rx::GetAttachmentRenderTarget(attachment, &renderTarget);
- if (error.isError())
+ checkAssociatedDevice(device);
+
+ if (mResource == nullptr)
{
- return error;
+ HRESULT result = device->CreateBlendState(&mDesc, &mResource);
+ ASSERT(SUCCEEDED(result));
+ UNUSED_ASSERTION_VARIABLE(result);
+ d3d11::SetDebugName(mResource, mDebugName);
}
- *outRT = RenderTarget11::makeRenderTarget11(renderTarget);
- return gl::Error(GL_NO_ERROR);
+
+ return mResource;
}
-Workarounds GenerateWorkarounds(D3D_FEATURE_LEVEL featureLevel)
+WorkaroundsD3D GenerateWorkarounds(D3D_FEATURE_LEVEL featureLevel)
{
- Workarounds workarounds;
+ WorkaroundsD3D workarounds;
workarounds.mrtPerfWorkaround = true;
workarounds.setDataFasterThanImageUpload = true;
workarounds.zeroMaxLodWorkaround = (featureLevel <= D3D_FEATURE_LEVEL_9_3);
@@ -1373,6 +1593,188 @@ Workarounds GenerateWorkarounds(D3D_FEATURE_LEVEL featureLevel)
return workarounds;
}
+} // namespace d3d11
+
+TextureHelper11::TextureHelper11()
+ : mTextureType(GL_NONE),
+ mFormat(DXGI_FORMAT_UNKNOWN),
+ mSampleCount(0),
+ mTexture2D(nullptr),
+ mTexture3D(nullptr)
+{
+}
+
+TextureHelper11::TextureHelper11(TextureHelper11 &&toCopy)
+ : mTextureType(toCopy.mTextureType),
+ mExtents(toCopy.mExtents),
+ mFormat(toCopy.mFormat),
+ mSampleCount(toCopy.mSampleCount),
+ mTexture2D(toCopy.mTexture2D),
+ mTexture3D(toCopy.mTexture3D)
+{
+ toCopy.reset();
+}
+
+// static
+TextureHelper11 TextureHelper11::MakeAndReference(ID3D11Resource *genericResource)
+{
+ TextureHelper11 newHelper;
+ newHelper.mTexture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(genericResource);
+ newHelper.mTexture3D = d3d11::DynamicCastComObject<ID3D11Texture3D>(genericResource);
+ newHelper.mTextureType = newHelper.mTexture2D ? GL_TEXTURE_2D : GL_TEXTURE_3D;
+ newHelper.initDesc();
+ return newHelper;
+}
+
+// static
+TextureHelper11 TextureHelper11::MakeAndPossess2D(ID3D11Texture2D *texToOwn)
+{
+ TextureHelper11 newHelper;
+ newHelper.mTexture2D = texToOwn;
+ newHelper.mTextureType = GL_TEXTURE_2D;
+ newHelper.initDesc();
+ return newHelper;
+}
+
+// static
+TextureHelper11 TextureHelper11::MakeAndPossess3D(ID3D11Texture3D *texToOwn)
+{
+ TextureHelper11 newHelper;
+ newHelper.mTexture3D = texToOwn;
+ newHelper.mTextureType = GL_TEXTURE_3D;
+ newHelper.initDesc();
+ return newHelper;
+}
+
+void TextureHelper11::initDesc()
+{
+ if (mTextureType == GL_TEXTURE_2D)
+ {
+ ASSERT(!mTexture3D);
+ D3D11_TEXTURE2D_DESC desc2D;
+ mTexture2D->GetDesc(&desc2D);
+
+ mExtents.width = static_cast<int>(desc2D.Width);
+ mExtents.height = static_cast<int>(desc2D.Height);
+ mExtents.depth = 1;
+ mFormat = desc2D.Format;
+ mSampleCount = desc2D.SampleDesc.Count;
+ }
+ else
+ {
+ ASSERT(mTexture3D && mTextureType == GL_TEXTURE_3D);
+ D3D11_TEXTURE3D_DESC desc3D;
+ mTexture3D->GetDesc(&desc3D);
+
+ mExtents.width = static_cast<int>(desc3D.Width);
+ mExtents.height = static_cast<int>(desc3D.Height);
+ mExtents.depth = static_cast<int>(desc3D.Depth);
+ mFormat = desc3D.Format;
+ mSampleCount = 1;
+ }
+}
+
+TextureHelper11::~TextureHelper11()
+{
+ SafeRelease(mTexture2D);
+ SafeRelease(mTexture3D);
+}
+
+ID3D11Resource *TextureHelper11::getResource() const
+{
+ return mTexture2D ? static_cast<ID3D11Resource *>(mTexture2D)
+ : static_cast<ID3D11Resource *>(mTexture3D);
+}
+
+TextureHelper11 &TextureHelper11::operator=(TextureHelper11 &&texture)
+{
+ SafeRelease(mTexture2D);
+ SafeRelease(mTexture3D);
+
+ mTextureType = texture.mTextureType;
+ mExtents = texture.mExtents;
+ mFormat = texture.mFormat;
+ mSampleCount = texture.mSampleCount;
+ mTexture2D = texture.mTexture2D;
+ mTexture3D = texture.mTexture3D;
+ texture.reset();
+ return *this;
+}
+
+void TextureHelper11::reset()
+{
+ mTextureType = GL_NONE;
+ mExtents = gl::Extents();
+ mFormat = DXGI_FORMAT_UNKNOWN;
+ mSampleCount = 0;
+ mTexture2D = nullptr;
+ mTexture3D = nullptr;
+}
+
+gl::ErrorOrResult<TextureHelper11> CreateStagingTexture(GLenum textureType,
+ DXGI_FORMAT dxgiFormat,
+ const gl::Extents &size,
+ ID3D11Device *device)
+{
+ if (textureType == GL_TEXTURE_2D)
+ {
+ D3D11_TEXTURE2D_DESC stagingDesc;
+ stagingDesc.Width = size.width;
+ stagingDesc.Height = size.height;
+ stagingDesc.MipLevels = 1;
+ stagingDesc.ArraySize = 1;
+ stagingDesc.Format = dxgiFormat;
+ stagingDesc.SampleDesc.Count = 1;
+ stagingDesc.SampleDesc.Quality = 0;
+ stagingDesc.Usage = D3D11_USAGE_STAGING;
+ stagingDesc.BindFlags = 0;
+ stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+ stagingDesc.MiscFlags = 0;
+
+ ID3D11Texture2D *stagingTex = nullptr;
+ HRESULT result = device->CreateTexture2D(&stagingDesc, nullptr, &stagingTex);
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "CreateStagingTextureFor failed, HRESULT: 0x%X.",
+ result);
+ }
+
+ return TextureHelper11::MakeAndPossess2D(stagingTex);
+ }
+ ASSERT(textureType == GL_TEXTURE_3D);
+
+ D3D11_TEXTURE3D_DESC stagingDesc;
+ stagingDesc.Width = size.width;
+ stagingDesc.Height = size.height;
+ stagingDesc.Depth = 1;
+ stagingDesc.MipLevels = 1;
+ stagingDesc.Format = dxgiFormat;
+ stagingDesc.Usage = D3D11_USAGE_STAGING;
+ stagingDesc.BindFlags = 0;
+ stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+ stagingDesc.MiscFlags = 0;
+
+ ID3D11Texture3D *stagingTex = nullptr;
+ HRESULT result = device->CreateTexture3D(&stagingDesc, nullptr, &stagingTex);
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "CreateStagingTextureFor failed, HRESULT: 0x%X.",
+ result);
+ }
+
+ return TextureHelper11::MakeAndPossess3D(stagingTex);
}
+bool UsePresentPathFast(const Renderer11 *renderer,
+ const gl::FramebufferAttachment *framebufferAttachment)
+{
+ if (framebufferAttachment == nullptr)
+ {
+ return false;
+ }
+
+ return (framebufferAttachment->type() == GL_FRAMEBUFFER_DEFAULT &&
+ renderer->presentPathFastEnabled());
}
+
+} // namespace rx
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h
index 207e6b5404..4925a2d227 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h
@@ -10,11 +10,13 @@
#ifndef LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_
#define LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_
+#include <array>
+#include <vector>
+
#include "libANGLE/angletypes.h"
#include "libANGLE/Caps.h"
#include "libANGLE/Error.h"
-
-#include <vector>
+#include "libANGLE/renderer/d3d/RendererD3D.h"
namespace gl
{
@@ -23,8 +25,12 @@ class FramebufferAttachment;
namespace rx
{
+class Renderer11;
class RenderTarget11;
-struct Workarounds;
+struct WorkaroundsD3D;
+struct Renderer11DeviceCaps;
+
+using RenderTargetArray = std::array<ID3D11RenderTargetView *, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS>;
namespace gl_d3d11
{
@@ -45,24 +51,46 @@ D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap);
D3D11_QUERY ConvertQueryType(GLenum queryType);
-}
+} // namespace gl_d3d11
namespace d3d11_gl
{
+unsigned int GetReservedVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel);
+
+unsigned int GetReservedFragmentUniformVectors(D3D_FEATURE_LEVEL featureLevel);
+
GLint GetMaximumClientVersion(D3D_FEATURE_LEVEL featureLevel);
-void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions);
+void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, const Renderer11DeviceCaps &renderer11DeviceCaps, gl::Caps *caps,
+ gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions, gl::Limitations *limitations);
-}
+} // namespace d3d11_gl
namespace d3d11
{
+enum ANGLED3D11DeviceType
+{
+ ANGLE_D3D11_DEVICE_TYPE_UNKNOWN,
+ ANGLE_D3D11_DEVICE_TYPE_HARDWARE,
+ ANGLE_D3D11_DEVICE_TYPE_SOFTWARE_REF_OR_NULL,
+ ANGLE_D3D11_DEVICE_TYPE_WARP,
+};
+
+ANGLED3D11DeviceType GetDeviceType(ID3D11Device *device);
+
void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset);
-void GenerateInitialTextureData(GLint internalFormat, D3D_FEATURE_LEVEL featureLevel, GLuint width, GLuint height, GLuint depth,
- GLuint mipLevels, std::vector<D3D11_SUBRESOURCE_DATA> *outSubresourceData,
- std::vector< std::vector<BYTE> > *outData);
+void GenerateInitialTextureData(GLint internalFormat,
+ const Renderer11DeviceCaps &renderer11DeviceCaps,
+ GLuint width,
+ GLuint height,
+ GLuint depth,
+ GLuint mipLevels,
+ std::vector<D3D11_SUBRESOURCE_DATA> *outSubresourceData,
+ std::vector<std::vector<BYTE>> *outData);
+
+UINT GetPrimitiveRestartIndex();
struct PositionTexCoordVertex
{
@@ -133,58 +161,230 @@ inline bool isDeviceLostError(HRESULT errorCode)
}
}
-template <unsigned int N>
-inline ID3D11VertexShader *CompileVS(ID3D11Device *device, const BYTE (&byteCode)[N], const char *name)
+inline ID3D11VertexShader *CompileVS(ID3D11Device *device, const BYTE *byteCode, size_t N, const char *name)
{
- ID3D11VertexShader *vs = NULL;
- HRESULT result = device->CreateVertexShader(byteCode, N, NULL, &vs);
- UNUSED_ASSERTION_VARIABLE(result);
+ ID3D11VertexShader *vs = nullptr;
+ HRESULT result = device->CreateVertexShader(byteCode, N, nullptr, &vs);
ASSERT(SUCCEEDED(result));
- SetDebugName(vs, name);
- return vs;
+ if (SUCCEEDED(result))
+ {
+ SetDebugName(vs, name);
+ return vs;
+ }
+ return nullptr;
}
template <unsigned int N>
-inline ID3D11GeometryShader *CompileGS(ID3D11Device *device, const BYTE (&byteCode)[N], const char *name)
+ID3D11VertexShader *CompileVS(ID3D11Device *device, const BYTE (&byteCode)[N], const char *name)
+{
+ return CompileVS(device, byteCode, N, name);
+}
+
+inline ID3D11GeometryShader *CompileGS(ID3D11Device *device, const BYTE *byteCode, size_t N, const char *name)
{
- ID3D11GeometryShader *gs = NULL;
- HRESULT result = device->CreateGeometryShader(byteCode, N, NULL, &gs);
- UNUSED_ASSERTION_VARIABLE(result);
+ ID3D11GeometryShader *gs = nullptr;
+ HRESULT result = device->CreateGeometryShader(byteCode, N, nullptr, &gs);
ASSERT(SUCCEEDED(result));
- SetDebugName(gs, name);
- return gs;
+ if (SUCCEEDED(result))
+ {
+ SetDebugName(gs, name);
+ return gs;
+ }
+ return nullptr;
}
template <unsigned int N>
-inline ID3D11PixelShader *CompilePS(ID3D11Device *device, const BYTE (&byteCode)[N], const char *name)
+ID3D11GeometryShader *CompileGS(ID3D11Device *device, const BYTE (&byteCode)[N], const char *name)
+{
+ return CompileGS(device, byteCode, N, name);
+}
+
+inline ID3D11PixelShader *CompilePS(ID3D11Device *device, const BYTE *byteCode, size_t N, const char *name)
{
- ID3D11PixelShader *ps = NULL;
- HRESULT result = device->CreatePixelShader(byteCode, N, NULL, &ps);
- UNUSED_ASSERTION_VARIABLE(result);
+ ID3D11PixelShader *ps = nullptr;
+ HRESULT result = device->CreatePixelShader(byteCode, N, nullptr, &ps);
ASSERT(SUCCEEDED(result));
- SetDebugName(ps, name);
- return ps;
+ if (SUCCEEDED(result))
+ {
+ SetDebugName(ps, name);
+ return ps;
+ }
+ return nullptr;
}
-// Copy data to small D3D11 buffers, such as for small constant buffers, which use one struct to
-// represent an entire buffer.
-template <class T>
-inline void SetBufferData(ID3D11DeviceContext *context, ID3D11Buffer *constantBuffer, const T &value)
+template <unsigned int N>
+ID3D11PixelShader *CompilePS(ID3D11Device *device, const BYTE (&byteCode)[N], const char *name)
+{
+ return CompilePS(device, byteCode, N, name);
+}
+
+template <typename ResourceType>
+class LazyResource : public angle::NonCopyable
{
- D3D11_MAPPED_SUBRESOURCE mappedResource;
- context->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+ public:
+ LazyResource() : mResource(nullptr), mAssociatedDevice(nullptr) {}
+ virtual ~LazyResource() { release(); }
+
+ virtual ResourceType *resolve(ID3D11Device *device) = 0;
+ void release() { SafeRelease(mResource); }
- memcpy(mappedResource.pData, &value, sizeof(T));
+ protected:
+ void checkAssociatedDevice(ID3D11Device *device);
- context->Unmap(constantBuffer, 0);
+ ResourceType *mResource;
+ ID3D11Device *mAssociatedDevice;
+};
+
+template <typename ResourceType>
+void LazyResource<ResourceType>::checkAssociatedDevice(ID3D11Device *device)
+{
+ ASSERT(mAssociatedDevice == nullptr || device == mAssociatedDevice);
+ mAssociatedDevice = device;
}
-gl::Error GetAttachmentRenderTarget(const gl::FramebufferAttachment *attachment, RenderTarget11 **outRT);
+template <typename D3D11ShaderType>
+class LazyShader final : public LazyResource<D3D11ShaderType>
+{
+ public:
+ // All parameters must be constexpr. Not supported in VS2013.
+ LazyShader(const BYTE *byteCode,
+ size_t byteCodeSize,
+ const char *name)
+ : mByteCode(byteCode),
+ mByteCodeSize(byteCodeSize),
+ mName(name)
+ {
+ }
-Workarounds GenerateWorkarounds(D3D_FEATURE_LEVEL featureLevel);
+ D3D11ShaderType *resolve(ID3D11Device *device) override;
+ private:
+ const BYTE *mByteCode;
+ size_t mByteCodeSize;
+ const char *mName;
+};
+
+template <>
+inline ID3D11VertexShader *LazyShader<ID3D11VertexShader>::resolve(ID3D11Device *device)
+{
+ checkAssociatedDevice(device);
+ if (mResource == nullptr)
+ {
+ mResource = CompileVS(device, mByteCode, mByteCodeSize, mName);
+ }
+ return mResource;
}
+template <>
+inline ID3D11GeometryShader *LazyShader<ID3D11GeometryShader>::resolve(ID3D11Device *device)
+{
+ checkAssociatedDevice(device);
+ if (mResource == nullptr)
+ {
+ mResource = CompileGS(device, mByteCode, mByteCodeSize, mName);
+ }
+ return mResource;
}
+template <>
+inline ID3D11PixelShader *LazyShader<ID3D11PixelShader>::resolve(ID3D11Device *device)
+{
+ checkAssociatedDevice(device);
+ if (mResource == nullptr)
+ {
+ mResource = CompilePS(device, mByteCode, mByteCodeSize, mName);
+ }
+ return mResource;
+}
+
+class LazyInputLayout final : public LazyResource<ID3D11InputLayout>
+{
+ public:
+ LazyInputLayout(const D3D11_INPUT_ELEMENT_DESC *inputDesc,
+ size_t inputDescLen,
+ const BYTE *byteCode,
+ size_t byteCodeLen,
+ const char *debugName);
+
+ ID3D11InputLayout *resolve(ID3D11Device *device) override;
+
+ private:
+ std::vector<D3D11_INPUT_ELEMENT_DESC> mInputDesc;
+ size_t mByteCodeLen;
+ const BYTE *mByteCode;
+ const char *mDebugName;
+};
+
+class LazyBlendState final : public LazyResource<ID3D11BlendState>
+{
+ public:
+ LazyBlendState(const D3D11_BLEND_DESC &desc, const char *debugName);
+
+ ID3D11BlendState *resolve(ID3D11Device *device) override;
+
+ private:
+ D3D11_BLEND_DESC mDesc;
+ const char *mDebugName;
+};
+
+// Copy data to small D3D11 buffers, such as for small constant buffers, which use one struct to
+// represent an entire buffer.
+template <class T>
+void SetBufferData(ID3D11DeviceContext *context, ID3D11Buffer *constantBuffer, const T &value)
+{
+ D3D11_MAPPED_SUBRESOURCE mappedResource = {};
+ HRESULT result = context->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+ ASSERT(SUCCEEDED(result));
+ if (SUCCEEDED(result))
+ {
+ memcpy(mappedResource.pData, &value, sizeof(T));
+ context->Unmap(constantBuffer, 0);
+ }
+}
+
+WorkaroundsD3D GenerateWorkarounds(D3D_FEATURE_LEVEL featureLevel);
+} // namespace d3d11
+
+// A helper class which wraps a 2D or 3D texture.
+class TextureHelper11 : angle::NonCopyable
+{
+ public:
+ TextureHelper11();
+ TextureHelper11(TextureHelper11 &&toCopy);
+ ~TextureHelper11();
+ TextureHelper11 &operator=(TextureHelper11 &&texture);
+
+ static TextureHelper11 MakeAndReference(ID3D11Resource *genericResource);
+ static TextureHelper11 MakeAndPossess2D(ID3D11Texture2D *texToOwn);
+ static TextureHelper11 MakeAndPossess3D(ID3D11Texture3D *texToOwn);
+
+ GLenum getTextureType() const { return mTextureType; }
+ gl::Extents getExtents() const { return mExtents; }
+ DXGI_FORMAT getFormat() const { return mFormat; }
+ int getSampleCount() const { return mSampleCount; }
+ ID3D11Texture2D *getTexture2D() const { return mTexture2D; }
+ ID3D11Texture3D *getTexture3D() const { return mTexture3D; }
+ ID3D11Resource *getResource() const;
+
+ private:
+ void reset();
+ void initDesc();
+
+ GLenum mTextureType;
+ gl::Extents mExtents;
+ DXGI_FORMAT mFormat;
+ int mSampleCount;
+ ID3D11Texture2D *mTexture2D;
+ ID3D11Texture3D *mTexture3D;
+};
+
+gl::ErrorOrResult<TextureHelper11> CreateStagingTexture(GLenum textureType,
+ DXGI_FORMAT dxgiFormat,
+ const gl::Extents &size,
+ ID3D11Device *device);
+
+bool UsePresentPathFast(const Renderer11 *renderer, const gl::FramebufferAttachment *colorbuffer);
+
+} // namespace rx
+
#endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_data.json b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_data.json
new file mode 100644
index 0000000000..3e9e6877d9
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_data.json
@@ -0,0 +1,77 @@
+{
+ "GL_UNSIGNED_NORMALIZED": {
+ "8": {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM"
+ },
+ "16": {
+ "texFormat": "DXGI_FORMAT_R16G16B16A16_UNORM",
+ "srvFormat": "DXGI_FORMAT_R16G16B16A16_UNORM",
+ "rtvFormat": "DXGI_FORMAT_R16G16B16A16_UNORM"
+ },
+ "24": {
+ "texFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
+ "srvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
+ "rtvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT"
+ },
+ "32": {
+ "texFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
+ "srvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
+ "rtvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT"
+ }
+ },
+ "GL_SIGNED_NORMALIZED": {
+ "8": {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_SNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_SNORM",
+ "rtvFormat": "DXGI_FORMAT_R8G8B8A8_SNORM"
+ }
+ },
+ "GL_FLOAT": {
+ "16": {
+ "texFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "srvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "rtvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT"
+ },
+ "32": {
+ "texFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
+ "srvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
+ "rtvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT"
+ }
+ },
+ "GL_UNSIGNED_INT": {
+ "8": {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UINT",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UINT",
+ "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UINT"
+ },
+ "16": {
+ "texFormat": "DXGI_FORMAT_R16G16B16A16_UINT",
+ "srvFormat": "DXGI_FORMAT_R16G16B16A16_UINT",
+ "rtvFormat": "DXGI_FORMAT_R16G16B16A16_UINT"
+ },
+ "32": {
+ "texFormat": "DXGI_FORMAT_R32G32B32A32_UINT",
+ "srvFormat": "DXGI_FORMAT_R32G32B32A32_UINT",
+ "rtvFormat": "DXGI_FORMAT_R32G32B32A32_UINT"
+ }
+ },
+ "GL_INT": {
+ "8": {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_SINT",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_SINT",
+ "rtvFormat": "DXGI_FORMAT_R8G8B8A8_SINT"
+ },
+ "16": {
+ "texFormat": "DXGI_FORMAT_R16G16B16A16_SINT",
+ "srvFormat": "DXGI_FORMAT_R16G16B16A16_SINT",
+ "rtvFormat": "DXGI_FORMAT_R16G16B16A16_SINT"
+ },
+ "32": {
+ "texFormat": "DXGI_FORMAT_R32G32B32A32_SINT",
+ "srvFormat": "DXGI_FORMAT_R32G32B32A32_SINT",
+ "rtvFormat": "DXGI_FORMAT_R32G32B32A32_SINT"
+ }
+ }
+} \ No newline at end of file
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_info.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_info.h
new file mode 100644
index 0000000000..df9a30ff50
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_info.h
@@ -0,0 +1,51 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// swizzle_format_info:
+// Provides information for swizzle format and a map from type->formatinfo
+//
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_SWIZZLEFORMATINFO_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_SWIZZLEFORMATINFO_H_
+
+#include <GLES2/gl2.h>
+#include <map>
+
+#include "common/platform.h"
+
+namespace rx
+{
+
+namespace d3d11
+{
+
+struct SwizzleSizeType
+{
+ size_t maxComponentSize;
+ GLenum componentType;
+
+ SwizzleSizeType();
+ SwizzleSizeType(size_t maxComponentSize, GLenum componentType);
+
+ bool operator<(const SwizzleSizeType &other) const;
+};
+
+struct SwizzleFormatInfo
+{
+ DXGI_FORMAT mTexFormat;
+ DXGI_FORMAT mSRVFormat;
+ DXGI_FORMAT mRTVFormat;
+
+ SwizzleFormatInfo();
+ SwizzleFormatInfo(DXGI_FORMAT texFormat, DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat);
+};
+
+const SwizzleFormatInfo &GetSwizzleFormatInfo(GLuint maxBits, GLenum componentType);
+
+} // namespace d3d11
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_SWIZZLEFORMATINFO_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_info_autogen.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_info_autogen.cpp
new file mode 100644
index 0000000000..84d6fada97
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_info_autogen.cpp
@@ -0,0 +1,203 @@
+// GENERATED FILE - DO NOT EDIT
+// Generated by gen_swizzle_format_table.py using data from swizzle_format_data.json
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// swizzle_format_info:
+// Provides information for swizzle format and a map from type->formatinfo
+//
+
+#include "libANGLE/renderer/d3d/d3d11/swizzle_format_info.h"
+
+#include <GLES3/gl3.h>
+
+namespace rx
+{
+
+namespace d3d11
+{
+
+SwizzleSizeType::SwizzleSizeType() : maxComponentSize(0), componentType(GL_NONE)
+{
+}
+
+SwizzleSizeType::SwizzleSizeType(size_t maxComponentSize, GLenum componentType)
+ : maxComponentSize(maxComponentSize), componentType(componentType)
+{
+}
+
+bool SwizzleSizeType::operator<(const SwizzleSizeType &other) const
+{
+ return (maxComponentSize != other.maxComponentSize)
+ ? (maxComponentSize < other.maxComponentSize)
+ : (componentType < other.componentType);
+}
+
+SwizzleFormatInfo::SwizzleFormatInfo()
+ : mTexFormat(DXGI_FORMAT_UNKNOWN),
+ mSRVFormat(DXGI_FORMAT_UNKNOWN),
+ mRTVFormat(DXGI_FORMAT_UNKNOWN)
+{
+}
+
+SwizzleFormatInfo::SwizzleFormatInfo(DXGI_FORMAT texFormat,
+ DXGI_FORMAT srvFormat,
+ DXGI_FORMAT rtvFormat)
+ : mTexFormat(texFormat), mSRVFormat(srvFormat), mRTVFormat(rtvFormat)
+{
+}
+
+const SwizzleFormatInfo &GetSwizzleFormatInfo(GLuint maxBits, GLenum componentType)
+{
+ // clang-format off
+ switch (componentType)
+ {
+ case GL_FLOAT:
+ {
+ switch (maxBits)
+ {
+ case 16:
+ {
+ static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT);
+ return formatInfo;
+ }
+ case 32:
+ {
+ static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT);
+ return formatInfo;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_INT:
+ {
+ switch (maxBits)
+ {
+ case 16:
+ {
+ static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R16G16B16A16_SINT,
+ DXGI_FORMAT_R16G16B16A16_SINT,
+ DXGI_FORMAT_R16G16B16A16_SINT);
+ return formatInfo;
+ }
+ case 32:
+ {
+ static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R32G32B32A32_SINT,
+ DXGI_FORMAT_R32G32B32A32_SINT,
+ DXGI_FORMAT_R32G32B32A32_SINT);
+ return formatInfo;
+ }
+ case 8:
+ {
+ static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R8G8B8A8_SINT,
+ DXGI_FORMAT_R8G8B8A8_SINT,
+ DXGI_FORMAT_R8G8B8A8_SINT);
+ return formatInfo;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_SIGNED_NORMALIZED:
+ {
+ switch (maxBits)
+ {
+ case 8:
+ {
+ static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R8G8B8A8_SNORM,
+ DXGI_FORMAT_R8G8B8A8_SNORM,
+ DXGI_FORMAT_R8G8B8A8_SNORM);
+ return formatInfo;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_UNSIGNED_INT:
+ {
+ switch (maxBits)
+ {
+ case 16:
+ {
+ static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R16G16B16A16_UINT,
+ DXGI_FORMAT_R16G16B16A16_UINT,
+ DXGI_FORMAT_R16G16B16A16_UINT);
+ return formatInfo;
+ }
+ case 32:
+ {
+ static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R32G32B32A32_UINT,
+ DXGI_FORMAT_R32G32B32A32_UINT,
+ DXGI_FORMAT_R32G32B32A32_UINT);
+ return formatInfo;
+ }
+ case 8:
+ {
+ static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R8G8B8A8_UINT,
+ DXGI_FORMAT_R8G8B8A8_UINT,
+ DXGI_FORMAT_R8G8B8A8_UINT);
+ return formatInfo;
+ }
+ default:
+ break;
+ }
+ }
+ case GL_UNSIGNED_NORMALIZED:
+ {
+ switch (maxBits)
+ {
+ case 16:
+ {
+ static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R16G16B16A16_UNORM,
+ DXGI_FORMAT_R16G16B16A16_UNORM,
+ DXGI_FORMAT_R16G16B16A16_UNORM);
+ return formatInfo;
+ }
+ case 24:
+ {
+ static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT);
+ return formatInfo;
+ }
+ case 32:
+ {
+ static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT);
+ return formatInfo;
+ }
+ case 8:
+ {
+ static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM);
+ return formatInfo;
+ }
+ default:
+ break;
+ }
+ }
+
+ default:
+ {
+ static const SwizzleFormatInfo defaultInfo(DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return defaultInfo;
+ }
+ }
+ // clang-format on
+
+} // GetSwizzleFormatInfo
+
+} // namespace d3d11
+
+} // namespace rx
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_data.json b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_data.json
new file mode 100644
index 0000000000..87d303437f
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_data.json
@@ -0,0 +1,692 @@
+{
+ "GL_ALPHA": [
+ {
+ "texFormat": "DXGI_FORMAT_A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_A8_UNORM",
+ "rtvFormat": "DXGI_FORMAT_A8_UNORM",
+ "requirementsFcn": "OnlyFL10Plus"
+ },
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "requirementsFcn": "OnlyFL9_3"
+ }
+ ],
+ "GL_ALPHA16F_EXT": [
+ {
+ "texFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "srvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "rtvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT"
+ }
+ ],
+ "GL_ALPHA32F_EXT": [
+ {
+ "texFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
+ "srvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
+ "rtvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT"
+ }
+ ],
+ "GL_ALPHA8_EXT": [
+ {
+ "texFormat": "DXGI_FORMAT_A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_A8_UNORM",
+ "rtvFormat": "DXGI_FORMAT_A8_UNORM",
+ "requirementsFcn": "OnlyFL10Plus"
+ },
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "requirementsFcn": "OnlyFL9_3"
+ }
+ ],
+ "GL_BGR5_A1_ANGLEX": [
+ {
+ "texFormat": "DXGI_FORMAT_B8G8R8A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM",
+ "rtvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM"
+ }
+ ],
+ "GL_BGRA4_ANGLEX": [
+ {
+ "texFormat": "DXGI_FORMAT_B8G8R8A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM",
+ "rtvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM"
+ }
+ ],
+ "GL_BGRA8_EXT": [
+ {
+ "texFormat": "DXGI_FORMAT_B8G8R8A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM",
+ "rtvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM"
+ }
+ ],
+ "GL_BGRA_EXT": [
+ {
+ "texFormat": "DXGI_FORMAT_B8G8R8A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM",
+ "rtvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM"
+ }
+ ],
+ "GL_COMPRESSED_R11_EAC": [
+ {
+ "texFormat": "DXGI_FORMAT_R8_UNORM",
+ "srvFormat": "DXGI_FORMAT_R8_UNORM",
+ "requirementsFcn": "OnlyFL10Plus"
+ }
+ ],
+ "GL_COMPRESSED_RG11_EAC": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8_UNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8_UNORM",
+ "requirementsFcn": "OnlyFL10Plus"
+ }
+ ],
+ "GL_COMPRESSED_RGB8_ETC2": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "requirementsFcn": "OnlyFL10Plus"
+ }
+ ],
+ "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "requirementsFcn": "OnlyFL10Plus"
+ }
+ ],
+ "GL_COMPRESSED_RGBA8_ETC2_EAC": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "requirementsFcn": "OnlyFL10Plus"
+ }
+ ],
+ "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT": [
+ {
+ "texFormat": "DXGI_FORMAT_BC1_UNORM",
+ "srvFormat": "DXGI_FORMAT_BC1_UNORM"
+ }
+ ],
+ "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE": [
+ {
+ "texFormat": "DXGI_FORMAT_BC2_UNORM",
+ "srvFormat": "DXGI_FORMAT_BC2_UNORM"
+ }
+ ],
+ "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE": [
+ {
+ "texFormat": "DXGI_FORMAT_BC3_UNORM",
+ "srvFormat": "DXGI_FORMAT_BC3_UNORM"
+ }
+ ],
+ "GL_COMPRESSED_RGB_S3TC_DXT1_EXT": [
+ {
+ "texFormat": "DXGI_FORMAT_BC1_UNORM",
+ "srvFormat": "DXGI_FORMAT_BC1_UNORM"
+ }
+ ],
+ "GL_COMPRESSED_SIGNED_R11_EAC": [
+ {
+ "texFormat": "DXGI_FORMAT_R8_SNORM",
+ "srvFormat": "DXGI_FORMAT_R8_SNORM",
+ "requirementsFcn": "OnlyFL10Plus"
+ }
+ ],
+ "GL_COMPRESSED_SIGNED_RG11_EAC": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8_SNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8_SNORM",
+ "requirementsFcn": "OnlyFL10Plus"
+ }
+ ],
+ "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB",
+ "requirementsFcn": "OnlyFL10Plus"
+ }
+ ],
+ "GL_COMPRESSED_SRGB8_ETC2": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB",
+ "requirementsFcn": "OnlyFL10Plus"
+ }
+ ],
+ "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB",
+ "requirementsFcn": "OnlyFL10Plus"
+ }
+ ],
+ "GL_DEPTH24_STENCIL8": [
+ {
+ "texFormat": "DXGI_FORMAT_R24G8_TYPELESS",
+ "srvFormat": "DXGI_FORMAT_R24_UNORM_X8_TYPELESS",
+ "dsvFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT",
+ "requirementsFcn": "OnlyFL10Plus"
+ },
+ {
+ "texFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT",
+ "dsvFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT",
+ "requirementsFcn": "OnlyFL9_3"
+ }
+ ],
+ "GL_DEPTH32F_STENCIL8": [
+ {
+ "texFormat": "DXGI_FORMAT_R32G8X24_TYPELESS",
+ "srvFormat": "DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS",
+ "dsvFormat": "DXGI_FORMAT_D32_FLOAT_S8X24_UINT",
+ "requirementsFcn": "OnlyFL10Plus"
+ },
+ {
+ "requirementsFcn": "OnlyFL9_3"
+ }
+ ],
+ "GL_DEPTH_COMPONENT16": [
+ {
+ "texFormat": "DXGI_FORMAT_R16_TYPELESS",
+ "srvFormat": "DXGI_FORMAT_R16_UNORM",
+ "dsvFormat": "DXGI_FORMAT_D16_UNORM",
+ "requirementsFcn": "OnlyFL10Plus"
+ },
+ {
+ "texFormat": "DXGI_FORMAT_D16_UNORM",
+ "dsvFormat": "DXGI_FORMAT_D16_UNORM",
+ "requirementsFcn": "OnlyFL9_3"
+ }
+ ],
+ "GL_DEPTH_COMPONENT24": [
+ {
+ "texFormat": "DXGI_FORMAT_R24G8_TYPELESS",
+ "srvFormat": "DXGI_FORMAT_R24_UNORM_X8_TYPELESS",
+ "dsvFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT",
+ "requirementsFcn": "OnlyFL10Plus"
+ },
+ {
+ "texFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT",
+ "dsvFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT",
+ "requirementsFcn": "OnlyFL9_3"
+ }
+ ],
+ "GL_DEPTH_COMPONENT32F": [
+ {
+ "texFormat": "DXGI_FORMAT_R32_TYPELESS",
+ "srvFormat": "DXGI_FORMAT_R32_FLOAT",
+ "dsvFormat": "DXGI_FORMAT_D32_FLOAT",
+ "requirementsFcn": "OnlyFL10Plus"
+ },
+ {
+ "requirementsFcn": "OnlyFL9_3"
+ }
+ ],
+ "GL_DEPTH_COMPONENT32_OES": [
+ {
+ "texFormat": "DXGI_FORMAT_R24G8_TYPELESS",
+ "srvFormat": "DXGI_FORMAT_R24_UNORM_X8_TYPELESS",
+ "dsvFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT",
+ "requirementsFcn": "OnlyFL10Plus"
+ }
+ ],
+ "GL_ETC1_RGB8_OES": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM"
+ }
+ ],
+ "GL_ETC1_RGB8_LOSSY_DECODE_ANGLE": [
+ {
+ "texFormat": "DXGI_FORMAT_BC1_UNORM",
+ "srvFormat": "DXGI_FORMAT_BC1_UNORM"
+ }
+ ],
+ "GL_LUMINANCE": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM"
+ }
+ ],
+ "GL_LUMINANCE16F_EXT": [
+ {
+ "texFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "srvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "rtvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT"
+ }
+ ],
+ "GL_LUMINANCE32F_EXT": [
+ {
+ "texFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
+ "srvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
+ "rtvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT"
+ }
+ ],
+ "GL_LUMINANCE8_ALPHA8_EXT": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM"
+ }
+ ],
+ "GL_LUMINANCE8_EXT": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM"
+ }
+ ],
+ "GL_LUMINANCE_ALPHA": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM"
+ }
+ ],
+ "GL_LUMINANCE_ALPHA16F_EXT": [
+ {
+ "texFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "srvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "rtvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT"
+ }
+ ],
+ "GL_LUMINANCE_ALPHA32F_EXT": [
+ {
+ "texFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
+ "srvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
+ "rtvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT"
+ }
+ ],
+ "GL_NONE": [
+ {
+ }
+ ],
+ "GL_R11F_G11F_B10F": [
+ {
+ "texFormat": "DXGI_FORMAT_R11G11B10_FLOAT",
+ "srvFormat": "DXGI_FORMAT_R11G11B10_FLOAT",
+ "rtvFormat": "DXGI_FORMAT_R11G11B10_FLOAT"
+ }
+ ],
+ "GL_R16F": [
+ {
+ "texFormat": "DXGI_FORMAT_R16_FLOAT",
+ "srvFormat": "DXGI_FORMAT_R16_FLOAT",
+ "rtvFormat": "DXGI_FORMAT_R16_FLOAT"
+ }
+ ],
+ "GL_R16I": [
+ {
+ "texFormat": "DXGI_FORMAT_R16_SINT",
+ "srvFormat": "DXGI_FORMAT_R16_SINT",
+ "rtvFormat": "DXGI_FORMAT_R16_SINT"
+ }
+ ],
+ "GL_R16UI": [
+ {
+ "texFormat": "DXGI_FORMAT_R16_UINT",
+ "srvFormat": "DXGI_FORMAT_R16_UINT",
+ "rtvFormat": "DXGI_FORMAT_R16_UINT"
+ }
+ ],
+ "GL_R32F": [
+ {
+ "texFormat": "DXGI_FORMAT_R32_FLOAT",
+ "srvFormat": "DXGI_FORMAT_R32_FLOAT",
+ "rtvFormat": "DXGI_FORMAT_R32_FLOAT"
+ }
+ ],
+ "GL_R32I": [
+ {
+ "texFormat": "DXGI_FORMAT_R32_SINT",
+ "srvFormat": "DXGI_FORMAT_R32_SINT",
+ "rtvFormat": "DXGI_FORMAT_R32_SINT"
+ }
+ ],
+ "GL_R32UI": [
+ {
+ "texFormat": "DXGI_FORMAT_R32_UINT",
+ "srvFormat": "DXGI_FORMAT_R32_UINT",
+ "rtvFormat": "DXGI_FORMAT_R32_UINT"
+ }
+ ],
+ "GL_R8": [
+ {
+ "texFormat": "DXGI_FORMAT_R8_UNORM",
+ "srvFormat": "DXGI_FORMAT_R8_UNORM",
+ "rtvFormat": "DXGI_FORMAT_R8_UNORM"
+ }
+ ],
+ "GL_R8I": [
+ {
+ "texFormat": "DXGI_FORMAT_R8_SINT",
+ "srvFormat": "DXGI_FORMAT_R8_SINT",
+ "rtvFormat": "DXGI_FORMAT_R8_SINT"
+ }
+ ],
+ "GL_R8UI": [
+ {
+ "texFormat": "DXGI_FORMAT_R8_UINT",
+ "srvFormat": "DXGI_FORMAT_R8_UINT",
+ "rtvFormat": "DXGI_FORMAT_R8_UINT"
+ }
+ ],
+ "GL_R8_SNORM": [
+ {
+ "texFormat": "DXGI_FORMAT_R8_SNORM",
+ "srvFormat": "DXGI_FORMAT_R8_SNORM"
+ }
+ ],
+ "GL_RG16F": [
+ {
+ "texFormat": "DXGI_FORMAT_R16G16_FLOAT",
+ "srvFormat": "DXGI_FORMAT_R16G16_FLOAT",
+ "rtvFormat": "DXGI_FORMAT_R16G16_FLOAT"
+ }
+ ],
+ "GL_RG16I": [
+ {
+ "texFormat": "DXGI_FORMAT_R16G16_SINT",
+ "srvFormat": "DXGI_FORMAT_R16G16_SINT",
+ "rtvFormat": "DXGI_FORMAT_R16G16_SINT"
+ }
+ ],
+ "GL_RG16UI": [
+ {
+ "texFormat": "DXGI_FORMAT_R16G16_UINT",
+ "srvFormat": "DXGI_FORMAT_R16G16_UINT",
+ "rtvFormat": "DXGI_FORMAT_R16G16_UINT"
+ }
+ ],
+ "GL_RG32F": [
+ {
+ "texFormat": "DXGI_FORMAT_R32G32_FLOAT",
+ "srvFormat": "DXGI_FORMAT_R32G32_FLOAT",
+ "rtvFormat": "DXGI_FORMAT_R32G32_FLOAT"
+ }
+ ],
+ "GL_RG32I": [
+ {
+ "texFormat": "DXGI_FORMAT_R32G32_SINT",
+ "srvFormat": "DXGI_FORMAT_R32G32_SINT",
+ "rtvFormat": "DXGI_FORMAT_R32G32_SINT"
+ }
+ ],
+ "GL_RG32UI": [
+ {
+ "texFormat": "DXGI_FORMAT_R32G32_UINT",
+ "srvFormat": "DXGI_FORMAT_R32G32_UINT",
+ "rtvFormat": "DXGI_FORMAT_R32G32_UINT"
+ }
+ ],
+ "GL_RG8": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8_UNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8_UNORM",
+ "rtvFormat": "DXGI_FORMAT_R8G8_UNORM"
+ }
+ ],
+ "GL_RG8I": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8_SINT",
+ "srvFormat": "DXGI_FORMAT_R8G8_SINT",
+ "rtvFormat": "DXGI_FORMAT_R8G8_SINT"
+ }
+ ],
+ "GL_RG8UI": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8_UINT",
+ "srvFormat": "DXGI_FORMAT_R8G8_UINT",
+ "rtvFormat": "DXGI_FORMAT_R8G8_UINT"
+ }
+ ],
+ "GL_RG8_SNORM": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8_SNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8_SNORM"
+ }
+ ],
+ "GL_RGB": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM"
+ }
+ ],
+ "GL_RGB10_A2": [
+ {
+ "texFormat": "DXGI_FORMAT_R10G10B10A2_UNORM",
+ "srvFormat": "DXGI_FORMAT_R10G10B10A2_UNORM",
+ "rtvFormat": "DXGI_FORMAT_R10G10B10A2_UNORM"
+ }
+ ],
+ "GL_RGB10_A2UI": [
+ {
+ "texFormat": "DXGI_FORMAT_R10G10B10A2_UINT",
+ "srvFormat": "DXGI_FORMAT_R10G10B10A2_UINT",
+ "rtvFormat": "DXGI_FORMAT_R10G10B10A2_UINT"
+ }
+ ],
+ "GL_RGB16F": [
+ {
+ "texFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "srvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "rtvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT"
+ }
+ ],
+ "GL_RGB16I": [
+ {
+ "texFormat": "DXGI_FORMAT_R16G16B16A16_SINT",
+ "srvFormat": "DXGI_FORMAT_R16G16B16A16_SINT",
+ "rtvFormat": "DXGI_FORMAT_R16G16B16A16_SINT"
+ }
+ ],
+ "GL_RGB16UI": [
+ {
+ "texFormat": "DXGI_FORMAT_R16G16B16A16_UINT",
+ "srvFormat": "DXGI_FORMAT_R16G16B16A16_UINT",
+ "rtvFormat": "DXGI_FORMAT_R16G16B16A16_UINT"
+ }
+ ],
+ "GL_RGB32F": [
+ {
+ "texFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
+ "srvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
+ "rtvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT"
+ }
+ ],
+ "GL_RGB32I": [
+ {
+ "texFormat": "DXGI_FORMAT_R32G32B32A32_SINT",
+ "srvFormat": "DXGI_FORMAT_R32G32B32A32_SINT",
+ "rtvFormat": "DXGI_FORMAT_R32G32B32A32_SINT"
+ }
+ ],
+ "GL_RGB32UI": [
+ {
+ "texFormat": "DXGI_FORMAT_R32G32B32A32_UINT",
+ "srvFormat": "DXGI_FORMAT_R32G32B32A32_UINT",
+ "rtvFormat": "DXGI_FORMAT_R32G32B32A32_UINT"
+ }
+ ],
+ "GL_RGB565": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "requirementsFcn": "SupportsFormat<DXGI_FORMAT_B5G6R5_UNORM,false>"
+ },
+ {
+ "texFormat": "DXGI_FORMAT_B5G6R5_UNORM",
+ "srvFormat": "DXGI_FORMAT_B5G6R5_UNORM",
+ "rtvFormat": "DXGI_FORMAT_B5G6R5_UNORM",
+ "requirementsFcn": "SupportsFormat<DXGI_FORMAT_B5G6R5_UNORM,true>"
+ }
+ ],
+ "GL_RGB5_A1": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "requirementsFcn": "SupportsFormat<DXGI_FORMAT_B5G5R5A1_UNORM,false>"
+ },
+ {
+ "texFormat": "DXGI_FORMAT_B5G5R5A1_UNORM",
+ "srvFormat": "DXGI_FORMAT_B5G5R5A1_UNORM",
+ "rtvFormat": "DXGI_FORMAT_B5G5R5A1_UNORM",
+ "requirementsFcn": "SupportsFormat<DXGI_FORMAT_B5G5R5A1_UNORM,true>"
+ }
+ ],
+ "GL_RGB8": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM"
+ }
+ ],
+ "GL_RGB8I": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_SINT",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_SINT",
+ "rtvFormat": "DXGI_FORMAT_R8G8B8A8_SINT"
+ }
+ ],
+ "GL_RGB8UI": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UINT",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UINT",
+ "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UINT"
+ }
+ ],
+ "GL_RGB8_SNORM": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_SNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_SNORM"
+ }
+ ],
+ "GL_RGB9_E5": [
+ {
+ "texFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP",
+ "srvFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP"
+ }
+ ],
+ "GL_RGBA": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM"
+ }
+ ],
+ "GL_RGBA16F": [
+ {
+ "texFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "srvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
+ "rtvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT"
+ }
+ ],
+ "GL_RGBA16I": [
+ {
+ "texFormat": "DXGI_FORMAT_R16G16B16A16_SINT",
+ "srvFormat": "DXGI_FORMAT_R16G16B16A16_SINT",
+ "rtvFormat": "DXGI_FORMAT_R16G16B16A16_SINT"
+ }
+ ],
+ "GL_RGBA16UI": [
+ {
+ "texFormat": "DXGI_FORMAT_R16G16B16A16_UINT",
+ "srvFormat": "DXGI_FORMAT_R16G16B16A16_UINT",
+ "rtvFormat": "DXGI_FORMAT_R16G16B16A16_UINT"
+ }
+ ],
+ "GL_RGBA32F": [
+ {
+ "texFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
+ "srvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
+ "rtvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT"
+ }
+ ],
+ "GL_RGBA32I": [
+ {
+ "texFormat": "DXGI_FORMAT_R32G32B32A32_SINT",
+ "srvFormat": "DXGI_FORMAT_R32G32B32A32_SINT",
+ "rtvFormat": "DXGI_FORMAT_R32G32B32A32_SINT"
+ }
+ ],
+ "GL_RGBA32UI": [
+ {
+ "texFormat": "DXGI_FORMAT_R32G32B32A32_UINT",
+ "srvFormat": "DXGI_FORMAT_R32G32B32A32_UINT",
+ "rtvFormat": "DXGI_FORMAT_R32G32B32A32_UINT"
+ }
+ ],
+ "GL_RGBA4": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "requirementsFcn": "SupportsFormat<DXGI_FORMAT_B4G4R4A4_UNORM,false>"
+ },
+ {
+ "texFormat": "DXGI_FORMAT_B4G4R4A4_UNORM",
+ "srvFormat": "DXGI_FORMAT_B4G4R4A4_UNORM",
+ "rtvFormat": "DXGI_FORMAT_B4G4R4A4_UNORM",
+ "requirementsFcn": "SupportsFormat<DXGI_FORMAT_B4G4R4A4_UNORM,true>"
+ }
+ ],
+ "GL_RGBA8": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
+ "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM"
+ }
+ ],
+ "GL_RGBA8I": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_SINT",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_SINT",
+ "rtvFormat": "DXGI_FORMAT_R8G8B8A8_SINT"
+ }
+ ],
+ "GL_RGBA8UI": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UINT",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UINT",
+ "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UINT"
+ }
+ ],
+ "GL_RGBA8_SNORM": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_SNORM",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_SNORM"
+ }
+ ],
+ "GL_SRGB8": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB"
+ }
+ ],
+ "GL_SRGB8_ALPHA8": [
+ {
+ "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB",
+ "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB",
+ "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB"
+ }
+ ],
+ "GL_STENCIL_INDEX8": [
+ {
+ "texFormat": "DXGI_FORMAT_R24G8_TYPELESS",
+ "srvFormat": "DXGI_FORMAT_X24_TYPELESS_G8_UINT",
+ "dsvFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT",
+ "requirementsFcn": "OnlyFL10Plus"
+ },
+ {
+ "texFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT",
+ "dsvFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT",
+ "requirementsFcn": "OnlyFL9_3"
+ }
+ ]
+}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h
new file mode 100644
index 0000000000..1606a28a73
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h
@@ -0,0 +1,64 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// texture_format_table:
+// Queries for full textureFormat information based on internalFormat
+//
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_TEXTUREFORMATTABLE_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_TEXTUREFORMATTABLE_H_
+
+#include <map>
+
+#include "common/platform.h"
+#include "libANGLE/renderer/d3d/formatutilsD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+
+namespace rx
+{
+
+namespace d3d11
+{
+
+struct LoadImageFunctionInfo
+{
+ LoadImageFunctionInfo() : loadFunction(nullptr), requiresConversion(false) {}
+ LoadImageFunctionInfo(LoadImageFunction loadFunction, bool requiresConversion)
+ : loadFunction(loadFunction), requiresConversion(requiresConversion)
+ {
+ }
+
+ LoadImageFunction loadFunction;
+ bool requiresConversion;
+};
+
+struct TextureFormat
+{
+ TextureFormat();
+
+ DXGI_FORMAT texFormat;
+ DXGI_FORMAT srvFormat;
+ DXGI_FORMAT rtvFormat;
+ DXGI_FORMAT dsvFormat;
+ DXGI_FORMAT renderFormat;
+
+ DXGI_FORMAT swizzleTexFormat;
+ DXGI_FORMAT swizzleSRVFormat;
+ DXGI_FORMAT swizzleRTVFormat;
+
+ InitializeTextureDataFunction dataInitializerFunction;
+ typedef std::map<GLenum, LoadImageFunctionInfo> LoadFunctionMap;
+
+ LoadFunctionMap loadFunctions;
+};
+
+const TextureFormat &GetTextureFormatInfo(GLenum internalformat,
+ const Renderer11DeviceCaps &renderer11DeviceCaps);
+
+} // namespace d3d11
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_TEXTUREFORMATTABLE_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp
new file mode 100644
index 0000000000..0b214c9756
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp
@@ -0,0 +1,1791 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_texture_format_table.py using data from texture_format_data.json
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// texture_format_table:
+// Queries for full textureFormat information based in internalFormat
+//
+
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
+
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.h"
+#include "libANGLE/renderer/d3d/d3d11/load_functions_table.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/d3d11/swizzle_format_info.h"
+#include "libANGLE/renderer/d3d/loadimage.h"
+
+namespace rx
+{
+
+namespace d3d11
+{
+
+namespace
+{
+
+typedef bool (*FormatSupportFunction)(const Renderer11DeviceCaps &);
+
+bool AnyDevice(const Renderer11DeviceCaps &deviceCaps)
+{
+ return true;
+}
+
+bool OnlyFL10Plus(const Renderer11DeviceCaps &deviceCaps)
+{
+ return (deviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0);
+}
+
+bool OnlyFL9_3(const Renderer11DeviceCaps &deviceCaps)
+{
+ return (deviceCaps.featureLevel == D3D_FEATURE_LEVEL_9_3);
+}
+
+template <DXGI_FORMAT format, bool requireSupport>
+bool SupportsFormat(const Renderer11DeviceCaps &deviceCaps)
+{
+ // Must support texture, SRV and RTV support
+ UINT mustSupport = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURECUBE |
+ D3D11_FORMAT_SUPPORT_SHADER_SAMPLE | D3D11_FORMAT_SUPPORT_MIP |
+ D3D11_FORMAT_SUPPORT_RENDER_TARGET;
+
+ if (d3d11_gl::GetMaximumClientVersion(deviceCaps.featureLevel) > 2)
+ {
+ mustSupport |= D3D11_FORMAT_SUPPORT_TEXTURE3D;
+ }
+
+ bool fullSupport = false;
+ if (format == DXGI_FORMAT_B5G6R5_UNORM)
+ {
+ // All hardware that supports DXGI_FORMAT_B5G6R5_UNORM should support autogen mipmaps, but
+ // check anyway.
+ mustSupport |= D3D11_FORMAT_SUPPORT_MIP_AUTOGEN;
+ fullSupport = ((deviceCaps.B5G6R5support & mustSupport) == mustSupport);
+ }
+ else if (format == DXGI_FORMAT_B4G4R4A4_UNORM)
+ {
+ fullSupport = ((deviceCaps.B4G4R4A4support & mustSupport) == mustSupport);
+ }
+ else if (format == DXGI_FORMAT_B5G5R5A1_UNORM)
+ {
+ fullSupport = ((deviceCaps.B5G5R5A1support & mustSupport) == mustSupport);
+ }
+ else
+ {
+ UNREACHABLE();
+ return false;
+ }
+
+ // This 'SupportsFormat' function is used by individual entries in the D3D11 Format Map below,
+ // which maps GL formats to DXGI formats.
+ if (requireSupport)
+ {
+ // This means that ANGLE would like to use the entry in the map if the inputted DXGI format
+ // *IS* supported.
+ // e.g. the entry might map GL_RGB5_A1 to DXGI_FORMAT_B5G5R5A1, which should only be used if
+ // DXGI_FORMAT_B5G5R5A1 is supported.
+ // In this case, we should only return 'true' if the format *IS* supported.
+ return fullSupport;
+ }
+ else
+ {
+ // This means that ANGLE would like to use the entry in the map if the inputted DXGI format
+ // *ISN'T* supported.
+ // This might be a fallback entry. e.g. for ANGLE to use DXGI_FORMAT_R8G8B8A8_UNORM if
+ // DXGI_FORMAT_B5G5R5A1 isn't supported.
+ // In this case, we should only return 'true' if the format *ISN'T* supported.
+ return !fullSupport;
+ }
+}
+
+// End Format Support Functions
+
+// For sized GL internal formats, there are several possible corresponding D3D11 formats depending
+// on device capabilities.
+// This function allows querying for the DXGI texture formats to use for textures, SRVs, RTVs and
+// DSVs given a GL internal format.
+const TextureFormat GetD3D11FormatInfo(GLenum internalFormat,
+ DXGI_FORMAT texFormat,
+ DXGI_FORMAT srvFormat,
+ DXGI_FORMAT rtvFormat,
+ DXGI_FORMAT dsvFormat)
+{
+ TextureFormat info;
+ info.texFormat = texFormat;
+ info.srvFormat = srvFormat;
+ info.rtvFormat = rtvFormat;
+ info.dsvFormat = dsvFormat;
+
+ // Given a GL internal format, the renderFormat is the DSV format if it is depth- or
+ // stencil-renderable,
+ // the RTV format if it is color-renderable, and the (nonrenderable) texture format otherwise.
+ if (dsvFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ info.renderFormat = dsvFormat;
+ }
+ else if (rtvFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ info.renderFormat = rtvFormat;
+ }
+ else if (texFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ info.renderFormat = texFormat;
+ }
+ else
+ {
+ info.renderFormat = DXGI_FORMAT_UNKNOWN;
+ }
+
+ // Compute the swizzle formats
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
+ if (internalFormat != GL_NONE && formatInfo.pixelBytes > 0)
+ {
+ if (formatInfo.componentCount != 4 || texFormat == DXGI_FORMAT_UNKNOWN ||
+ srvFormat == DXGI_FORMAT_UNKNOWN || rtvFormat == DXGI_FORMAT_UNKNOWN)
+ {
+ // Get the maximum sized component
+ unsigned int maxBits = 1;
+ if (formatInfo.compressed)
+ {
+ unsigned int compressedBitsPerBlock = formatInfo.pixelBytes * 8;
+ unsigned int blockSize =
+ formatInfo.compressedBlockWidth * formatInfo.compressedBlockHeight;
+ maxBits = std::max(compressedBitsPerBlock / blockSize, maxBits);
+ }
+ else
+ {
+ maxBits = std::max(maxBits, formatInfo.alphaBits);
+ maxBits = std::max(maxBits, formatInfo.redBits);
+ maxBits = std::max(maxBits, formatInfo.greenBits);
+ maxBits = std::max(maxBits, formatInfo.blueBits);
+ maxBits = std::max(maxBits, formatInfo.luminanceBits);
+ maxBits = std::max(maxBits, formatInfo.depthBits);
+ }
+
+ maxBits = roundUp(maxBits, 8U);
+
+ const SwizzleFormatInfo &swizzleInfo =
+ GetSwizzleFormatInfo(maxBits, formatInfo.componentType);
+ info.swizzleTexFormat = swizzleInfo.mTexFormat;
+ info.swizzleSRVFormat = swizzleInfo.mSRVFormat;
+ info.swizzleRTVFormat = swizzleInfo.mRTVFormat;
+ }
+ else
+ {
+ // The original texture format is suitable for swizzle operations
+ info.swizzleTexFormat = texFormat;
+ info.swizzleSRVFormat = srvFormat;
+ info.swizzleRTVFormat = rtvFormat;
+ }
+ }
+ else
+ {
+ // Not possible to swizzle with this texture format since it is either unsized or GL_NONE
+ info.swizzleTexFormat = DXGI_FORMAT_UNKNOWN;
+ info.swizzleSRVFormat = DXGI_FORMAT_UNKNOWN;
+ info.swizzleRTVFormat = DXGI_FORMAT_UNKNOWN;
+ }
+
+ // Check if there is an initialization function for this texture format
+ info.dataInitializerFunction = GetInternalFormatInitializer(internalFormat, texFormat);
+ // Gather all the load functions for this internal format
+ info.loadFunctions = GetLoadFunctionsMap(internalFormat, texFormat);
+
+ ASSERT(info.loadFunctions.size() != 0 || internalFormat == GL_NONE);
+
+ return info;
+}
+
+} // namespace
+
+TextureFormat::TextureFormat()
+ : texFormat(DXGI_FORMAT_UNKNOWN),
+ srvFormat(DXGI_FORMAT_UNKNOWN),
+ rtvFormat(DXGI_FORMAT_UNKNOWN),
+ dsvFormat(DXGI_FORMAT_UNKNOWN),
+ renderFormat(DXGI_FORMAT_UNKNOWN),
+ swizzleTexFormat(DXGI_FORMAT_UNKNOWN),
+ swizzleSRVFormat(DXGI_FORMAT_UNKNOWN),
+ swizzleRTVFormat(DXGI_FORMAT_UNKNOWN),
+ dataInitializerFunction(NULL),
+ loadFunctions()
+{
+}
+
+const TextureFormat &GetTextureFormatInfo(GLenum internalFormat,
+ const Renderer11DeviceCaps &renderer11DeviceCaps)
+{
+ // clang-format off
+ switch (internalFormat)
+ {
+ case GL_ALPHA:
+ {
+ if (OnlyFL10Plus(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_A8_UNORM,
+ DXGI_FORMAT_A8_UNORM,
+ DXGI_FORMAT_A8_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else if (OnlyFL9_3(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_ALPHA16F_EXT:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_ALPHA32F_EXT:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_ALPHA8_EXT:
+ {
+ if (OnlyFL10Plus(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_A8_UNORM,
+ DXGI_FORMAT_A8_UNORM,
+ DXGI_FORMAT_A8_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else if (OnlyFL9_3(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_BGR5_A1_ANGLEX:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_BGRA4_ANGLEX:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_BGRA8_EXT:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_BGRA_EXT:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_COMPRESSED_R11_EAC:
+ {
+ if (OnlyFL10Plus(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8_UNORM,
+ DXGI_FORMAT_R8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_COMPRESSED_RG11_EAC:
+ {
+ if (OnlyFL10Plus(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8_UNORM,
+ DXGI_FORMAT_R8G8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_COMPRESSED_RGB8_ETC2:
+ {
+ if (OnlyFL10Plus(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ {
+ if (OnlyFL10Plus(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_COMPRESSED_RGBA8_ETC2_EAC:
+ {
+ if (OnlyFL10Plus(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_BC1_UNORM,
+ DXGI_FORMAT_BC1_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_BC2_UNORM,
+ DXGI_FORMAT_BC2_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_BC3_UNORM,
+ DXGI_FORMAT_BC3_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_BC1_UNORM,
+ DXGI_FORMAT_BC1_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_COMPRESSED_SIGNED_R11_EAC:
+ {
+ if (OnlyFL10Plus(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8_SNORM,
+ DXGI_FORMAT_R8_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_COMPRESSED_SIGNED_RG11_EAC:
+ {
+ if (OnlyFL10Plus(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8_SNORM,
+ DXGI_FORMAT_R8G8_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+ {
+ if (OnlyFL10Plus(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_COMPRESSED_SRGB8_ETC2:
+ {
+ if (OnlyFL10Plus(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ {
+ if (OnlyFL10Plus(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_DEPTH24_STENCIL8:
+ {
+ if (OnlyFL9_3(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_D24_UNORM_S8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D24_UNORM_S8_UINT);
+ return textureFormat;
+ }
+ else if (OnlyFL10Plus(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R24G8_TYPELESS,
+ DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D24_UNORM_S8_UINT);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_DEPTH32F_STENCIL8:
+ {
+ if (OnlyFL9_3(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else if (OnlyFL10Plus(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R32G8X24_TYPELESS,
+ DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D32_FLOAT_S8X24_UINT);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_DEPTH_COMPONENT16:
+ {
+ if (OnlyFL9_3(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_D16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D16_UNORM);
+ return textureFormat;
+ }
+ else if (OnlyFL10Plus(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R16_TYPELESS,
+ DXGI_FORMAT_R16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D16_UNORM);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_DEPTH_COMPONENT24:
+ {
+ if (OnlyFL9_3(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_D24_UNORM_S8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D24_UNORM_S8_UINT);
+ return textureFormat;
+ }
+ else if (OnlyFL10Plus(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R24G8_TYPELESS,
+ DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D24_UNORM_S8_UINT);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_DEPTH_COMPONENT32F:
+ {
+ if (OnlyFL9_3(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else if (OnlyFL10Plus(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R32_TYPELESS,
+ DXGI_FORMAT_R32_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D32_FLOAT);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_DEPTH_COMPONENT32_OES:
+ {
+ if (OnlyFL10Plus(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R24G8_TYPELESS,
+ DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D24_UNORM_S8_UINT);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_BC1_UNORM,
+ DXGI_FORMAT_BC1_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_ETC1_RGB8_OES:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_LUMINANCE:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_LUMINANCE16F_EXT:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_LUMINANCE32F_EXT:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_LUMINANCE8_ALPHA8_EXT:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_LUMINANCE8_EXT:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_LUMINANCE_ALPHA:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_LUMINANCE_ALPHA16F_EXT:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_LUMINANCE_ALPHA32F_EXT:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_NONE:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_R11F_G11F_B10F:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R11G11B10_FLOAT,
+ DXGI_FORMAT_R11G11B10_FLOAT,
+ DXGI_FORMAT_R11G11B10_FLOAT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_R16F:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R16_FLOAT,
+ DXGI_FORMAT_R16_FLOAT,
+ DXGI_FORMAT_R16_FLOAT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_R16I:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R16_SINT,
+ DXGI_FORMAT_R16_SINT,
+ DXGI_FORMAT_R16_SINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_R16UI:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R16_UINT,
+ DXGI_FORMAT_R16_UINT,
+ DXGI_FORMAT_R16_UINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_R32F:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R32_FLOAT,
+ DXGI_FORMAT_R32_FLOAT,
+ DXGI_FORMAT_R32_FLOAT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_R32I:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R32_SINT,
+ DXGI_FORMAT_R32_SINT,
+ DXGI_FORMAT_R32_SINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_R32UI:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R32_UINT,
+ DXGI_FORMAT_R32_UINT,
+ DXGI_FORMAT_R32_UINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_R8:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8_UNORM,
+ DXGI_FORMAT_R8_UNORM,
+ DXGI_FORMAT_R8_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_R8I:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8_SINT,
+ DXGI_FORMAT_R8_SINT,
+ DXGI_FORMAT_R8_SINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_R8UI:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8_UINT,
+ DXGI_FORMAT_R8_UINT,
+ DXGI_FORMAT_R8_UINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_R8_SNORM:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8_SNORM,
+ DXGI_FORMAT_R8_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RG16F:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R16G16_FLOAT,
+ DXGI_FORMAT_R16G16_FLOAT,
+ DXGI_FORMAT_R16G16_FLOAT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RG16I:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R16G16_SINT,
+ DXGI_FORMAT_R16G16_SINT,
+ DXGI_FORMAT_R16G16_SINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RG16UI:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R16G16_UINT,
+ DXGI_FORMAT_R16G16_UINT,
+ DXGI_FORMAT_R16G16_UINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RG32F:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R32G32_FLOAT,
+ DXGI_FORMAT_R32G32_FLOAT,
+ DXGI_FORMAT_R32G32_FLOAT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RG32I:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R32G32_SINT,
+ DXGI_FORMAT_R32G32_SINT,
+ DXGI_FORMAT_R32G32_SINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RG32UI:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R32G32_UINT,
+ DXGI_FORMAT_R32G32_UINT,
+ DXGI_FORMAT_R32G32_UINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RG8:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8_UNORM,
+ DXGI_FORMAT_R8G8_UNORM,
+ DXGI_FORMAT_R8G8_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RG8I:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8_SINT,
+ DXGI_FORMAT_R8G8_SINT,
+ DXGI_FORMAT_R8G8_SINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RG8UI:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8_UINT,
+ DXGI_FORMAT_R8G8_UINT,
+ DXGI_FORMAT_R8G8_UINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RG8_SNORM:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8_SNORM,
+ DXGI_FORMAT_R8G8_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGB:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGB10_A2:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R10G10B10A2_UNORM,
+ DXGI_FORMAT_R10G10B10A2_UNORM,
+ DXGI_FORMAT_R10G10B10A2_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGB10_A2UI:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R10G10B10A2_UINT,
+ DXGI_FORMAT_R10G10B10A2_UINT,
+ DXGI_FORMAT_R10G10B10A2_UINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGB16F:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGB16I:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R16G16B16A16_SINT,
+ DXGI_FORMAT_R16G16B16A16_SINT,
+ DXGI_FORMAT_R16G16B16A16_SINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGB16UI:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R16G16B16A16_UINT,
+ DXGI_FORMAT_R16G16B16A16_UINT,
+ DXGI_FORMAT_R16G16B16A16_UINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGB32F:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGB32I:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R32G32B32A32_SINT,
+ DXGI_FORMAT_R32G32B32A32_SINT,
+ DXGI_FORMAT_R32G32B32A32_SINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGB32UI:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R32G32B32A32_UINT,
+ DXGI_FORMAT_R32G32B32A32_UINT,
+ DXGI_FORMAT_R32G32B32A32_UINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGB565:
+ {
+ if (SupportsFormat<DXGI_FORMAT_B5G6R5_UNORM,false>(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else if (SupportsFormat<DXGI_FORMAT_B5G6R5_UNORM,true>(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_B5G6R5_UNORM,
+ DXGI_FORMAT_B5G6R5_UNORM,
+ DXGI_FORMAT_B5G6R5_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGB5_A1:
+ {
+ if (SupportsFormat<DXGI_FORMAT_B5G5R5A1_UNORM,false>(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else if (SupportsFormat<DXGI_FORMAT_B5G5R5A1_UNORM,true>(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_B5G5R5A1_UNORM,
+ DXGI_FORMAT_B5G5R5A1_UNORM,
+ DXGI_FORMAT_B5G5R5A1_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGB8:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGB8I:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_SINT,
+ DXGI_FORMAT_R8G8B8A8_SINT,
+ DXGI_FORMAT_R8G8B8A8_SINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGB8UI:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UINT,
+ DXGI_FORMAT_R8G8B8A8_UINT,
+ DXGI_FORMAT_R8G8B8A8_UINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGB8_SNORM:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_SNORM,
+ DXGI_FORMAT_R8G8B8A8_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGB9_E5:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R9G9B9E5_SHAREDEXP,
+ DXGI_FORMAT_R9G9B9E5_SHAREDEXP,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGBA:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGBA16F:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGBA16I:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R16G16B16A16_SINT,
+ DXGI_FORMAT_R16G16B16A16_SINT,
+ DXGI_FORMAT_R16G16B16A16_SINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGBA16UI:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R16G16B16A16_UINT,
+ DXGI_FORMAT_R16G16B16A16_UINT,
+ DXGI_FORMAT_R16G16B16A16_UINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGBA32F:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGBA32I:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R32G32B32A32_SINT,
+ DXGI_FORMAT_R32G32B32A32_SINT,
+ DXGI_FORMAT_R32G32B32A32_SINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGBA32UI:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R32G32B32A32_UINT,
+ DXGI_FORMAT_R32G32B32A32_UINT,
+ DXGI_FORMAT_R32G32B32A32_UINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGBA4:
+ {
+ if (SupportsFormat<DXGI_FORMAT_B4G4R4A4_UNORM,false>(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else if (SupportsFormat<DXGI_FORMAT_B4G4R4A4_UNORM,true>(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_B4G4R4A4_UNORM,
+ DXGI_FORMAT_B4G4R4A4_UNORM,
+ DXGI_FORMAT_B4G4R4A4_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGBA8:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGBA8I:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_SINT,
+ DXGI_FORMAT_R8G8B8A8_SINT,
+ DXGI_FORMAT_R8G8B8A8_SINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGBA8UI:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UINT,
+ DXGI_FORMAT_R8G8B8A8_UINT,
+ DXGI_FORMAT_R8G8B8A8_UINT,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_RGBA8_SNORM:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_SNORM,
+ DXGI_FORMAT_R8G8B8A8_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_SRGB8:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_SRGB8_ALPHA8:
+ {
+ if (AnyDevice(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+ case GL_STENCIL_INDEX8:
+ {
+ if (OnlyFL9_3(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_D24_UNORM_S8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D24_UNORM_S8_UINT);
+ return textureFormat;
+ }
+ else if (OnlyFL10Plus(renderer11DeviceCaps))
+ {
+ static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat,
+ DXGI_FORMAT_R24G8_TYPELESS,
+ DXGI_FORMAT_X24_TYPELESS_G8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D24_UNORM_S8_UINT);
+ return textureFormat;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ default:
+ break;
+ }
+ // clang-format on
+
+ static const TextureFormat defaultInfo;
+ return defaultInfo;
+} // GetTextureFormatInfo
+
+} // namespace d3d11
+
+} // namespace rx
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp
index 696dfd72f8..da6460b136 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp
@@ -7,19 +7,42 @@
// NativeWindow.cpp: Handler for managing HWND native window types.
#include "libANGLE/renderer/d3d/d3d11/NativeWindow.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "common/debug.h"
+#include <initguid.h>
+#if !defined(__MINGW32__)
+#include <dcomp.h>
+#endif
+
namespace rx
{
-NativeWindow::NativeWindow(EGLNativeWindowType window) : mWindow(window)
+NativeWindow::NativeWindow(EGLNativeWindowType window,
+ const egl::Config *config,
+ bool directComposition)
+ : mWindow(window),
+ mDirectComposition(directComposition),
+ mDevice(nullptr),
+ mCompositionTarget(nullptr),
+ mVisual(nullptr),
+ mConfig(config)
{
}
+NativeWindow::~NativeWindow()
+{
+#if !defined(__MINGW32__)
+ SafeRelease(mCompositionTarget);
+ SafeRelease(mDevice);
+ SafeRelease(mVisual);
+#endif
+}
+
bool NativeWindow::initialize()
-{
- return true;
+{
+ return true;
}
bool NativeWindow::getClientRect(LPRECT rect)
@@ -47,7 +70,117 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory
return E_INVALIDARG;
}
- DXGI_SWAP_CHAIN_DESC swapChainDesc = { 0 };
+#if !defined(__MINGW32__)
+ if (mDirectComposition)
+ {
+ HMODULE dcomp = ::GetModuleHandle(TEXT("dcomp.dll"));
+ if (!dcomp)
+ {
+ return E_INVALIDARG;
+ }
+
+ typedef HRESULT(WINAPI * PFN_DCOMPOSITION_CREATE_DEVICE)(
+ IDXGIDevice * dxgiDevice, REFIID iid, void **dcompositionDevice);
+ PFN_DCOMPOSITION_CREATE_DEVICE createDComp =
+ reinterpret_cast<PFN_DCOMPOSITION_CREATE_DEVICE>(
+ GetProcAddress(dcomp, "DCompositionCreateDevice"));
+ if (!createDComp)
+ {
+ return E_INVALIDARG;
+ }
+
+ if (!mDevice)
+ {
+ IDXGIDevice *dxgiDevice = d3d11::DynamicCastComObject<IDXGIDevice>(device);
+ HRESULT result = createDComp(dxgiDevice, __uuidof(IDCompositionDevice),
+ reinterpret_cast<void **>(&mDevice));
+ SafeRelease(dxgiDevice);
+
+ if (FAILED(result))
+ {
+ return result;
+ }
+ }
+
+ if (!mCompositionTarget)
+ {
+ HRESULT result = mDevice->CreateTargetForHwnd(mWindow, TRUE, &mCompositionTarget);
+ if (FAILED(result))
+ {
+ return result;
+ }
+ }
+
+ if (!mVisual)
+ {
+ HRESULT result = mDevice->CreateVisual(&mVisual);
+ if (FAILED(result))
+ {
+ return result;
+ }
+ }
+
+ IDXGIFactory2 *factory2 = d3d11::DynamicCastComObject<IDXGIFactory2>(factory);
+ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
+ swapChainDesc.Width = width;
+ swapChainDesc.Height = height;
+ swapChainDesc.Format = format;
+ swapChainDesc.Stereo = FALSE;
+ swapChainDesc.SampleDesc.Count = 1;
+ swapChainDesc.SampleDesc.Quality = 0;
+ swapChainDesc.BufferUsage =
+ DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_SHADER_INPUT;
+ swapChainDesc.BufferCount = 2;
+ swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
+ swapChainDesc.AlphaMode =
+ mConfig->alphaSize == 0 ? DXGI_ALPHA_MODE_IGNORE : DXGI_ALPHA_MODE_PREMULTIPLIED;
+ swapChainDesc.Flags = 0;
+ IDXGISwapChain1 *swapChain1 = nullptr;
+ HRESULT result =
+ factory2->CreateSwapChainForComposition(device, &swapChainDesc, nullptr, &swapChain1);
+ if (SUCCEEDED(result))
+ {
+ *swapChain = static_cast<DXGISwapChain *>(swapChain1);
+ }
+ mVisual->SetContent(swapChain1);
+ mCompositionTarget->SetRoot(mVisual);
+ SafeRelease(factory2);
+ return result;
+ }
+
+ // Use IDXGIFactory2::CreateSwapChainForHwnd if DXGI 1.2 is available to create a DXGI_SWAP_EFFECT_SEQUENTIAL swap chain.
+ IDXGIFactory2 *factory2 = d3d11::DynamicCastComObject<IDXGIFactory2>(factory);
+ if (factory2 != nullptr)
+ {
+ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 };
+ swapChainDesc.Width = width;
+ swapChainDesc.Height = height;
+ swapChainDesc.Format = format;
+ swapChainDesc.Stereo = FALSE;
+ swapChainDesc.SampleDesc.Count = 1;
+ swapChainDesc.SampleDesc.Quality = 0;
+ swapChainDesc.BufferUsage =
+ DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_BACK_BUFFER;
+ swapChainDesc.BufferCount = 1;
+ swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL;
+ swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
+ swapChainDesc.Flags = 0;
+ IDXGISwapChain1 *swapChain1 = nullptr;
+ HRESULT result = factory2->CreateSwapChainForHwnd(device, mWindow, &swapChainDesc, nullptr, nullptr, &swapChain1);
+ if (SUCCEEDED(result))
+ {
+ const HRESULT makeWindowAssociationResult = factory->MakeWindowAssociation(mWindow, DXGI_MWA_NO_ALT_ENTER);
+ UNUSED_VARIABLE(makeWindowAssociationResult);
+ *swapChain = static_cast<DXGISwapChain*>(swapChain1);
+ }
+ SafeRelease(factory2);
+ return result;
+ }
+#endif // !__MINGW32__
+
+ DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
swapChainDesc.BufferCount = 1;
swapChainDesc.BufferDesc.Format = format;
swapChainDesc.BufferDesc.Width = width;
@@ -56,7 +189,8 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
- swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
+ swapChainDesc.BufferUsage =
+ DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_BACK_BUFFER;
swapChainDesc.Flags = 0;
swapChainDesc.OutputWindow = mWindow;
swapChainDesc.SampleDesc.Count = 1;
@@ -68,9 +202,19 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory
if (SUCCEEDED(result))
{
const HRESULT makeWindowAssociationResult = factory->MakeWindowAssociation(mWindow, DXGI_MWA_NO_ALT_ENTER);
- UNUSED_TRACE_VARIABLE(makeWindowAssociationResult);
+ UNUSED_VARIABLE(makeWindowAssociationResult);
}
return result;
}
#endif
+
+void NativeWindow::commitChange()
+{
+#if !defined(__MINGW32__)
+ if (mDevice)
+ {
+ mDevice->Commit();
+ }
+#endif
+}
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp
index f45a077d97..f401db614b 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp
@@ -23,7 +23,6 @@ bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet
ComPtr<IPropertySet> props = propertySet;
ComPtr<IInspectable> win = window;
SIZE swapChainSize = {};
- bool swapChainSizeSpecified = false;
HRESULT result = S_OK;
// IPropertySet is an optional parameter and can be null.
@@ -32,12 +31,40 @@ bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet
if (propertySet)
{
result = props.As(&mPropertyMap);
- if (SUCCEEDED(result))
+ if (FAILED(result))
+ {
+ return false;
+ }
+
+ // The EGLRenderSurfaceSizeProperty is optional and may be missing. The IPropertySet
+ // was prevalidated to contain the EGLNativeWindowType before being passed to
+ // this host.
+ result = GetOptionalSizePropertyValue(mPropertyMap, EGLRenderSurfaceSizeProperty, &swapChainSize, &mSwapChainSizeSpecified);
+ if (FAILED(result))
+ {
+ return false;
+ }
+
+ // The EGLRenderResolutionScaleProperty is optional and may be missing. The IPropertySet
+ // was prevalidated to contain the EGLNativeWindowType before being passed to
+ // this host.
+ result = GetOptionalSinglePropertyValue(mPropertyMap, EGLRenderResolutionScaleProperty, &mSwapChainScale, &mSwapChainScaleSpecified);
+ if (FAILED(result))
+ {
+ return false;
+ }
+
+ if (!mSwapChainScaleSpecified)
{
- // The EGLRenderSurfaceSizeProperty is optional and may be missing. The IPropertySet
- // was prevalidated to contain the EGLNativeWindowType before being passed to
- // this host.
- result = GetOptionalSizePropertyValue(mPropertyMap, EGLRenderSurfaceSizeProperty, &swapChainSize, &swapChainSizeSpecified);
+ // Default value for the scale is 1.0f
+ mSwapChainScale = 1.0f;
+ }
+
+ // A EGLRenderSurfaceSizeProperty and a EGLRenderResolutionScaleProperty can't both be specified
+ if (mSwapChainScaleSpecified && mSwapChainSizeSpecified)
+ {
+ ERR("It is invalid to specify both an EGLRenderSurfaceSizeProperty and a EGLRenderResolutionScaleProperty.");
+ return false;
}
}
@@ -54,14 +81,19 @@ bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet
// of the host.
// Scaling of the swapchain output occurs automatically because if
// the scaling mode setting DXGI_SCALING_STRETCH on the swapchain.
- if (swapChainSizeSpecified)
+ if (mSwapChainSizeSpecified)
{
mClientRect = { 0, 0, swapChainSize.cx, swapChainSize.cy };
- mSupportsSwapChainResize = false;
}
else
{
- result = GetCoreWindowSizeInPixels(mCoreWindow, &mClientRect);
+ SIZE coreWindowSize;
+ result = GetCoreWindowSizeInPixels(mCoreWindow, &coreWindowSize);
+
+ if (SUCCEEDED(result))
+ {
+ mClientRect = { 0, 0, static_cast<long>(coreWindowSize.cx * mSwapChainScale), static_cast<long>(coreWindowSize.cy * mSwapChainScale) };
+ }
}
}
@@ -118,17 +150,25 @@ void CoreWindowNativeWindow::unregisterForSizeChangeEvents()
{
(void)mCoreWindow->remove_SizeChanged(mSizeChangedEventToken);
}
+
#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
if (mDisplayInformation)
{
(void)mDisplayInformation->remove_OrientationChanged(mOrientationChangedEventToken);
}
#endif
+
mSizeChangedEventToken.value = 0;
mOrientationChangedEventToken.value = 0;
}
-HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain)
+HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device,
+ DXGIFactory *factory,
+ DXGI_FORMAT format,
+ unsigned int width,
+ unsigned int height,
+ bool containsAlpha,
+ DXGISwapChain **swapChain)
{
if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0)
{
@@ -142,10 +182,12 @@ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactor
swapChainDesc.Stereo = FALSE;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
- swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
+ swapChainDesc.BufferUsage =
+ DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
swapChainDesc.BufferCount = 2;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
+ swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
*swapChain = nullptr;
@@ -180,13 +222,20 @@ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactor
return result;
}
-HRESULT GetCoreWindowSizeInPixels(const ComPtr<ABI::Windows::UI::Core::ICoreWindow>& coreWindow, RECT *windowSize)
+inline HRESULT CoreWindowNativeWindow::scaleSwapChain(const Size &windowSize, const RECT &clientRect)
+{
+ // We don't need to do any additional work to scale CoreWindow swapchains.
+ // Using DXGI_SCALING_STRETCH to create the swapchain above does all the necessary work.
+ return S_OK;
+}
+
+HRESULT GetCoreWindowSizeInPixels(const ComPtr<ABI::Windows::UI::Core::ICoreWindow>& coreWindow, SIZE *windowSize)
{
ABI::Windows::Foundation::Rect bounds;
HRESULT result = coreWindow->get_Bounds(&bounds);
if (SUCCEEDED(result))
{
- *windowSize = { 0, 0, ConvertDipsToPixels(bounds.Width), ConvertDipsToPixels(bounds.Height) };
+ *windowSize = { ConvertDipsToPixels(bounds.Width), ConvertDipsToPixels(bounds.Height) };
}
return result;
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h
index 87cdfe6f22..fc1cd124a1 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h
@@ -19,16 +19,25 @@ typedef ABI::Windows::Foundation::__FITypedEventHandler_2_Windows__CGraphics__CD
namespace rx
{
-
class CoreWindowNativeWindow : public InspectableNativeWindow, public std::enable_shared_from_this<CoreWindowNativeWindow>
{
public:
~CoreWindowNativeWindow();
- bool initialize(EGLNativeWindowType window, IPropertySet *propertySet);
+ bool initialize(EGLNativeWindowType window, IPropertySet *propertySet) override;
+ HRESULT createSwapChain(ID3D11Device *device,
+ DXGIFactory *factory,
+ DXGI_FORMAT format,
+ unsigned int width,
+ unsigned int height,
+ bool containsAlpha,
+ DXGISwapChain **swapChain) override;
+
+ protected:
+ HRESULT scaleSwapChain(const Size &windowSize, const RECT &clientRect) override;
+
bool registerForSizeChangeEvents();
void unregisterForSizeChangeEvents();
- HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain);
private:
ComPtr<ABI::Windows::UI::Core::ICoreWindow> mCoreWindow;
@@ -70,39 +79,40 @@ class CoreWindowSizeChangedHandler :
return S_OK;
}
- IFACEMETHOD(Invoke)(ABI::Windows::Graphics::Display::IDisplayInformation *displayInformation, IInspectable *)
- {
-#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
- NativeWindow::RotationFlags flags = NativeWindow::RotateNone;
- ABI::Windows::Graphics::Display::DisplayOrientations orientation;
- if (SUCCEEDED(displayInformation->get_CurrentOrientation(&orientation)))
+ IFACEMETHOD(Invoke)(ABI::Windows::Graphics::Display::IDisplayInformation *displayInformation, IInspectable *)
{
- switch (orientation)
+ #if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+ NativeWindow::RotationFlags flags = NativeWindow::RotateNone;
+ ABI::Windows::Graphics::Display::DisplayOrientations orientation;
+ if (SUCCEEDED(displayInformation->get_CurrentOrientation(&orientation)))
{
- case ABI::Windows::Graphics::Display::DisplayOrientations_Landscape:
- flags = NativeWindow::RotateLeft;
- break;
- case ABI::Windows::Graphics::Display::DisplayOrientations_LandscapeFlipped:
- flags = NativeWindow::RotateRight;
- break;
- default:
- break;
+ switch (orientation)
+ {
+ case ABI::Windows::Graphics::Display::DisplayOrientations_Landscape:
+ flags = NativeWindow::RotateLeft;
+ break;
+ case ABI::Windows::Graphics::Display::DisplayOrientations_LandscapeFlipped:
+ flags = NativeWindow::RotateRight;
+ break;
+ default:
+ break;
+ }
}
+ std::shared_ptr<InspectableNativeWindow> host = mHost.lock();
+ if (host)
+ {
+ host->setRotationFlags(flags);
+ }
+ #endif
+ return S_OK;
}
- std::shared_ptr<InspectableNativeWindow> host = mHost.lock();
- if (host)
- {
- host->setRotationFlags(flags);
- }
-#endif
- return S_OK;
- }
+
private:
std::weak_ptr<InspectableNativeWindow> mHost;
};
-HRESULT GetCoreWindowSizeInPixels(const ComPtr<ABI::Windows::UI::Core::ICoreWindow>& coreWindow, RECT *windowSize);
+HRESULT GetCoreWindowSizeInPixels(const ComPtr<ABI::Windows::UI::Core::ICoreWindow>& coreWindow, SIZE *windowSize);
}
#endif // LIBANGLE_RENDERER_D3D_D3D11_WINRT_COREWINDOWNATIVEWINDOW_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp
index e83f47929f..aacfadd2f0 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp
@@ -11,9 +11,20 @@
namespace rx
{
-NativeWindow::NativeWindow(EGLNativeWindowType window)
+NativeWindow::NativeWindow(EGLNativeWindowType window,
+ const egl::Config *config,
+ bool directComposition)
{
mWindow = window;
+ mConfig = config;
+}
+
+NativeWindow::~NativeWindow()
+{
+}
+
+void NativeWindow::commitChange()
+{
}
bool NativeWindow::initialize()
@@ -95,7 +106,9 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory
{
if (mImpl)
{
- return mImpl->createSwapChain(device, factory, format, width, height, swapChain);
+ bool containsAlpha = (mConfig->alphaSize > 0);
+ return mImpl->createSwapChain(device, factory, format, width, height, containsAlpha,
+ swapChain);
}
return E_UNEXPECTED;
@@ -209,16 +222,47 @@ bool IsEGLConfiguredPropertySet(EGLNativeWindowType window, ABI::Windows::Founda
// A Valid EGLNativeWindowType IInspectable can only be:
//
// ICoreWindow
+// ISwapChainPanel
// IPropertySet
-//
+//
// Anything else will be rejected as an invalid IInspectable.
bool IsValidEGLNativeWindowType(EGLNativeWindowType window)
{
return IsCoreWindow(window) || IsSwapChainPanel(window) || IsEGLConfiguredPropertySet(window);
}
+// Retrieve an optional property from a property set
+HRESULT GetOptionalPropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>> &propertyMap,
+ const wchar_t *propertyName,
+ boolean *hasKey,
+ ComPtr<ABI::Windows::Foundation::IPropertyValue> &propertyValue)
+{
+ if (!propertyMap || !hasKey)
+ {
+ return E_INVALIDARG;
+ }
+
+ // Assume that the value does not exist
+ *hasKey = false;
+
+ HRESULT result = propertyMap->HasKey(HStringReference(propertyName).Get(), hasKey);
+ if (SUCCEEDED(result) && !(*hasKey))
+ {
+ // Value does not exist, so return S_OK and set the exists parameter to false to indicate
+ // that a the optional property does not exist.
+ return S_OK;
+ }
+
+ if (SUCCEEDED(result))
+ {
+ result = propertyMap->Lookup(HStringReference(propertyName).Get(), &propertyValue);
+ }
+
+ return result;
+}
+
// Attempts to read an optional SIZE property value that is assumed to be in the form of
-// an ABI::Windows::Foundation::Size. This function validates the Size value before returning
+// an ABI::Windows::Foundation::Size. This function validates the Size value before returning
// it to the caller.
//
// Possible return values are:
@@ -229,62 +273,110 @@ bool IsValidEGLNativeWindowType(EGLNativeWindowType window)
// * Invalid property value (width/height must be > 0)
// Additional errors may be returned from IMap or IPropertyValue
//
-HRESULT GetOptionalSizePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>>& propertyMap, const wchar_t *propertyName, SIZE *value, bool *valueExists)
+HRESULT GetOptionalSizePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>> &propertyMap,
+ const wchar_t *propertyName, SIZE *value, bool *valueExists)
{
- if (!propertyMap || !propertyName || !value || !valueExists)
+ ComPtr<ABI::Windows::Foundation::IPropertyValue> propertyValue;
+ ABI::Windows::Foundation::PropertyType propertyType = ABI::Windows::Foundation::PropertyType::PropertyType_Empty;
+ Size sizeValue = { 0, 0 };
+ boolean hasKey = false;
+
+ if (!propertyMap || !value || !valueExists)
{
- return false;
+ return E_INVALIDARG;
}
// Assume that the value does not exist
*valueExists = false;
*value = { 0, 0 };
+ HRESULT result = GetOptionalPropertyValue(propertyMap, propertyName, &hasKey, propertyValue);
+ if (SUCCEEDED(result) && hasKey)
+ {
+ result = propertyValue->get_Type(&propertyType);
+
+ // Check if the expected Size property is of PropertyType_Size type.
+ if (SUCCEEDED(result) && propertyType == ABI::Windows::Foundation::PropertyType::PropertyType_Size)
+ {
+ if (SUCCEEDED(propertyValue->GetSize(&sizeValue)) && (sizeValue.Width > 0 && sizeValue.Height > 0))
+ {
+ // A valid property value exists
+ *value = { static_cast<long>(sizeValue.Width), static_cast<long>(sizeValue.Height) };
+ *valueExists = true;
+ result = S_OK;
+ }
+ else
+ {
+ // An invalid Size property was detected. Width/Height values must > 0
+ result = E_INVALIDARG;
+ }
+ }
+ else
+ {
+ // An invalid property type was detected. Size property must be of PropertyType_Size
+ result = E_INVALIDARG;
+ }
+ }
+
+ return result;
+}
+
+// Attempts to read an optional float property value that is assumed to be in the form of
+// an ABI::Windows::Foundation::Single. This function validates the Single value before returning
+// it to the caller.
+//
+// Possible return values are:
+// S_OK, valueExists == true - optional Single value was successfully retrieved and validated
+// S_OK, valueExists == false - optional Single value was not found
+// E_INVALIDARG, valueExists = false - optional Single value was malformed in the property set.
+// * Incorrect property type ( must be PropertyType_Single)
+// * Invalid property value (must be > 0)
+// Additional errors may be returned from IMap or IPropertyValue
+//
+HRESULT GetOptionalSinglePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>> &propertyMap,
+ const wchar_t *propertyName, float *value, bool *valueExists)
+{
ComPtr<ABI::Windows::Foundation::IPropertyValue> propertyValue;
ABI::Windows::Foundation::PropertyType propertyType = ABI::Windows::Foundation::PropertyType::PropertyType_Empty;
- Size sizeValue = { 0, 0 };
+ float scaleValue = 0.0f;
boolean hasKey = false;
- HRESULT result = propertyMap->HasKey(HStringReference(propertyName).Get(), &hasKey);
- if (SUCCEEDED(result) && !hasKey)
+ if (!propertyMap || !value || !valueExists)
{
- // Value does not exist, so return S_OK and set the exists parameter to false to indicate
- // that a the optional property does not exist.
- *valueExists = false;
- return S_OK;
+ return E_INVALIDARG;
}
- if (SUCCEEDED(result))
- {
- result = propertyMap->Lookup(HStringReference(propertyName).Get(), &propertyValue);
- }
+ // Assume that the value does not exist
+ *valueExists = false;
+ *value = 0.0f;
- if (SUCCEEDED(result))
+ HRESULT result = GetOptionalPropertyValue(propertyMap, propertyName, &hasKey, propertyValue);
+ if (SUCCEEDED(result) && hasKey)
{
result = propertyValue->get_Type(&propertyType);
- }
- // Check if the expected Size property is of PropertyType_Size type.
- if (SUCCEEDED(result) && propertyType == ABI::Windows::Foundation::PropertyType::PropertyType_Size)
- {
- if (SUCCEEDED(propertyValue->GetSize(&sizeValue)) && (sizeValue.Width > 0 && sizeValue.Height > 0))
+ // Check if the expected Scale property is of PropertyType_Single type.
+ if (SUCCEEDED(result) && propertyType == ABI::Windows::Foundation::PropertyType::PropertyType_Single)
{
- // A valid property value exists
- *value = { static_cast<long>(sizeValue.Width), static_cast<long>(sizeValue.Height) };
- *valueExists = true;
- result = S_OK;
+ if (SUCCEEDED(propertyValue->GetSingle(&scaleValue)) && (scaleValue > 0.0f))
+ {
+ // A valid property value exists
+ *value = scaleValue;
+ *valueExists = true;
+ result = S_OK;
+ }
+ else
+ {
+ // An invalid scale was set
+ result = E_INVALIDARG;
+ }
}
else
{
- // An invalid Size property was detected. Width/Height values must > 0
+ // An invalid property type was detected. Size property must be of PropertyType_Single
result = E_INVALIDARG;
}
}
- else
- {
- // An invalid property type was detected. Size property must be of PropertyType_Size
- result = E_INVALIDARG;
- }
return result;
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h
index f0534077ae..2d58f1c00a 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h
@@ -33,7 +33,9 @@ class InspectableNativeWindow
public:
InspectableNativeWindow() :
mSupportsSwapChainResize(true),
- mRequiresSwapChainScaling(false),
+ mSwapChainSizeSpecified(false),
+ mSwapChainScaleSpecified(false),
+ mSwapChainScale(1.0f),
mClientRectChanged(false),
mClientRect({0,0,0,0}),
mNewClientRect({0,0,0,0}),
@@ -44,14 +46,17 @@ class InspectableNativeWindow
virtual ~InspectableNativeWindow(){}
virtual bool initialize(EGLNativeWindowType window, IPropertySet *propertySet) = 0;
- virtual HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain) = 0;
- virtual bool registerForSizeChangeEvents() = 0;
- virtual void unregisterForSizeChangeEvents() = 0;
- virtual HRESULT scaleSwapChain(const Size& newSize) { return S_OK; }
+ virtual HRESULT createSwapChain(ID3D11Device *device,
+ DXGIFactory *factory,
+ DXGI_FORMAT format,
+ unsigned int width,
+ unsigned int height,
+ bool containsAlpha,
+ DXGISwapChain **swapChain) = 0;
bool getClientRect(RECT *rect)
{
- if (mClientRectChanged && mSupportsSwapChainResize)
+ if (mClientRectChanged)
{
mClientRect = mNewClientRect;
}
@@ -61,17 +66,34 @@ class InspectableNativeWindow
return true;
}
- void setNewClientSize(const Size &newSize)
+ // setNewClientSize is used by the WinRT size change handler. It isn't used by the rest of ANGLE.
+ void setNewClientSize(const Size &newWindowSize)
{
- if (mSupportsSwapChainResize)
- {
- mNewClientRect = { 0, 0, ConvertDipsToPixels(newSize.Width), ConvertDipsToPixels(newSize.Height) };
- mClientRectChanged = true;
- }
+ // If the client doesn't support swapchain resizing then we should have already unregistered from size change handler
+ ASSERT(mSupportsSwapChainResize);
- if (mRequiresSwapChainScaling)
+ if (mSupportsSwapChainResize)
{
- scaleSwapChain(newSize);
+ // If the swapchain size was specified then we should ignore this call too
+ if (!mSwapChainSizeSpecified)
+ {
+ // We don't have to check if a swapchain scale was specified here; the default value is 1.0f which will have no effect.
+ mNewClientRect = { 0, 0, ConvertDipsToPixels(newWindowSize.Width), ConvertDipsToPixels(newWindowSize.Height) };
+ mClientRectChanged = true;
+
+ // If a scale was specified, then now is the time to apply the scale matrix for the new swapchain size and window size
+ if (mSwapChainScaleSpecified)
+ {
+ scaleSwapChain(newWindowSize, mNewClientRect);
+ }
+ }
+
+ // Even if the swapchain size was fixed, the window might have changed size.
+ // In this case, we should recalculate the scale matrix to account for the new window size
+ if (mSwapChainSizeSpecified)
+ {
+ scaleSwapChain(newWindowSize, mClientRect);
+ }
}
}
@@ -85,9 +107,13 @@ class InspectableNativeWindow
mRotationFlags = flags;
}
-protected:
- bool mSupportsSwapChainResize;
- bool mRequiresSwapChainScaling;
+ protected:
+ virtual HRESULT scaleSwapChain(const Size &windowSize, const RECT &clientRect) = 0;
+
+ bool mSupportsSwapChainResize; // Support for IDXGISwapChain::ResizeBuffers method
+ bool mSwapChainSizeSpecified; // If an EGLRenderSurfaceSizeProperty was specified
+ bool mSwapChainScaleSpecified; // If an EGLRenderResolutionScaleProperty was specified
+ float mSwapChainScale; // The scale value specified by the EGLRenderResolutionScaleProperty property
RECT mClientRect;
RECT mNewClientRect;
bool mClientRectChanged;
@@ -100,8 +126,17 @@ bool IsValidEGLNativeWindowType(EGLNativeWindowType window);
bool IsCoreWindow(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Core::ICoreWindow> *coreWindow = nullptr);
bool IsSwapChainPanel(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> *swapChainPanel = nullptr);
bool IsEGLConfiguredPropertySet(EGLNativeWindowType window, ABI::Windows::Foundation::Collections::IPropertySet **propertySet = nullptr, IInspectable **inspectable = nullptr);
-HRESULT GetOptionalSizePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>>& propertyMap, const wchar_t *propertyName, SIZE *value, bool *valueExists);
+HRESULT GetOptionalPropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>> &propertyMap,
+ const wchar_t *propertyName,
+ boolean *hasKey,
+ ComPtr<ABI::Windows::Foundation::IPropertyValue> &propertyValue);
+
+HRESULT GetOptionalSizePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>> &propertyMap,
+ const wchar_t *propertyName, SIZE *value, bool *valueExists);
+
+HRESULT GetOptionalSinglePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>> &propertyMap,
+ const wchar_t *propertyName, float *value, bool *valueExists);
}
#endif // LIBANGLE_RENDERER_D3D_D3D11_WINRT_INSPECTABLENATIVEWINDOW_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp
index 0b48b54334..d3ed35b3c6 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp
@@ -11,7 +11,11 @@
#include <algorithm>
#include <math.h>
+using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Foundation::Collections;
+using namespace ABI::Windows::UI::Core;
+using namespace ABI::Windows::UI::Xaml;
+using namespace Microsoft::WRL;
namespace rx
{
@@ -20,12 +24,74 @@ SwapChainPanelNativeWindow::~SwapChainPanelNativeWindow()
unregisterForSizeChangeEvents();
}
+template <typename T>
+struct AddFtmBase
+{
+ typedef Implements<RuntimeClassFlags<ClassicCom>, T, FtmBase> Type;
+};
+
+template <typename CODE>
+HRESULT RunOnUIThread(CODE &&code, const ComPtr<ICoreDispatcher> &dispatcher)
+{
+ ComPtr<IAsyncAction> asyncAction;
+ HRESULT result = S_OK;
+
+ boolean hasThreadAccess;
+ result = dispatcher->get_HasThreadAccess(&hasThreadAccess);
+ if (FAILED(result))
+ {
+ return result;
+ }
+
+ if (hasThreadAccess)
+ {
+ return code();
+ }
+ else
+ {
+ Event waitEvent(CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS));
+ if (!waitEvent.IsValid())
+ {
+ return E_FAIL;
+ }
+
+ HRESULT codeResult = E_FAIL;
+ auto handler =
+ Callback<AddFtmBase<IDispatchedHandler>::Type>([&codeResult, &code, &waitEvent]
+ {
+ codeResult = code();
+ SetEvent(waitEvent.Get());
+ return S_OK;
+ });
+
+ result = dispatcher->RunAsync(CoreDispatcherPriority_Normal, handler.Get(),
+ asyncAction.GetAddressOf());
+ if (FAILED(result))
+ {
+ return result;
+ }
+
+ auto waitResult = WaitForSingleObjectEx(waitEvent.Get(), 10 * 1000, true);
+ if (waitResult != WAIT_OBJECT_0)
+ {
+ // Wait 10 seconds before giving up. At this point, the application is in an
+ // unrecoverable state (probably deadlocked). We therefore terminate the application
+ // entirely. This also prevents stack corruption if the async operation is eventually
+ // run.
+ ERR("Timeout waiting for async action on UI thread. The UI thread might be blocked.");
+ std::terminate();
+ return E_FAIL;
+ }
+
+ return codeResult;
+ }
+}
+
bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, IPropertySet *propertySet)
{
ComPtr<IPropertySet> props = propertySet;
ComPtr<IInspectable> win = window;
SIZE swapChainSize = {};
- bool swapChainSizeSpecified = false;
HRESULT result = S_OK;
// IPropertySet is an optional parameter and can be null.
@@ -34,12 +100,40 @@ bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, IPropert
if (propertySet)
{
result = props.As(&mPropertyMap);
- if (SUCCEEDED(result))
+ if (FAILED(result))
+ {
+ return false;
+ }
+
+ // The EGLRenderSurfaceSizeProperty is optional and may be missing. The IPropertySet
+ // was prevalidated to contain the EGLNativeWindowType before being passed to
+ // this host.
+ result = GetOptionalSizePropertyValue(mPropertyMap, EGLRenderSurfaceSizeProperty, &swapChainSize, &mSwapChainSizeSpecified);
+ if (FAILED(result))
+ {
+ return false;
+ }
+
+ // The EGLRenderResolutionScaleProperty is optional and may be missing. The IPropertySet
+ // was prevalidated to contain the EGLNativeWindowType before being passed to
+ // this host.
+ result = GetOptionalSinglePropertyValue(mPropertyMap, EGLRenderResolutionScaleProperty, &mSwapChainScale, &mSwapChainScaleSpecified);
+ if (FAILED(result))
+ {
+ return false;
+ }
+
+ if (!mSwapChainScaleSpecified)
+ {
+ // Default value for the scale is 1.0f
+ mSwapChainScale = 1.0f;
+ }
+
+ // A EGLRenderSurfaceSizeProperty and a EGLRenderResolutionScaleProperty can't both be specified
+ if (mSwapChainScaleSpecified && mSwapChainSizeSpecified)
{
- // The EGLRenderSurfaceSizeProperty is optional and may be missing. The IPropertySet
- // was prevalidated to contain the EGLNativeWindowType before being passed to
- // this host.
- result = GetOptionalSizePropertyValue(mPropertyMap, EGLRenderSurfaceSizeProperty, &swapChainSize, &swapChainSizeSpecified);
+ ERR("It is invalid to specify both an EGLRenderSurfaceSizeProperty and a EGLRenderResolutionScaleProperty.");
+ return false;
}
}
@@ -48,6 +142,18 @@ bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, IPropert
result = win.As(&mSwapChainPanel);
}
+ ComPtr<IDependencyObject> swapChainPanelDependencyObject;
+ if (SUCCEEDED(result))
+ {
+ result = mSwapChainPanel.As(&swapChainPanelDependencyObject);
+ }
+
+ if (SUCCEEDED(result))
+ {
+ result = swapChainPanelDependencyObject->get_Dispatcher(
+ mSwapChainPanelDispatcher.GetAddressOf());
+ }
+
if (SUCCEEDED(result))
{
// If a swapchain size is specfied, then the automatic resize
@@ -57,16 +163,24 @@ bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, IPropert
// Scaling of the swapchain output needs to be handled by the
// host for swapchain panels even though the scaling mode setting
// DXGI_SCALING_STRETCH is configured on the swapchain.
- if (swapChainSizeSpecified)
+ if (mSwapChainSizeSpecified)
{
mClientRect = { 0, 0, swapChainSize.cx, swapChainSize.cy };
-
- // Enable host swapchain scaling
- mRequiresSwapChainScaling = true;
}
else
{
- result = GetSwapChainPanelSize(mSwapChainPanel, &mClientRect, &mRequiresSwapChainScaling);
+ SIZE swapChainPanelSize;
+ result = GetSwapChainPanelSize(mSwapChainPanel, mSwapChainPanelDispatcher,
+ &swapChainPanelSize, &mSwapChainScale);
+ if (mSwapChainScale != 1.0f)
+ mSwapChainScaleSpecified = true;
+
+ if (SUCCEEDED(result))
+ {
+ // Update the client rect to account for any swapchain scale factor
+ mClientRect = { 0, 0, static_cast<long>(ConvertDipsToPixels(swapChainPanelSize.cx * mSwapChainScale)),
+ static_cast<long>(ConvertDipsToPixels(swapChainPanelSize.cy * mSwapChainScale)) };
+ }
}
}
@@ -82,8 +196,8 @@ bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, IPropert
bool SwapChainPanelNativeWindow::registerForSizeChangeEvents()
{
- ComPtr<ABI::Windows::UI::Xaml::ISizeChangedEventHandler> sizeChangedHandler;
- ComPtr<ABI::Windows::UI::Xaml::IFrameworkElement> frameworkElement;
+ ComPtr<ISizeChangedEventHandler> sizeChangedHandler;
+ ComPtr<IFrameworkElement> frameworkElement;
HRESULT result = Microsoft::WRL::MakeAndInitialize<SwapChainPanelSizeChangedHandler>(sizeChangedHandler.ReleaseAndGetAddressOf(), this->shared_from_this());
if (SUCCEEDED(result))
@@ -93,7 +207,13 @@ bool SwapChainPanelNativeWindow::registerForSizeChangeEvents()
if (SUCCEEDED(result))
{
- result = frameworkElement->add_SizeChanged(sizeChangedHandler.Get(), &mSizeChangedEventToken);
+ result = RunOnUIThread(
+ [this, frameworkElement, sizeChangedHandler]
+ {
+ return frameworkElement->add_SizeChanged(sizeChangedHandler.Get(),
+ &mSizeChangedEventToken);
+ },
+ mSwapChainPanelDispatcher);
}
if (SUCCEEDED(result))
@@ -106,16 +226,27 @@ bool SwapChainPanelNativeWindow::registerForSizeChangeEvents()
void SwapChainPanelNativeWindow::unregisterForSizeChangeEvents()
{
- ComPtr<ABI::Windows::UI::Xaml::IFrameworkElement> frameworkElement;
- if (SUCCEEDED(mSwapChainPanel.As(&frameworkElement)))
+ ComPtr<IFrameworkElement> frameworkElement;
+ if (mSwapChainPanel && SUCCEEDED(mSwapChainPanel.As(&frameworkElement)))
{
- (void)frameworkElement->remove_SizeChanged(mSizeChangedEventToken);
+ RunOnUIThread(
+ [this, frameworkElement]
+ {
+ return frameworkElement->remove_SizeChanged(mSizeChangedEventToken);
+ },
+ mSwapChainPanelDispatcher);
}
mSizeChangedEventToken.value = 0;
}
-HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain)
+HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device,
+ DXGIFactory *factory,
+ DXGI_FORMAT format,
+ unsigned int width,
+ unsigned int height,
+ bool containsAlpha,
+ DXGISwapChain **swapChain)
{
if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0)
{
@@ -129,11 +260,13 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFa
swapChainDesc.Stereo = FALSE;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
- swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
+ swapChainDesc.BufferUsage =
+ DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
swapChainDesc.BufferCount = 2;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
- swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
+ swapChainDesc.AlphaMode =
+ containsAlpha ? DXGI_ALPHA_MODE_PREMULTIPLIED : DXGI_ALPHA_MODE_IGNORE;
*swapChain = nullptr;
@@ -149,7 +282,12 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFa
if (SUCCEEDED(result))
{
- result = swapChainPanelNative->SetSwapChain(newSwapChain.Get());
+ result = RunOnUIThread(
+ [swapChainPanelNative, newSwapChain]
+ {
+ return swapChainPanelNative->SetSwapChain(newSwapChain.Get());
+ },
+ mSwapChainPanelDispatcher);
}
if (SUCCEEDED(result))
@@ -164,34 +302,28 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFa
// If the host is responsible for scaling the output of the swapchain, then
// scale it now before returning an instance to the caller. This is done by
// first reading the current size of the swapchain panel, then scaling
- if (SUCCEEDED(result) && mRequiresSwapChainScaling)
- {
- ComPtr<ABI::Windows::UI::Xaml::IUIElement> uiElement;
- result = mSwapChainPanel.As(&uiElement);
- ASSERT(SUCCEEDED(result));
-
- Size currentSize;
- result = uiElement->get_RenderSize(&currentSize);
- ASSERT(SUCCEEDED(result));
- result = scaleSwapChain(currentSize);
- }
-
if (SUCCEEDED(result))
{
- // If automatic swapchain resize behaviors have been disabled, then
- // unregister for the resize change events.
- if (mSupportsSwapChainResize == false)
+ if (mSwapChainSizeSpecified || mSwapChainScaleSpecified)
{
- unregisterForSizeChangeEvents();
+ ComPtr<ABI::Windows::UI::Xaml::IUIElement> uiElement;
+ result = mSwapChainPanel.As(&uiElement);
+ ASSERT(SUCCEEDED(result));
+
+ Size currentSize;
+ result = uiElement->get_RenderSize(&currentSize);
+ ASSERT(SUCCEEDED(result));
+ result = scaleSwapChain(currentSize, mClientRect);
}
}
return result;
}
-HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const Size &newSize)
+HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const Size &windowSize, const RECT &clientRect)
{
- ABI::Windows::Foundation::Size renderScale = { newSize.Width / mNewClientRect.right, newSize.Height / mNewClientRect.bottom };
+ Size renderScale = {windowSize.Width / clientRect.right,
+ windowSize.Height / clientRect.bottom};
// Setup a scale matrix for the swap chain
DXGI_MATRIX_3X2_F scaleMatrix = {};
scaleMatrix._11 = renderScale.Width;
@@ -207,25 +339,33 @@ HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const Size &newSize)
return result;
}
-HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize, bool *scalingActive)
+HRESULT GetSwapChainPanelSize(
+ const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel,
+ const ComPtr<ICoreDispatcher> &dispatcher,
+ SIZE *windowSize, float *scaleFactor)
{
- ComPtr<ABI::Windows::UI::Xaml::IUIElement> uiElement;
- ABI::Windows::Foundation::Size renderSize = { 0, 0 };
+ ComPtr<IUIElement> uiElement;
+ Size renderSize = {0, 0};
HRESULT result = swapChainPanel.As(&uiElement);
if (SUCCEEDED(result))
{
- result = uiElement->get_RenderSize(&renderSize);
+ result = RunOnUIThread(
+ [uiElement, &renderSize]
+ {
+ return uiElement->get_RenderSize(&renderSize);
+ },
+ dispatcher);
}
if (SUCCEEDED(result))
{
long width = ConvertDipsToPixels(renderSize.Width);
long height = ConvertDipsToPixels(renderSize.Height);
- *windowSize = { 0, 0, width, height };
+ *windowSize = { width, height };
- if (scalingActive)
+ if (scaleFactor)
{
- *scalingActive = width != renderSize.Width || height != renderSize.Height;
+ *scaleFactor = renderSize.Width / width;
}
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h
index 5debd2fd0b..09d87ad523 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h
@@ -18,14 +18,24 @@ class SwapChainPanelNativeWindow : public InspectableNativeWindow, public std::e
public:
~SwapChainPanelNativeWindow();
- bool initialize(EGLNativeWindowType window, IPropertySet *propertySet);
+ bool initialize(EGLNativeWindowType window, IPropertySet *propertySet) override;
+ HRESULT createSwapChain(ID3D11Device *device,
+ DXGIFactory *factory,
+ DXGI_FORMAT format,
+ unsigned int width,
+ unsigned int height,
+ bool containsAlpha,
+ DXGISwapChain **swapChain) override;
+
+ protected:
+ HRESULT scaleSwapChain(const Size &windowSize, const RECT &clientRect) override;
+
bool registerForSizeChangeEvents();
void unregisterForSizeChangeEvents();
- HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain);
- HRESULT scaleSwapChain(const Size &newSize) override;
private:
ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> mSwapChainPanel;
+ ComPtr<ABI::Windows::UI::Core::ICoreDispatcher> mSwapChainPanelDispatcher;
ComPtr<IMap<HSTRING, IInspectable*>> mPropertyMap;
ComPtr<DXGISwapChain> mSwapChain;
};
@@ -73,6 +83,9 @@ class SwapChainPanelSizeChangedHandler :
std::weak_ptr<InspectableNativeWindow> mHost;
};
-HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize, bool *scalingActive = nullptr);
+HRESULT GetSwapChainPanelSize(
+ const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel,
+ const ComPtr<ABI::Windows::UI::Core::ICoreDispatcher> &dispatcher,
+ SIZE *windowSize, float *scaleFactor);
}
#endif // LIBANGLE_RENDERER_D3D_D3D11_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_