diff options
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11')
67 files changed, 18598 insertions, 4366 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 ¶ms); + gl::Error packPixels(const gl::FramebufferAttachment &readAttachment, + const PackPixelsParams ¶ms); 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 ¶ms) +gl::Error Buffer11::packPixels(const gl::FramebufferAttachment &readAttachment, + const PackPixelsParams ¶ms) { - 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 ¶ms) +gl::Error Buffer11::PackStorage::packPixels(const gl::FramebufferAttachment &readAttachment, + const PackPixelsParams ¶ms) { 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 ¶ms); + gl::Error packPixels(const gl::FramebufferAttachment &readAttachment, + const PackPixelsParams ¶ms); + 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(¤tCounter); 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 ®ion) { - 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 ®ion); - 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..972c289412 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp @@ -18,7 +18,14 @@ typedef struct D3D11_QUERY_DATA_SO_STATISTICS { UINT64 NumPrimitivesWritten; UINT64 PrimitivesStorageNeeded; } D3D11_QUERY_DATA_SO_STATISTICS; -#endif +#endif // ANGLE_MINGW32_COMPAT + +#ifdef __MINGW32__ +typedef struct D3D11_QUERY_DATA_TIMESTAMP_DISJOINT { + UINT64 Frequency; + BOOL Disjoint; +} D3D11_QUERY_DATA_TIMESTAMP_DISJOINT; +#endif // MINGW32 namespace rx { @@ -28,38 +35,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 +117,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 +144,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 +177,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 +221,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 ¤tSRVs = (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 ¶ms, uint8_t *pixelsOut) +gl::Error Renderer11::packPixels(const TextureHelper11 &textureHelper, + const PackPixelsParams ¶ms, + 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 ¤tSRVs = (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 ¶ms, uint8_t *pixelsOut); + gl::Error packPixels(const TextureHelper11 &textureHelper, + const PackPixelsParams ¶ms, + 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 ¤tSRVs = (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 ¤tSRVs = (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 ¤tSRVs = (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, ¶ms); + } + 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, ¶ms); + } + } + 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 ¤tValue, - 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 ¤tValue, - 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(¤tSize); - 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(¤tSize); + 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_ |