diff options
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11')
32 files changed, 3016 insertions, 2626 deletions
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp index 9b0f336ac7..d43e65ea78 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -7,12 +6,12 @@ // Blit11.cpp: Texture copy utility class. -#include "libGLESv2/main.h" -#include "libGLESv2/formatutils.h" #include "libGLESv2/renderer/d3d/d3d11/Blit11.h" #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" +#include "libGLESv2/main.h" +#include "libGLESv2/formatutils.h" #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough2dvs.h" #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2dps.h" @@ -315,7 +314,6 @@ Blit11::Blit11(rx::Renderer11 *renderer) result = device->CreateGeometryShader(g_GS_Passthrough3D, ArraySize(g_GS_Passthrough3D), NULL, &mQuad3DGS); ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mQuad3DGS, "Renderer11 copy 3D texture geometry shader"); - } buildShaderMap(); @@ -373,18 +371,20 @@ static inline unsigned int GetSwizzleIndex(GLenum swizzle) return colorIndex; } -bool 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) { HRESULT result; ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc; source->GetDesc(&sourceSRVDesc); - GLenum sourceInternalFormat = d3d11_gl::GetInternalFormat(sourceSRVDesc.Format); + + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(sourceSRVDesc.Format); + const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(dxgiFormatInfo.internalFormat); GLenum shaderType = GL_NONE; - switch (gl::GetComponentType(sourceInternalFormat)) + switch (sourceFormatInfo.componentType) { case GL_UNSIGNED_NORMALIZED: case GL_SIGNED_NORMALIZED: @@ -410,7 +410,7 @@ bool Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderTarget if (i == mSwizzleShaderMap.end()) { UNREACHABLE(); - return false; + return gl::Error(GL_INVALID_OPERATION, "Internal error, missing swizzle shader."); } const Shader &shader = i->second; @@ -420,8 +420,7 @@ bool Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderTarget result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); if (FAILED(result)) { - ERR("Failed to map vertex buffer for texture swizzle, HRESULT: 0x%X.", result); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer for swizzle, HRESULT: 0x%X.", result); } UINT stride = 0; @@ -438,8 +437,7 @@ bool Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderTarget result = deviceContext->Map(mSwizzleCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); if (FAILED(result)) { - ERR("Failed to map constant buffer for texture swizzle, HRESULT: 0x%X.", result); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal constant buffer for swizzle, HRESULT: 0x%X.", result); } unsigned int *swizzleIndices = reinterpret_cast<unsigned int*>(mappedResource.pData); @@ -506,7 +504,7 @@ bool Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderTarget mRenderer->markAllStateDirty(); - return true; + return gl::Error(GL_NO_ERROR); } bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, @@ -520,11 +518,13 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source // be GL_XXXX_INTEGER but it does not tell us if it is signed or unsigned. D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc; source->GetDesc(&sourceSRVDesc); - GLenum sourceInternalFormat = d3d11_gl::GetInternalFormat(sourceSRVDesc.Format); + + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(sourceSRVDesc.Format); + const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(dxgiFormatInfo.internalFormat); BlitParameters parameters = { 0 }; parameters.mDestinationFormat = destFormat; - parameters.mSignedInteger = gl::GetComponentType(sourceInternalFormat) == GL_INT; + parameters.mSignedInteger = (internalFormatInfo.componentType == GL_INT); parameters.m3DBlit = sourceArea.depth > 1; BlitShaderMap::const_iterator i = mBlitShaderMap.find(parameters); @@ -770,18 +770,19 @@ bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubreso DXGI_FORMAT format = GetTextureFormat(source); ASSERT(format == GetTextureFormat(dest)); - unsigned int pixelSize = d3d11::GetFormatPixelBytes(format); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format); + unsigned int pixelSize = dxgiFormatInfo.pixelBytes; unsigned int copyOffset = 0; unsigned int copySize = pixelSize; if (stencilOnly) { - copyOffset = d3d11::GetStencilOffset(format) / 8; - copySize = d3d11::GetStencilBits(format) / 8; + copyOffset = dxgiFormatInfo.depthBits / 8; + copySize = dxgiFormatInfo.stencilBits / 8; // It would be expensive to have non-byte sized stencil sizes since it would // require reading from the destination, currently there aren't any though. - ASSERT(d3d11::GetStencilBits(format) % 8 == 0 && - d3d11::GetStencilOffset(format) % 8 == 0); + ASSERT(dxgiFormatInfo.stencilBits % 8 == 0 && + dxgiFormatInfo.depthBits % 8 == 0); } D3D11_MAPPED_SUBRESOURCE sourceMapping, destMapping; @@ -995,18 +996,17 @@ void Blit11::buildShaderMap() 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" )); - 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_RG, false, d3d11::CompilePS(device, g_PS_PassthroughRG3D, "Blit11 3D RG 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_RED, false, d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R 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" )); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h index fba89e20ba..d6a0b795f4 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h @@ -11,6 +11,9 @@ #include "common/angleutils.h" #include "libGLESv2/angletypes.h" +#include "libGLESv2/Error.h" + +#include <map> namespace rx { @@ -28,8 +31,8 @@ class Blit11 explicit Blit11(Renderer11 *renderer); ~Blit11(); - bool swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderTargetView *dest, const gl::Extents &size, - GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha); + gl::Error swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderTargetView *dest, const gl::Extents &size, + GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha); bool copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize, diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp index 1301124b2d..ecd4d4672b 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright 2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -8,13 +7,9 @@ // Buffer11.cpp Defines the Buffer11 class. #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h" -#include "libGLESv2/main.h" #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" - -#if defined(__MINGW32__) && !defined(D3D11_MAP_FLAG_DO_NOT_WAIT) -# define D3D11_MAP_FLAG_DO_NOT_WAIT 0x100000L -#endif +#include "libGLESv2/main.h" namespace rx { @@ -122,6 +117,8 @@ class Buffer11::NativeBuffer11 : public Buffer11::BufferStorage11 virtual void *map(size_t offset, size_t length, GLbitfield access); virtual void unmap(); + bool setData(D3D11_MAP mapMode, const uint8_t *data, size_t size, size_t offset); + private: ID3D11Buffer *mNativeBuffer; @@ -143,7 +140,7 @@ class Buffer11::PackStorage11 : public Buffer11::BufferStorage11 virtual void *map(size_t offset, size_t length, GLbitfield access); virtual void unmap(); - void packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams ¶ms); + gl::Error packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams ¶ms); private: @@ -166,12 +163,14 @@ Buffer11::Buffer11(Renderer11 *renderer) mMappedStorage(NULL), mResolvedDataRevision(0), mReadUsageCount(0) -{ -} +{} Buffer11::~Buffer11() { - clear(); + for (auto it = mBufferStorages.begin(); it != mBufferStorages.end(); it++) + { + SafeDelete(it->second); + } } Buffer11 *Buffer11::makeBuffer11(BufferImpl *buffer) @@ -180,29 +179,20 @@ Buffer11 *Buffer11::makeBuffer11(BufferImpl *buffer) return static_cast<Buffer11*>(buffer); } -void Buffer11::clear() +gl::Error Buffer11::setData(const void *data, size_t size, GLenum usage) { - for (auto it = mBufferStorages.begin(); it != mBufferStorages.end(); it++) + gl::Error error = setSubData(data, size, 0); + if (error.isError()) { - SafeDelete(it->second); + return error; } - mBufferStorages.clear(); - - mSize = 0; - mResolvedDataRevision = 0; -} - -void Buffer11::setData(const void* data, size_t size, GLenum usage) -{ - mIndexRangeCache.clear(); - - setSubData(data, size, 0); - if (usage == GL_STATIC_DRAW) { initializeStaticData(); } + + return error; } void *Buffer11::getData() @@ -243,16 +233,23 @@ void *Buffer11::getData() mReadUsageCount = 0; + // Only happens if we initialized the buffer with no data (NULL) + if (mResolvedData.empty()) + { + if (!mResolvedData.resize(mSize)) + { + return gl::error(GL_OUT_OF_MEMORY, (void*)NULL); + } + } + + ASSERT(mResolvedData.size() >= mSize); + return mResolvedData.data(); } -void Buffer11::setSubData(const void* data, size_t size, size_t offset) +gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset) { size_t requiredSize = size + offset; - mSize = std::max(mSize, requiredSize); - - mIndexRangeCache.invalidateRange(offset, size); - invalidateStaticData(); if (data && size > 0) { @@ -260,8 +257,7 @@ void Buffer11::setSubData(const void* data, size_t size, size_t offset) if (!stagingBuffer) { - // Out-of-memory - return; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal staging buffer."); } // Explicitly resize the staging buffer, preserving data if the new data will not @@ -271,65 +267,78 @@ void Buffer11::setSubData(const void* data, size_t size, size_t offset) bool preserveData = (offset > 0); if (!stagingBuffer->resize(requiredSize, preserveData)) { - // Out-of-memory - return; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal staging buffer."); } } - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - - D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = context->Map(stagingBuffer->getNativeBuffer(), 0, D3D11_MAP_WRITE, 0, &mappedResource); - if (FAILED(result)) + if (!stagingBuffer->setData(D3D11_MAP_WRITE, reinterpret_cast<const uint8_t *>(data), size, offset)) { - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to set data on internal staging buffer."); } - unsigned char *offsetBufferPointer = reinterpret_cast<unsigned char *>(mappedResource.pData) + offset; - memcpy(offsetBufferPointer, data, size); - - context->Unmap(stagingBuffer->getNativeBuffer(), 0); - stagingBuffer->setDataRevision(stagingBuffer->getDataRevision() + 1); } + + mSize = std::max(mSize, requiredSize); + invalidateStaticData(); + + return gl::Error(GL_NO_ERROR); } -void 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); - if (sourceBuffer) + ASSERT(sourceBuffer != NULL); + + BufferStorage11 *copyDest = getLatestBufferStorage(); + if (!copyDest) + { + copyDest = getStagingBuffer(); + } + + BufferStorage11 *copySource = sourceBuffer->getLatestBufferStorage(); + + if (!copySource || !copyDest) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal staging buffer."); + } + + // If copying to/from a pixel pack buffer, we must have a staging or + // pack buffer partner, because other native buffers can't be mapped + if (copyDest->getUsage() == BUFFER_USAGE_PIXEL_PACK && !copySource->isMappable()) { - BufferStorage11 *dest = getLatestBufferStorage(); - if (!dest) + copySource = sourceBuffer->getStagingBuffer(); + } + else if (copySource->getUsage() == BUFFER_USAGE_PIXEL_PACK && !copyDest->isMappable()) + { + copyDest = getStagingBuffer(); + } + + // D3D11 does not allow overlapped copies until 11.1, and only if the + // device supports D3D11_FEATURE_DATA_D3D11_OPTIONS::CopyWithOverlap + // Get around this via a different source buffer + if (copySource == copyDest) + { + if (copySource->getUsage() == BUFFER_USAGE_STAGING) { - dest = getStagingBuffer(); + copySource = getBufferStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); } - - BufferStorage11 *source = sourceBuffer->getLatestBufferStorage(); - if (source && dest) + else { - // If copying to/from a pixel pack buffer, we must have a staging or - // pack buffer partner, because other native buffers can't be mapped - if (dest->getUsage() == BUFFER_USAGE_PIXEL_PACK && !source->isMappable()) - { - source = sourceBuffer->getStagingBuffer(); - } - else if (source->getUsage() == BUFFER_USAGE_PIXEL_PACK && !dest->isMappable()) - { - dest = getStagingBuffer(); - } - - dest->copyFromStorage(source, sourceOffset, size, destOffset); - dest->setDataRevision(dest->getDataRevision() + 1); + copySource = getStagingBuffer(); } - - mSize = std::max<size_t>(mSize, destOffset + size); } + copyDest->copyFromStorage(copySource, sourceOffset, size, destOffset); + copyDest->setDataRevision(copyDest->getDataRevision() + 1); + + mSize = std::max<size_t>(mSize, destOffset + size); invalidateStaticData(); + + return gl::Error(GL_NO_ERROR); } -GLvoid *Buffer11::map(size_t offset, size_t length, GLbitfield access) +gl::Error Buffer11::map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) { ASSERT(!mMappedStorage); @@ -350,8 +359,7 @@ GLvoid *Buffer11::map(size_t offset, size_t length, GLbitfield access) if (!mMappedStorage) { - // Out-of-memory - return NULL; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate mappable internal buffer."); } if ((access & GL_MAP_WRITE_BIT) > 0) @@ -360,14 +368,22 @@ GLvoid *Buffer11::map(size_t offset, size_t length, GLbitfield access) mMappedStorage->setDataRevision(mMappedStorage->getDataRevision() + 1); } - return mMappedStorage->map(offset, length, access); + void *mappedBuffer = mMappedStorage->map(offset, length, access); + if (!mappedBuffer) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer."); + } + + *mapPtr = mappedBuffer; + return gl::Error(GL_NO_ERROR); } -void Buffer11::unmap() +gl::Error Buffer11::unmap() { ASSERT(mMappedStorage); mMappedStorage->unmap(); mMappedStorage = NULL; + return gl::Error(GL_NO_ERROR); } void Buffer11::markTransformFeedbackUsage() @@ -448,9 +464,11 @@ ID3D11ShaderResourceView *Buffer11::getSRV(DXGI_FORMAT srvFormat) ID3D11Device *device = mRenderer->getDevice(); ID3D11ShaderResourceView *bufferSRV = NULL; + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(srvFormat); + D3D11_SHADER_RESOURCE_VIEW_DESC bufferSRVDesc; bufferSRVDesc.Buffer.ElementOffset = 0; - bufferSRVDesc.Buffer.ElementWidth = mSize / d3d11::GetFormatPixelBytes(srvFormat); + bufferSRVDesc.Buffer.ElementWidth = mSize / dxgiFormatInfo.pixelBytes; bufferSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; bufferSRVDesc.Format = srvFormat; @@ -463,7 +481,7 @@ ID3D11ShaderResourceView *Buffer11::getSRV(DXGI_FORMAT srvFormat) return bufferSRV; } -void Buffer11::packPixels(ID3D11Texture2D *srcTexture, UINT srcSubresource, const PackPixelsParams ¶ms) +gl::Error Buffer11::packPixels(ID3D11Texture2D *srcTexture, UINT srcSubresource, const PackPixelsParams ¶ms) { PackStorage11 *packStorage = getPackStorage(); @@ -471,9 +489,15 @@ void Buffer11::packPixels(ID3D11Texture2D *srcTexture, UINT srcSubresource, cons if (packStorage) { - packStorage->packPixels(srcTexture, srcSubresource, params); + gl::Error error = packStorage->packPixels(srcTexture, srcSubresource, params); + if (error.isError()) + { + return error; + } packStorage->setDataRevision(latestStorage ? latestStorage->getDataRevision() + 1 : 1); } + + return gl::Error(GL_NO_ERROR); } Buffer11::BufferStorage11 *Buffer11::getBufferStorage(BufferUsage usage) @@ -584,6 +608,14 @@ Buffer11::PackStorage11 *Buffer11::getPackStorage() return static_cast<PackStorage11*>(packStorage); } +bool Buffer11::supportsDirectBinding() const +{ + // Do not support direct buffers for dynamic data. The streaming buffer + // offers better performance for data which changes every frame. + // Check for absence of static buffer interfaces to detect dynamic data. + return (mStaticVertexBuffer && mStaticIndexBuffer); +} + Buffer11::BufferStorage11::BufferStorage11(Renderer11 *renderer, BufferUsage usage) : mRenderer(renderer), mUsage(usage), @@ -605,7 +637,7 @@ Buffer11::NativeBuffer11::~NativeBuffer11() // Returns true if it recreates the direct buffer bool Buffer11::NativeBuffer11::copyFromStorage(BufferStorage11 *source, size_t sourceOffset, - size_t size, size_t destOffset) + size_t size, size_t destOffset) { ID3D11DeviceContext *context = mRenderer->getDeviceContext(); @@ -716,7 +748,7 @@ void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Ren case BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK: bufferDesc->Usage = D3D11_USAGE_DEFAULT; bufferDesc->BindFlags = D3D11_BIND_VERTEX_BUFFER; - if (renderer->getMaxTransformFeedbackBuffers() > 0) + if (!static_cast<Renderer11 *>(renderer)->isLevel9()) bufferDesc->BindFlags |= D3D11_BIND_STREAM_OUTPUT; bufferDesc->CPUAccessFlags = 0; break; @@ -741,7 +773,7 @@ void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Ren // 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(bufferDesc->ByteWidth, renderer->getMaxUniformBufferSize()); + bufferDesc->ByteWidth = std::min<UINT>(bufferDesc->ByteWidth, renderer->getRendererCaps().maxUniformBlockSize); break; default: @@ -765,6 +797,25 @@ void *Buffer11::NativeBuffer11::map(size_t offset, size_t length, GLbitfield acc return static_cast<GLubyte*>(mappedResource.pData) + offset; } +bool Buffer11::NativeBuffer11::setData(D3D11_MAP mapMode, const uint8_t *data, size_t size, size_t offset) +{ + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = context->Map(mNativeBuffer, 0, mapMode, 0, &mappedResource); + if (FAILED(result)) + { + return gl::error(GL_OUT_OF_MEMORY, false); + } + + uint8_t *offsetBufferPointer = reinterpret_cast<uint8_t *>(mappedResource.pData) + offset; + memcpy(offsetBufferPointer, data, size); + + context->Unmap(mNativeBuffer, 0); + + return true; +} + void Buffer11::NativeBuffer11::unmap() { ASSERT(mUsage == BUFFER_USAGE_STAGING); @@ -788,9 +839,11 @@ Buffer11::PackStorage11::~PackStorage11() } bool Buffer11::PackStorage11::copyFromStorage(BufferStorage11 *source, size_t sourceOffset, - size_t size, size_t destOffset) + size_t size, size_t destOffset) { - UNIMPLEMENTED(); + // We copy through a staging buffer when drawing with a pack buffer, + // or for other cases where we access the pack buffer + UNREACHABLE(); return false; } @@ -827,7 +880,7 @@ void Buffer11::PackStorage11::unmap() // No-op } -void Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams ¶ms) +gl::Error Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams ¶ms) { flushQueuedPackCommand(); mQueuedPackCommand = new PackPixelsParams(params); @@ -869,13 +922,15 @@ void Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSub stagingDesc.MiscFlags = 0; hr = device->CreateTexture2D(&stagingDesc, NULL, &mStagingTexture); - ASSERT(SUCCEEDED(hr)); + if (FAILED(hr)) + { + ASSERT(hr == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal staging texture."); + } } - if (textureDesc.SampleDesc.Count > 1) - { - UNIMPLEMENTED(); - } + // ReadPixels from multisampled FBOs isn't supported in current GL + ASSERT(textureDesc.SampleDesc.Count <= 1); ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); D3D11_BOX srcBox; @@ -888,6 +943,8 @@ void Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSub // Asynchronous copy immediateContext->CopySubresourceRegion(mStagingTexture, 0, 0, 0, 0, srcTexure, srcSubresource, &srcBox); + + return gl::Error(GL_NO_ERROR); } void Buffer11::PackStorage11::flushQueuedPackCommand() diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h index e56be247c4..5f24fb4e2d 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h @@ -55,21 +55,20 @@ class Buffer11 : public BufferD3D ID3D11Buffer *getBuffer(BufferUsage usage); ID3D11ShaderResourceView *getSRV(DXGI_FORMAT srvFormat); bool isMapped() const { return mMappedStorage != NULL; } - void packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams ¶ms); + gl::Error packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams ¶ms); // BufferD3D implementation virtual size_t getSize() const { return mSize; } - virtual void clear(); - virtual bool supportsDirectBinding() const { return true; } + virtual bool supportsDirectBinding() const; virtual Renderer* getRenderer(); // BufferImpl implementation - virtual void setData(const void* data, size_t size, GLenum usage); + virtual gl::Error setData(const void* data, size_t size, GLenum usage); virtual void *getData(); - virtual void setSubData(const void* data, size_t size, size_t offset); - virtual void copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); - virtual GLvoid* map(size_t offset, size_t length, GLbitfield access); - virtual void unmap(); + 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 void markTransformFeedbackUsage(); private: diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp index 5121950da0..765d34fd3f 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -11,11 +10,11 @@ #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h" - #include "libGLESv2/formatutils.h" #include "libGLESv2/Framebuffer.h" #include "libGLESv2/FramebufferAttachment.h" +// Precompiled shaders #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloatvs.h" #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloatps.h" @@ -155,7 +154,7 @@ Clear11::~Clear11() SafeRelease(mRasterizerState); } -void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) +gl::Error Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) { // First determine if a scissored clear is needed, this will always require drawing a quad. // @@ -190,7 +189,7 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame else { UNREACHABLE(); - return; + return gl::Error(GL_INVALID_OPERATION); } if (clearParams.scissorEnabled && (clearParams.scissor.x >= framebufferSize.width || @@ -199,7 +198,7 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame clearParams.scissor.y + clearParams.scissor.height <= 0)) { // Scissor is enabled and the scissor rectangle is outside the renderbuffer - return; + return gl::Error(GL_NO_ERROR); } bool needScissoredClear = clearParams.scissorEnabled && (clearParams.scissor.x > 0 || clearParams.scissor.y > 0 || @@ -218,41 +217,35 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(colorAttachment); if (attachment) { - RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(attachment->getRenderTarget()); + RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(attachment); if (!renderTarget) { - ERR("Render target pointer unexpectedly null."); - return; + return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null."); } - GLenum internalFormat = attachment->getInternalFormat(); - GLenum actualFormat = attachment->getActualFormat(); - GLenum componentType = gl::GetComponentType(internalFormat); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment->getInternalFormat()); + if (clearParams.colorClearType == GL_FLOAT && - !(componentType == GL_FLOAT || componentType == GL_UNSIGNED_NORMALIZED || componentType == GL_SIGNED_NORMALIZED)) + !(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, internalFormat); + "point to floating point values (color attachment %u has internal format 0x%X).", colorAttachment, + attachment->getInternalFormat()); } - GLuint internalRedBits = gl::GetRedBits(internalFormat); - GLuint internalGreenBits = gl::GetGreenBits(internalFormat); - GLuint internalBlueBits = gl::GetBlueBits(internalFormat); - GLuint internalAlphaBits = gl::GetAlphaBits(internalFormat); - - if ((internalRedBits == 0 || !clearParams.colorMaskRed) && - (internalGreenBits == 0 || !clearParams.colorMaskGreen) && - (internalBlueBits == 0 || !clearParams.colorMaskBlue) && - (internalAlphaBits == 0 || !clearParams.colorMaskAlpha)) + if ((formatInfo.redBits == 0 || !clearParams.colorMaskRed) && + (formatInfo.greenBits == 0 || !clearParams.colorMaskGreen) && + (formatInfo.blueBits == 0 || !clearParams.colorMaskBlue) && + (formatInfo.alphaBits == 0 || !clearParams.colorMaskAlpha)) { // Every channel either does not exist in the render target or is masked out continue; } else if (needScissoredClear || clearParams.colorClearType != GL_FLOAT || - (internalRedBits > 0 && !clearParams.colorMaskRed) || - (internalGreenBits > 0 && !clearParams.colorMaskGreen) || - (internalBlueBits > 0 && !clearParams.colorMaskBlue) || - (internalAlphaBits > 0 && !clearParams.colorMaskAlpha)) + (formatInfo.redBits > 0 && !clearParams.colorMaskRed) || + (formatInfo.greenBits > 0 && !clearParams.colorMaskGreen) || + (formatInfo.blueBits > 0 && !clearParams.colorMaskBlue) || + (formatInfo.alphaBits > 0 && !clearParams.colorMaskAlpha)) { // A scissored or masked clear is required MaskedRenderTarget maskAndRt; @@ -271,23 +264,19 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame ID3D11RenderTargetView *framebufferRTV = renderTarget->getRenderTargetView(); if (!framebufferRTV) { - ERR("Render target view pointer unexpectedly null."); - return; + return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null."); } + const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(attachment->getActualFormat()); + // Check if the actual format has a channel that the internal format does not and set them to the // default values - GLuint actualRedBits = gl::GetRedBits(actualFormat); - GLuint actualGreenBits = gl::GetGreenBits(actualFormat); - GLuint actualBlueBits = gl::GetBlueBits(actualFormat); - GLuint actualAlphaBits = gl::GetAlphaBits(actualFormat); - const float clearValues[4] = { - ((internalRedBits == 0 && actualRedBits > 0) ? 0.0f : clearParams.colorFClearValue.red), - ((internalGreenBits == 0 && actualGreenBits > 0) ? 0.0f : clearParams.colorFClearValue.green), - ((internalBlueBits == 0 && actualBlueBits > 0) ? 0.0f : clearParams.colorFClearValue.blue), - ((internalAlphaBits == 0 && actualAlphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha), + ((formatInfo.redBits == 0 && actualFormatInfo.redBits > 0) ? 0.0f : clearParams.colorFClearValue.red), + ((formatInfo.greenBits == 0 && actualFormatInfo.greenBits > 0) ? 0.0f : clearParams.colorFClearValue.green), + ((formatInfo.blueBits == 0 && actualFormatInfo.blueBits > 0) ? 0.0f : clearParams.colorFClearValue.blue), + ((formatInfo.alphaBits == 0 && actualFormatInfo.alphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha), }; deviceContext->ClearRenderTargetView(framebufferRTV, clearValues); @@ -301,16 +290,15 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame gl::FramebufferAttachment *attachment = frameBuffer->getDepthOrStencilbuffer(); if (attachment) { - RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(attachment->getDepthStencil()); + RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(attachment); if (!renderTarget) { - ERR("Depth stencil render target pointer unexpectedly null."); - return; + return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil view pointer unexpectedly null."); } - GLenum actualFormat = attachment->getActualFormat(); + const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(attachment->getActualFormat()); - unsigned int stencilUnmasked = frameBuffer->hasStencil() ? (1 << gl::GetStencilBits(actualFormat)) - 1 : 0; + unsigned int stencilUnmasked = frameBuffer->hasStencil() ? (1 << actualFormatInfo.stencilBits) - 1 : 0; bool needMaskedStencilClear = clearParams.clearStencil && (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked; if (needScissoredClear || needMaskedStencilClear) @@ -322,8 +310,7 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame ID3D11DepthStencilView *framebufferDSV = renderTarget->getDepthStencilView(); if (!framebufferDSV) { - ERR("Depth stencil view pointer unexpectedly null."); - return; + return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil view pointer unexpectedly null."); } UINT clearFlags = (clearParams.clearDepth ? D3D11_CLEAR_DEPTH : 0) | @@ -370,8 +357,7 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame ID3D11RenderTargetView *rtv = renderTarget->getRenderTargetView(); if (!rtv) { - ERR("Render target view unexpectedly null."); - return; + return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null."); } rtvs[i] = rtv; @@ -393,8 +379,7 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame HRESULT result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); if (FAILED(result)) { - ERR("Failed to map masked clear vertex buffer, HRESULT: 0x%X.", result); - return; + 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; @@ -459,6 +444,8 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame // Clean up mRenderer->markAllStateDirty(); } + + return gl::Error(GL_NO_ERROR); } ID3D11BlendState *Clear11::getBlendState(const std::vector<MaskedRenderTarget>& rts) @@ -469,12 +456,12 @@ ID3D11BlendState *Clear11::getBlendState(const std::vector<MaskedRenderTarget>& if (i < rts.size()) { RenderTarget11 *rt = rts[i].renderTarget; - GLint internalFormat = rt->getInternalFormat(); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(rt->getInternalFormat()); - blendKey.maskChannels[i][0] = (rts[i].colorMask[0] && gl::GetRedBits(internalFormat) > 0); - blendKey.maskChannels[i][1] = (rts[i].colorMask[1] && gl::GetGreenBits(internalFormat) > 0); - blendKey.maskChannels[i][2] = (rts[i].colorMask[2] && gl::GetBlueBits(internalFormat) > 0); - blendKey.maskChannels[i][3] = (rts[i].colorMask[3] && gl::GetAlphaBits(internalFormat) > 0); + blendKey.maskChannels[i][0] = (rts[i].colorMask[0] && formatInfo.redBits > 0); + blendKey.maskChannels[i][1] = (rts[i].colorMask[1] && formatInfo.greenBits > 0); + blendKey.maskChannels[i][2] = (rts[i].colorMask[2] && formatInfo.blueBits > 0); + blendKey.maskChannels[i][3] = (rts[i].colorMask[3] && formatInfo.alphaBits > 0); } else { diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h index 0cb9a85a6d..be8e187c40 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h @@ -10,6 +10,10 @@ #define LIBGLESV2_RENDERER_CLEAR11_H_ #include "libGLESv2/angletypes.h" +#include "libGLESv2/Error.h" + +#include <map> +#include <vector> namespace gl { @@ -28,7 +32,7 @@ class Clear11 ~Clear11(); // Clears the framebuffer with the supplied clear parameters, assumes that the framebuffer is currently applied. - void clearFramebuffer(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); + gl::Error clearFramebuffer(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); private: Renderer11 *mRenderer; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp index 8698776650..a841b52862 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -8,8 +7,8 @@ // Fence11.cpp: Defines the rx::Fence11 class which implements rx::FenceImpl. #include "libGLESv2/renderer/d3d/d3d11/Fence11.h" -#include "libGLESv2/main.h" #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" +#include "libGLESv2/main.h" namespace rx { diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp index 2165bec305..7536713af4 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -11,13 +10,13 @@ #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #include "libGLESv2/renderer/d3d/d3d11/Image11.h" #include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h" +#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" +#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/Framebuffer.h" #include "libGLESv2/FramebufferAttachment.h" - #include "libGLESv2/main.h" + #include "common/utilities.h" -#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" -#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" namespace rx { @@ -27,11 +26,17 @@ Image11::Image11() mStagingTexture = NULL; mRenderer = NULL; mDXGIFormat = DXGI_FORMAT_UNKNOWN; + mRecoverFromStorage = false; + mAssociatedStorage = NULL; + mAssociatedStorageLevel = 0; + mAssociatedStorageLayerTarget = 0; + mRecoveredFromStorageCount = 0; } Image11::~Image11() { - SafeRelease(mStagingTexture); + disassociateStorage(); + releaseStagingTexture(); } Image11 *Image11::makeImage11(Image *img) @@ -46,8 +51,8 @@ void Image11::generateMipmap(Image11 *dest, Image11 *src) ASSERT(src->getWidth() == 1 || src->getWidth() / 2 == dest->getWidth()); ASSERT(src->getHeight() == 1 || src->getHeight() / 2 == dest->getHeight()); - MipGenerationFunction mipFunction = d3d11::GetMipGenerationFunction(src->getDXGIFormat()); - ASSERT(mipFunction != NULL); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(src->getDXGIFormat()); + ASSERT(dxgiFormatInfo.mipGenerationFunction != NULL); D3D11_MAPPED_SUBRESOURCE destMapped; HRESULT destMapResult = dest->map(D3D11_MAP_WRITE, &destMapped); @@ -70,8 +75,9 @@ void Image11::generateMipmap(Image11 *dest, Image11 *src) const uint8_t *sourceData = reinterpret_cast<const uint8_t*>(srcMapped.pData); uint8_t *destData = reinterpret_cast<uint8_t*>(destMapped.pData); - mipFunction(src->getWidth(), src->getHeight(), src->getDepth(), sourceData, srcMapped.RowPitch, srcMapped.DepthPitch, - destData, destMapped.RowPitch, destMapped.DepthPitch); + dxgiFormatInfo.mipGenerationFunction(src->getWidth(), src->getHeight(), src->getDepth(), + sourceData, srcMapped.RowPitch, srcMapped.DepthPitch, + destData, destMapped.RowPitch, destMapped.DepthPitch); dest->unmap(); src->unmap(); @@ -81,33 +87,117 @@ void Image11::generateMipmap(Image11 *dest, Image11 *src) bool Image11::isDirty() const { - // Make sure that this image is marked as dirty even if the staging texture hasn't been created yet - // if initialization is required before use. - return (mDirty && (mStagingTexture || gl_d3d11::RequiresTextureDataInitialization(mInternalFormat))); + // If mDirty is true + // 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).dataInitializerFunction != NULL)) + { + return false; + } + + return mDirty; +} + +bool Image11::copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +{ + TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage); + return copyToStorageImpl(storage11, level, 0, xoffset, yoffset, width, height); } -bool Image11::copyToStorage(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +bool Image11::copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) { - TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage->getStorageInstance()); - return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, 0, xoffset, yoffset, 0, width, height, 1); + TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage); + return copyToStorageImpl(storage11, level, face, xoffset, yoffset, width, height); } -bool Image11::copyToStorage(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +bool Image11::copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) { - TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage->getStorageInstance()); - return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, face, xoffset, yoffset, 0, width, height, 1); + TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage); + return copyToStorageImpl(storage11, level, 0, xoffset, yoffset, width, height); } -bool Image11::copyToStorage(TextureStorageInterface3D *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) +bool Image11::copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint arrayLayer, GLsizei width, GLsizei height) { - TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage->getStorageInstance()); - return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, 0, xoffset, yoffset, zoffset, width, height, depth); + TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage); + return copyToStorageImpl(storage11, level, arrayLayer, xoffset, yoffset, width, height); } -bool Image11::copyToStorage(TextureStorageInterface2DArray *storage, int level, GLint xoffset, GLint yoffset, GLint arrayLayer, GLsizei width, GLsizei height) +bool Image11::copyToStorageImpl(TextureStorage11 *storage11, int level, int layerTarget, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) { - TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage->getStorageInstance()); - return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, arrayLayer, xoffset, yoffset, 0, width, height, 1); + // 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. + // We allow the Image11 to copy its data to/from TextureStorage once. + // This accounts for an app making a late call to glGenerateMipmap. + bool attemptToReleaseStagingTexture = (mRecoveredFromStorageCount < 2); + + if (attemptToReleaseStagingTexture) + { + // If another image is relying on this Storage for its data, then we must let it recover its data before we overwrite it. + storage11->releaseAssociatedImage(level, layerTarget, this); + } + + bool updateSubresourceSuccess = storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, layerTarget, xoffset, yoffset, 0, width, height, 1); + + // Once the image data has been copied into the Storage, we can release it locally. + if (attemptToReleaseStagingTexture && updateSubresourceSuccess) + { + storage11->associateImage(this, level, layerTarget); + releaseStagingTexture(); + mRecoverFromStorage = true; + mAssociatedStorage = storage11; + mAssociatedStorageLevel = level; + mAssociatedStorageLayerTarget = layerTarget; + } + + return updateSubresourceSuccess; +} + +bool Image11::isAssociatedStorageValid(TextureStorage11* textureStorage) const +{ + return (mAssociatedStorage == textureStorage); +} + +bool Image11::recoverFromAssociatedStorage() +{ + if (mRecoverFromStorage) + { + createStagingTexture(); + + bool textureStorageCorrect = mAssociatedStorage->isAssociatedImageValid(mAssociatedStorageLevel, mAssociatedStorageLayerTarget, this); + + // This means that the cached TextureStorage has been modified after this Image11 released its copy of its data. + // This should not have happened. The TextureStorage should have told this Image11 to recover its data before it was overwritten. + ASSERT(textureStorageCorrect); + + if (textureStorageCorrect) + { + // CopySubResource from the Storage to the Staging texture + mAssociatedStorage->copySubresourceLevel(mStagingTexture, mStagingSubresource, mAssociatedStorageLevel, mAssociatedStorageLayerTarget, 0, 0, 0, mWidth, mHeight, mDepth); + mRecoveredFromStorageCount += 1; + } + + // Reset all the recovery parameters, even if the texture storage association is broken. + disassociateStorage(); + + return textureStorageCorrect; + } + + return false; +} + +void Image11::disassociateStorage() +{ + if (mRecoverFromStorage) + { + // Make the texturestorage release the Image11 too + mAssociatedStorage->disassociateImage(mAssociatedStorageLevel, mAssociatedStorageLayerTarget, this); + + mRecoverFromStorage = false; + mAssociatedStorage = NULL; + mAssociatedStorageLevel = 0; + mAssociatedStorageLayerTarget = 0; + } } bool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) @@ -117,6 +207,11 @@ bool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat, mInternalFormat != internalformat || forceRelease) { + // End the association with the TextureStorage, since that data will be out of date. + // Also reset mRecoveredFromStorageCount since this Image is getting completely redefined. + disassociateStorage(); + mRecoveredFromStorageCount = 0; + mRenderer = Renderer11::makeRenderer11(renderer); mWidth = width; @@ -126,12 +221,14 @@ bool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat, mTarget = target; // compute the d3d format that will be used - mDXGIFormat = gl_d3d11::GetTexFormat(internalformat); - mActualFormat = d3d11_gl::GetInternalFormat(mDXGIFormat); - mRenderable = gl_d3d11::GetRTVFormat(internalformat) != DXGI_FORMAT_UNKNOWN; + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(formatInfo.texFormat); + mDXGIFormat = formatInfo.texFormat; + mActualFormat = dxgiFormatInfo.internalFormat; + mRenderable = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN); SafeRelease(mStagingTexture); - mDirty = gl_d3d11::RequiresTextureDataInitialization(mInternalFormat); + mDirty = (formatInfo.dataInitializerFunction != NULL); return true; } @@ -153,12 +250,15 @@ DXGI_FORMAT Image11::getDXGIFormat() const void Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLint unpackAlignment, GLenum type, const void *input) { - GLsizei inputRowPitch = gl::GetRowPitch(mInternalFormat, type, width, unpackAlignment); - GLsizei inputDepthPitch = gl::GetDepthPitch(mInternalFormat, type, width, height, unpackAlignment); - GLuint outputPixelSize = d3d11::GetFormatPixelBytes(mDXGIFormat); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); + GLsizei inputRowPitch = formatInfo.computeRowPitch(type, width, unpackAlignment); + GLsizei inputDepthPitch = formatInfo.computeDepthPitch(type, width, height, unpackAlignment); - LoadImageFunction loadFunction = d3d11::GetImageLoadFunction(mInternalFormat, type); - ASSERT(loadFunction != NULL); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mDXGIFormat); + GLuint outputPixelSize = dxgiFormatInfo.pixelBytes; + + const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat); + LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(type); D3D11_MAPPED_SUBRESOURCE mappedImage; HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); @@ -179,18 +279,20 @@ void Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei widt void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, const void *input) { - GLsizei inputRowPitch = gl::GetRowPitch(mInternalFormat, GL_UNSIGNED_BYTE, width, 1); - GLsizei inputDepthPitch = gl::GetDepthPitch(mInternalFormat, GL_UNSIGNED_BYTE, width, height, 1); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); + GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, width, 1); + GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, width, height, 1); - GLuint outputPixelSize = d3d11::GetFormatPixelBytes(mDXGIFormat); - GLuint outputBlockWidth = d3d11::GetBlockWidth(mDXGIFormat); - GLuint outputBlockHeight = d3d11::GetBlockHeight(mDXGIFormat); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mDXGIFormat); + GLuint outputPixelSize = dxgiFormatInfo.pixelBytes; + GLuint outputBlockWidth = dxgiFormatInfo.blockWidth; + GLuint outputBlockHeight = dxgiFormatInfo.blockHeight; ASSERT(xoffset % outputBlockWidth == 0); ASSERT(yoffset % outputBlockHeight == 0); - LoadImageFunction loadFunction = d3d11::GetImageLoadFunction(mInternalFormat, GL_UNSIGNED_BYTE); - ASSERT(loadFunction != NULL); + const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat); + LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(GL_UNSIGNED_BYTE); D3D11_MAPPED_SUBRESOURCE mappedImage; HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); @@ -287,13 +389,12 @@ void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y } // determine the offset coordinate into the destination buffer - GLsizei rowOffset = gl::GetPixelBytes(mActualFormat) * xoffset; - void *dataOffset = static_cast<unsigned char*>(mappedImage.pData) + mappedImage.RowPitch * yoffset + rowOffset + zoffset * mappedImage.DepthPitch; + GLsizei rowOffset = gl::GetInternalFormatInfo(mActualFormat).pixelBytes * xoffset; + uint8_t *dataOffset = static_cast<uint8_t*>(mappedImage.pData) + mappedImage.RowPitch * yoffset + rowOffset + zoffset * mappedImage.DepthPitch; - GLenum format = gl::GetFormat(mInternalFormat); - GLenum type = gl::GetType(mInternalFormat); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); - mRenderer->readPixels(source, x, y, width, height, format, type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset); + mRenderer->readPixels(source, x, y, width, height, formatInfo.format, formatInfo.type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset); unmap(); } @@ -306,6 +407,11 @@ ID3D11Resource *Image11::getStagingTexture() return mStagingTexture; } +void Image11::releaseStagingTexture() +{ + SafeRelease(mStagingTexture); +} + unsigned int Image11::getStagingSubresource() { createStagingTexture(); @@ -349,7 +455,7 @@ void Image11::createStagingTexture() desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; desc.MiscFlags = 0; - if (gl_d3d11::RequiresTextureDataInitialization(mInternalFormat)) + if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) { std::vector<D3D11_SUBRESOURCE_DATA> initialData; std::vector< std::vector<BYTE> > textureData; @@ -390,7 +496,7 @@ void Image11::createStagingTexture() desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; desc.MiscFlags = 0; - if (gl_d3d11::RequiresTextureDataInitialization(mInternalFormat)) + if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) { std::vector<D3D11_SUBRESOURCE_DATA> initialData; std::vector< std::vector<BYTE> > textureData; @@ -427,6 +533,9 @@ HRESULT Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map) { createStagingTexture(); + // We must recover from the TextureStorage if necessary, even for D3D11_MAP_WRITE. + recoverFromAssociatedStorage(); + HRESULT result = E_FAIL; if (mStagingTexture) diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h index 7d873a2794..a76a61f036 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h @@ -23,8 +23,7 @@ namespace rx { class Renderer; class Renderer11; -class TextureStorageInterface2D; -class TextureStorageInterfaceCube; +class TextureStorage11; class Image11 : public ImageD3D { @@ -38,10 +37,10 @@ class Image11 : public ImageD3D virtual bool isDirty() const; - virtual bool copyToStorage(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); - virtual bool copyToStorage(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); - virtual bool copyToStorage(TextureStorageInterface3D *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); - virtual bool copyToStorage(TextureStorageInterface2DArray *storage, int level, GLint xoffset, GLint yoffset, GLint arrayLayer, GLsizei width, GLsizei height); + virtual bool copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + virtual bool copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + virtual bool copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); + virtual bool copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint arrayLayer, GLsizei width, GLsizei height); virtual bool redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease); @@ -54,6 +53,10 @@ class Image11 : public ImageD3D virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); + bool recoverFromAssociatedStorage(); + bool isAssociatedStorageValid(TextureStorage11* textureStorage) const; + void disassociateStorage(); + protected: HRESULT map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map); void unmap(); @@ -61,15 +64,24 @@ class Image11 : public ImageD3D private: DISALLOW_COPY_AND_ASSIGN(Image11); + bool copyToStorageImpl(TextureStorage11 *storage11, int level, int layerTarget, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + ID3D11Resource *getStagingTexture(); unsigned int getStagingSubresource(); void createStagingTexture(); + void releaseStagingTexture(); Renderer11 *mRenderer; DXGI_FORMAT mDXGIFormat; ID3D11Resource *mStagingTexture; unsigned int mStagingSubresource; + + bool mRecoverFromStorage; + TextureStorage11 *mAssociatedStorage; + int mAssociatedStorageLevel; + int mAssociatedStorageLayerTarget; + unsigned int mRecoveredFromStorageCount; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.cpp index 03e4e6611b..9a61182ee9 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -25,7 +24,7 @@ IndexBuffer11::~IndexBuffer11() SafeRelease(mBuffer); } -bool IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) +gl::Error IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) { SafeRelease(mBuffer); @@ -46,7 +45,7 @@ bool IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool d HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer); if (FAILED(result)) { - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal index buffer of size, %lu.", bufferSize); } } @@ -54,7 +53,7 @@ bool IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool d mIndexType = indexType; mDynamicUsage = dynamic; - return true; + return gl::Error(GL_NO_ERROR); } IndexBuffer11 *IndexBuffer11::makeIndexBuffer11(IndexBuffer *indexBuffer) @@ -63,50 +62,42 @@ IndexBuffer11 *IndexBuffer11::makeIndexBuffer11(IndexBuffer *indexBuffer) return static_cast<IndexBuffer11*>(indexBuffer); } -bool IndexBuffer11::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) +gl::Error IndexBuffer11::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) { - if (mBuffer) + if (!mBuffer) { - // Check for integer overflows and out-out-bounds map requests - if (offset + size < offset || offset + size > mBufferSize) - { - ERR("Index buffer map range is not inside the buffer."); - return false; - } + return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); + } - ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); + // Check for integer overflows and out-out-bounds map requests + if (offset + size < offset || offset + size > mBufferSize) + { + return gl::Error(GL_OUT_OF_MEMORY, "Index buffer map range is not inside the buffer."); + } - D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); - if (FAILED(result)) - { - ERR("Index buffer map failed with error 0x%08x", result); - return false; - } + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); - *outMappedMemory = reinterpret_cast<char*>(mappedResource.pData) + offset; - return true; - } - else + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); + if (FAILED(result)) { - ERR("Index buffer not initialized."); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal index buffer, HRESULT: 0x%08x.", result); } + + *outMappedMemory = reinterpret_cast<char*>(mappedResource.pData) + offset; + return gl::Error(GL_NO_ERROR); } -bool IndexBuffer11::unmapBuffer() +gl::Error IndexBuffer11::unmapBuffer() { - if (mBuffer) + if (!mBuffer) { - ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); - dxContext->Unmap(mBuffer, 0); - return true; - } - else - { - ERR("Index buffer not initialized."); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); } + + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); + dxContext->Unmap(mBuffer, 0); + return gl::Error(GL_NO_ERROR); } GLenum IndexBuffer11::getIndexType() const @@ -119,7 +110,7 @@ unsigned int IndexBuffer11::getBufferSize() const return mBufferSize; } -bool IndexBuffer11::setSize(unsigned int bufferSize, GLenum indexType) +gl::Error IndexBuffer11::setSize(unsigned int bufferSize, GLenum indexType) { if (bufferSize > mBufferSize || indexType != mIndexType) { @@ -127,33 +118,29 @@ bool IndexBuffer11::setSize(unsigned int bufferSize, GLenum indexType) } else { - return true; + return gl::Error(GL_NO_ERROR); } } -bool IndexBuffer11::discard() +gl::Error IndexBuffer11::discard() { - if (mBuffer) + if (!mBuffer) { - ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); - - D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); - if (FAILED(result)) - { - ERR("Index buffer map failed with error 0x%08x", result); - return false; - } + return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); + } - dxContext->Unmap(mBuffer, 0); + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); - return true; - } - else + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) { - ERR("Index buffer not initialized."); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal index buffer, HRESULT: 0x%08x.", result); } + + dxContext->Unmap(mBuffer, 0); + + return gl::Error(GL_NO_ERROR); } DXGI_FORMAT IndexBuffer11::getIndexFormat() const @@ -172,4 +159,4 @@ ID3D11Buffer *IndexBuffer11::getBuffer() const return mBuffer; } -}
\ No newline at end of file +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h index e821b7f3d1..f7c2b38e7e 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h @@ -21,18 +21,18 @@ class IndexBuffer11 : public IndexBuffer explicit IndexBuffer11(Renderer11 *const renderer); virtual ~IndexBuffer11(); - virtual bool initialize(unsigned int bufferSize, GLenum indexType, bool dynamic); + virtual gl::Error initialize(unsigned int bufferSize, GLenum indexType, bool dynamic); static IndexBuffer11 *makeIndexBuffer11(IndexBuffer *indexBuffer); - virtual bool mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory); - virtual bool unmapBuffer(); + virtual gl::Error mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory); + virtual gl::Error unmapBuffer(); virtual GLenum getIndexType() const; virtual unsigned int getBufferSize() const; - virtual bool setSize(unsigned int bufferSize, GLenum indexType); + virtual gl::Error setSize(unsigned int bufferSize, GLenum indexType); - virtual bool discard(); + virtual gl::Error discard(); DXGI_FORMAT getIndexFormat() const; ID3D11Buffer *getBuffer() const; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp index 3536fafac9..d835e4fa68 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -12,10 +11,10 @@ #include "libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h" #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h" #include "libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h" +#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" +#include "libGLESv2/renderer/d3d/VertexDataManager.h" #include "libGLESv2/ProgramBinary.h" #include "libGLESv2/VertexAttribute.h" -#include "libGLESv2/renderer/d3d/VertexDataManager.h" -#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" #include "third_party/murmurhash/MurmurHash3.h" @@ -86,16 +85,15 @@ void InputLayoutCache::markDirty() } } -GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], - gl::ProgramBinary *programBinary) +gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], + gl::ProgramBinary *programBinary) { int sortedSemanticIndices[gl::MAX_VERTEX_ATTRIBS]; programBinary->sortAttributesByLayout(attributes, sortedSemanticIndices); if (!mDevice || !mDeviceContext) { - ERR("InputLayoutCache is not initialized."); - return GL_INVALID_OPERATION; + return gl::Error(GL_OUT_OF_MEMORY, "Internal input layout cache is not initialized."); } InputLayoutKey ilKey = { 0 }; @@ -109,7 +107,7 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M D3D11_INPUT_CLASSIFICATION inputClass = attributes[i].divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA; gl::VertexFormat vertexFormat(*attributes[i].attribute, attributes[i].currentValueType); - DXGI_FORMAT dxgiFormat = gl_d3d11::GetNativeVertexFormat(vertexFormat); + const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat); // Record the type of the associated vertex shader vector in our key // This will prevent mismatched vertex shaders from using the same input layout @@ -118,7 +116,7 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M ilKey.elements[ilKey.elementCount].desc.SemanticName = semanticName; ilKey.elements[ilKey.elementCount].desc.SemanticIndex = i; - ilKey.elements[ilKey.elementCount].desc.Format = dxgiFormat; + 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; @@ -150,8 +148,7 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M HRESULT result = mDevice->CreateInputLayout(descs, ilKey.elementCount, shader->getFunction(), shader->getLength(), &inputLayout); if (FAILED(result)) { - ERR("Failed to crate input layout, result: 0x%08x", result); - return GL_INVALID_OPERATION; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal input layout, HRESULT: 0x%08x", result); } if (mInputLayoutMap.size() >= kMaxInputLayouts) @@ -223,7 +220,7 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M mCurrentVertexStrides + minDiff, mCurrentVertexOffsets + minDiff); } - return GL_NO_ERROR; + return gl::Error(GL_NO_ERROR); } std::size_t InputLayoutCache::hashInputLayout(const InputLayoutKey &inputLayout) diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h index 5d0ac60537..cc71ac3f6f 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h @@ -11,8 +11,14 @@ #define LIBGLESV2_RENDERER_INPUTLAYOUTCACHE_H_ #include "libGLESv2/Constants.h" +#include "libGLESv2/Error.h" #include "common/angleutils.h" +#include <GLES2/gl2.h> + +#include <cstddef> +#include <unordered_map> + namespace gl { class ProgramBinary; @@ -32,8 +38,8 @@ class InputLayoutCache void clear(); void markDirty(); - GLenum applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], - gl::ProgramBinary *programBinary); + gl::Error applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], + gl::ProgramBinary *programBinary); private: DISALLOW_COPY_AND_ASSIGN(InputLayoutCache); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp index 07040342c7..a4e84f91c2 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -11,15 +10,15 @@ // #include "libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h" -#include "libGLESv2/formatutils.h" -#include "libGLESv2/Texture.h" -#include "libGLESv2/Buffer.h" #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h" #include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h" #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h" +#include "libGLESv2/formatutils.h" +#include "libGLESv2/Texture.h" +#include "libGLESv2/Buffer.h" #include "libGLESv2/Context.h" // Precompiled shaders @@ -125,7 +124,7 @@ void PixelTransfer11::setBufferToTextureCopyParams(const gl::Box &destArea, cons float texelCenterX = 0.5f / static_cast<float>(destSize.width - 1); float texelCenterY = 0.5f / static_cast<float>(destSize.height - 1); - unsigned int bytesPerPixel = gl::GetPixelBytes(internalFormat); + unsigned int bytesPerPixel = gl::GetInternalFormatInfo(internalFormat).pixelBytes; unsigned int alignmentBytes = static_cast<unsigned int>(unpack.alignment); unsigned int alignmentPixels = (alignmentBytes <= bytesPerPixel ? 1 : alignmentBytes / bytesPerPixel); @@ -160,10 +159,11 @@ bool PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, un // The SRV must be in the proper read format, which may be different from the destination format // EG: for half float data, we can load full precision floats with implicit conversion - GLenum unsizedFormat = gl::GetFormat(destinationFormat); - GLenum sourceFormat = gl::GetSizedInternalFormat(unsizedFormat, sourcePixelsType); + GLenum unsizedFormat = gl::GetInternalFormatInfo(destinationFormat).format; + GLenum sourceFormat = gl::GetFormatTypeInfo(unsizedFormat, sourcePixelsType).internalFormat; - DXGI_FORMAT srvFormat = gl_d3d11::GetSRVFormat(sourceFormat); + const d3d11::TextureFormat &sourceFormatInfo = d3d11::GetTextureFormatInfo(sourceFormat); + DXGI_FORMAT srvFormat = sourceFormatInfo.srvFormat; ASSERT(srvFormat != DXGI_FORMAT_UNKNOWN); Buffer11 *bufferStorage11 = Buffer11::makeBuffer11(sourceBuffer.getImplementation()); ID3D11ShaderResourceView *bufferSRV = bufferStorage11->getSRV(srvFormat); @@ -239,8 +239,7 @@ void PixelTransfer11::buildShaderMap() ID3D11PixelShader *PixelTransfer11::findBufferToTexturePS(GLenum internalFormat) const { - GLenum componentType = gl::GetComponentType(internalFormat); - + GLenum componentType = gl::GetInternalFormatInfo(internalFormat).componentType; if (componentType == GL_SIGNED_NORMALIZED || componentType == GL_UNSIGNED_NORMALIZED) { componentType = GL_FLOAT; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h index 2e2fee8f50..ed1a3ae1d0 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h @@ -13,6 +13,10 @@ #include "common/platform.h" +#include <GLES2/gl2.h> + +#include <map> + namespace gl { diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp index e5e00325b2..7109be3e28 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -12,35 +11,18 @@ #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/main.h" -#if defined(__MINGW32__) // Provide undefined struct -typedef struct D3D11_QUERY_DATA_SO_STATISTICS -{ - UINT64 NumPrimitivesWritten; - UINT64 PrimitivesStorageNeeded; -} D3D11_QUERY_DATA_SO_STATISTICS; -#endif +#include <GLES2/gl2ext.h> namespace rx { -static bool checkOcclusionQuery(ID3D11DeviceContext *context, ID3D11Query *query, UINT64 *numPixels) -{ - HRESULT result = context->GetData(query, numPixels, sizeof(UINT64), 0); - return (result == S_OK); -} - -static bool checkStreamOutPrimitivesWritten(ID3D11DeviceContext *context, ID3D11Query *query, UINT64 *numPrimitives) -{ - D3D11_QUERY_DATA_SO_STATISTICS soStats = { 0 }; - HRESULT result = context->GetData(query, &soStats, sizeof(D3D11_QUERY_DATA_SO_STATISTICS), 0); - *numPrimitives = soStats.NumPrimitivesWritten; - return (result == S_OK); -} - -Query11::Query11(rx::Renderer11 *renderer, GLenum type) : QueryImpl(type) +Query11::Query11(rx::Renderer11 *renderer, GLenum type) + : QueryImpl(type), + mResult(0), + mQueryFinished(false), + mRenderer(renderer), + mQuery(NULL) { - mRenderer = renderer; - mQuery = NULL; } Query11::~Query11() @@ -48,7 +30,7 @@ Query11::~Query11() SafeRelease(mQuery); } -void Query11::begin() +gl::Error Query11::begin() { if (mQuery == NULL) { @@ -56,69 +38,85 @@ void Query11::begin() queryDesc.Query = gl_d3d11::ConvertQueryType(getType()); queryDesc.MiscFlags = 0; - if (FAILED(mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery))) + HRESULT result = mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery); + if (FAILED(result)) { - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.", result); } } mRenderer->getDeviceContext()->Begin(mQuery); + return gl::Error(GL_NO_ERROR); } -void Query11::end() +gl::Error Query11::end() { ASSERT(mQuery); mRenderer->getDeviceContext()->End(mQuery); - mStatus = GL_FALSE; + mQueryFinished = false; mResult = GL_FALSE; + + return gl::Error(GL_NO_ERROR); } -GLuint Query11::getResult() +gl::Error Query11::getResult(GLuint *params) { - if (mQuery != NULL) + while (!mQueryFinished) { - while (!testQuery()) + gl::Error error = testQuery(); + if (error.isError()) + { + return error; + } + + if (!mQueryFinished) { Sleep(0); - // explicitly check for device loss, some drivers seem to return S_FALSE - // if the device is lost - if (mRenderer->testDeviceLost(true)) - { - return gl::error(GL_OUT_OF_MEMORY, 0); - } } } - return mResult; + ASSERT(mQueryFinished); + *params = mResult; + + return gl::Error(GL_NO_ERROR); } -GLboolean Query11::isResultAvailable() +gl::Error Query11::isResultAvailable(GLuint *available) { - if (mQuery != NULL) + gl::Error error = testQuery(); + if (error.isError()) { - testQuery(); + return error; } - return mStatus; + *available = (mQueryFinished ? GL_TRUE : GL_FALSE); + + return gl::Error(GL_NO_ERROR); } -GLboolean Query11::testQuery() +gl::Error Query11::testQuery() { - if (mQuery != NULL && mStatus != GL_TRUE) + if (!mQueryFinished) { - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + ASSERT(mQuery); - bool queryFinished = false; + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); switch (getType()) { case GL_ANY_SAMPLES_PASSED_EXT: case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: { UINT64 numPixels = 0; - queryFinished = checkOcclusionQuery(context, mQuery, &numPixels); - if (queryFinished) + HRESULT result = context->GetData(mQuery, &numPixels, sizeof(numPixels), 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) + { + mQueryFinished = true; mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE; } } @@ -126,11 +124,17 @@ GLboolean Query11::testQuery() case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: { - UINT64 numPrimitives = 0; - queryFinished = checkStreamOutPrimitivesWritten(context, mQuery, &numPrimitives); - if (queryFinished) + D3D11_QUERY_DATA_SO_STATISTICS soStats = { 0 }; + HRESULT result = context->GetData(mQuery, &soStats, sizeof(soStats), 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) { - mResult = static_cast<GLuint>(numPrimitives); + mQueryFinished = true; + mResult = static_cast<GLuint>(soStats.NumPrimitivesWritten); } } break; @@ -140,24 +144,13 @@ GLboolean Query11::testQuery() break; } - if (queryFinished) - { - mStatus = GL_TRUE; - } - else if (mRenderer->testDeviceLost(true)) + if (!mQueryFinished && mRenderer->testDeviceLost(true)) { - return gl::error(GL_OUT_OF_MEMORY, GL_TRUE); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to test get query result, device is lost."); } - - return mStatus; } - return GL_TRUE; // prevent blocking when query is null -} - -bool Query11::isStarted() const -{ - return (mQuery != NULL); + return gl::Error(GL_NO_ERROR); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h index 7a3df46d4f..822f2542ee 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h @@ -21,16 +21,19 @@ class Query11 : public QueryImpl Query11(rx::Renderer11 *renderer, GLenum type); virtual ~Query11(); - virtual void begin(); - virtual void end(); - virtual GLuint getResult(); - virtual GLboolean isResultAvailable(); - virtual bool isStarted() const; + virtual gl::Error begin(); + virtual gl::Error end(); + virtual gl::Error getResult(GLuint *params); + virtual gl::Error isResultAvailable(GLuint *available); private: DISALLOW_COPY_AND_ASSIGN(Query11); - GLboolean testQuery(); + gl::Error testQuery(); + + GLuint mResult; + + bool mQueryFinished; rx::Renderer11 *mRenderer; ID3D11Query *mQuery; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp index b185d97604..71b931f27e 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -15,6 +14,7 @@ #include "libGLESv2/FramebufferAttachment.h" #include "common/debug.h" + #include "third_party/murmurhash/MurmurHash3.h" namespace rx @@ -79,39 +79,37 @@ bool RenderStateCache::compareBlendStates(const BlendStateKey &a, const BlendSta return memcmp(&a, &b, sizeof(BlendStateKey)) == 0; } -ID3D11BlendState *RenderStateCache::getBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState) +gl::Error RenderStateCache::getBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, + ID3D11BlendState **outBlendState) { if (!mDevice) { - ERR("RenderStateCache is not initialized."); - return NULL; + return gl::Error(GL_OUT_OF_MEMORY, "Internal error, RenderStateCache is not initialized."); } bool mrt = false; + const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender(); + BlendStateKey key = { 0 }; key.blendState = blendState; - for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment) { - const gl::FramebufferAttachment *attachment = framebuffer->getColorbuffer(i); + const gl::FramebufferAttachment *attachment = colorbuffers[colorAttachment]; + + auto rtChannels = key.rtChannels[colorAttachment]; + if (attachment) { - if (i > 0) + if (colorAttachment > 0) { mrt = true; } - key.rtChannels[i][0] = attachment->getRedSize() > 0; - key.rtChannels[i][1] = attachment->getGreenSize() > 0; - key.rtChannels[i][2] = attachment->getBlueSize() > 0; - key.rtChannels[i][3] = attachment->getAlphaSize() > 0; - } - else - { - key.rtChannels[i][0] = false; - key.rtChannels[i][1] = false; - key.rtChannels[i][2] = false; - key.rtChannels[i][3] = false; + rtChannels[0] = attachment->getRedSize() > 0; + rtChannels[1] = attachment->getGreenSize() > 0; + rtChannels[2] = attachment->getBlueSize() > 0; + rtChannels[3] = attachment->getAlphaSize() > 0; } } @@ -120,7 +118,8 @@ ID3D11BlendState *RenderStateCache::getBlendState(const gl::Framebuffer *framebu { BlendStateCounterPair &state = keyIter->second; state.second = mCounter++; - return state.first; + *outBlendState = state.first; + return gl::Error(GL_NO_ERROR); } else { @@ -172,13 +171,13 @@ ID3D11BlendState *RenderStateCache::getBlendState(const gl::Framebuffer *framebu HRESULT result = mDevice->CreateBlendState(&blendDesc, &dx11BlendState); if (FAILED(result) || !dx11BlendState) { - ERR("Unable to create a ID3D11BlendState, HRESULT: 0x%X.", result); - return NULL; + return gl::Error(GL_OUT_OF_MEMORY, "Unable to create a ID3D11BlendState, HRESULT: 0x%X.", result); } mBlendStateCache.insert(std::make_pair(key, std::make_pair(dx11BlendState, mCounter++))); - return dx11BlendState; + *outBlendState = dx11BlendState; + return gl::Error(GL_NO_ERROR); } } @@ -196,12 +195,12 @@ bool RenderStateCache::compareRasterizerStates(const RasterizerStateKey &a, cons return memcmp(&a, &b, sizeof(RasterizerStateKey)) == 0; } -ID3D11RasterizerState *RenderStateCache::getRasterizerState(const gl::RasterizerState &rasterState, bool scissorEnabled) +gl::Error RenderStateCache::getRasterizerState(const gl::RasterizerState &rasterState, bool scissorEnabled, + ID3D11RasterizerState **outRasterizerState) { if (!mDevice) { - ERR("RenderStateCache is not initialized."); - return NULL; + return gl::Error(GL_OUT_OF_MEMORY, "Internal error, RenderStateCache is not initialized."); } RasterizerStateKey key = { 0 }; @@ -213,7 +212,8 @@ ID3D11RasterizerState *RenderStateCache::getRasterizerState(const gl::Rasterizer { RasterizerStateCounterPair &state = keyIter->second; state.second = mCounter++; - return state.first; + *outRasterizerState = state.first; + return gl::Error(GL_NO_ERROR); } else { @@ -267,13 +267,13 @@ ID3D11RasterizerState *RenderStateCache::getRasterizerState(const gl::Rasterizer HRESULT result = mDevice->CreateRasterizerState(&rasterDesc, &dx11RasterizerState); if (FAILED(result) || !dx11RasterizerState) { - ERR("Unable to create a ID3D11RasterizerState, HRESULT: 0x%X.", result); - return NULL; + return gl::Error(GL_OUT_OF_MEMORY, "Unable to create a ID3D11RasterizerState, HRESULT: 0x%X.", result); } mRasterizerStateCache.insert(std::make_pair(key, std::make_pair(dx11RasterizerState, mCounter++))); - return dx11RasterizerState; + *outRasterizerState = dx11RasterizerState; + return gl::Error(GL_NO_ERROR); } } @@ -291,12 +291,11 @@ bool RenderStateCache::compareDepthStencilStates(const gl::DepthStencilState &a, return memcmp(&a, &b, sizeof(gl::DepthStencilState)) == 0; } -ID3D11DepthStencilState *RenderStateCache::getDepthStencilState(const gl::DepthStencilState &dsState) +gl::Error RenderStateCache::getDepthStencilState(const gl::DepthStencilState &dsState, ID3D11DepthStencilState **outDSState) { if (!mDevice) { - ERR("RenderStateCache is not initialized."); - return NULL; + return gl::Error(GL_OUT_OF_MEMORY, "Internal error, RenderStateCache is not initialized."); } DepthStencilStateMap::iterator keyIter = mDepthStencilStateCache.find(dsState); @@ -304,7 +303,8 @@ ID3D11DepthStencilState *RenderStateCache::getDepthStencilState(const gl::DepthS { DepthStencilStateCounterPair &state = keyIter->second; state.second = mCounter++; - return state.first; + *outDSState = state.first; + return gl::Error(GL_NO_ERROR); } else { @@ -345,13 +345,13 @@ ID3D11DepthStencilState *RenderStateCache::getDepthStencilState(const gl::DepthS HRESULT result = mDevice->CreateDepthStencilState(&dsDesc, &dx11DepthStencilState); if (FAILED(result) || !dx11DepthStencilState) { - ERR("Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result); - return NULL; + 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++))); - return dx11DepthStencilState; + *outDSState = dx11DepthStencilState; + return gl::Error(GL_NO_ERROR); } } @@ -369,12 +369,11 @@ bool RenderStateCache::compareSamplerStates(const gl::SamplerState &a, const gl: return memcmp(&a, &b, sizeof(gl::SamplerState)) == 0; } -ID3D11SamplerState *RenderStateCache::getSamplerState(const gl::SamplerState &samplerState) +gl::Error RenderStateCache::getSamplerState(const gl::SamplerState &samplerState, ID3D11SamplerState **outSamplerState) { if (!mDevice) { - ERR("RenderStateCache is not initialized."); - return NULL; + return gl::Error(GL_OUT_OF_MEMORY, "Internal error, RenderStateCache is not initialized."); } SamplerStateMap::iterator keyIter = mSamplerStateCache.find(samplerState); @@ -382,7 +381,8 @@ ID3D11SamplerState *RenderStateCache::getSamplerState(const gl::SamplerState &sa { SamplerStateCounterPair &state = keyIter->second; state.second = mCounter++; - return state.first; + *outSamplerState = state.first; + return gl::Error(GL_NO_ERROR); } else { @@ -423,13 +423,13 @@ ID3D11SamplerState *RenderStateCache::getSamplerState(const gl::SamplerState &sa HRESULT result = mDevice->CreateSamplerState(&samplerDesc, &dx11SamplerState); if (FAILED(result) || !dx11SamplerState) { - ERR("Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result); - return NULL; + return gl::Error(GL_OUT_OF_MEMORY, "Unable to create a ID3D11SamplerState, HRESULT: 0x%X.", result); } mSamplerStateCache.insert(std::make_pair(samplerState, std::make_pair(dx11SamplerState, mCounter++))); - return dx11SamplerState; + *outSamplerState = dx11SamplerState; + return gl::Error(GL_NO_ERROR); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h index e6380fbd82..d5471a3061 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h @@ -11,8 +11,11 @@ #define LIBGLESV2_RENDERER_RENDERSTATECACHE_H_ #include "libGLESv2/angletypes.h" +#include "libGLESv2/Error.h" #include "common/angleutils.h" +#include <unordered_map> + namespace gl { class Framebuffer; @@ -31,10 +34,10 @@ class RenderStateCache void initialize(ID3D11Device *device); void clear(); - ID3D11BlendState *getBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState); - ID3D11RasterizerState *getRasterizerState(const gl::RasterizerState &rasterState, bool scissorEnabled); - ID3D11DepthStencilState *getDepthStencilState(const gl::DepthStencilState &dsState); - ID3D11SamplerState *getSamplerState(const gl::SamplerState &samplerState); + 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 getSamplerState(const gl::SamplerState &samplerState, ID3D11SamplerState **outSamplerState); private: DISALLOW_COPY_AND_ASSIGN(RenderStateCache); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp index 6aa75ae5bd..3041f21faa 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -10,7 +9,6 @@ #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h" #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" - #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" #include "libGLESv2/main.h" @@ -219,8 +217,9 @@ RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, mDepth = depth; mSamples = samples; - mInternalFormat = d3d11_gl::GetInternalFormat(desc.Format); - mActualFormat = d3d11_gl::GetInternalFormat(desc.Format); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format); + mInternalFormat = dxgiFormatInfo.internalFormat; + mActualFormat = dxgiFormatInfo.internalFormat; } } @@ -265,8 +264,9 @@ RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, mDepth = depth; mSamples = samples; - mInternalFormat = d3d11_gl::GetInternalFormat(desc.Format); - mActualFormat = d3d11_gl::GetInternalFormat(desc.Format); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format); + mInternalFormat = dxgiFormatInfo.internalFormat; + mActualFormat = dxgiFormatInfo.internalFormat; } } @@ -278,18 +278,11 @@ RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height mDepthStencil = NULL; mShaderResource = NULL; - DXGI_FORMAT texFormat = gl_d3d11::GetTexFormat(internalFormat); - DXGI_FORMAT srvFormat = gl_d3d11::GetSRVFormat(internalFormat); - DXGI_FORMAT rtvFormat = gl_d3d11::GetRTVFormat(internalFormat); - DXGI_FORMAT dsvFormat = gl_d3d11::GetDSVFormat(internalFormat); + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(formatInfo.texFormat); - DXGI_FORMAT multisampleFormat = (dsvFormat != DXGI_FORMAT_UNKNOWN ? dsvFormat : rtvFormat); - int supportedSamples = mRenderer->getNearestSupportedSamples(multisampleFormat, samples); - if (supportedSamples < 0) - { - gl::error(GL_OUT_OF_MEMORY); - return; - } + const gl::TextureCaps &textureCaps = mRenderer->getRendererTextureCaps().get(internalFormat); + GLuint supportedSamples = textureCaps.getNearestSamples(samples); if (width > 0 && height > 0) { @@ -299,7 +292,7 @@ RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height desc.Height = height; desc.MipLevels = 1; desc.ArraySize = 1; - desc.Format = texFormat; + desc.Format = formatInfo.texFormat; desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_DEFAULT; @@ -310,14 +303,14 @@ RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height // we'll flag it to allow binding that way. Shader resource views are a little // more complicated. bool bindRTV = false, bindDSV = false, bindSRV = false; - bindRTV = (rtvFormat != DXGI_FORMAT_UNKNOWN); - bindDSV = (dsvFormat != DXGI_FORMAT_UNKNOWN); - if (srvFormat != DXGI_FORMAT_UNKNOWN) + bindRTV = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN); + bindDSV = (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN); + if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN) { // Multisample targets flagged for binding as depth stencil cannot also be // flagged for binding as SRV, so make certain not to add the SRV flag for // these targets. - bindSRV = !(dsvFormat != DXGI_FORMAT_UNKNOWN && desc.SampleDesc.Count > 1); + bindSRV = !(formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN && desc.SampleDesc.Count > 1); } desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET : 0) | @@ -339,7 +332,7 @@ RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height if (bindSRV) { D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = srvFormat; + srvDesc.Format = formatInfo.srvFormat; srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS; srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MipLevels = 1; @@ -357,7 +350,7 @@ RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height if (bindDSV) { D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = dsvFormat; + dsvDesc.Format = formatInfo.dsvFormat; dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS; dsvDesc.Texture2D.MipSlice = 0; dsvDesc.Flags = 0; @@ -376,7 +369,7 @@ RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height if (bindRTV) { D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = rtvFormat; + rtvDesc.Format = formatInfo.rtvFormat; rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS; rtvDesc.Texture2D.MipSlice = 0; result = device->CreateRenderTargetView(mTexture, &rtvDesc, &mRenderTarget); @@ -391,7 +384,7 @@ RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height } ASSERT(SUCCEEDED(result)); - if (gl_d3d11::RequiresTextureDataInitialization(internalFormat)) + if (formatInfo.dataInitializerFunction != NULL) { ID3D11DeviceContext *context = mRenderer->getDeviceContext(); @@ -401,12 +394,13 @@ RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height } } + mWidth = width; mHeight = height; mDepth = 1; mInternalFormat = internalFormat; mSamples = supportedSamples; - mActualFormat = d3d11_gl::GetInternalFormat(texFormat); + mActualFormat = dxgiFormatInfo.internalFormat; mSubresourceIndex = D3D11CalcSubresource(0, 0, 1); } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp index 3ba0cc767b..b29b2ef910 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -7,14 +6,16 @@ // Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer. -#include "libGLESv2/main.h" -#include "common/utilities.h" #include "common/platform.h" +#include "libGLESv2/main.h" #include "libGLESv2/Buffer.h" #include "libGLESv2/FramebufferAttachment.h" #include "libGLESv2/ProgramBinary.h" #include "libGLESv2/Framebuffer.h" +#include "libGLESv2/renderer/d3d/ProgramD3D.h" +#include "libGLESv2/renderer/d3d/ShaderD3D.h" #include "libGLESv2/renderer/d3d/TextureD3D.h" +#include "libGLESv2/renderer/d3d/TransformFeedbackD3D.h" #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h" #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" @@ -35,8 +36,15 @@ #include "libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h" #include "libGLESv2/renderer/d3d/d3d11/VertexArray11.h" #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h" + #include "libEGL/Display.h" +#include "common/utilities.h" + +#include <EGL/eglext.h> + +#include <sstream> + // 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. #ifndef ANGLE_SKIP_DXGI_1_2_CHECK @@ -49,31 +57,6 @@ #define ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS 1 #endif -#ifndef D3D11_PS_INPUT_REGISTER_COUNT -# define D3D11_PS_INPUT_REGISTER_COUNT 32 -#endif -#ifndef D3D10_1_VS_OUTPUT_REGISTER_COUNT -# define D3D10_1_VS_OUTPUT_REGISTER_COUNT 32 -#endif -#ifndef D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT -# define D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT 14 -#endif -#ifndef D3D11_SO_BUFFER_SLOT_COUNT -# define D3D11_SO_BUFFER_SLOT_COUNT 4 -#endif -#ifndef D3D10_1_SO_BUFFER_SLOT_COUNT -# define D3D10_1_SO_BUFFER_SLOT_COUNT 4 -#endif -#ifndef D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT -# define D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT 4096 -#endif -#ifndef D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP -# define D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP 32 -#endif -#ifndef D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP -# define D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP 32 -#endif - namespace rx { static const DXGI_FORMAT RenderTargetFormats[] = @@ -117,8 +100,6 @@ Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, EGLint r mDeviceLost = false; - mMaxSupportedSamples = 0; - mDevice = NULL; mDeviceContext = NULL; mDxgiAdapter = NULL; @@ -320,16 +301,6 @@ EGLint Renderer11::initialize() } #endif - mMaxSupportedSamples = 0; - - const d3d11::DXGIFormatSet &dxgiFormats = d3d11::GetAllUsedDXGIFormats(); - for (d3d11::DXGIFormatSet::const_iterator i = dxgiFormats.begin(); i != dxgiFormats.end(); ++i) - { - MultisampleSupportInfo support = getMultisampleSupportInfo(*i); - mMultisampleSupportMap.insert(std::make_pair(*i, support)); - mMaxSupportedSamples = std::max(mMaxSupportedSamples, support.maxSupportedSamples); - } - #if !defined(ANGLE_PLATFORM_WINRT) static wchar_t *qt_d3dcreate_multihreaded_var = _wgetenv(L"QT_D3DCREATE_MULTITHREADED"); if (qt_d3dcreate_multihreaded_var && wcsstr(qt_d3dcreate_multihreaded_var, L"1")) @@ -369,6 +340,17 @@ void Renderer11::initializeDevice() ASSERT(!mPixelTransfer); mPixelTransfer = new PixelTransfer11(this); + const gl::Caps &rendererCaps = getRendererCaps(); + + mForceSetVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); + mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); + + mForceSetPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); + mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); + + mCurVertexSRVs.resize(rendererCaps.maxVertexTextureImageUnits); + mCurPixelSRVs.resize(rendererCaps.maxTextureImageUnits); + markAllStateDirty(); } @@ -378,34 +360,22 @@ int Renderer11::generateConfigs(ConfigDesc **configDescList) unsigned int numDepthFormats = ArraySize(DepthStencilFormats); (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats]; int numConfigs = 0; - + for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++) { - for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++) + const d3d11::DXGIFormat &renderTargetFormatInfo = d3d11::GetDXGIFormatInfo(RenderTargetFormats[formatIndex]); + const gl::TextureCaps &renderTargetFormatCaps = getRendererTextureCaps().get(renderTargetFormatInfo.internalFormat); + if (renderTargetFormatCaps.renderable) { - DXGI_FORMAT renderTargetFormat = RenderTargetFormats[formatIndex]; - - UINT formatSupport = 0; - HRESULT result = mDevice->CheckFormatSupport(renderTargetFormat, &formatSupport); - - if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET)) + for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++) { - DXGI_FORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex]; - - bool depthStencilFormatOK = true; - - if (depthStencilFormat != DXGI_FORMAT_UNKNOWN) - { - UINT depthStencilSupport = 0; - result = mDevice->CheckFormatSupport(depthStencilFormat, &depthStencilSupport); - depthStencilFormatOK = SUCCEEDED(result) && (depthStencilSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL); - } - - if (depthStencilFormatOK) + const d3d11::DXGIFormat &depthStencilFormatInfo = d3d11::GetDXGIFormatInfo(DepthStencilFormats[depthStencilIndex]); + const gl::TextureCaps &depthStencilFormatCaps = getRendererTextureCaps().get(depthStencilFormatInfo.internalFormat); + if (depthStencilFormatCaps.renderable || DepthStencilFormats[depthStencilIndex] == DXGI_FORMAT_UNKNOWN) { ConfigDesc newConfig; - newConfig.renderTargetFormat = d3d11_gl::GetInternalFormat(renderTargetFormat); - newConfig.depthStencilFormat = d3d11_gl::GetInternalFormat(depthStencilFormat); + newConfig.renderTargetFormat = renderTargetFormatInfo.internalFormat; + newConfig.depthStencilFormat = depthStencilFormatInfo.internalFormat; newConfig.multiSample = 0; // FIXME: enumerate multi-sampling newConfig.fastConfig = true; // Assume all DX11 format conversions to be fast newConfig.es3Capable = true; @@ -468,43 +438,45 @@ SwapChain *Renderer11::createSwapChain(EGLNativeWindowType window, HANDLE shareH return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat); } -void Renderer11::generateSwizzle(gl::Texture *texture) +gl::Error Renderer11::generateSwizzle(gl::Texture *texture) { if (texture) { - TextureStorageInterface *texStorage = texture->getNativeTexture(); + TextureStorage *texStorage = texture->getNativeTexture(); if (texStorage) { - TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage->getStorageInstance()); + TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage); - storage11->generateSwizzles(texture->getSamplerState().swizzleRed, - texture->getSamplerState().swizzleGreen, - texture->getSamplerState().swizzleBlue, - texture->getSamplerState().swizzleAlpha); + gl::Error error = storage11->generateSwizzles(texture->getSamplerState().swizzleRed, + texture->getSamplerState().swizzleGreen, + texture->getSamplerState().swizzleBlue, + texture->getSamplerState().swizzleAlpha); + if (error.isError()) + { + return error; + } } } + + return gl::Error(GL_NO_ERROR); } -void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState) +gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState) { if (type == gl::SAMPLER_PIXEL) { - if (index < 0 || index >= gl::MAX_TEXTURE_IMAGE_UNITS) - { - ERR("Pixel shader sampler index %i is not valid.", index); - return; - } + ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits); if (mForceSetPixelSamplerStates[index] || memcmp(&samplerState, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0) { - ID3D11SamplerState *dxSamplerState = mStateCache.getSamplerState(samplerState); - - if (!dxSamplerState) + ID3D11SamplerState *dxSamplerState = NULL; + gl::Error error = mStateCache.getSamplerState(samplerState, &dxSamplerState); + if (error.isError()) { - ERR("NULL sampler state returned by RenderStateCache::getSamplerState, setting the default" - "sampler state for pixel shaders at slot %i.", index); + return error; } + ASSERT(dxSamplerState != NULL); mDeviceContext->PSSetSamplers(index, 1, &dxSamplerState); mCurPixelSamplerStates[index] = samplerState; @@ -514,22 +486,18 @@ void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::Samp } else if (type == gl::SAMPLER_VERTEX) { - if (index < 0 || index >= (int)getMaxVertexTextureImageUnits()) - { - ERR("Vertex shader sampler index %i is not valid.", index); - return; - } + ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits); if (mForceSetVertexSamplerStates[index] || memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0) { - ID3D11SamplerState *dxSamplerState = mStateCache.getSamplerState(samplerState); - - if (!dxSamplerState) + ID3D11SamplerState *dxSamplerState = NULL; + gl::Error error = mStateCache.getSamplerState(samplerState, &dxSamplerState); + if (error.isError()) { - ERR("NULL sampler state returned by RenderStateCache::getSamplerState, setting the default" - "sampler state for vertex shaders at slot %i.", index); + return error; } + ASSERT(dxSamplerState != NULL); mDeviceContext->VSSetSamplers(index, 1, &dxSamplerState); mCurVertexSamplerStates[index] = samplerState; @@ -538,38 +506,37 @@ void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::Samp mForceSetVertexSamplerStates[index] = false; } else UNREACHABLE(); + + return gl::Error(GL_NO_ERROR); } -void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture) +gl::Error Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture) { ID3D11ShaderResourceView *textureSRV = NULL; bool forceSetTexture = false; if (texture) { - TextureStorageInterface *texStorage = texture->getNativeTexture(); - if (texStorage) - { - TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage->getStorageInstance()); - gl::SamplerState samplerState; - texture->getSamplerStateWithNativeOffset(&samplerState); - textureSRV = storage11->getSRV(samplerState); - } + TextureD3D* textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation()); + TextureStorage *texStorage = textureImpl->getNativeTexture(); + ASSERT(texStorage != NULL); + + TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage); + gl::SamplerState samplerState; + texture->getSamplerStateWithNativeOffset(&samplerState); + textureSRV = storage11->getSRV(samplerState); // If we get NULL back from getSRV here, something went wrong in the texture class and we're unexpectedly // missing the shader resource view ASSERT(textureSRV != NULL); - forceSetTexture = texture->hasDirtyImages(); + forceSetTexture = textureImpl->hasDirtyImages(); + textureImpl->resetDirty(); } if (type == gl::SAMPLER_PIXEL) { - if (index < 0 || index >= gl::MAX_TEXTURE_IMAGE_UNITS) - { - ERR("Pixel shader sampler index %i is not valid.", index); - return; - } + ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits); if (forceSetTexture || mCurPixelSRVs[index] != textureSRV) { @@ -580,11 +547,7 @@ void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *textur } else if (type == gl::SAMPLER_VERTEX) { - if (index < 0 || index >= (int)getMaxVertexTextureImageUnits()) - { - ERR("Vertex shader sampler index %i is not valid.", index); - return; - } + ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits); if (forceSetTexture || mCurVertexSRVs[index] != textureSRV) { @@ -594,9 +557,11 @@ void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *textur mCurVertexSRVs[index] = textureSRV; } else UNREACHABLE(); + + return gl::Error(GL_NO_ERROR); } -bool Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]) +gl::Error Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]) { for (unsigned int uniformBufferIndex = 0; uniformBufferIndex < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; uniformBufferIndex++) { @@ -608,7 +573,7 @@ bool Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], con if (!constantBuffer) { - return false; + return gl::Error(GL_OUT_OF_MEMORY); } if (mCurrentConstantBufferVS[uniformBufferIndex] != bufferStorage->getSerial()) @@ -630,7 +595,7 @@ bool Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], con if (!constantBuffer) { - return false; + return gl::Error(GL_OUT_OF_MEMORY); } if (mCurrentConstantBufferPS[uniformBufferIndex] != bufferStorage->getSerial()) @@ -642,18 +607,18 @@ bool Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], con } } - return true; + return gl::Error(GL_NO_ERROR); } -void Renderer11::setRasterizerState(const gl::RasterizerState &rasterState) +gl::Error Renderer11::setRasterizerState(const gl::RasterizerState &rasterState) { if (mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0) { - ID3D11RasterizerState *dxRasterState = mStateCache.getRasterizerState(rasterState, mScissorEnabled); - if (!dxRasterState) + ID3D11RasterizerState *dxRasterState = NULL; + gl::Error error = mStateCache.getRasterizerState(rasterState, mScissorEnabled, &dxRasterState); + if (error.isError()) { - ERR("NULL rasterizer state returned by RenderStateCache::getRasterizerState, setting the default" - "rasterizer state."); + return error; } mDeviceContext->RSSetState(dxRasterState); @@ -662,23 +627,27 @@ void Renderer11::setRasterizerState(const gl::RasterizerState &rasterState) } mForceSetRasterState = false; + + return gl::Error(GL_NO_ERROR); } -void Renderer11::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, - unsigned int sampleMask) +gl::Error Renderer11::setBlendState(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 = mStateCache.getBlendState(framebuffer, blendState); - if (!dxBlendState) + ID3D11BlendState *dxBlendState = NULL; + gl::Error error = mStateCache.getBlendState(framebuffer, blendState, &dxBlendState); + if (error.isError()) { - ERR("NULL blend state returned by RenderStateCache::getBlendState, setting the default " - "blend state."); + 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) @@ -704,10 +673,12 @@ void Renderer11::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendStat } mForceSetBlendState = false; + + return gl::Error(GL_NO_ERROR); } -void Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, - int stencilBackRef, bool frontFaceCCW) +gl::Error Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, + int stencilBackRef, bool frontFaceCCW) { if (mForceSetDepthStencilState || memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0 || @@ -717,13 +688,15 @@ void Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilS ASSERT(stencilRef == stencilBackRef); ASSERT(depthStencilState.stencilMask == depthStencilState.stencilBackMask); - ID3D11DepthStencilState *dxDepthStencilState = mStateCache.getDepthStencilState(depthStencilState); - if (!dxDepthStencilState) + ID3D11DepthStencilState *dxDepthStencilState = NULL; + gl::Error error = mStateCache.getDepthStencilState(depthStencilState, &dxDepthStencilState); + if (error.isError()) { - ERR("NULL depth stencil state returned by RenderStateCache::getDepthStencilState, " - "setting the default depth stencil state."); + 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 META_ASSERT(D3D11_DEFAULT_STENCIL_READ_MASK == 0xFF); @@ -738,6 +711,8 @@ void Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilS } mForceSetDepthStencilState = false; + + return gl::Error(GL_NO_ERROR); } void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) @@ -768,7 +743,7 @@ void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) mForceSetScissor = false; } -bool Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, +void Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, bool ignoreViewport) { gl::Rectangle actualViewport = viewport; @@ -795,11 +770,6 @@ bool Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float z dxViewport.MinDepth = actualZNear; dxViewport.MaxDepth = actualZFar; - if (dxViewport.Width <= 0 || dxViewport.Height <= 0) - { - return false; // Nothing to render - } - bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 || actualZNear != mCurNear || actualZFar != mCurFar; @@ -829,7 +799,6 @@ bool Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float z } mForceSetViewport = false; - return true; } bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count) @@ -862,7 +831,7 @@ bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count) return count >= minCount; } -bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) +gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) { // Get the color render buffer and serial // Also extract the render target dimensions and view @@ -873,39 +842,37 @@ bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) ID3D11RenderTargetView* framebufferRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL}; bool missingColorRenderTarget = true; - for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) + const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender(); + + for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment) { - const GLenum drawBufferState = framebuffer->getDrawBufferState(colorAttachment); - gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(colorAttachment); + gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment]; - if (colorbuffer && drawBufferState != GL_NONE) + if (colorbuffer) { // the draw buffer must be either "none", "back" for the default buffer or the same index as this color (in order) - ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment)); // 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 false; + return gl::Error(GL_NO_ERROR); } - renderTargetSerials[colorAttachment] = colorbuffer->getSerial(); + renderTargetSerials[colorAttachment] = GetAttachmentSerial(colorbuffer); // Extract the render target dimensions and view - RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget()); + RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); if (!renderTarget) { - ERR("render target pointer unexpectedly null."); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Internal render target pointer unexpectedly null."); } framebufferRTVs[colorAttachment] = renderTarget->getRenderTargetView(); if (!framebufferRTVs[colorAttachment]) { - ERR("render target view pointer unexpectedly null."); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null."); } if (missingColorRenderTarget) @@ -921,37 +888,35 @@ bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) } } - // Get the depth stencil render buffer and serials + // Get the depth stencil render buffter and serials gl::FramebufferAttachment *depthStencil = framebuffer->getDepthbuffer(); unsigned int depthbufferSerial = 0; unsigned int stencilbufferSerial = 0; if (depthStencil) { - depthbufferSerial = depthStencil->getSerial(); + depthbufferSerial = GetAttachmentSerial(depthStencil); } else if (framebuffer->getStencilbuffer()) { depthStencil = framebuffer->getStencilbuffer(); - stencilbufferSerial = depthStencil->getSerial(); + stencilbufferSerial = GetAttachmentSerial(depthStencil); } ID3D11DepthStencilView* framebufferDSV = NULL; if (depthStencil) { - RenderTarget11 *depthStencilRenderTarget = RenderTarget11::makeRenderTarget11(depthStencil->getDepthStencil()); + RenderTarget11 *depthStencilRenderTarget = d3d11::GetAttachmentRenderTarget(depthStencil); if (!depthStencilRenderTarget) { - ERR("render target pointer unexpectedly null."); SafeRelease(framebufferRTVs); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Internal render target pointer unexpectedly null."); } framebufferDSV = depthStencilRenderTarget->getDepthStencilView(); if (!framebufferDSV) { - ERR("depth stencil view pointer unexpectedly null."); SafeRelease(framebufferRTVs); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil view pointer unexpectedly null."); } // If there is no render buffer, the width, height and format values come from @@ -996,54 +961,54 @@ bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) invalidateFramebufferSwizzles(framebuffer); - return true; + return gl::Error(GL_NO_ERROR); } -GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], - GLint first, GLsizei count, GLsizei instances) +gl::Error Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], + GLint first, GLsizei count, GLsizei instances) { TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS]; - GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances); - if (err != GL_NO_ERROR) + gl::Error error = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances); + if (error.isError()) { - return err; + return error; } return mInputLayoutCache.applyVertexBuffers(attributes, programBinary); } -GLenum Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) +gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) { - GLenum err = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo); - - if (err == GL_NO_ERROR) + gl::Error error = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo); + if (error.isError()) { - IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer); + return error; + } - ID3D11Buffer *buffer = NULL; - DXGI_FORMAT bufferFormat = indexBuffer->getIndexFormat(); + ID3D11Buffer *buffer = NULL; + DXGI_FORMAT bufferFormat = (indexInfo->indexType == GL_UNSIGNED_INT) ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT; - if (indexInfo->storage) - { - Buffer11 *storage = Buffer11::makeBuffer11(indexInfo->storage); - buffer = storage->getBuffer(BUFFER_USAGE_INDEX); - } - else - { - buffer = indexBuffer->getBuffer(); - } + if (indexInfo->storage) + { + Buffer11 *storage = Buffer11::makeBuffer11(indexInfo->storage); + buffer = storage->getBuffer(BUFFER_USAGE_INDEX); + } + else + { + IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer); + buffer = indexBuffer->getBuffer(); + } - if (buffer != mAppliedIB || bufferFormat != mAppliedIBFormat || indexInfo->startOffset != mAppliedIBOffset) - { - mDeviceContext->IASetIndexBuffer(buffer, bufferFormat, indexInfo->startOffset); + if (buffer != mAppliedIB || bufferFormat != mAppliedIBFormat || indexInfo->startOffset != mAppliedIBOffset) + { + mDeviceContext->IASetIndexBuffer(buffer, bufferFormat, indexInfo->startOffset); - mAppliedIB = buffer; - mAppliedIBFormat = bufferFormat; - mAppliedIBOffset = indexInfo->startOffset; - } + mAppliedIB = buffer; + mAppliedIBFormat = bufferFormat; + mAppliedIBOffset = indexInfo->startOffset; } - return err; + return gl::Error(GL_NO_ERROR); } void Renderer11::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]) @@ -1084,7 +1049,7 @@ void Renderer11::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuff } } -void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) +gl::Error Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) { if (mode == GL_POINTS && transformFeedbackActive) { @@ -1117,43 +1082,51 @@ void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool } mDeviceContext->GSSetShader(mAppliedGeometryShader, NULL, 0); + + return gl::Error(GL_NO_ERROR); } else if (mode == GL_LINE_LOOP) { - drawLineLoop(count, GL_NONE, NULL, 0, NULL); + return drawLineLoop(count, GL_NONE, NULL, 0, NULL); } else if (mode == GL_TRIANGLE_FAN) { - drawTriangleFan(count, GL_NONE, NULL, 0, NULL, instances); + return drawTriangleFan(count, GL_NONE, NULL, 0, NULL, instances); } else if (instances > 0) { mDeviceContext->DrawInstanced(count, instances, 0, 0); + return gl::Error(GL_NO_ERROR); } else { mDeviceContext->Draw(count, 0); + return gl::Error(GL_NO_ERROR); } } -void Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, - gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) +gl::Error Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, + gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) { + int minIndex = static_cast<int>(indexInfo.indexRange.start); + if (mode == GL_LINE_LOOP) { - drawLineLoop(count, type, indices, indexInfo.minIndex, elementArrayBuffer); + return drawLineLoop(count, type, indices, minIndex, elementArrayBuffer); } else if (mode == GL_TRIANGLE_FAN) { - drawTriangleFan(count, type, indices, indexInfo.minIndex, elementArrayBuffer, instances); + return drawTriangleFan(count, type, indices, minIndex, elementArrayBuffer, instances); } else if (instances > 0) { - mDeviceContext->DrawIndexedInstanced(count, instances, 0, -static_cast<int>(indexInfo.minIndex), 0); + mDeviceContext->DrawIndexedInstanced(count, instances, 0, -minIndex, 0); + return gl::Error(GL_NO_ERROR); } else { - mDeviceContext->DrawIndexed(count, 0, -static_cast<int>(indexInfo.minIndex)); + mDeviceContext->DrawIndexed(count, 0, -minIndex); + return gl::Error(GL_NO_ERROR); } } @@ -1235,7 +1208,7 @@ static void fillTriangleFanIndices(GLenum type, unsigned int numTris, const GLvo } } -void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer) +gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer) { // Get the raw indices for an indexed draw if (type != GL_NONE && elementArrayBuffer) @@ -1252,13 +1225,11 @@ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, if (!mLineLoopIB) { mLineLoopIB = new StreamingIndexBufferInterface(this); - if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, indexType)) + gl::Error error = mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, indexType); + if (error.isError()) { - delete mLineLoopIB; - mLineLoopIB = NULL; - - ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + SafeDelete(mLineLoopIB); + return error; } } @@ -1268,23 +1239,22 @@ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int indexTypeSize = indexType == GL_UNSIGNED_SHORT ? sizeof(unsigned short) : sizeof(unsigned int); if (static_cast<unsigned int>(count) + 1 > (std::numeric_limits<unsigned int>::max() / indexTypeSize)) { - ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required."); - return gl::error(GL_OUT_OF_MEMORY); + 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) * indexTypeSize; - if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, indexType)) + const unsigned int spaceNeeded = (static_cast<unsigned int>(count) + 1) * sizeof(unsigned int); + gl::Error error = mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT); + if (error.isError()) { - ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } void* mappedMemory = NULL; unsigned int offset; - if (!mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset)) + error = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset); + if (error.isError()) { - ERR("Could not map index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } if (indexType == GL_UNSIGNED_SHORT) @@ -1293,10 +1263,10 @@ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, fillLineLoopIndices(type, count, indices, reinterpret_cast<unsigned int*>(mappedMemory)); unsigned int indexBufferOffset = offset; - if (!mLineLoopIB->unmapBuffer()) + error = mLineLoopIB->unmapBuffer(); + if (error.isError()) { - ERR("Could not unmap index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mLineLoopIB->getIndexBuffer()); @@ -1305,16 +1275,18 @@ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat || mAppliedIBOffset != indexBufferOffset) { - mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexBufferOffset); + mDeviceContext->IASetIndexBuffer(d3dIndexBuffer, indexFormat, indexBufferOffset); mAppliedIB = d3dIndexBuffer; mAppliedIBFormat = indexFormat; mAppliedIBOffset = indexBufferOffset; } mDeviceContext->DrawIndexed(count + 1, 0, -minIndex); + + return gl::Error(GL_NO_ERROR); } -void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances) +gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances) { // Get the raw indices for an indexed draw if (type != GL_NONE && elementArrayBuffer) @@ -1330,13 +1302,11 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic if (!mTriangleFanIB) { mTriangleFanIB = new StreamingIndexBufferInterface(this); - if (!mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, indexType)) + gl::Error error = mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, indexType); + if (error.isError()) { - delete mTriangleFanIB; - mTriangleFanIB = NULL; - - ERR("Could not create a scratch index buffer for GL_TRIANGLE_FAN."); - return gl::error(GL_OUT_OF_MEMORY); + SafeDelete(mTriangleFanIB); + return error; } } @@ -1348,35 +1318,35 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic int indexTypeSize = indexType == GL_UNSIGNED_SHORT ? sizeof(unsigned short) : sizeof(unsigned int); if (numTris > (std::numeric_limits<unsigned int>::max() / (indexTypeSize * 3))) { - ERR("Could not create a scratch index buffer for GL_TRIANGLE_FAN, too many indices required."); - return gl::error(GL_OUT_OF_MEMORY); + 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) * indexTypeSize; - if (!mTriangleFanIB->reserveBufferSpace(spaceNeeded, indexType)) + gl::Error error = mTriangleFanIB->reserveBufferSpace(spaceNeeded, indexType); + if (error.isError()) { - ERR("Could not reserve enough space in scratch index buffer for GL_TRIANGLE_FAN."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } void* mappedMemory = NULL; unsigned int offset; - if (!mTriangleFanIB->mapBuffer(spaceNeeded, &mappedMemory, &offset)) + error = mTriangleFanIB->mapBuffer(spaceNeeded, &mappedMemory, &offset); + if (error.isError()) { - ERR("Could not map scratch index buffer for GL_TRIANGLE_FAN."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } if (indexType == GL_UNSIGNED_SHORT) fillTriangleFanIndices(type, numTris, indices, reinterpret_cast<unsigned short*>(mappedMemory)); else fillTriangleFanIndices(type, numTris, indices, reinterpret_cast<unsigned int*>(mappedMemory)); + unsigned int indexBufferOffset = offset; - if (!mTriangleFanIB->unmapBuffer()) + error = mTriangleFanIB->unmapBuffer(); + if (error.isError()) { - ERR("Could not unmap scratch index buffer for GL_TRIANGLE_FAN."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mTriangleFanIB->getIndexBuffer()); @@ -1385,7 +1355,7 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat || mAppliedIBOffset != indexBufferOffset) { - mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexBufferOffset); + mDeviceContext->IASetIndexBuffer(d3dIndexBuffer, indexFormat, indexBufferOffset); mAppliedIB = d3dIndexBuffer; mAppliedIBFormat = indexFormat; mAppliedIBOffset = indexBufferOffset; @@ -1399,10 +1369,12 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic { mDeviceContext->DrawIndexed(numTris * 3, 0, -minIndex); } + + return gl::Error(GL_NO_ERROR); } -void Renderer11::applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, - bool rasterizerDiscard, bool transformFeedbackActive) +gl::Error Renderer11::applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, + bool rasterizerDiscard, bool transformFeedbackActive) { ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout); ShaderExecutable *pixelExe = programBinary->getPixelExecutableForFramebuffer(framebuffer); @@ -1463,9 +1435,11 @@ void Renderer11::applyShaders(gl::ProgramBinary *programBinary, const gl::Vertex { programBinary->dirtyAllUniforms(); } + + return gl::Error(GL_NO_ERROR); } -void Renderer11::applyUniforms(const gl::ProgramBinary &programBinary) +gl::Error Renderer11::applyUniforms(const gl::ProgramBinary &programBinary) { const std::vector<gl::LinkedUniform*> &uniformArray = programBinary.getUniforms(); @@ -1492,8 +1466,9 @@ void Renderer11::applyUniforms(const gl::ProgramBinary &programBinary) } } - const UniformStorage11 *vertexUniformStorage = UniformStorage11::makeUniformStorage11(&programBinary.getVertexUniformStorage()); - const UniformStorage11 *fragmentUniformStorage = UniformStorage11::makeUniformStorage11(&programBinary.getFragmentUniformStorage()); + const ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary.getImplementation()); + const UniformStorage11 *vertexUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getVertexUniformStorage()); + const UniformStorage11 *fragmentUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getFragmentUniformStorage()); ASSERT(vertexUniformStorage); ASSERT(fragmentUniformStorage); @@ -1619,12 +1594,21 @@ void Renderer11::applyUniforms(const gl::ProgramBinary &programBinary) mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS); mCurrentGeometryConstantBuffer = mDriverConstantBufferPS; } + + return gl::Error(GL_NO_ERROR); } -void Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) +gl::Error Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) { - mClear->clearFramebuffer(clearParams, frameBuffer); + gl::Error error = mClear->clearFramebuffer(clearParams, frameBuffer); + if (error.isError()) + { + return error; + } + invalidateFramebufferSwizzles(frameBuffer); + + return gl::Error(GL_NO_ERROR); } void Renderer11::markAllStateDirty() @@ -1638,15 +1622,18 @@ void Renderer11::markAllStateDirty() mDepthStencilInitialized = false; mRenderTargetDescInitialized = false; - for (int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++) + ASSERT(mForceSetVertexSamplerStates.size() == mCurVertexSRVs.size()); + for (size_t vsamplerId = 0; vsamplerId < mForceSetVertexSamplerStates.size(); ++vsamplerId) { - mForceSetVertexSamplerStates[i] = true; - mCurVertexSRVs[i] = NULL; + mForceSetVertexSamplerStates[vsamplerId] = true; + mCurVertexSRVs[vsamplerId] = NULL; } - for (int i = 0; i < gl::MAX_TEXTURE_IMAGE_UNITS; i++) + + ASSERT(mForceSetPixelSamplerStates.size() == mCurPixelSRVs.size()); + for (size_t fsamplerId = 0; fsamplerId < mForceSetPixelSamplerStates.size(); ++fsamplerId) { - mForceSetPixelSamplerStates[i] = true; - mCurPixelSRVs[i] = NULL; + mForceSetPixelSamplerStates[fsamplerId] = true; + mCurPixelSRVs[fsamplerId] = NULL; } mForceSetBlendState = true; @@ -1803,6 +1790,7 @@ bool Renderer11::testDeviceResettable() void Renderer11::release() { + releaseShaderCompiler(); releaseDeviceResources(); SafeRelease(mDxgiFactory); @@ -1877,29 +1865,6 @@ GUID Renderer11::getAdapterIdentifier() const return adapterId; } -unsigned int Renderer11::getMaxVertexTextureImageUnits() const -{ - META_ASSERT(MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 <= gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS); - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_0: - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: - return MAX_TEXTURE_IMAGE_UNITS_VTF_SM4; - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return 0; - default: UNREACHABLE(); - return 0; - } -} - -unsigned int Renderer11::getMaxCombinedTextureImageUnits() const -{ - return gl::MAX_TEXTURE_IMAGE_UNITS + getMaxVertexTextureImageUnits(); -} - unsigned int Renderer11::getReservedVertexUniformVectors() const { return 0; // Driver uniforms are stored in a separate constant buffer @@ -1910,85 +1875,6 @@ unsigned int Renderer11::getReservedFragmentUniformVectors() const return 0; // Driver uniforms are stored in a separate constant buffer } -unsigned int Renderer11::getMaxVertexUniformVectors() const -{ - META_ASSERT(MAX_VERTEX_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT); - ASSERT(mFeatureLevel >= D3D_FEATURE_LEVEL_9_1); - return MAX_VERTEX_UNIFORM_VECTORS_D3D11; -} - -unsigned int Renderer11::getMaxFragmentUniformVectors() const -{ - META_ASSERT(MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT); - ASSERT(mFeatureLevel >= D3D_FEATURE_LEVEL_9_1); - return MAX_FRAGMENT_UNIFORM_VECTORS_D3D11; -} - -unsigned int Renderer11::getMaxVaryingVectors() const -{ - META_ASSERT(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT); - META_ASSERT(D3D11_VS_OUTPUT_REGISTER_COUNT <= D3D11_PS_INPUT_REGISTER_COUNT); - META_ASSERT(D3D10_VS_OUTPUT_REGISTER_COUNT <= D3D10_PS_INPUT_REGISTER_COUNT); - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_0: - return D3D11_VS_OUTPUT_REGISTER_COUNT - getReservedVaryings(); - case D3D_FEATURE_LEVEL_10_1: - return D3D10_1_VS_OUTPUT_REGISTER_COUNT - getReservedVaryings(); - case D3D_FEATURE_LEVEL_10_0: - return D3D10_VS_OUTPUT_REGISTER_COUNT - getReservedVaryings(); - case D3D_FEATURE_LEVEL_9_3: - return 10 - getReservedVaryings(); - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return 8 - getReservedVaryings(); - default: UNREACHABLE(); - return 0; - } -} - -unsigned int Renderer11::getMaxVertexShaderUniformBuffers() const -{ - META_ASSERT(gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS >= D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT && - gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS >= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT); - - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_0: - return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - getReservedVertexUniformBuffers(); - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: - return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - getReservedVertexUniformBuffers(); - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return 0; - default: UNREACHABLE(); - return 0; - } -} - -unsigned int Renderer11::getMaxFragmentShaderUniformBuffers() const -{ - META_ASSERT(gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS >= D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT && - gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS >= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT); - - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_0: - return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - getReservedFragmentUniformBuffers(); - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: - return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - getReservedFragmentUniformBuffers(); - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return 0; - default: UNREACHABLE(); - return 0; - } -} - unsigned int Renderer11::getReservedVertexUniformBuffers() const { // we reserve one buffer for the application uniforms, and one for driver uniforms @@ -2001,81 +1887,6 @@ unsigned int Renderer11::getReservedFragmentUniformBuffers() const return 2; } -unsigned int Renderer11::getReservedVaryings() const -{ - // We potentially reserve varyings for gl_Position, dx_Position, gl_FragCoord and gl_PointSize - return 4; -} - - -unsigned int Renderer11::getMaxTransformFeedbackBuffers() const -{ - META_ASSERT(gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS >= D3D11_SO_BUFFER_SLOT_COUNT && - gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS >= D3D10_SO_BUFFER_SLOT_COUNT); - - switch (mFeatureLevel) - { - 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; - case D3D_FEATURE_LEVEL_10_0: - return D3D10_SO_BUFFER_SLOT_COUNT; - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return 0; - default: UNREACHABLE(); - return 0; - } -} - -unsigned int Renderer11::getMaxTransformFeedbackSeparateComponents() const -{ - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_0: - return getMaxTransformFeedbackInterleavedComponents() / getMaxTransformFeedbackBuffers(); - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: - // D3D 10 and 10.1 only allow one output per output slot if an output slot other than zero - // is used. - return 4; - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return 0; - default: UNREACHABLE(); - return 0; - } -} - -unsigned int Renderer11::getMaxTransformFeedbackInterleavedComponents() const -{ - return (getMaxVaryingVectors() * 4); -} - -unsigned int Renderer11::getMaxUniformBufferSize() const -{ - // Each component is a 4-element vector of 4-byte units (floats) - const unsigned int bytesPerComponent = 4 * sizeof(float); - - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_0: - return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent; - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: - return D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent; - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return 0; - default: UNREACHABLE(); - return 0; - } -} - bool Renderer11::getShareHandleSupport() const { // We only currently support share handles with BGRA surfaces, because @@ -2090,29 +1901,6 @@ bool Renderer11::getPostSubBufferSupport() const return false; } -int Renderer11::getMaxRecommendedElementsIndices() const -{ - META_ASSERT(D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32); - META_ASSERT(D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32); - - // D3D11 allows up to 2^32 elements, but we report max signed int for convenience. - return std::numeric_limits<GLint>::max(); -} - -int Renderer11::getMaxRecommendedElementsVertices() const -{ - META_ASSERT(D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32); - META_ASSERT(D3D10_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32); - - // D3D11 allows up to 2^32 elements, but we report max signed int for convenience. - return std::numeric_limits<GLint>::max(); -} - -bool Renderer11::getSRGBTextureSupport() const -{ - return true; -} - int Renderer11::getMajorShaderModel() const { switch (mFeatureLevel) @@ -2122,8 +1910,7 @@ int Renderer11::getMajorShaderModel() const case D3D_FEATURE_LEVEL_10_0: case D3D_FEATURE_LEVEL_9_3: case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return D3D10_SHADER_MAJOR_VERSION; // 4 + case D3D_FEATURE_LEVEL_9_1: return D3D10_SHADER_MAJOR_VERSION; // 4 default: UNREACHABLE(); return 0; } } @@ -2152,100 +1939,12 @@ int Renderer11::getMaxSwapInterval() const return 4; } -int Renderer11::getMaxSupportedSamples() const -{ - return mMaxSupportedSamples; -} - -GLsizei Renderer11::getMaxSupportedFormatSamples(GLenum internalFormat) const -{ - DXGI_FORMAT format = gl_d3d11::GetRenderableFormat(internalFormat); - MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format); - return (iter != mMultisampleSupportMap.end()) ? iter->second.maxSupportedSamples : 0; -} - -GLsizei Renderer11::getNumSampleCounts(GLenum internalFormat) const -{ - unsigned int numCounts = 0; - - // D3D11 supports multisampling for signed and unsigned format, but ES 3.0 does not - GLenum componentType = gl::GetComponentType(internalFormat); - if (componentType != GL_INT && componentType != GL_UNSIGNED_INT) - { - DXGI_FORMAT format = gl_d3d11::GetRenderableFormat(internalFormat); - MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format); - - if (iter != mMultisampleSupportMap.end()) - { - const MultisampleSupportInfo& info = iter->second; - for (int i = 0; i < D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++) - { - if (info.qualityLevels[i] > 0) - { - numCounts++; - } - } - } - } - - return numCounts; -} - -void Renderer11::getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const -{ - // D3D11 supports multisampling for signed and unsigned format, but ES 3.0 does not - GLenum componentType = gl::GetComponentType(internalFormat); - if (componentType == GL_INT || componentType == GL_UNSIGNED_INT) - { - return; - } - - DXGI_FORMAT format = gl_d3d11::GetRenderableFormat(internalFormat); - MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format); - - if (iter != mMultisampleSupportMap.end()) - { - const MultisampleSupportInfo& info = iter->second; - int bufPos = 0; - for (int i = D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT - 1; i >= 0 && bufPos < bufSize; i--) - { - if (info.qualityLevels[i] > 0) - { - params[bufPos++] = i + 1; - } - } - } -} - -int Renderer11::getNearestSupportedSamples(DXGI_FORMAT format, unsigned int requested) const -{ - if (requested == 0) - { - return 0; - } - - MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format); - if (iter != mMultisampleSupportMap.end()) - { - const MultisampleSupportInfo& info = iter->second; - for (unsigned int i = requested - 1; i < D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++) - { - if (info.qualityLevels[i] > 0) - { - return i + 1; - } - } - } - - return -1; -} - -bool Renderer11::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source) +bool Renderer11::copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source) { if (source && dest) { - TextureStorage11_2D *source11 = TextureStorage11_2D::makeTextureStorage11_2D(source->getStorageInstance()); - TextureStorage11_2D *dest11 = TextureStorage11_2D::makeTextureStorage11_2D(dest->getStorageInstance()); + TextureStorage11_2D *source11 = TextureStorage11_2D::makeTextureStorage11_2D(source); + TextureStorage11_2D *dest11 = TextureStorage11_2D::makeTextureStorage11_2D(dest); mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); @@ -2257,12 +1956,12 @@ bool Renderer11::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStor return false; } -bool Renderer11::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source) +bool Renderer11::copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source) { if (source && dest) { - TextureStorage11_Cube *source11 = TextureStorage11_Cube::makeTextureStorage11_Cube(source->getStorageInstance()); - TextureStorage11_Cube *dest11 = TextureStorage11_Cube::makeTextureStorage11_Cube(dest->getStorageInstance()); + TextureStorage11_Cube *source11 = TextureStorage11_Cube::makeTextureStorage11_Cube(source); + TextureStorage11_Cube *dest11 = TextureStorage11_Cube::makeTextureStorage11_Cube(dest); mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); @@ -2274,12 +1973,12 @@ bool Renderer11::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureSt return false; } -bool Renderer11::copyToRenderTarget(TextureStorageInterface3D *dest, TextureStorageInterface3D *source) +bool Renderer11::copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source) { if (source && dest) { - TextureStorage11_3D *source11 = TextureStorage11_3D::makeTextureStorage11_3D(source->getStorageInstance()); - TextureStorage11_3D *dest11 = TextureStorage11_3D::makeTextureStorage11_3D(dest->getStorageInstance()); + TextureStorage11_3D *source11 = TextureStorage11_3D::makeTextureStorage11_3D(source); + TextureStorage11_3D *dest11 = TextureStorage11_3D::makeTextureStorage11_3D(dest); mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); @@ -2291,12 +1990,12 @@ bool Renderer11::copyToRenderTarget(TextureStorageInterface3D *dest, TextureStor return false; } -bool Renderer11::copyToRenderTarget(TextureStorageInterface2DArray *dest, TextureStorageInterface2DArray *source) +bool Renderer11::copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source) { if (source && dest) { - TextureStorage11_2DArray *source11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(source->getStorageInstance()); - TextureStorage11_2DArray *dest11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(dest->getStorageInstance()); + TextureStorage11_2DArray *source11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(source); + TextureStorage11_2DArray *dest11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(dest); mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); @@ -2308,8 +2007,8 @@ bool Renderer11::copyToRenderTarget(TextureStorageInterface2DArray *dest, Textur return false; } -bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level) +bool Renderer11::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) { gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); if (!colorbuffer) @@ -2318,7 +2017,7 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget()); + RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); if (!sourceRenderTarget) { ERR("Failed to retrieve the render target from the frame buffer."); @@ -2332,14 +2031,15 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return gl::error(GL_OUT_OF_MEMORY, false); } - TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage->getStorageInstance()); + TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage); if (!storage11) { ERR("Failed to retrieve the texture storage from the destination."); return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(level)); + gl::ImageIndex index = gl::ImageIndex::Make2D(level); + RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index)); if (!destRenderTarget) { ERR("Failed to retrieve the render target from the destination storage."); @@ -2369,8 +2069,8 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return ret; } -bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level) +bool Renderer11::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) { gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); if (!colorbuffer) @@ -2379,7 +2079,7 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget()); + RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); if (!sourceRenderTarget) { ERR("Failed to retrieve the render target from the frame buffer."); @@ -2393,14 +2093,15 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return gl::error(GL_OUT_OF_MEMORY, false); } - TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage->getStorageInstance()); + TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage); if (!storage11) { ERR("Failed to retrieve the texture storage from the destination."); return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTargetFace(target, level)); + gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level); + RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index)); if (!destRenderTarget) { ERR("Failed to retrieve the render target from the destination storage."); @@ -2430,8 +2131,8 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return ret; } -bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface3D *storage, GLint level) +bool Renderer11::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) { gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); if (!colorbuffer) @@ -2440,7 +2141,7 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget()); + RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); if (!sourceRenderTarget) { ERR("Failed to retrieve the render target from the frame buffer."); @@ -2454,14 +2155,15 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return gl::error(GL_OUT_OF_MEMORY, false); } - TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage->getStorageInstance()); + TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage); if (!storage11) { ERR("Failed to retrieve the texture storage from the destination."); return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTargetLayer(level, zOffset)); + gl::ImageIndex index = gl::ImageIndex::Make3D(level, zOffset); + RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index)); if (!destRenderTarget) { ERR("Failed to retrieve the render target from the destination storage."); @@ -2491,8 +2193,8 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return ret; } -bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level) +bool Renderer11::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) { gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); if (!colorbuffer) @@ -2501,7 +2203,7 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget()); + RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); if (!sourceRenderTarget) { ERR("Failed to retrieve the render target from the frame buffer."); @@ -2515,7 +2217,7 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return gl::error(GL_OUT_OF_MEMORY, false); } - TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage->getStorageInstance()); + TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage); if (!storage11) { SafeRelease(source); @@ -2523,7 +2225,8 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTargetLayer(level, zOffset)); + gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, zOffset); + RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index)); if (!destRenderTarget) { SafeRelease(source); @@ -2604,6 +2307,21 @@ RenderTarget *Renderer11::createRenderTarget(int width, int height, GLenum forma return renderTarget; } +ShaderImpl *Renderer11::createShader(GLenum type) +{ + return new ShaderD3D(type, this); +} + +ProgramImpl *Renderer11::createProgram() +{ + return new ProgramD3D(this); +} + +void Renderer11::releaseShaderCompiler() +{ + ShaderD3D::releaseCompiler(); +} + ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length, rx::ShaderType type, const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, bool separatedOutputBuffers) @@ -2818,30 +2536,39 @@ FenceImpl *Renderer11::createFence() return new Fence11(this); } +TransformFeedbackImpl* Renderer11::createTransformFeedback() +{ + return new TransformFeedbackD3D(); +} + bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const { ASSERT(getRendererExtensions().pixelBufferObject); + const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat); + const d3d11::TextureFormat &d3d11FormatInfo = d3d11::GetTextureFormatInfo(internalFormat); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3d11FormatInfo.texFormat); + // sRGB formats do not work with D3D11 buffer SRVs - if (gl::GetColorEncoding(internalFormat) == GL_SRGB) + if (internalFormatInfo.colorEncoding == GL_SRGB) { return false; } // We cannot support direct copies to non-color-renderable formats - if (gl_d3d11::GetRTVFormat(internalFormat) != DXGI_FORMAT_UNKNOWN) + if (d3d11FormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) { return false; } // We skip all 3-channel formats since sometimes format support is missing - if (gl::GetComponentCount(internalFormat) == 3) + if (internalFormatInfo.componentCount == 3) { return false; } // We don't support formats which we can't represent without conversion - if (getNativeTextureFormat(internalFormat) != internalFormat) + if (dxgiFormatInfo.internalFormat != internalFormat) { return false; } @@ -2860,7 +2587,7 @@ bool Renderer11::getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, { ASSERT(colorbuffer != NULL); - RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget()); + RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); if (renderTarget) { *subresourceIndex = renderTarget->getSubresourceIndex(); @@ -2905,7 +2632,7 @@ bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &read return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget *readRenderTarget = readBuffer->getRenderTarget(); + RenderTarget *readRenderTarget = GetAttachmentRenderTarget(readBuffer); for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) { @@ -2919,7 +2646,7 @@ bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &read return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget *drawRenderTarget = drawBuffer->getRenderTarget(); + RenderTarget *drawRenderTarget = GetAttachmentRenderTarget(drawBuffer); if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, blitRenderTarget, false, false)) @@ -2947,8 +2674,9 @@ bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &read return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget *readRenderTarget = readBuffer->getDepthStencil(); - RenderTarget *drawRenderTarget = drawBuffer->getDepthStencil(); + RenderTarget *readRenderTarget = GetAttachmentRenderTarget(readBuffer); + RenderTarget *drawRenderTarget = GetAttachmentRenderTarget(drawBuffer); + ASSERT(readRenderTarget && drawRenderTarget); if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, false, blitDepth, blitStencil)) @@ -2962,8 +2690,8 @@ bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &read return true; } -void Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, - GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void* pixels) +gl::Error Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, + GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) { ID3D11Texture2D *colorBufferTexture = NULL; unsigned int subresourceIndex = 0; @@ -2978,19 +2706,33 @@ void Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsi area.width = width; area.height = height; - if (pack.pixelBuffer.get() != NULL) + gl::Buffer *packBuffer = pack.pixelBuffer.get(); + if (packBuffer != NULL) { - rx::Buffer11 *packBufferStorage = Buffer11::makeBuffer11(pack.pixelBuffer.get()->getImplementation()); + rx::Buffer11 *packBufferStorage = Buffer11::makeBuffer11(packBuffer->getImplementation()); PackPixelsParams packParams(area, format, type, outputPitch, pack, reinterpret_cast<ptrdiff_t>(pixels)); - packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams); + + gl::Error error = packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams); + if (error.isError()) + { + return error; + } + + packBuffer->getIndexRangeCache()->clear(); } else { - readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels); + gl::Error error = readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels); + if (error.isError()) + { + return error; + } } SafeRelease(colorBufferTexture); } + + return gl::Error(GL_NO_ERROR); } Image *Renderer11::createImage() @@ -3031,28 +2773,23 @@ TextureStorage *Renderer11::createTextureStorage2DArray(GLenum internalformat, b return new TextureStorage11_2DArray(this, internalformat, renderTarget, width, height, depth, levels); } -Texture2DImpl *Renderer11::createTexture2D() +TextureImpl *Renderer11::createTexture(GLenum target) { - return new TextureD3D_2D(this); -} - -TextureCubeImpl *Renderer11::createTextureCube() -{ - return new TextureD3D_Cube(this); -} - -Texture3DImpl *Renderer11::createTexture3D() -{ - return new TextureD3D_3D(this); -} + switch(target) + { + case GL_TEXTURE_2D: return new TextureD3D_2D(this); + case GL_TEXTURE_CUBE_MAP: return new TextureD3D_Cube(this); + case GL_TEXTURE_3D: return new TextureD3D_3D(this); + case GL_TEXTURE_2D_ARRAY: return new TextureD3D_2DArray(this); + default: + UNREACHABLE(); + } -Texture2DArrayImpl *Renderer11::createTexture2DArray() -{ - return new TextureD3D_2DArray(this); + return NULL; } -void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format, - GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void *pixels) +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) { ASSERT(area.width >= 0); ASSERT(area.height >= 0); @@ -3077,7 +2814,7 @@ void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResou if (safeArea.width == 0 || safeArea.height == 0) { // no work to do - return; + return gl::Error(GL_NO_ERROR); } D3D11_TEXTURE2D_DESC stagingDesc; @@ -3097,8 +2834,7 @@ void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResou HRESULT result = mDevice->CreateTexture2D(&stagingDesc, NULL, &stagingTex); if (FAILED(result)) { - ERR("Failed to create staging texture for readPixels, HRESULT: 0x%X.", result); - return; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal staging texture for ReadPixels, HRESULT: 0x%X.", result); } ID3D11Texture2D* srcTex = NULL; @@ -3120,9 +2856,8 @@ void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResou result = mDevice->CreateTexture2D(&resolveDesc, NULL, &srcTex); if (FAILED(result)) { - ERR("Failed to create resolve texture for readPixels, HRESULT: 0x%X.", result); SafeRelease(stagingTex); - return; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal resolve texture for ReadPixels, HRESULT: 0x%X.", result); } mDeviceContext->ResolveSubresource(srcTex, 0, texture, subResource, textureDesc.Format); @@ -3150,9 +2885,11 @@ void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResou packPixels(stagingTex, packParams, pixels); SafeRelease(stagingTex); + + return gl::Error(GL_NO_ERROR); } -void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams ¶ms, void *pixelsOut) +void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams ¶ms, uint8_t *pixelsOut) { D3D11_TEXTURE2D_DESC textureDesc; readTexture->GetDesc(&textureDesc); @@ -3162,39 +2899,37 @@ void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams UNUSED_ASSERTION_VARIABLE(hr); ASSERT(SUCCEEDED(hr)); - unsigned char *source; + uint8_t *source; int inputPitch; if (params.pack.reverseRowOrder) { - source = static_cast<unsigned char*>(mapping.pData) + mapping.RowPitch * (params.area.height - 1); + source = static_cast<uint8_t*>(mapping.pData) + mapping.RowPitch * (params.area.height - 1); inputPitch = -static_cast<int>(mapping.RowPitch); } else { - source = static_cast<unsigned char*>(mapping.pData); + source = static_cast<uint8_t*>(mapping.pData); inputPitch = static_cast<int>(mapping.RowPitch); } - GLenum sourceInternalFormat = d3d11_gl::GetInternalFormat(textureDesc.Format); - GLenum sourceFormat = gl::GetFormat(sourceInternalFormat); - GLenum sourceType = gl::GetType(sourceInternalFormat); - - GLuint sourcePixelSize = gl::GetPixelBytes(sourceInternalFormat); - - if (sourceFormat == params.format && sourceType == params.type) + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(textureDesc.Format); + const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(dxgiFormatInfo.internalFormat); + if (sourceFormatInfo.format == params.format && sourceFormatInfo.type == params.type) { - unsigned char *dest = static_cast<unsigned char*>(pixelsOut) + params.offset; + uint8_t *dest = pixelsOut + params.offset; for (int y = 0; y < params.area.height; y++) { - memcpy(dest + y * params.outputPitch, source + y * inputPitch, params.area.width * sourcePixelSize); + memcpy(dest + y * params.outputPitch, source + y * inputPitch, params.area.width * sourceFormatInfo.pixelBytes); } } else { - GLenum destInternalFormat = gl::GetSizedInternalFormat(params.format, params.type); - GLuint destPixelSize = gl::GetPixelBytes(destInternalFormat); + const d3d11::DXGIFormat &sourceDXGIFormatInfo = d3d11::GetDXGIFormatInfo(textureDesc.Format); + ColorCopyFunction fastCopyFunc = sourceDXGIFormatInfo.getFastCopyFunction(params.format, params.type); + + const gl::FormatType &destFormatTypeInfo = gl::GetFormatTypeInfo(params.format, params.type); + const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(destFormatTypeInfo.internalFormat); - ColorCopyFunction fastCopyFunc = d3d11::GetFastCopyFunction(textureDesc.Format, params.format, params.type); if (fastCopyFunc) { // Fast copy is possible through some special function @@ -3202,8 +2937,8 @@ void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams { for (int x = 0; x < params.area.width; x++) { - void *dest = static_cast<unsigned char*>(pixelsOut) + params.offset + y * params.outputPitch + x * destPixelSize; - void *src = static_cast<unsigned char*>(source) + y * inputPitch + x * sourcePixelSize; + uint8_t *dest = pixelsOut + params.offset + y * params.outputPitch + x * destFormatInfo.pixelBytes; + const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes; fastCopyFunc(src, dest); } @@ -3211,10 +2946,7 @@ void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams } else { - ColorReadFunction readFunc = d3d11::GetColorReadFunction(textureDesc.Format); - ColorWriteFunction writeFunc = gl::GetColorWriteFunction(params.format, params.type); - - unsigned char temp[16]; // Maximum size of any Color<T> type used. + uint8_t temp[16]; // Maximum size of any Color<T> type used. META_ASSERT(sizeof(temp) >= sizeof(gl::ColorF) && sizeof(temp) >= sizeof(gl::ColorUI) && sizeof(temp) >= sizeof(gl::ColorI)); @@ -3223,13 +2955,13 @@ void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams { for (int x = 0; x < params.area.width; x++) { - void *dest = static_cast<unsigned char*>(pixelsOut) + params.offset + y * params.outputPitch + x * destPixelSize; - void *src = static_cast<unsigned char*>(source) + y * inputPitch + x * sourcePixelSize; + uint8_t *dest = pixelsOut + params.offset + y * params.outputPitch + x * destFormatInfo.pixelBytes; + const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes; // readFunc and writeFunc will be using the same type of color, CopyTexImage // will not allow the copy otherwise. - readFunc(src, temp); - writeFunc(temp, dest); + sourceDXGIFormatInfo.colorReadFunction(src, temp); + destFormatTypeInfo.colorWriteFunction(temp, dest); } } } @@ -3328,9 +3060,8 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R drawRect.x < 0 || drawRect.x + drawRect.width > drawSize.width || drawRect.y < 0 || drawRect.y + drawRect.height > drawSize.height; - bool hasDepth = gl::GetDepthBits(drawRenderTarget11->getActualFormat()) > 0; - bool hasStencil = gl::GetStencilBits(drawRenderTarget11->getActualFormat()) > 0; - bool partialDSBlit = (hasDepth && depthBlit) != (hasStencil && stencilBlit); + const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(drawRenderTarget->getActualFormat()); + bool partialDSBlit = (actualFormatInfo.depthBits > 0 && depthBlit) != (actualFormatInfo.stencilBits > 0 && stencilBlit); if (readRenderTarget11->getActualFormat() == drawRenderTarget->getActualFormat() && !stretchRequired && !outOfBounds && !flipRequired && !partialDSBlit && @@ -3404,7 +3135,7 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R } else { - GLenum format = gl::GetFormat(drawRenderTarget->getInternalFormat()); + GLenum format = gl::GetInternalFormatInfo(drawRenderTarget->getInternalFormat()).format; result = mBlit->copyTexture(readSRV, readArea, readSize, drawRTV, drawArea, drawSize, scissor, format, filter); } @@ -3457,7 +3188,9 @@ ID3D11Texture2D *Renderer11::resolveMultisampledTexture(ID3D11Texture2D *source, void Renderer11::invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *attachment, int mipLevel) { ASSERT(attachment->isTexture()); - TextureStorage *texStorage = attachment->getTextureStorage(); + gl::Texture *texture = attachment->getTexture(); + + TextureStorage *texStorage = texture->getNativeTexture(); if (texStorage) { TextureStorage11 *texStorage11 = TextureStorage11::makeTextureStorage11(texStorage); @@ -3515,46 +3248,14 @@ bool Renderer11::getLUID(LUID *adapterLuid) const return true; } -GLenum Renderer11::getNativeTextureFormat(GLenum internalFormat) const -{ - return d3d11_gl::GetInternalFormat(gl_d3d11::GetTexFormat(internalFormat)); -} - rx::VertexConversionType Renderer11::getVertexConversionType(const gl::VertexFormat &vertexFormat) const { - return gl_d3d11::GetVertexConversionType(vertexFormat); + return d3d11::GetVertexFormatInfo(vertexFormat).conversionType; } GLenum Renderer11::getVertexComponentType(const gl::VertexFormat &vertexFormat) const { - return d3d11::GetComponentType(gl_d3d11::GetNativeVertexFormat(vertexFormat)); -} - -Renderer11::MultisampleSupportInfo Renderer11::getMultisampleSupportInfo(DXGI_FORMAT format) -{ - MultisampleSupportInfo supportInfo = { 0 }; - - UINT formatSupport; - HRESULT result; - - result = mDevice->CheckFormatSupport(format, &formatSupport); - if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET)) - { - for (unsigned int i = 1; i <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++) - { - result = mDevice->CheckMultisampleQualityLevels(format, i, &supportInfo.qualityLevels[i - 1]); - if (SUCCEEDED(result) && supportInfo.qualityLevels[i - 1] > 0) - { - supportInfo.maxSupportedSamples = std::max(supportInfo.maxSupportedSamples, i); - } - else - { - supportInfo.qualityLevels[i - 1] = 0; - } - } - } - - return supportInfo; + return d3d11::GetDXGIFormatInfo(d3d11::GetVertexFormatInfo(vertexFormat).nativeFormat).componentType; } void Renderer11::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h index b54f75d859..2a53fa1672 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h @@ -59,37 +59,37 @@ class Renderer11 : public Renderer virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat); - virtual void generateSwizzle(gl::Texture *texture); - virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler); - virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture); + virtual gl::Error generateSwizzle(gl::Texture *texture); + virtual gl::Error setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler); + virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture); - virtual bool setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]); + virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]); - virtual void setRasterizerState(const gl::RasterizerState &rasterState); - virtual void setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, - unsigned int sampleMask); - virtual void setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, - int stencilBackRef, bool frontFaceCCW); + virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState); + virtual gl::Error setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, + unsigned int sampleMask); + virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, + int stencilBackRef, bool frontFaceCCW); virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled); - virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, + virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, bool ignoreViewport); virtual bool applyPrimitiveType(GLenum mode, GLsizei count); - virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer); - virtual void applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, - bool rasterizerDiscard, bool transformFeedbackActive); - virtual void applyUniforms(const gl::ProgramBinary &programBinary); - virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], - GLint first, GLsizei count, GLsizei instances); - virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo); + virtual gl::Error applyRenderTarget(gl::Framebuffer *frameBuffer); + virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, + bool rasterizerDiscard, bool transformFeedbackActive); + virtual gl::Error applyUniforms(const gl::ProgramBinary &programBinary); + virtual gl::Error applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], + GLint first, GLsizei count, GLsizei instances); + virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo); virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]); - virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive); - virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, - gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances); + virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive); + virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, + gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances); - virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); + virtual gl::Error clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); virtual void markAllStateDirty(); @@ -103,63 +103,48 @@ class Renderer11 : public Renderer virtual std::string getRendererDescription() const; virtual GUID getAdapterIdentifier() const; - virtual unsigned int getMaxVertexTextureImageUnits() const; - virtual unsigned int getMaxCombinedTextureImageUnits() const; virtual unsigned int getReservedVertexUniformVectors() const; virtual unsigned int getReservedFragmentUniformVectors() const; - virtual unsigned int getMaxVertexUniformVectors() const; - virtual unsigned int getMaxFragmentUniformVectors() const; - virtual unsigned int getMaxVaryingVectors() const; - virtual unsigned int getMaxVertexShaderUniformBuffers() const; - virtual unsigned int getMaxFragmentShaderUniformBuffers() const; virtual unsigned int getReservedVertexUniformBuffers() const; virtual unsigned int getReservedFragmentUniformBuffers() const; - unsigned int getReservedVaryings() const; - virtual unsigned int getMaxTransformFeedbackBuffers() const; - virtual unsigned int getMaxTransformFeedbackSeparateComponents() const; - virtual unsigned int getMaxTransformFeedbackInterleavedComponents() const; - virtual unsigned int getMaxUniformBufferSize() const; virtual bool getShareHandleSupport() const; virtual bool getPostSubBufferSupport() const; - virtual int getMaxRecommendedElementsIndices() const; - virtual int getMaxRecommendedElementsVertices() const; - virtual bool getSRGBTextureSupport() const; virtual int getMajorShaderModel() const; virtual int getMinSwapInterval() const; virtual int getMaxSwapInterval() const; - virtual GLsizei getMaxSupportedSamples() const; - virtual GLsizei getMaxSupportedFormatSamples(GLenum internalFormat) const; - virtual GLsizei getNumSampleCounts(GLenum internalFormat) const; - virtual void getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const; - int getNearestSupportedSamples(DXGI_FORMAT format, unsigned int requested) const; - // Pixel operations - virtual bool copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source); - virtual bool copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source); - virtual bool copyToRenderTarget(TextureStorageInterface3D *dest, TextureStorageInterface3D *source); - virtual bool copyToRenderTarget(TextureStorageInterface2DArray *dest, TextureStorageInterface2DArray *source); - - virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level); - virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level); - virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface3D *storage, GLint level); - virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level); + virtual bool copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source); + virtual bool copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source); + virtual bool copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source); + virtual bool copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source); + + virtual bool copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level); + virtual bool copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level); + virtual bool copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level); + virtual bool copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level); virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter); - virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, - GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void* pixels); + + virtual gl::Error readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, + GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels); // RenderTarget creation virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth); virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples); + // Shader creation + virtual ShaderImpl *createShader(GLenum type); + virtual ProgramImpl *createProgram(); + // Shader operations + virtual void releaseShaderCompiler(); virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type, const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, bool separatedOutputBuffers); @@ -178,10 +163,7 @@ class Renderer11 : public Renderer virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); // Texture creation - virtual Texture2DImpl *createTexture2D(); - virtual TextureCubeImpl *createTextureCube(); - virtual Texture3DImpl *createTexture3D(); - virtual Texture2DArrayImpl *createTexture2DArray(); + virtual TextureImpl *createTexture(GLenum target); // Buffer creation virtual BufferImpl *createBuffer(); @@ -195,6 +177,9 @@ class Renderer11 : public Renderer virtual QueryImpl *createQuery(GLenum type); virtual FenceImpl *createFence(); + // Transform Feedback creation + virtual TransformFeedbackImpl* createTransformFeedback(); + // D3D11-renderer specific methods ID3D11Device *getDevice() { return mDevice; } ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; }; @@ -211,10 +196,9 @@ class Renderer11 : public Renderer bool getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource); void unapplyRenderTargets(); void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView); - void packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams ¶ms, void *pixelsOut); + void packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams ¶ms, uint8_t *pixelsOut); virtual bool getLUID(LUID *adapterLuid) const; - virtual GLenum getNativeTextureFormat(GLenum internalFormat) const; virtual rx::VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const; virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const; @@ -223,11 +207,11 @@ class Renderer11 : public Renderer virtual void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const; - void drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); - void drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances); + 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); - void readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format, - GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void *pixels); + 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); bool blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget, RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor, @@ -253,19 +237,6 @@ class Renderer11 : public Renderer RenderStateCache mStateCache; - // Multisample format support - struct MultisampleSupportInfo - { - unsigned int qualityLevels[D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT]; - unsigned int maxSupportedSamples; - }; - MultisampleSupportInfo getMultisampleSupportInfo(DXGI_FORMAT format); - - typedef std::unordered_map<GLenum, MultisampleSupportInfo> MultisampleSupportMap; - MultisampleSupportMap mMultisampleSupportMap; - - unsigned int mMaxSupportedSamples; - // current render target states unsigned int mAppliedRenderTargetSerials[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS]; unsigned int mAppliedDepthbufferSerial; @@ -275,15 +246,15 @@ class Renderer11 : public Renderer rx::RenderTarget::Desc mRenderTargetDesc; // Currently applied sampler states - bool mForceSetVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; - gl::SamplerState mCurVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; + std::vector<bool> mForceSetVertexSamplerStates; + std::vector<gl::SamplerState> mCurVertexSamplerStates; - bool mForceSetPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS]; - gl::SamplerState mCurPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS]; + std::vector<bool> mForceSetPixelSamplerStates; + std::vector<gl::SamplerState> mCurPixelSamplerStates; // Currently applied textures - ID3D11ShaderResourceView *mCurVertexSRVs[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; - ID3D11ShaderResourceView *mCurPixelSRVs[gl::MAX_TEXTURE_IMAGE_UNITS]; + std::vector<ID3D11ShaderResourceView*> mCurVertexSRVs; + std::vector<ID3D11ShaderResourceView*> mCurPixelSRVs; // Currently applied blend state bool mForceSetBlendState; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.cpp index 5a7c987494..52f34887fb 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -9,7 +8,6 @@ // executable implementation details. #include "libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h" - #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" namespace rx diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp index 0341df10f9..4b29be055d 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -7,12 +6,13 @@ // SwapChain11.cpp: Implements a back-end specific class for the D3D11 swap chain. -#include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h" - #include "common/platform.h" +#include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h" #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" + +// Precompiled shaders #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough2dvs.h" #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dps.h" @@ -94,8 +94,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei ASSERT(backbufferWidth >= 1); ASSERT(backbufferHeight >= 1); -#if !defined(ANGLE_PLATFORM_WINRT) // Preserve the render target content +#if !defined(ANGLE_PLATFORM_WINRT) ID3D11Texture2D *previousOffscreenTexture = mOffscreenTexture; if (previousOffscreenTexture) { @@ -107,6 +107,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei releaseOffscreenTexture(); + const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat); + // If the app passed in a share handle, open the resource // See EGL_ANGLE_d3d_share_handle_client_buffer if (mAppCreatedShareHandle) @@ -135,11 +137,11 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; mOffscreenTexture->GetDesc(&offscreenTextureDesc); - if (offscreenTextureDesc.Width != (UINT)backbufferWidth - || offscreenTextureDesc.Height != (UINT)backbufferHeight - || offscreenTextureDesc.Format != gl_d3d11::GetTexFormat(mBackBufferFormat) - || offscreenTextureDesc.MipLevels != 1 - || offscreenTextureDesc.ArraySize != 1) + if (offscreenTextureDesc.Width != (UINT)backbufferWidth || + offscreenTextureDesc.Height != (UINT)backbufferHeight || + offscreenTextureDesc.Format != backbufferFormatInfo.texFormat || + offscreenTextureDesc.MipLevels != 1 || + offscreenTextureDesc.ArraySize != 1) { ERR("Invalid texture parameters in the shared offscreen texture pbuffer"); release(); @@ -153,7 +155,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; offscreenTextureDesc.Width = backbufferWidth; offscreenTextureDesc.Height = backbufferHeight; - offscreenTextureDesc.Format = gl_d3d11::GetTexFormat(mBackBufferFormat); + offscreenTextureDesc.Format = backbufferFormatInfo.texFormat; offscreenTextureDesc.MipLevels = 1; offscreenTextureDesc.ArraySize = 1; offscreenTextureDesc.SampleDesc.Count = 1; @@ -209,7 +211,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei D3D11_RENDER_TARGET_VIEW_DESC offscreenRTVDesc; - offscreenRTVDesc.Format = gl_d3d11::GetRTVFormat(mBackBufferFormat); + offscreenRTVDesc.Format = backbufferFormatInfo.rtvFormat; offscreenRTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; offscreenRTVDesc.Texture2D.MipSlice = 0; @@ -218,7 +220,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei d3d11::SetDebugName(mOffscreenRTView, "Offscreen back buffer render target"); D3D11_SHADER_RESOURCE_VIEW_DESC offscreenSRVDesc; - offscreenSRVDesc.Format = gl_d3d11::GetSRVFormat(mBackBufferFormat); + offscreenSRVDesc.Format = backbufferFormatInfo.srvFormat; offscreenSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; offscreenSRVDesc.Texture2D.MostDetailedMip = 0; offscreenSRVDesc.Texture2D.MipLevels = -1; @@ -227,12 +229,14 @@ 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); + if (mDepthBufferFormat != GL_NONE) { D3D11_TEXTURE2D_DESC depthStencilTextureDesc; depthStencilTextureDesc.Width = backbufferWidth; depthStencilTextureDesc.Height = backbufferHeight; - depthStencilTextureDesc.Format = gl_d3d11::GetTexFormat(mDepthBufferFormat); + depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat; depthStencilTextureDesc.MipLevels = 1; depthStencilTextureDesc.ArraySize = 1; depthStencilTextureDesc.SampleDesc.Count = 1; @@ -260,7 +264,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei d3d11::SetDebugName(mDepthStencilTexture, "Offscreen depth stencil texture"); D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilDesc; - depthStencilDesc.Format = gl_d3d11::GetDSVFormat(mDepthBufferFormat); + depthStencilDesc.Format = depthBufferFormatInfo.dsvFormat; depthStencilDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilDesc.Flags = 0; depthStencilDesc.Texture2D.MipSlice = 0; @@ -270,7 +274,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei d3d11::SetDebugName(mDepthStencilDSView, "Offscreen depth stencil view"); D3D11_SHADER_RESOURCE_VIEW_DESC depthStencilSRVDesc; - depthStencilSRVDesc.Format = gl_d3d11::GetSRVFormat(mDepthBufferFormat); + depthStencilSRVDesc.Format = depthBufferFormatInfo.srvFormat; depthStencilSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; depthStencilSRVDesc.Texture2D.MostDetailedMip = 0; depthStencilSRVDesc.Texture2D.MipLevels = -1; @@ -343,8 +347,8 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) #else const int bufferCount = 2; #endif - DXGI_FORMAT backbufferDXGIFormat = gl_d3d11::GetTexFormat(mBackBufferFormat); - result = mSwapChain->ResizeBuffers(bufferCount, backbufferWidth, backbufferHeight, backbufferDXGIFormat, 0); + const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat); + result = mSwapChain->ResizeBuffers(bufferCount, backbufferWidth, backbufferHeight, backbufferFormatInfo.texFormat, 0); if (FAILED(result)) { @@ -361,6 +365,7 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) } } #endif + result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture); ASSERT(SUCCEEDED(result)); if (SUCCEEDED(result)) @@ -409,14 +414,17 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap if (mWindow) { + const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat); + IDXGIFactory *factory = mRenderer->getDxgiFactory(); + #if !defined(ANGLE_PLATFORM_WINRT) DXGI_SWAP_CHAIN_DESC swapChainDesc = {0}; swapChainDesc.BufferDesc.Width = backbufferWidth; swapChainDesc.BufferDesc.Height = backbufferHeight; swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; - swapChainDesc.BufferDesc.Format = gl_d3d11::GetTexFormat(mBackBufferFormat); + swapChainDesc.BufferDesc.Format = backbufferFormatInfo.texFormat; swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; swapChainDesc.SampleDesc.Count = 1; @@ -437,7 +445,7 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0}; swapChainDesc.Width = 0; swapChainDesc.Height = 0; - swapChainDesc.Format = gl_d3d11::GetTexFormat(mBackBufferFormat); + swapChainDesc.Format = backbufferFormatInfo.texFormat; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; @@ -460,7 +468,6 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap mViewportWidth = swapChainDesc.Width; mViewportHeight = swapChainDesc.Height; #endif - if (FAILED(result)) { ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result); @@ -530,7 +537,7 @@ void SwapChain11::initPassThroughResources() samplerDesc.BorderColor[2] = 0.0f; samplerDesc.BorderColor[3] = 0.0f; samplerDesc.MinLOD = 0; - samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; + samplerDesc.MaxLOD = FLT_MAX; result = device->CreateSamplerState(&samplerDesc, &mPassThroughSampler); ASSERT(SUCCEEDED(result)); @@ -636,7 +643,7 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EG // Draw deviceContext->Draw(4, 0); -#if ANGLE_FORCE_VSYNC_OFF +#ifdef ANGLE_FORCE_VSYNC_OFF result = mSwapChain->Present(0, 0); #else result = mSwapChain->Present(mSwapInterval, 0); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp index 00b81b7c92..91e7147da6 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -9,17 +8,18 @@ // classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture. #include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h" - -#include "libGLESv2/renderer/d3d/TextureD3D.h" #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h" #include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h" #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/renderer/d3d/d3d11/Blit11.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" +#include "libGLESv2/renderer/d3d/d3d11/Image11.h" +#include "libGLESv2/renderer/d3d/TextureD3D.h" +#include "libGLESv2/main.h" +#include "libGLESv2/ImageIndex.h" #include "common/utilities.h" -#include "libGLESv2/main.h" namespace rx { @@ -126,15 +126,16 @@ DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, bool renderTa { UINT bindFlags = 0; - if (gl_d3d11::GetSRVFormat(internalFormat) != DXGI_FORMAT_UNKNOWN) + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat); + if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN) { bindFlags |= D3D11_BIND_SHADER_RESOURCE; } - if (gl_d3d11::GetDSVFormat(internalFormat) != DXGI_FORMAT_UNKNOWN) + if (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN) { bindFlags |= D3D11_BIND_DEPTH_STENCIL; } - if (gl_d3d11::GetRTVFormat(internalFormat) != DXGI_FORMAT_UNKNOWN && renderTarget) + if (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN && renderTarget) { bindFlags |= D3D11_BIND_RENDER_TARGET; } @@ -195,7 +196,7 @@ UINT TextureStorage11::getSubresourceIndex(int mipLevel, int layerTarget) const ID3D11ShaderResourceView *TextureStorage11::getSRV(const gl::SamplerState &samplerState) { bool swizzleRequired = samplerState.swizzleRequired(); - bool mipmapping = IsMipmapFiltered(samplerState); + bool mipmapping = gl::IsMipmapFiltered(samplerState); unsigned int mipLevels = mipmapping ? (samplerState.maxLevel - samplerState.baseLevel) : 1; // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level, which corresponds to GL level 0) @@ -239,7 +240,7 @@ ID3D11ShaderResourceView *TextureStorage11::getSRVLevel(int mipLevel) } } -void TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha) +gl::Error TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha) { SwizzleCacheValue swizzleTarget(swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha); for (int level = 0; level < getLevelCount(); level++) @@ -255,16 +256,17 @@ void TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, Blit11 *blitter = mRenderer->getBlitter(); - if (blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha)) + gl::Error error = blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha); + if (error.isError()) { - mSwizzleCache[level] = swizzleTarget; - } - else - { - ERR("Failed to swizzle texture."); + return error; } + + mSwizzleCache[level] = swizzleTarget; } } + + return gl::Error(GL_NO_ERROR); } void TextureStorage11::invalidateSwizzleCacheLevel(int mipLevel) @@ -308,7 +310,8 @@ bool TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsign ASSERT(dstTexture); - if (!fullCopy && (d3d11::GetDepthBits(mTextureFormat) > 0 || d3d11::GetStencilBits(mTextureFormat) > 0)) + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat); + if (!fullCopy && (dxgiFormatInfo.depthBits > 0 || dxgiFormatInfo.stencilBits > 0)) { // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead Blit11 *blitter = mRenderer->getBlitter(); @@ -319,11 +322,13 @@ bool TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsign } else { + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat); + D3D11_BOX srcBox; srcBox.left = copyArea.x; srcBox.top = copyArea.y; - srcBox.right = copyArea.x + roundUp((unsigned int)width, d3d11::GetBlockWidth(mTextureFormat)); - srcBox.bottom = copyArea.y + roundUp((unsigned int)height, d3d11::GetBlockHeight(mTextureFormat)); + srcBox.right = copyArea.x + roundUp((unsigned int)width, dxgiFormatInfo.blockWidth); + srcBox.bottom = copyArea.y + roundUp((unsigned int)height, dxgiFormatInfo.blockHeight); srcBox.front = copyArea.z; srcBox.back = copyArea.z + copyArea.depth; @@ -338,6 +343,27 @@ bool TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsign return false; } +bool TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource, + int level, int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth) +{ + if (dstTexture) + { + ID3D11Resource *srcTexture = getResource(); + unsigned int srcSubresource = getSubresourceIndex(level + mTopLevel, layerTarget); + + ASSERT(srcTexture); + + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + + context->CopySubresourceRegion(dstTexture, dstSubresource, xoffset, yoffset, zoffset, + srcTexture, srcSubresource, NULL); + return true; + } + + return false; +} + void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest) { if (source && dest) @@ -356,7 +382,7 @@ void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget1 Blit11 *blitter = mRenderer->getBlitter(); blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL, - gl::GetFormat(source->getInternalFormat()), GL_LINEAR); + gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR); } } } @@ -371,14 +397,15 @@ void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGree } TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain) - : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE) + : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE), + mTexture(swapchain->getOffscreenTexture()), + mSwizzleTexture(NULL) { - mTexture = swapchain->getOffscreenTexture(); mTexture->AddRef(); - mSwizzleTexture = NULL; for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) { + mAssociatedImages[i] = NULL; mRenderTarget[i] = NULL; mSwizzleRenderTargets[i] = NULL; } @@ -401,33 +428,37 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapch offscreenRTV->GetDesc(&rtvDesc); mRenderTargetFormat = rtvDesc.Format; - GLenum internalFormat = d3d11_gl::GetInternalFormat(mTextureFormat); - mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalFormat); - mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalFormat); - mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalFormat); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat); + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(dxgiFormatInfo.internalFormat); + mSwizzleTextureFormat = formatInfo.swizzleTexFormat; + mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; + mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; mDepthStencilFormat = DXGI_FORMAT_UNKNOWN; + + initializeSerials(1, 1); } TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) - : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget)) + : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget)), + mTexture(NULL), + mSwizzleTexture(NULL) { - mTexture = NULL; - mSwizzleTexture = NULL; - for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) { + mAssociatedImages[i] = NULL; mRenderTarget[i] = NULL; mSwizzleRenderTargets[i] = NULL; } - mTextureFormat = gl_d3d11::GetTexFormat(internalformat); - mShaderResourceFormat = gl_d3d11::GetSRVFormat(internalformat); - mDepthStencilFormat = gl_d3d11::GetDSVFormat(internalformat); - mRenderTargetFormat = gl_d3d11::GetRTVFormat(internalformat); - mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalformat); - mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalformat); - mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalformat); + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat); + mTextureFormat = formatInfo.texFormat; + mShaderResourceFormat = formatInfo.srvFormat; + mDepthStencilFormat = formatInfo.dsvFormat; + mRenderTargetFormat = formatInfo.rtvFormat; + mSwizzleTextureFormat = formatInfo.swizzleTexFormat; + mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; + mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; // if the width or height is not positive this should be treated as an incomplete texture // we handle that here by skipping the d3d texture creation @@ -441,7 +472,7 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalform D3D11_TEXTURE2D_DESC desc; desc.Width = width; // Compressed texture size constraints? desc.Height = height; - desc.MipLevels = mRenderer->isLevel9() ? 1 : ((levels > 0) ? (mTopLevel + levels) : 0); + desc.MipLevels = desc.MipLevels = mRenderer->isLevel9() ? 1 : ((levels > 0) ? (mTopLevel + levels) : 0); desc.ArraySize = 1; desc.Format = mTextureFormat; desc.SampleDesc.Count = 1; @@ -474,10 +505,27 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalform mTextureDepth = 1; } } + + initializeSerials(getLevelCount(), 1); } TextureStorage11_2D::~TextureStorage11_2D() { + for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + if (mAssociatedImages[i] != NULL) + { + bool imageAssociationCorrect = mAssociatedImages[i]->isAssociatedStorageValid(this); + ASSERT(imageAssociationCorrect); + + if (imageAssociationCorrect) + { + // We must let the Images recover their data before we delete it from the TextureStorage. + mAssociatedImages[i]->recoverFromAssociatedStorage(); + } + } + } + SafeRelease(mTexture); SafeRelease(mSwizzleTexture); @@ -494,13 +542,80 @@ TextureStorage11_2D *TextureStorage11_2D::makeTextureStorage11_2D(TextureStorage return static_cast<TextureStorage11_2D*>(storage); } +void TextureStorage11_2D::associateImage(Image11* image, int level, int layerTarget) +{ + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + mAssociatedImages[level] = image; + } +} + +bool TextureStorage11_2D::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage) +{ + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + // This validation check should never return false. It means the Image/TextureStorage association is broken. + bool retValue = (mAssociatedImages[level] == expectedImage); + ASSERT(retValue); + return retValue; + } + + return false; +} + +// disassociateImage allows an Image to end its association with a Storage. +void TextureStorage11_2D::disassociateImage(int level, int layerTarget, Image11* expectedImage) +{ + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + ASSERT(mAssociatedImages[level] == expectedImage); + + if (mAssociatedImages[level] == expectedImage) + { + mAssociatedImages[level] = NULL; + } + } +} + +// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association. +void TextureStorage11_2D::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage) +{ + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + // No need to let the old Image recover its data, if it is also the incoming Image. + if (mAssociatedImages[level] != NULL && mAssociatedImages[level] != incomingImage) + { + // Ensure that the Image is still associated with this TextureStorage. This should be true. + bool imageAssociationCorrect = mAssociatedImages[level]->isAssociatedStorageValid(this); + ASSERT(imageAssociationCorrect); + + if (imageAssociationCorrect) + { + // Force the image to recover from storage before its data is overwritten. + // This will reset mAssociatedImages[level] to NULL too. + mAssociatedImages[level]->recoverFromAssociatedStorage(); + } + } + } +} + ID3D11Resource *TextureStorage11_2D::getResource() const { return mTexture; } -RenderTarget *TextureStorage11_2D::getRenderTarget(int level) +RenderTarget *TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index) { + ASSERT(!index.hasLayer()); + + int level = index.mipIndex; + if (level >= 0 && level < getLevelCount()) { if (!mRenderTarget[level]) @@ -595,14 +710,22 @@ ID3D11ShaderResourceView *TextureStorage11_2D::createSRV(int baseLevel, int mipL return SRV; } -void TextureStorage11_2D::generateMipmap(int level) +void TextureStorage11_2D::generateMipmaps() { - invalidateSwizzleCacheLevel(level); + // Base level must already be defined + + for (int level = 1; level < getLevelCount(); level++) + { + invalidateSwizzleCacheLevel(level); + + gl::ImageIndex srcIndex = gl::ImageIndex::Make2D(level - 1); + gl::ImageIndex destIndex = gl::ImageIndex::Make2D(level); - RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(level - 1)); - RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(level)); + RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex)); + RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex)); - generateMipmapLayer(source, dest); + generateMipmapLayer(source, dest); + } } ID3D11Resource *TextureStorage11_2D::getSwizzleTexture() @@ -671,11 +794,6 @@ ID3D11RenderTargetView *TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel } } -unsigned int TextureStorage11_2D::getTextureLevelDepth(int mipLevel) const -{ - return 1; -} - TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels) : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget)) { @@ -687,17 +805,19 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internal mSwizzleRenderTargets[level] = NULL; for (unsigned int face = 0; face < 6; face++) { + mAssociatedImages[face][level] = NULL; mRenderTarget[face][level] = NULL; } } - mTextureFormat = gl_d3d11::GetTexFormat(internalformat); - mShaderResourceFormat = gl_d3d11::GetSRVFormat(internalformat); - mDepthStencilFormat = gl_d3d11::GetDSVFormat(internalformat); - mRenderTargetFormat = gl_d3d11::GetRTVFormat(internalformat); - mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalformat); - mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalformat); - mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalformat); + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat); + mTextureFormat = formatInfo.texFormat; + mShaderResourceFormat = formatInfo.srvFormat; + mDepthStencilFormat = formatInfo.dsvFormat; + mRenderTargetFormat = formatInfo.rtvFormat; + mSwizzleTextureFormat = formatInfo.swizzleTexFormat; + mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; + mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; // if the size is not positive this should be treated as an incomplete texture // we handle that here by skipping the d3d texture creation @@ -739,10 +859,31 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internal mTextureDepth = 1; } } + + initializeSerials(getLevelCount() * 6, 6); } + TextureStorage11_Cube::~TextureStorage11_Cube() { + for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) + { + for (unsigned int face = 0; face < 6; face++) + { + if (mAssociatedImages[face][level] != NULL) + { + bool imageAssociationCorrect = mAssociatedImages[face][level]->isAssociatedStorageValid(this); + ASSERT(imageAssociationCorrect); + + if (imageAssociationCorrect) + { + // We must let the Images recover their data before we delete it from the TextureStorage. + mAssociatedImages[face][level]->recoverFromAssociatedStorage(); + } + } + } + } + SafeRelease(mTexture); SafeRelease(mSwizzleTexture); @@ -762,16 +903,96 @@ TextureStorage11_Cube *TextureStorage11_Cube::makeTextureStorage11_Cube(TextureS return static_cast<TextureStorage11_Cube*>(storage); } +void TextureStorage11_Cube::associateImage(Image11* image, int level, int layerTarget) +{ + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(0 <= layerTarget && layerTarget < 6); + + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + if (0 <= layerTarget && layerTarget < 6) + { + mAssociatedImages[layerTarget][level] = image; + } + } +} + +bool TextureStorage11_Cube::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage) +{ + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + if (0 <= layerTarget && layerTarget < 6) + { + // This validation check should never return false. It means the Image/TextureStorage association is broken. + bool retValue = (mAssociatedImages[layerTarget][level] == expectedImage); + ASSERT(retValue); + return retValue; + } + } + + return false; +} + +// disassociateImage allows an Image to end its association with a Storage. +void TextureStorage11_Cube::disassociateImage(int level, int layerTarget, Image11* expectedImage) +{ + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(0 <= layerTarget && layerTarget < 6); + + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + if (0 <= layerTarget && layerTarget < 6) + { + ASSERT(mAssociatedImages[layerTarget][level] == expectedImage); + + if (mAssociatedImages[layerTarget][level] == expectedImage) + { + mAssociatedImages[layerTarget][level] = NULL; + } + } + } +} + +// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association. +void TextureStorage11_Cube::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage) +{ + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(0 <= layerTarget && layerTarget < 6); + + if ((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)) + { + if (0 <= layerTarget && layerTarget < 6) + { + // No need to let the old Image recover its data, if it is also the incoming Image. + if (mAssociatedImages[layerTarget][level] != NULL && mAssociatedImages[layerTarget][level] != incomingImage) + { + // Ensure that the Image is still associated with this TextureStorage. This should be true. + bool imageAssociationCorrect = mAssociatedImages[layerTarget][level]->isAssociatedStorageValid(this); + ASSERT(imageAssociationCorrect); + + if (imageAssociationCorrect) + { + // Force the image to recover from storage before its data is overwritten. + // This will reset mAssociatedImages[level] to NULL too. + mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage(); + } + } + } + } +} + ID3D11Resource *TextureStorage11_Cube::getResource() const { return mTexture; } -RenderTarget *TextureStorage11_Cube::getRenderTargetFace(GLenum faceTarget, int level) +RenderTarget *TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index) { + int faceIndex = index.layerIndex; + int level = index.mipIndex; + if (level >= 0 && level < getLevelCount()) { - int faceIndex = TextureD3D_Cube::targetToIndex(faceTarget); if (!mRenderTarget[faceIndex][level]) { ID3D11Device *device = mRenderer->getDevice(); @@ -865,10 +1086,8 @@ ID3D11ShaderResourceView *TextureStorage11_Cube::createSRV(int baseLevel, int mi srvDesc.Format = format; // Unnormalized integer cube maps are not supported by DX11; we emulate them as an array of six 2D textures - bool unnormalizedInteger = (d3d11::GetComponentType(mTextureFormat) == GL_INT || - d3d11::GetComponentType(mTextureFormat) == GL_UNSIGNED_INT); - - if(unnormalizedInteger) + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format); + if (dxgiFormatInfo.componentType == GL_INT || dxgiFormatInfo.componentType == GL_UNSIGNED_INT) { srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel; @@ -897,14 +1116,25 @@ ID3D11ShaderResourceView *TextureStorage11_Cube::createSRV(int baseLevel, int mi return SRV; } -void TextureStorage11_Cube::generateMipmap(int faceIndex, int level) +void TextureStorage11_Cube::generateMipmaps() { - invalidateSwizzleCacheLevel(level); + // Base level must already be defined - RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTargetFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level - 1)); - RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTargetFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level)); + for (int faceIndex = 0; faceIndex < 6; faceIndex++) + { + for (int level = 1; level < getLevelCount(); level++) + { + invalidateSwizzleCacheLevel(level); + + gl::ImageIndex srcIndex = gl::ImageIndex::MakeCube(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level - 1); + gl::ImageIndex destIndex = gl::ImageIndex::MakeCube(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level); - generateMipmapLayer(source, dest); + RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex)); + RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex)); + + generateMipmapLayer(source, dest); + } + } } ID3D11Resource *TextureStorage11_Cube::getSwizzleTexture() @@ -976,11 +1206,6 @@ ID3D11RenderTargetView *TextureStorage11_Cube::getSwizzleRenderTarget(int mipLev } } -unsigned int TextureStorage11_Cube::getTextureLevelDepth(int mipLevel) const -{ - return 6; -} - TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget)) @@ -990,17 +1215,19 @@ TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalform for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) { + mAssociatedImages[i] = NULL; mLevelRenderTargets[i] = NULL; mSwizzleRenderTargets[i] = NULL; } - mTextureFormat = gl_d3d11::GetTexFormat(internalformat); - mShaderResourceFormat = gl_d3d11::GetSRVFormat(internalformat); - mDepthStencilFormat = gl_d3d11::GetDSVFormat(internalformat); - mRenderTargetFormat = gl_d3d11::GetRTVFormat(internalformat); - mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalformat); - mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalformat); - mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalformat); + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat); + mTextureFormat = formatInfo.texFormat; + mShaderResourceFormat = formatInfo.srvFormat; + mDepthStencilFormat = formatInfo.dsvFormat; + mRenderTargetFormat = formatInfo.rtvFormat; + mSwizzleTextureFormat = formatInfo.swizzleTexFormat; + mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; + mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; // If the width, height or depth are not positive this should be treated as an incomplete texture // we handle that here by skipping the d3d texture creation @@ -1045,10 +1272,27 @@ TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalform mTextureDepth = desc.Depth; } } + + initializeSerials(getLevelCount() * depth, depth); } TextureStorage11_3D::~TextureStorage11_3D() { + for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + if (mAssociatedImages[i] != NULL) + { + bool imageAssociationCorrect = mAssociatedImages[i]->isAssociatedStorageValid(this); + ASSERT(imageAssociationCorrect); + + if (imageAssociationCorrect) + { + // We must let the Images recover their data before we delete it from the TextureStorage. + mAssociatedImages[i]->recoverFromAssociatedStorage(); + } + } + } + SafeRelease(mTexture); SafeRelease(mSwizzleTexture); @@ -1071,6 +1315,69 @@ TextureStorage11_3D *TextureStorage11_3D::makeTextureStorage11_3D(TextureStorage return static_cast<TextureStorage11_3D*>(storage); } +void TextureStorage11_3D::associateImage(Image11* image, int level, int layerTarget) +{ + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + mAssociatedImages[level] = image; + } +} + +bool TextureStorage11_3D::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage) +{ + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + // This validation check should never return false. It means the Image/TextureStorage association is broken. + bool retValue = (mAssociatedImages[level] == expectedImage); + ASSERT(retValue); + return retValue; + } + + return false; +} + +// disassociateImage allows an Image to end its association with a Storage. +void TextureStorage11_3D::disassociateImage(int level, int layerTarget, Image11* expectedImage) +{ + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + ASSERT(mAssociatedImages[level] == expectedImage); + + if (mAssociatedImages[level] == expectedImage) + { + mAssociatedImages[level] = NULL; + } + } +} + +// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association. +void TextureStorage11_3D::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage) +{ + ASSERT((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)); + + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + // No need to let the old Image recover its data, if it is also the incoming Image. + if (mAssociatedImages[level] != NULL && mAssociatedImages[level] != incomingImage) + { + // Ensure that the Image is still associated with this TextureStorage. This should be true. + bool imageAssociationCorrect = mAssociatedImages[level]->isAssociatedStorageValid(this); + ASSERT(imageAssociationCorrect); + + if (imageAssociationCorrect) + { + // Force the image to recover from storage before its data is overwritten. + // This will reset mAssociatedImages[level] to NULL too. + mAssociatedImages[level]->recoverFromAssociatedStorage(); + } + } + } +} + ID3D11Resource *TextureStorage11_3D::getResource() const { return mTexture; @@ -1098,20 +1405,24 @@ ID3D11ShaderResourceView *TextureStorage11_3D::createSRV(int baseLevel, int mipL return SRV; } -RenderTarget *TextureStorage11_3D::getRenderTarget(int mipLevel) +RenderTarget *TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index) { + int mipLevel = index.mipIndex; + if (mipLevel >= 0 && mipLevel < getLevelCount()) { - if (!mLevelRenderTargets[mipLevel]) + ASSERT(mRenderTargetFormat != DXGI_FORMAT_UNKNOWN); + + if (!index.hasLayer()) { - ID3D11ShaderResourceView *srv = getSRVLevel(mipLevel); - if (!srv) + if (!mLevelRenderTargets[mipLevel]) { - return NULL; - } + ID3D11ShaderResourceView *srv = getSRVLevel(mipLevel); + if (!srv) + { + return NULL; + } - if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) - { ID3D11Device *device = mRenderer->getDevice(); D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; @@ -1136,35 +1447,22 @@ RenderTarget *TextureStorage11_3D::getRenderTarget(int mipLevel) // RenderTarget will take ownership of these resources SafeRelease(rtv); } - else - { - UNREACHABLE(); - } - } - return mLevelRenderTargets[mipLevel]; - } - else - { - return NULL; - } -} - -RenderTarget *TextureStorage11_3D::getRenderTargetLayer(int mipLevel, int layer) -{ - if (mipLevel >= 0 && mipLevel < getLevelCount()) - { - LevelLayerKey key(mipLevel, layer); - if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end()) + return mLevelRenderTargets[mipLevel]; + } + else { - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result; + int layer = index.layerIndex; - // TODO, what kind of SRV is expected here? - ID3D11ShaderResourceView *srv = NULL; - - if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) + LevelLayerKey key(mipLevel, layer); + if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end()) { + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result; + + // TODO, what kind of SRV is expected here? + ID3D11ShaderResourceView *srv = NULL; + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; rtvDesc.Format = mRenderTargetFormat; rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; @@ -1188,28 +1486,30 @@ RenderTarget *TextureStorage11_3D::getRenderTargetLayer(int mipLevel, int layer) SafeRelease(rtv); SafeRelease(srv); } - else - { - UNREACHABLE(); - } - } - return mLevelLayerRenderTargets[key]; - } - else - { - return NULL; + return mLevelLayerRenderTargets[key]; + } } + + return NULL; } -void TextureStorage11_3D::generateMipmap(int level) +void TextureStorage11_3D::generateMipmaps() { - invalidateSwizzleCacheLevel(level); + // Base level must already be defined + + for (int level = 1; level < getLevelCount(); level++) + { + invalidateSwizzleCacheLevel(level); + + gl::ImageIndex srcIndex = gl::ImageIndex::Make3D(level - 1); + gl::ImageIndex destIndex = gl::ImageIndex::Make3D(level); - RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(level - 1)); - RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(level)); + RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex)); + RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex)); - generateMipmapLayer(source, dest); + generateMipmapLayer(source, dest); + } } ID3D11Resource *TextureStorage11_3D::getSwizzleTexture() @@ -1279,12 +1579,6 @@ ID3D11RenderTargetView *TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel } } -unsigned int TextureStorage11_3D::getTextureLevelDepth(int mipLevel) const -{ - return std::max(mTextureDepth >> mipLevel, 1U); -} - - TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget)) @@ -1297,13 +1591,14 @@ TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum in mSwizzleRenderTargets[level] = NULL; } - mTextureFormat = gl_d3d11::GetTexFormat(internalformat); - mShaderResourceFormat = gl_d3d11::GetSRVFormat(internalformat); - mDepthStencilFormat = gl_d3d11::GetDSVFormat(internalformat); - mRenderTargetFormat = gl_d3d11::GetRTVFormat(internalformat); - mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalformat); - mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalformat); - mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalformat); + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat); + mTextureFormat = formatInfo.texFormat; + mShaderResourceFormat = formatInfo.srvFormat; + mDepthStencilFormat = formatInfo.dsvFormat; + mRenderTargetFormat = formatInfo.rtvFormat; + mSwizzleTextureFormat = formatInfo.swizzleTexFormat; + mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; + mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; // if the width, height or depth is not positive this should be treated as an incomplete texture // we handle that here by skipping the d3d texture creation @@ -1350,10 +1645,25 @@ TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum in mTextureDepth = desc.ArraySize; } } + + initializeSerials(getLevelCount() * depth, depth); } TextureStorage11_2DArray::~TextureStorage11_2DArray() { + for (ImageMap::iterator i = mAssociatedImages.begin(); i != mAssociatedImages.end(); i++) + { + bool imageAssociationCorrect = i->second->isAssociatedStorageValid(this); + ASSERT(imageAssociationCorrect); + + if (imageAssociationCorrect) + { + // We must let the Images recover their data before we delete it from the TextureStorage. + i->second->recoverFromAssociatedStorage(); + } + } + mAssociatedImages.clear(); + SafeRelease(mTexture); SafeRelease(mSwizzleTexture); @@ -1375,6 +1685,66 @@ TextureStorage11_2DArray *TextureStorage11_2DArray::makeTextureStorage11_2DArray return static_cast<TextureStorage11_2DArray*>(storage); } +void TextureStorage11_2DArray::associateImage(Image11* image, int level, int layerTarget) +{ + ASSERT(0 <= level && level < getLevelCount()); + + if (0 <= level && level < getLevelCount()) + { + LevelLayerKey key(level, layerTarget); + mAssociatedImages[key] = image; + } +} + +bool TextureStorage11_2DArray::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage) +{ + LevelLayerKey key(level, layerTarget); + + // This validation check should never return false. It means the Image/TextureStorage association is broken. + bool retValue = (mAssociatedImages.find(key) != mAssociatedImages.end() && (mAssociatedImages[key] == expectedImage)); + ASSERT(retValue); + return retValue; +} + +// disassociateImage allows an Image to end its association with a Storage. +void TextureStorage11_2DArray::disassociateImage(int level, int layerTarget, Image11* expectedImage) +{ + LevelLayerKey key(level, layerTarget); + + bool imageAssociationCorrect = (mAssociatedImages.find(key) != mAssociatedImages.end() && (mAssociatedImages[key] == expectedImage)); + ASSERT(imageAssociationCorrect); + + if (imageAssociationCorrect) + { + mAssociatedImages[key] = NULL; + } +} + +// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association. +void TextureStorage11_2DArray::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage) +{ + LevelLayerKey key(level, layerTarget); + + ASSERT(mAssociatedImages.find(key) != mAssociatedImages.end()); + + if (mAssociatedImages.find(key) != mAssociatedImages.end()) + { + if (mAssociatedImages[key] != NULL && mAssociatedImages[key] != incomingImage) + { + // Ensure that the Image is still associated with this TextureStorage. This should be true. + bool imageAssociationCorrect = mAssociatedImages[key]->isAssociatedStorageValid(this); + ASSERT(imageAssociationCorrect); + + if (imageAssociationCorrect) + { + // Force the image to recover from storage before its data is overwritten. + // This will reset mAssociatedImages[level] to NULL too. + mAssociatedImages[key]->recoverFromAssociatedStorage(); + } + } + } +} + ID3D11Resource *TextureStorage11_2DArray::getResource() const { return mTexture; @@ -1404,8 +1774,13 @@ ID3D11ShaderResourceView *TextureStorage11_2DArray::createSRV(int baseLevel, int return SRV; } -RenderTarget *TextureStorage11_2DArray::getRenderTargetLayer(int mipLevel, int layer) +RenderTarget *TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index) { + ASSERT(index.hasLayer()); + + int mipLevel = index.mipIndex; + int layer = index.layerIndex; + if (mipLevel >= 0 && mipLevel < getLevelCount()) { LevelLayerKey key(mipLevel, layer); @@ -1470,15 +1845,23 @@ RenderTarget *TextureStorage11_2DArray::getRenderTargetLayer(int mipLevel, int l } } -void TextureStorage11_2DArray::generateMipmap(int level) +void TextureStorage11_2DArray::generateMipmaps() { - invalidateSwizzleCacheLevel(level); - for (unsigned int layer = 0; layer < mTextureDepth; layer++) + // Base level must already be defined + + for (int level = 0; level < getLevelCount(); level++) { - RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTargetLayer(level - 1, layer)); - RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTargetLayer(level, layer)); + invalidateSwizzleCacheLevel(level); + for (unsigned int layer = 0; layer < mTextureDepth; layer++) + { + gl::ImageIndex sourceIndex = gl::ImageIndex::Make2DArray(level - 1, layer); + gl::ImageIndex destIndex = gl::ImageIndex::Make2DArray(level, layer); - generateMipmapLayer(source, dest); + RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(sourceIndex)); + RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex)); + + generateMipmapLayer(source, dest); + } } } @@ -1551,9 +1934,4 @@ ID3D11RenderTargetView *TextureStorage11_2DArray::getSwizzleRenderTarget(int mip } } -unsigned int TextureStorage11_2DArray::getTextureLevelDepth(int mipLevel) const -{ - return mTextureDepth; -} - } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h index 6be7bac8e2..9d63b2699d 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h @@ -11,8 +11,16 @@ #define LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_ #include "libGLESv2/Texture.h" +#include "libGLESv2/Error.h" #include "libGLESv2/renderer/d3d/TextureStorage.h" +#include <map> + +namespace gl +{ +struct ImageIndex; +} + namespace rx { class RenderTarget; @@ -20,6 +28,7 @@ class RenderTarget11; class Renderer; class Renderer11; class SwapChain11; +class Image11; class TextureStorage11 : public TextureStorage { @@ -34,12 +43,9 @@ class TextureStorage11 : public TextureStorage virtual ID3D11Resource *getResource() const = 0; virtual ID3D11ShaderResourceView *getSRV(const gl::SamplerState &samplerState); - virtual RenderTarget *getRenderTarget(int level) { return NULL; } - virtual RenderTarget *getRenderTargetFace(GLenum faceTarget, int level) { return NULL; } - virtual RenderTarget *getRenderTargetLayer(int mipLevel, int layer) { return NULL; } + virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0; - virtual void generateMipmap(int level) {}; - virtual void generateMipmap(int face, int level) {}; + virtual void generateMipmaps() = 0; virtual int getTopLevel() const; virtual bool isRenderTarget() const; @@ -47,7 +53,7 @@ class TextureStorage11 : public TextureStorage virtual int getLevelCount() const; UINT getSubresourceIndex(int mipLevel, int layerTarget) const; - void generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha); + gl::Error generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha); void invalidateSwizzleCacheLevel(int mipLevel); void invalidateSwizzleCache(); @@ -55,6 +61,15 @@ class TextureStorage11 : public TextureStorage int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); + bool copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource, int level, + int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth); + + virtual void associateImage(Image11* image, int level, int layerTarget) = 0; + virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage) = 0; + virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage) = 0; + virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage) = 0; + protected: TextureStorage11(Renderer *renderer, UINT bindFlags); void generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest); @@ -70,8 +85,6 @@ class TextureStorage11 : public TextureStorage void verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha); - virtual unsigned int getTextureLevelDepth(int mipLevel) const = 0; - Renderer11 *mRenderer; int mTopLevel; unsigned int mMipLevels; @@ -148,16 +161,19 @@ class TextureStorage11_2D : public TextureStorage11 static TextureStorage11_2D *makeTextureStorage11_2D(TextureStorage *storage); virtual ID3D11Resource *getResource() const; - virtual RenderTarget *getRenderTarget(int level); + virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); + + virtual void generateMipmaps(); - virtual void generateMipmap(int level); + virtual void associateImage(Image11* image, int level, int layerTarget); + virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage); + virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage); + virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage); protected: virtual ID3D11Resource *getSwizzleTexture(); virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel); - virtual unsigned int getTextureLevelDepth(int mipLevel) const; - private: DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2D); @@ -168,6 +184,8 @@ class TextureStorage11_2D : public TextureStorage11 ID3D11Texture2D *mSwizzleTexture; ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + + Image11 *mAssociatedImages[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; }; class TextureStorage11_Cube : public TextureStorage11 @@ -179,16 +197,19 @@ class TextureStorage11_Cube : public TextureStorage11 static TextureStorage11_Cube *makeTextureStorage11_Cube(TextureStorage *storage); virtual ID3D11Resource *getResource() const; - virtual RenderTarget *getRenderTargetFace(GLenum faceTarget, int level); + virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); - virtual void generateMipmap(int faceIndex, int level); + virtual void generateMipmaps(); + + virtual void associateImage(Image11* image, int level, int layerTarget); + virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage); + virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage); + virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage); protected: virtual ID3D11Resource *getSwizzleTexture(); virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel); - virtual unsigned int getTextureLevelDepth(int mipLevel) const; - private: DISALLOW_COPY_AND_ASSIGN(TextureStorage11_Cube); @@ -199,6 +220,8 @@ class TextureStorage11_Cube : public TextureStorage11 ID3D11Texture2D *mSwizzleTexture; ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + + Image11 *mAssociatedImages[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; }; class TextureStorage11_3D : public TextureStorage11 @@ -211,17 +234,21 @@ class TextureStorage11_3D : public TextureStorage11 static TextureStorage11_3D *makeTextureStorage11_3D(TextureStorage *storage); virtual ID3D11Resource *getResource() const; - virtual RenderTarget *getRenderTarget(int mipLevel); - virtual RenderTarget *getRenderTargetLayer(int mipLevel, int layer); - virtual void generateMipmap(int level); + // Handles both layer and non-layer RTs + virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); + + virtual void generateMipmaps(); + + virtual void associateImage(Image11* image, int level, int layerTarget); + virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage); + virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage); + virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage); protected: virtual ID3D11Resource *getSwizzleTexture(); virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel); - virtual unsigned int getTextureLevelDepth(int mipLevel) const; - private: DISALLOW_COPY_AND_ASSIGN(TextureStorage11_3D); @@ -236,6 +263,8 @@ class TextureStorage11_3D : public TextureStorage11 ID3D11Texture3D *mTexture; ID3D11Texture3D *mSwizzleTexture; ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + + Image11 *mAssociatedImages[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; }; class TextureStorage11_2DArray : public TextureStorage11 @@ -248,16 +277,19 @@ class TextureStorage11_2DArray : public TextureStorage11 static TextureStorage11_2DArray *makeTextureStorage11_2DArray(TextureStorage *storage); virtual ID3D11Resource *getResource() const; - virtual RenderTarget *getRenderTargetLayer(int mipLevel, int layer); + virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); + + virtual void generateMipmaps(); - virtual void generateMipmap(int level); + virtual void associateImage(Image11* image, int level, int layerTarget); + virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage); + virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage); + virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage); protected: virtual ID3D11Resource *getSwizzleTexture(); virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel); - virtual unsigned int getTextureLevelDepth(int mipLevel) const; - private: DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2DArray); @@ -271,6 +303,9 @@ class TextureStorage11_2DArray : public TextureStorage11 ID3D11Texture2D *mSwizzleTexture; ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + + typedef std::map<LevelLayerKey, Image11*> ImageMap; + ImageMap mAssociatedImages; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp index 2f47ec0a67..9bc5b1d2d1 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -9,11 +8,10 @@ #include "libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h" #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h" - -#include "libGLESv2/Buffer.h" #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" -#include "libGLESv2/VertexAttribute.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" +#include "libGLESv2/Buffer.h" +#include "libGLESv2/VertexAttribute.h" namespace rx { @@ -30,7 +28,7 @@ VertexBuffer11::~VertexBuffer11() SafeRelease(mBuffer); } -bool VertexBuffer11::initialize(unsigned int size, bool dynamicUsage) +gl::Error VertexBuffer11::initialize(unsigned int size, bool dynamicUsage) { SafeRelease(mBuffer); @@ -51,13 +49,14 @@ bool VertexBuffer11::initialize(unsigned int size, bool dynamicUsage) HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer); if (FAILED(result)) { - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal vertex buffer of size, %lu.", size); } } mBufferSize = size; mDynamicUsage = dynamicUsage; - return true; + + return gl::Error(GL_NO_ERROR); } VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer) @@ -66,66 +65,62 @@ VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer) return static_cast<VertexBuffer11*>(vetexBuffer); } -bool 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, const gl::VertexAttribCurrentValueData ¤tValue, + GLint start, GLsizei count, GLsizei instances, unsigned int offset) { - if (mBuffer) + if (!mBuffer) { - gl::Buffer *buffer = attrib.buffer.get(); - int inputStride = ComputeVertexAttributeStride(attrib); - ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); + return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized."); + } - D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); - if (FAILED(result)) - { - ERR("Vertex buffer map failed with error 0x%08x", result); - return false; - } + gl::Buffer *buffer = attrib.buffer.get(); + int inputStride = ComputeVertexAttributeStride(attrib); + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); - char* output = reinterpret_cast<char*>(mappedResource.pData) + offset; + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer, HRESULT: 0x%08x.", result); + } - const char *input = NULL; - if (attrib.enabled) + uint8_t *output = reinterpret_cast<uint8_t*>(mappedResource.pData) + offset; + + const uint8_t *input = NULL; + if (attrib.enabled) + { + if (buffer) { - if (buffer) - { - Buffer11 *storage = Buffer11::makeBuffer11(buffer->getImplementation()); - input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.offset); - } - else - { - input = static_cast<const char*>(attrib.pointer); - } + Buffer11 *storage = Buffer11::makeBuffer11(buffer->getImplementation()); + input = static_cast<const uint8_t*>(storage->getData()) + static_cast<int>(attrib.offset); } else { - input = reinterpret_cast<const char*>(currentValue.FloatValues); - } - - if (instances == 0 || attrib.divisor == 0) - { - input += inputStride * start; + input = static_cast<const uint8_t*>(attrib.pointer); } - - gl::VertexFormat vertexFormat(attrib, currentValue.Type); - VertexCopyFunction conversionFunc = gl_d3d11::GetVertexCopyFunction(vertexFormat); - ASSERT(conversionFunc != NULL); - conversionFunc(input, inputStride, count, output); - - dxContext->Unmap(mBuffer, 0); - - return true; } else { - ERR("Vertex buffer not initialized."); - return false; + input = reinterpret_cast<const uint8_t*>(currentValue.FloatValues); + } + + if (instances == 0 || attrib.divisor == 0) + { + input += inputStride * start; } + + gl::VertexFormat vertexFormat(attrib, currentValue.Type); + const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat); + ASSERT(vertexFormatInfo.copyFunction != NULL); + vertexFormatInfo.copyFunction(input, inputStride, count, output); + + dxContext->Unmap(mBuffer, 0); + + return gl::Error(GL_NO_ERROR); } -bool VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, - GLsizei instances, unsigned int *outSpaceRequired) const +gl::Error VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, + GLsizei instances, unsigned int *outSpaceRequired) const { unsigned int elementCount = 0; if (attrib.enabled) @@ -136,30 +131,25 @@ bool VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei } else { - if (static_cast<unsigned int>(instances) < std::numeric_limits<unsigned int>::max() - (attrib.divisor - 1)) - { - // Round up - elementCount = rx::roundUp(static_cast<unsigned int>(instances), attrib.divisor); - } - else - { - elementCount = instances / attrib.divisor; - } + // Round up to divisor, if possible + elementCount = rx::UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor); } gl::VertexFormat vertexFormat(attrib); - unsigned int elementSize = static_cast<unsigned int>(gl_d3d11::GetVertexElementSize(vertexFormat)); + const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(vertexFormatInfo.nativeFormat); + unsigned int elementSize = dxgiFormatInfo.pixelBytes; if (elementSize <= std::numeric_limits<unsigned int>::max() / elementCount) { if (outSpaceRequired) { *outSpaceRequired = elementSize * elementCount; } - return true; + return gl::Error(GL_NO_ERROR); } else { - return false; + return gl::Error(GL_OUT_OF_MEMORY, "New vertex buffer size would result in an overflow."); } } else @@ -169,7 +159,7 @@ bool VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei { *outSpaceRequired = elementSize * 4; } - return true; + return gl::Error(GL_NO_ERROR); } } @@ -178,7 +168,7 @@ unsigned int VertexBuffer11::getBufferSize() const return mBufferSize; } -bool VertexBuffer11::setBufferSize(unsigned int size) +gl::Error VertexBuffer11::setBufferSize(unsigned int size) { if (size > mBufferSize) { @@ -186,33 +176,29 @@ bool VertexBuffer11::setBufferSize(unsigned int size) } else { - return true; + return gl::Error(GL_NO_ERROR); } } -bool VertexBuffer11::discard() +gl::Error VertexBuffer11::discard() { - if (mBuffer) + if (!mBuffer) { - ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); - - D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); - if (FAILED(result)) - { - ERR("Vertex buffer map failed with error 0x%08x", result); - return false; - } + return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized."); + } - dxContext->Unmap(mBuffer, 0); + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); - return true; - } - else + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) { - ERR("Vertex buffer not initialized."); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer for discarding, HRESULT: 0x%08x", result); } + + dxContext->Unmap(mBuffer, 0); + + return gl::Error(GL_NO_ERROR); } ID3D11Buffer *VertexBuffer11::getBuffer() const diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h index c2a5aa7afd..0e10da1df8 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h @@ -21,19 +21,19 @@ class VertexBuffer11 : public VertexBuffer explicit VertexBuffer11(rx::Renderer11 *const renderer); virtual ~VertexBuffer11(); - virtual bool initialize(unsigned int size, bool dynamicUsage); + virtual gl::Error initialize(unsigned int size, bool dynamicUsage); static VertexBuffer11 *makeVertexBuffer11(VertexBuffer *vetexBuffer); - virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, - GLint start, GLsizei count, GLsizei instances, unsigned int offset); + virtual gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, + GLint start, GLsizei count, GLsizei instances, unsigned int offset); - virtual bool getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, - unsigned int *outSpaceRequired) const; + virtual gl::Error getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, + unsigned int *outSpaceRequired) const; virtual unsigned int getBufferSize() const; - virtual bool setBufferSize(unsigned int size); - virtual bool discard(); + virtual gl::Error setBufferSize(unsigned int size); + virtual gl::Error discard(); ID3D11Buffer *getBuffer() const; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp index c991fd4991..c07828757d 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -18,384 +17,236 @@ namespace rx { -struct D3D11FormatInfo +namespace d3d11 { - DXGI_FORMAT mTexFormat; - DXGI_FORMAT mSRVFormat; - DXGI_FORMAT mRTVFormat; - DXGI_FORMAT mDSVFormat; - - D3D11FormatInfo() - : mTexFormat(DXGI_FORMAT_UNKNOWN), mDSVFormat(DXGI_FORMAT_UNKNOWN), mRTVFormat(DXGI_FORMAT_UNKNOWN), mSRVFormat(DXGI_FORMAT_UNKNOWN) - { } - D3D11FormatInfo(DXGI_FORMAT texFormat, DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat, DXGI_FORMAT dsvFormat) - : mTexFormat(texFormat), mDSVFormat(dsvFormat), mRTVFormat(rtvFormat), mSRVFormat(srvFormat) - { } -}; +typedef std::map<DXGI_FORMAT, GLenum> DXGIToESFormatMap; -// 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::pair<GLenum, D3D11FormatInfo> D3D11ES3FormatPair; -typedef std::map<GLenum, D3D11FormatInfo> D3D11ES3FormatMap; +inline void AddDXGIToESEntry(DXGIToESFormatMap *map, DXGI_FORMAT key, GLenum value) +{ + map->insert(std::make_pair(key, value)); +} -static D3D11ES3FormatMap BuildD3D11FormatMap() +static DXGIToESFormatMap BuildDXGIToESFormatMap() { - D3D11ES3FormatMap map; + DXGIToESFormatMap map; - // | GL internal format | | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format | - map.insert(D3D11ES3FormatPair(GL_NONE, D3D11FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_R8, D3D11FormatInfo(DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_R8_SNORM, D3D11FormatInfo(DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RG8, D3D11FormatInfo(DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RG8_SNORM, D3D11FormatInfo(DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB8, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB8_SNORM, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB565, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA4, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB5_A1, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA8, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA8_SNORM, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB10_A2, D3D11FormatInfo(DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB10_A2UI, D3D11FormatInfo(DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_SRGB8, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_SRGB8_ALPHA8, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_R16F, D3D11FormatInfo(DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RG16F, D3D11FormatInfo(DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB16F, D3D11FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA16F, D3D11FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_R32F, D3D11FormatInfo(DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RG32F, D3D11FormatInfo(DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB32F, D3D11FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA32F, D3D11FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_R11F_G11F_B10F, D3D11FormatInfo(DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB9_E5, D3D11FormatInfo(DXGI_FORMAT_R9G9B9E5_SHAREDEXP, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_R8I, D3D11FormatInfo(DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_R8UI, D3D11FormatInfo(DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_R16I, D3D11FormatInfo(DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_R16UI, D3D11FormatInfo(DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_R32I, D3D11FormatInfo(DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_R32UI, D3D11FormatInfo(DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RG8I, D3D11FormatInfo(DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RG8UI, D3D11FormatInfo(DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RG16I, D3D11FormatInfo(DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RG16UI, D3D11FormatInfo(DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RG32I, D3D11FormatInfo(DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RG32UI, D3D11FormatInfo(DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB8I, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB8UI, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB16I, D3D11FormatInfo(DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB16UI, D3D11FormatInfo(DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB32I, D3D11FormatInfo(DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB32UI, D3D11FormatInfo(DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA8I, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA8UI, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA16I, D3D11FormatInfo(DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA16UI, D3D11FormatInfo(DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA32I, D3D11FormatInfo(DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA32UI, D3D11FormatInfo(DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_UNKNOWN))); + AddDXGIToESEntry(&map, DXGI_FORMAT_UNKNOWN, GL_NONE); - // Unsized formats, TODO: Are types of float and half float allowed for the unsized types? Would it change the DXGI format? - map.insert(D3D11ES3FormatPair(GL_ALPHA, D3D11FormatInfo(DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_LUMINANCE, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_LUMINANCE_ALPHA, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_BGRA_EXT, D3D11FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN))); + AddDXGIToESEntry(&map, DXGI_FORMAT_A8_UNORM, GL_ALPHA8_EXT); + AddDXGIToESEntry(&map, DXGI_FORMAT_R8_UNORM, GL_R8); + AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_UNORM, GL_RG8); + AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_UNORM, GL_RGBA8); + AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, GL_SRGB8_ALPHA8); + AddDXGIToESEntry(&map, DXGI_FORMAT_B8G8R8A8_UNORM, GL_BGRA8_EXT); - // From GL_EXT_texture_storage - // | GL internal format | | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format | - map.insert(D3D11ES3FormatPair(GL_ALPHA8_EXT, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN ))); - map.insert(D3D11ES3FormatPair(GL_LUMINANCE8_EXT, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN ))); - map.insert(D3D11ES3FormatPair(GL_ALPHA32F_EXT, D3D11FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN ))); - map.insert(D3D11ES3FormatPair(GL_LUMINANCE32F_EXT, D3D11FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN ))); - map.insert(D3D11ES3FormatPair(GL_ALPHA16F_EXT, D3D11FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN ))); - map.insert(D3D11ES3FormatPair(GL_LUMINANCE16F_EXT, D3D11FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN ))); - map.insert(D3D11ES3FormatPair(GL_LUMINANCE8_ALPHA8_EXT, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN ))); - map.insert(D3D11ES3FormatPair(GL_LUMINANCE_ALPHA32F_EXT, D3D11FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN ))); - map.insert(D3D11ES3FormatPair(GL_LUMINANCE_ALPHA16F_EXT, D3D11FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN ))); - map.insert(D3D11ES3FormatPair(GL_BGRA8_EXT, D3D11FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN ))); - map.insert(D3D11ES3FormatPair(GL_BGRA4_ANGLEX, D3D11FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN ))); - map.insert(D3D11ES3FormatPair(GL_BGR5_A1_ANGLEX, D3D11FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN ))); + AddDXGIToESEntry(&map, DXGI_FORMAT_R8_SNORM, GL_R8_SNORM); + AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_SNORM, GL_RG8_SNORM); + AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_SNORM, GL_RGBA8_SNORM); - // Depth stencil formats - map.insert(D3D11ES3FormatPair(GL_DEPTH_COMPONENT16, D3D11FormatInfo(DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D16_UNORM ))); - map.insert(D3D11ES3FormatPair(GL_DEPTH_COMPONENT24, D3D11FormatInfo(DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT ))); - map.insert(D3D11ES3FormatPair(GL_DEPTH_COMPONENT32F, D3D11FormatInfo(DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D32_FLOAT ))); - map.insert(D3D11ES3FormatPair(GL_DEPTH24_STENCIL8, D3D11FormatInfo(DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT ))); - map.insert(D3D11ES3FormatPair(GL_DEPTH32F_STENCIL8, D3D11FormatInfo(DXGI_FORMAT_R32G8X24_TYPELESS, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D32_FLOAT_S8X24_UINT))); - map.insert(D3D11ES3FormatPair(GL_STENCIL_INDEX8, D3D11FormatInfo(DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_X24_TYPELESS_G8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT ))); + AddDXGIToESEntry(&map, DXGI_FORMAT_R8_UINT, GL_R8UI); + AddDXGIToESEntry(&map, DXGI_FORMAT_R16_UINT, GL_R16UI); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32_UINT, GL_R32UI); + AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_UINT, GL_RG8UI); + AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16_UINT, GL_RG16UI); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32_UINT, GL_RG32UI); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32_UINT, GL_RGB32UI); + AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_UINT, GL_RGBA8UI); + AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16B16A16_UINT, GL_RGBA16UI); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32A32_UINT, GL_RGBA32UI); - // 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. - map.insert(D3D11ES3FormatPair(GL_DEPTH_COMPONENT32_OES, D3D11FormatInfo(DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT ))); + AddDXGIToESEntry(&map, DXGI_FORMAT_R8_SINT, GL_R8I); + AddDXGIToESEntry(&map, DXGI_FORMAT_R16_SINT, GL_R16I); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32_SINT, GL_R32I); + AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_SINT, GL_RG8I); + AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16_SINT, GL_RG16I); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32_SINT, GL_RG32I); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32_SINT, GL_RGB32I); + AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_SINT, GL_RGBA8I); + AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16B16A16_SINT, GL_RGBA16I); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32A32_SINT, GL_RGBA32I); - // 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 | - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_R11_EAC, D3D11FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SIGNED_R11_EAC, D3D11FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RG11_EAC, D3D11FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SIGNED_RG11_EAC, D3D11FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGB8_ETC2, D3D11FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SRGB8_ETC2, D3D11FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, D3D11FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, D3D11FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGBA8_ETC2_EAC, D3D11FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, D3D11FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + AddDXGIToESEntry(&map, DXGI_FORMAT_R10G10B10A2_UNORM, GL_RGB10_A2); + AddDXGIToESEntry(&map, DXGI_FORMAT_R10G10B10A2_UINT, GL_RGB10_A2UI); - // From GL_EXT_texture_compression_dxt1 - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, D3D11FormatInfo(DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, D3D11FormatInfo(DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + AddDXGIToESEntry(&map, DXGI_FORMAT_R16_FLOAT, GL_R16F); + AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16_FLOAT, GL_RG16F); + AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16B16A16_FLOAT, GL_RGBA16F); - // From GL_ANGLE_texture_compression_dxt3 - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, D3D11FormatInfo(DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32_FLOAT, GL_R32F); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32_FLOAT, GL_RG32F); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32_FLOAT, GL_RGB32F); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32A32_FLOAT, GL_RGBA32F); - // From GL_ANGLE_texture_compression_dxt5 - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, D3D11FormatInfo(DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + AddDXGIToESEntry(&map, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, GL_RGB9_E5); + AddDXGIToESEntry(&map, DXGI_FORMAT_R11G11B10_FLOAT, GL_R11F_G11F_B10F); + + AddDXGIToESEntry(&map, DXGI_FORMAT_R16_TYPELESS, GL_DEPTH_COMPONENT16); + AddDXGIToESEntry(&map, DXGI_FORMAT_R16_UNORM, GL_DEPTH_COMPONENT16); + AddDXGIToESEntry(&map, DXGI_FORMAT_D16_UNORM, GL_DEPTH_COMPONENT16); + AddDXGIToESEntry(&map, DXGI_FORMAT_R24G8_TYPELESS, GL_DEPTH24_STENCIL8_OES); + AddDXGIToESEntry(&map, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, GL_DEPTH24_STENCIL8_OES); + AddDXGIToESEntry(&map, DXGI_FORMAT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_OES); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32G8X24_TYPELESS, GL_DEPTH32F_STENCIL8); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, GL_DEPTH32F_STENCIL8); + AddDXGIToESEntry(&map, DXGI_FORMAT_D32_FLOAT_S8X24_UINT, GL_DEPTH32F_STENCIL8); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32_TYPELESS, GL_DEPTH_COMPONENT32F); + AddDXGIToESEntry(&map, DXGI_FORMAT_D32_FLOAT, GL_DEPTH_COMPONENT32F); + + AddDXGIToESEntry(&map, DXGI_FORMAT_BC1_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT); + AddDXGIToESEntry(&map, DXGI_FORMAT_BC2_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE); + AddDXGIToESEntry(&map, DXGI_FORMAT_BC3_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE); return map; } -static bool GetD3D11FormatInfo(GLenum internalFormat, D3D11FormatInfo *outFormatInfo) +struct D3D11FastCopyFormat { - static const D3D11ES3FormatMap formatMap = BuildD3D11FormatMap(); - D3D11ES3FormatMap::const_iterator iter = formatMap.find(internalFormat); - if (iter != formatMap.end()) - { - if (outFormatInfo) - { - *outFormatInfo = iter->second; - } - return true; - } - else + GLenum destFormat; + GLenum destType; + ColorCopyFunction copyFunction; + + D3D11FastCopyFormat(GLenum destFormat, GLenum destType, ColorCopyFunction copyFunction) + : destFormat(destFormat), destType(destType), copyFunction(copyFunction) + { } + + bool operator<(const D3D11FastCopyFormat& other) const { - return false; + return memcmp(this, &other, sizeof(D3D11FastCopyFormat)) < 0; } -} +}; -// 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, GLenum> InternalFormatTypePair; -typedef std::pair<InternalFormatTypePair, LoadImageFunction> D3D11LoadFunctionPair; -typedef std::map<InternalFormatTypePair, LoadImageFunction> D3D11LoadFunctionMap; +typedef std::multimap<DXGI_FORMAT, D3D11FastCopyFormat> D3D11FastCopyMap; -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) +static D3D11FastCopyMap BuildFastCopyMap() { - UNIMPLEMENTED(); -} + D3D11FastCopyMap map; -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(); -} + map.insert(std::make_pair(DXGI_FORMAT_B8G8R8A8_UNORM, D3D11FastCopyFormat(GL_RGBA, GL_UNSIGNED_BYTE, CopyBGRA8ToRGBA8))); -// 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->insert(D3D11LoadFunctionPair(InternalFormatTypePair(internalFormat, type), loadFunc)); + return map; } -D3D11LoadFunctionMap buildD3D11LoadFunctionMap() +struct DXGIDepthStencilInfo { - 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> ); + unsigned int depthBits; + unsigned int depthOffset; + unsigned int stencilBits; + unsigned int stencilOffset; +}; - // 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 ); +typedef std::map<DXGI_FORMAT, DXGIDepthStencilInfo> DepthStencilInfoMap; +typedef std::pair<DXGI_FORMAT, DXGIDepthStencilInfo> DepthStencilInfoPair; - // 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 ); +static inline void InsertDXGIDepthStencilInfo(DepthStencilInfoMap *map, DXGI_FORMAT format, unsigned int depthBits, + unsigned int depthOffset, unsigned int stencilBits, unsigned int stencilOffset) +{ + DXGIDepthStencilInfo info; + info.depthBits = depthBits; + info.depthOffset = depthOffset; + info.stencilBits = stencilBits; + info.stencilOffset = stencilOffset; - // 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 ); + map->insert(std::make_pair(format, info)); +} - // From GL_EXT_texture_storage - insertLoadFunction(&map, GL_ALPHA8_EXT, GL_UNSIGNED_BYTE, LoadA8ToBGRA8 ); - 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 ); +static DepthStencilInfoMap BuildDepthStencilInfoMap() +{ + DepthStencilInfoMap map; - // From GL_ANGLE_depth_texture - insertLoadFunction(&map, GL_DEPTH_COMPONENT32_OES, GL_UNSIGNED_INT, LoadR32ToR24G8 ); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R16_TYPELESS, 16, 0, 0, 0); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R16_UNORM, 16, 0, 0, 0); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D16_UNORM, 16, 0, 0, 0); - // 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> ); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R24G8_TYPELESS, 24, 0, 8, 24); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, 24, 0, 8, 24); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D24_UNORM_S8_UINT, 24, 0, 8, 24); - // 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 ); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R32_TYPELESS, 32, 0, 0, 0); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R32_FLOAT, 32, 0, 0, 0); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D32_FLOAT, 32, 0, 0, 0); - // 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>); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R32G8X24_TYPELESS, 32, 0, 8, 32); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, 32, 0, 8, 32); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D32_FLOAT_S8X24_UINT, 32, 0, 8, 32); - // From GL_ANGLE_texture_compression_dxt3 - insertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4, 16>); + return map; +} - // From GL_ANGLE_texture_compression_dxt5 - insertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4, 16>); +typedef std::map<DXGI_FORMAT, DXGIFormat> DXGIFormatInfoMap; + +DXGIFormat::DXGIFormat() + : pixelBytes(0), + blockWidth(0), + blockHeight(0), + depthBits(0), + depthOffset(0), + stencilBits(0), + stencilOffset(0), + internalFormat(GL_NONE), + componentType(GL_NONE), + mipGenerationFunction(NULL), + colorReadFunction(NULL), + fastCopyFunctions() +{ +} - return map; +ColorCopyFunction DXGIFormat::getFastCopyFunction(GLenum format, GLenum type) const +{ + FastCopyFunctionMap::const_iterator iter = fastCopyFunctions.find(std::make_pair(format, type)); + return (iter != fastCopyFunctions.end()) ? iter->second : NULL; } -// A map to determine the pixel size and mipmap generation function of a given DXGI format -struct DXGIFormatInfo +void AddDXGIFormat(DXGIFormatInfoMap *map, DXGI_FORMAT dxgiFormat, GLuint pixelBits, GLuint blockWidth, GLuint blockHeight, + GLenum componentType, MipGenerationFunction mipFunc, ColorReadFunction readFunc) { - GLuint mPixelBits; - GLuint mBlockWidth; - GLuint mBlockHeight; - GLenum mComponentType; + DXGIFormat info; + info.pixelBytes = pixelBits / 8; + info.blockWidth = blockWidth; + info.blockHeight = blockHeight; - MipGenerationFunction mMipGenerationFunction; - ColorReadFunction mColorReadFunction; + static const DepthStencilInfoMap dsInfoMap = BuildDepthStencilInfoMap(); + DepthStencilInfoMap::const_iterator dsInfoIter = dsInfoMap.find(dxgiFormat); + if (dsInfoIter != dsInfoMap.end()) + { + info.depthBits = dsInfoIter->second.depthBits; + info.depthOffset = dsInfoIter->second.depthOffset; + info.stencilBits = dsInfoIter->second.stencilBits; + info.stencilOffset = dsInfoIter->second.stencilOffset; + } + else + { + info.depthBits = 0; + info.depthOffset = 0; + info.stencilBits = 0; + info.stencilOffset = 0; + } - DXGIFormatInfo() - : mPixelBits(0), mBlockWidth(0), mBlockHeight(0), mComponentType(GL_NONE), mMipGenerationFunction(NULL), - mColorReadFunction(NULL) - { } + static const DXGIToESFormatMap dxgiToESMap = BuildDXGIToESFormatMap(); + DXGIToESFormatMap::const_iterator dxgiToESIter = dxgiToESMap.find(dxgiFormat); + info.internalFormat = (dxgiToESIter != dxgiToESMap.end()) ? dxgiToESIter->second : GL_NONE; - DXGIFormatInfo(GLuint pixelBits, GLuint blockWidth, GLuint blockHeight, GLenum componentType, - MipGenerationFunction mipFunc, ColorReadFunction readFunc) - : mPixelBits(pixelBits), mBlockWidth(blockWidth), mBlockHeight(blockHeight), mComponentType(componentType), - mMipGenerationFunction(mipFunc), mColorReadFunction(readFunc) - { } -}; + info.componentType = componentType; -typedef std::map<DXGI_FORMAT, DXGIFormatInfo> DXGIFormatInfoMap; + info.mipGenerationFunction = mipFunc; + info.colorReadFunction = readFunc; -void AddDXGIFormat(DXGIFormatInfoMap *map, DXGI_FORMAT dxgiFormat, GLuint pixelBits, GLuint blockWidth, GLuint blockHeight, - GLenum componentType, MipGenerationFunction mipFunc, ColorReadFunction readFunc) -{ - map->insert(std::make_pair(dxgiFormat, DXGIFormatInfo(pixelBits, blockWidth, blockHeight, componentType, mipFunc, readFunc))); + static const D3D11FastCopyMap fastCopyMap = BuildFastCopyMap(); + std::pair<D3D11FastCopyMap::const_iterator, D3D11FastCopyMap::const_iterator> fastCopyIter = fastCopyMap.equal_range(dxgiFormat); + for (D3D11FastCopyMap::const_iterator i = fastCopyIter.first; i != fastCopyIter.second; i++) + { + info.fastCopyFunctions.insert(std::make_pair(std::make_pair(i->second.destFormat, i->second.destType), i->second.copyFunction)); + } + + map->insert(std::make_pair(dxgiFormat, info)); } +// A map to determine the pixel size and mipmap generation function of a given DXGI format static DXGIFormatInfoMap BuildDXGIFormatInfoMap() { DXGIFormatInfoMap map; - // | DXGI format |S |W |H |Component Type | Mip generation function | Color read function + // | 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>); @@ -473,240 +324,38 @@ static DXGIFormatInfoMap BuildDXGIFormatInfoMap() return map; } -typedef std::map<DXGI_FORMAT, GLenum> DXGIToESFormatMap; - -inline void AddDXGIToESEntry(DXGIToESFormatMap *map, DXGI_FORMAT key, GLenum value) -{ - map->insert(std::make_pair(key, value)); -} - -static DXGIToESFormatMap BuildDXGIToESFormatMap() -{ - DXGIToESFormatMap map; - - AddDXGIToESEntry(&map, DXGI_FORMAT_UNKNOWN, GL_NONE); - - AddDXGIToESEntry(&map, DXGI_FORMAT_A8_UNORM, GL_ALPHA8_EXT); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8_UNORM, GL_R8); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_UNORM, GL_RG8); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_UNORM, GL_RGBA8); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, GL_SRGB8_ALPHA8); - AddDXGIToESEntry(&map, DXGI_FORMAT_B8G8R8A8_UNORM, GL_BGRA8_EXT); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R8_SNORM, GL_R8_SNORM); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_SNORM, GL_RG8_SNORM); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_SNORM, GL_RGBA8_SNORM); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R8_UINT, GL_R8UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16_UINT, GL_R16UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32_UINT, GL_R32UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_UINT, GL_RG8UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16_UINT, GL_RG16UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32_UINT, GL_RG32UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32_UINT, GL_RGB32UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_UINT, GL_RGBA8UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16B16A16_UINT, GL_RGBA16UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32A32_UINT, GL_RGBA32UI); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R8_SINT, GL_R8I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16_SINT, GL_R16I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32_SINT, GL_R32I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_SINT, GL_RG8I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16_SINT, GL_RG16I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32_SINT, GL_RG32I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32_SINT, GL_RGB32I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_SINT, GL_RGBA8I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16B16A16_SINT, GL_RGBA16I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32A32_SINT, GL_RGBA32I); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R10G10B10A2_UNORM, GL_RGB10_A2); - AddDXGIToESEntry(&map, DXGI_FORMAT_R10G10B10A2_UINT, GL_RGB10_A2UI); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R16_FLOAT, GL_R16F); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16_FLOAT, GL_RG16F); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16B16A16_FLOAT, GL_RGBA16F); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R32_FLOAT, GL_R32F); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32_FLOAT, GL_RG32F); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32_FLOAT, GL_RGB32F); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32A32_FLOAT, GL_RGBA32F); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, GL_RGB9_E5); - AddDXGIToESEntry(&map, DXGI_FORMAT_R11G11B10_FLOAT, GL_R11F_G11F_B10F); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R16_TYPELESS, GL_DEPTH_COMPONENT16); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16_UNORM, GL_DEPTH_COMPONENT16); - AddDXGIToESEntry(&map, DXGI_FORMAT_D16_UNORM, GL_DEPTH_COMPONENT16); - AddDXGIToESEntry(&map, DXGI_FORMAT_R24G8_TYPELESS, GL_DEPTH24_STENCIL8_OES); - AddDXGIToESEntry(&map, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, GL_DEPTH24_STENCIL8_OES); - AddDXGIToESEntry(&map, DXGI_FORMAT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_OES); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G8X24_TYPELESS, GL_DEPTH32F_STENCIL8); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, GL_DEPTH32F_STENCIL8); - AddDXGIToESEntry(&map, DXGI_FORMAT_D32_FLOAT_S8X24_UINT, GL_DEPTH32F_STENCIL8); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32_TYPELESS, GL_DEPTH_COMPONENT32F); - AddDXGIToESEntry(&map, DXGI_FORMAT_D32_FLOAT, GL_DEPTH_COMPONENT32F); - - AddDXGIToESEntry(&map, DXGI_FORMAT_BC1_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT); - AddDXGIToESEntry(&map, DXGI_FORMAT_BC2_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE); - AddDXGIToESEntry(&map, DXGI_FORMAT_BC3_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE); - - return map; -} - -static const DXGIToESFormatMap &GetDXGIToESFormatMap() -{ - static const DXGIToESFormatMap map = BuildDXGIToESFormatMap(); - return map; -} - -static const DXGIFormatInfoMap &GetDXGIFormatInfoMap() +const DXGIFormat &GetDXGIFormatInfo(DXGI_FORMAT format) { static const DXGIFormatInfoMap infoMap = BuildDXGIFormatInfoMap(); - return infoMap; -} - -static bool GetDXGIFormatInfo(DXGI_FORMAT format, DXGIFormatInfo *outFormatInfo) -{ - const DXGIFormatInfoMap &infoMap = GetDXGIFormatInfoMap(); DXGIFormatInfoMap::const_iterator iter = infoMap.find(format); if (iter != infoMap.end()) { - if (outFormatInfo) - { - *outFormatInfo = iter->second; - } - return true; - } - else - { - return false; - } -} - -static d3d11::DXGIFormatSet BuildAllDXGIFormatSet() -{ - d3d11::DXGIFormatSet set; - - const DXGIFormatInfoMap &infoMap = GetDXGIFormatInfoMap(); - for (DXGIFormatInfoMap::const_iterator i = infoMap.begin(); i != infoMap.end(); ++i) - { - set.insert(i->first); - } - - return set; -} - -struct D3D11FastCopyFormat -{ - DXGI_FORMAT mSourceFormat; - GLenum mDestFormat; - GLenum mDestType; - - D3D11FastCopyFormat(DXGI_FORMAT sourceFormat, GLenum destFormat, GLenum destType) - : mSourceFormat(sourceFormat), mDestFormat(destFormat), mDestType(destType) - { } - - bool operator<(const D3D11FastCopyFormat& other) const - { - return memcmp(this, &other, sizeof(D3D11FastCopyFormat)) < 0; - } -}; - -typedef std::map<D3D11FastCopyFormat, ColorCopyFunction> D3D11FastCopyMap; -typedef std::pair<D3D11FastCopyFormat, ColorCopyFunction> D3D11FastCopyPair; - -static D3D11FastCopyMap BuildFastCopyMap() -{ - D3D11FastCopyMap map; - - map.insert(D3D11FastCopyPair(D3D11FastCopyFormat(DXGI_FORMAT_B8G8R8A8_UNORM, GL_RGBA, GL_UNSIGNED_BYTE), CopyBGRAUByteToRGBAUByte)); - - return map; -} - -struct DXGIDepthStencilInfo -{ - unsigned int mDepthBits; - unsigned int mDepthOffset; - unsigned int mStencilBits; - unsigned int mStencilOffset; - - DXGIDepthStencilInfo() - : mDepthBits(0), mDepthOffset(0), mStencilBits(0), mStencilOffset(0) - { } - - DXGIDepthStencilInfo(unsigned int depthBits, unsigned int depthOffset, unsigned int stencilBits, unsigned int stencilOffset) - : mDepthBits(depthBits), mDepthOffset(depthOffset), mStencilBits(stencilBits), mStencilOffset(stencilOffset) - { } -}; - -typedef std::map<DXGI_FORMAT, DXGIDepthStencilInfo> DepthStencilInfoMap; -typedef std::pair<DXGI_FORMAT, DXGIDepthStencilInfo> DepthStencilInfoPair; - -static DepthStencilInfoMap BuildDepthStencilInfoMap() -{ - DepthStencilInfoMap map; - - map.insert(DepthStencilInfoPair(DXGI_FORMAT_R16_TYPELESS, DXGIDepthStencilInfo(16, 0, 0, 0))); - map.insert(DepthStencilInfoPair(DXGI_FORMAT_R16_UNORM, DXGIDepthStencilInfo(16, 0, 0, 0))); - map.insert(DepthStencilInfoPair(DXGI_FORMAT_D16_UNORM, DXGIDepthStencilInfo(16, 0, 0, 0))); - - map.insert(DepthStencilInfoPair(DXGI_FORMAT_R24G8_TYPELESS, DXGIDepthStencilInfo(24, 0, 8, 24))); - map.insert(DepthStencilInfoPair(DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGIDepthStencilInfo(24, 0, 8, 24))); - map.insert(DepthStencilInfoPair(DXGI_FORMAT_D24_UNORM_S8_UINT, DXGIDepthStencilInfo(24, 0, 8, 24))); - - map.insert(DepthStencilInfoPair(DXGI_FORMAT_R32_TYPELESS, DXGIDepthStencilInfo(32, 0, 0, 0))); - map.insert(DepthStencilInfoPair(DXGI_FORMAT_R32_FLOAT, DXGIDepthStencilInfo(32, 0, 0, 0))); - map.insert(DepthStencilInfoPair(DXGI_FORMAT_D32_FLOAT, DXGIDepthStencilInfo(32, 0, 0, 0))); - - map.insert(DepthStencilInfoPair(DXGI_FORMAT_R32G8X24_TYPELESS, DXGIDepthStencilInfo(32, 0, 8, 32))); - map.insert(DepthStencilInfoPair(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, DXGIDepthStencilInfo(32, 0, 8, 32))); - map.insert(DepthStencilInfoPair(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, DXGIDepthStencilInfo(32, 0, 8, 32))); - - return map; -} - -static const DepthStencilInfoMap &GetDepthStencilInfoMap() -{ - static const DepthStencilInfoMap infoMap = BuildDepthStencilInfoMap(); - return infoMap; -} - -bool GetDepthStencilInfo(DXGI_FORMAT format, DXGIDepthStencilInfo *outDepthStencilInfo) -{ - const DepthStencilInfoMap& infoMap = GetDepthStencilInfoMap(); - DepthStencilInfoMap::const_iterator iter = infoMap.find(format); - if (iter != infoMap.end()) - { - if (outDepthStencilInfo) - { - *outDepthStencilInfo = iter->second; - } - return true; + return iter->second; } else { - return false; + static DXGIFormat defaultInfo; + return defaultInfo; } } struct SwizzleSizeType { - unsigned int mMaxComponentSize; - GLenum mComponentType; + size_t maxComponentSize; + GLenum componentType; SwizzleSizeType() - : mMaxComponentSize(0), mComponentType(GL_NONE) + : maxComponentSize(0), componentType(GL_NONE) { } - SwizzleSizeType(unsigned int maxComponentSize, GLenum componentType) - : mMaxComponentSize(maxComponentSize), mComponentType(componentType) + SwizzleSizeType(size_t maxComponentSize, GLenum componentType) + : maxComponentSize(maxComponentSize), componentType(componentType) { } bool operator<(const SwizzleSizeType& other) const { - return (mMaxComponentSize != other.mMaxComponentSize) ? (mMaxComponentSize < other.mMaxComponentSize) - : (mComponentType < other.mComponentType); + return (maxComponentSize != other.maxComponentSize) ? (maxComponentSize < other.maxComponentSize) + : (componentType < other.componentType); } }; @@ -752,6 +401,7 @@ static SwizzleInfoMap BuildSwizzleInfoMap() return map; } + typedef std::pair<GLint, InitializeTextureDataFunction> InternalFormatInitializerPair; typedef std::map<GLint, InitializeTextureDataFunction> InternalFormatInitializerMap; @@ -774,430 +424,477 @@ static InternalFormatInitializerMap BuildInternalFormatInitializerMap() return map; } -static const SwizzleInfoMap &GetSwizzleInfoMap() +// 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) { - static const SwizzleInfoMap map = BuildSwizzleInfoMap(); - return map; + UNIMPLEMENTED(); } -static const SwizzleFormatInfo GetSwizzleFormatInfo(GLenum internalFormat) +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) { - // Get the maximum sized component - unsigned int maxBits = 1; + UNREACHABLE(); +} - if (gl::IsFormatCompressed(internalFormat)) - { - unsigned int compressedBitsPerBlock = gl::GetPixelBytes(internalFormat) * 8; - unsigned int blockSize = gl::GetCompressedBlockWidth(internalFormat) * - gl::GetCompressedBlockHeight(internalFormat); - maxBits = std::max(compressedBitsPerBlock / blockSize, maxBits); - } - else - { - maxBits = std::max(maxBits, gl::GetAlphaBits( internalFormat)); - maxBits = std::max(maxBits, gl::GetRedBits( internalFormat)); - maxBits = std::max(maxBits, gl::GetGreenBits( internalFormat)); - maxBits = std::max(maxBits, gl::GetBlueBits( internalFormat)); - maxBits = std::max(maxBits, gl::GetLuminanceBits(internalFormat)); - maxBits = std::max(maxBits, gl::GetDepthBits( internalFormat)); - } +// 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)); +} - maxBits = roundUp(maxBits, 8U); +D3D11LoadFunctionMap BuildD3D11LoadFunctionMap() +{ + D3D11LoadFunctionMap map; - GLenum componentType = gl::GetComponentType(internalFormat); + // | 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> ); - const SwizzleInfoMap &map = GetSwizzleInfoMap(); - SwizzleInfoMap::const_iterator iter = map.find(SwizzleSizeType(maxBits, componentType)); + // 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 ); - if (iter != map.end()) - { - return iter->second; - } - else - { - UNREACHABLE(); - static const SwizzleFormatInfo defaultFormatInfo; - return defaultFormatInfo; - } -} + // 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 ); -static const InternalFormatInitializerMap &GetInternalFormatInitializerMap() -{ - static const InternalFormatInitializerMap map = BuildInternalFormatInitializerMap(); - return map; -} + // 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 ); -namespace d3d11 -{ + // From GL_EXT_texture_storage + InsertLoadFunction(&map, GL_ALPHA8_EXT, GL_UNSIGNED_BYTE, LoadA8ToRGBA8 ); + 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 ); -MipGenerationFunction GetMipGenerationFunction(DXGI_FORMAT format) -{ - DXGIFormatInfo formatInfo; - if (GetDXGIFormatInfo(format, &formatInfo)) - { - return formatInfo.mMipGenerationFunction; - } - else - { - UNREACHABLE(); - return NULL; - } -} + // From GL_ANGLE_depth_texture + InsertLoadFunction(&map, GL_DEPTH_COMPONENT32_OES, GL_UNSIGNED_INT, LoadR32ToR24G8 ); -LoadImageFunction GetImageLoadFunction(GLenum internalFormat, GLenum type) -{ - static const D3D11LoadFunctionMap loadImageMap = buildD3D11LoadFunctionMap(); - D3D11LoadFunctionMap::const_iterator iter = loadImageMap.find(InternalFormatTypePair(internalFormat, type)); - if (iter != loadImageMap.end()) - { - return iter->second; - } - else - { - UNREACHABLE(); - return NULL; - } -} + // 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> ); -GLuint GetFormatPixelBytes(DXGI_FORMAT format) -{ - DXGIFormatInfo dxgiFormatInfo; - if (GetDXGIFormatInfo(format, &dxgiFormatInfo)) - { - return dxgiFormatInfo.mPixelBits / 8; - } - else - { - UNREACHABLE(); - return 0; - } -} + // 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 ); -GLuint GetBlockWidth(DXGI_FORMAT format) -{ - DXGIFormatInfo dxgiFormatInfo; - if (GetDXGIFormatInfo(format, &dxgiFormatInfo)) - { - return dxgiFormatInfo.mBlockWidth; - } - else - { - UNREACHABLE(); - return 0; - } -} + // 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>); -GLuint GetBlockHeight(DXGI_FORMAT format) -{ - DXGIFormatInfo dxgiFormatInfo; - if (GetDXGIFormatInfo(format, &dxgiFormatInfo)) - { - return dxgiFormatInfo.mBlockHeight; - } - else - { - UNREACHABLE(); - return 0; - } -} + // From GL_ANGLE_texture_compression_dxt3 + InsertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4, 16>); -GLenum GetComponentType(DXGI_FORMAT format) -{ - DXGIFormatInfo dxgiFormatInfo; - if (GetDXGIFormatInfo(format, &dxgiFormatInfo)) - { - return dxgiFormatInfo.mComponentType; - } - else - { - UNREACHABLE(); - return GL_NONE; - } -} + // From GL_ANGLE_texture_compression_dxt5 + InsertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4, 16>); -GLuint GetDepthBits(DXGI_FORMAT format) -{ - DXGIDepthStencilInfo dxgiDSInfo; - if (GetDepthStencilInfo(format, &dxgiDSInfo)) - { - return dxgiDSInfo.mDepthBits; - } - else - { - // Since the depth stencil info map does not contain all used DXGI formats, - // we should not assert that the format exists - return 0; - } + return map; } -GLuint GetDepthOffset(DXGI_FORMAT format) +// 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() { - DXGIDepthStencilInfo dxgiDSInfo; - if (GetDepthStencilInfo(format, &dxgiDSInfo)) - { - return dxgiDSInfo.mDepthOffset; - } - else - { - // Since the depth stencil info map does not contain all used DXGI formats, - // we should not assert that the format exists - return 0; - } } -GLuint GetStencilBits(DXGI_FORMAT format) +static inline void InsertD3D11FormatInfo(D3D11ES3FormatMap *map, GLenum internalFormat, DXGI_FORMAT texFormat, + DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat, DXGI_FORMAT dsvFormat) { - DXGIDepthStencilInfo dxgiDSInfo; - if (GetDepthStencilInfo(format, &dxgiDSInfo)) + 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) { - return dxgiDSInfo.mStencilBits; + info.renderFormat = dsvFormat; } - else + else if (rtvFormat != DXGI_FORMAT_UNKNOWN) { - // Since the depth stencil info map does not contain all used DXGI formats, - // we should not assert that the format exists - return 0; + info.renderFormat = rtvFormat; } -} - -GLuint GetStencilOffset(DXGI_FORMAT format) -{ - DXGIDepthStencilInfo dxgiDSInfo; - if (GetDepthStencilInfo(format, &dxgiDSInfo)) + else if (texFormat != DXGI_FORMAT_UNKNOWN) { - return dxgiDSInfo.mStencilOffset; + info.renderFormat = texFormat; } else { - // Since the depth stencil info map does not contain all used DXGI formats, - // we should not assert that the format exists - return 0; + info.renderFormat = DXGI_FORMAT_UNKNOWN; } -} -void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset) -{ - DXGIFormatInfo dxgiFormatInfo; - if (GetDXGIFormatInfo(format, &dxgiFormatInfo)) + // Compute the swizzle formats + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); + if (internalFormat != GL_NONE && formatInfo.pixelBytes > 0) { - int upsampleCount = 0; - - GLsizei blockWidth = dxgiFormatInfo.mBlockWidth; - GLsizei blockHeight = dxgiFormatInfo.mBlockHeight; - - // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already. - if (isImage || *requestWidth < blockWidth || *requestHeight < blockHeight) + if (formatInfo.componentCount != 4 || texFormat == DXGI_FORMAT_UNKNOWN || + srvFormat == DXGI_FORMAT_UNKNOWN || rtvFormat == DXGI_FORMAT_UNKNOWN) { - while (*requestWidth % blockWidth != 0 || *requestHeight % blockHeight != 0) + // 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 { - *requestWidth <<= 1; - *requestHeight <<= 1; - upsampleCount++; + 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; } - *levelOffset = upsampleCount; } else { - UNREACHABLE(); + // 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; } -} -const DXGIFormatSet &GetAllUsedDXGIFormats() -{ - static DXGIFormatSet formatSet = BuildAllDXGIFormatSet(); - return formatSet; -} + // 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; -ColorReadFunction GetColorReadFunction(DXGI_FORMAT format) -{ - DXGIFormatInfo dxgiFormatInfo; - if (GetDXGIFormatInfo(format, &dxgiFormatInfo)) + // Gather all the load functions for this internal format + static const D3D11LoadFunctionMap loadFunctions = BuildD3D11LoadFunctionMap(); + D3D11LoadFunctionMap::const_iterator loadFunctionIter = loadFunctions.find(internalFormat); + if (loadFunctionIter != loadFunctions.end()) { - return dxgiFormatInfo.mColorReadFunction; - } - else - { - UNREACHABLE(); - return NULL; + 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)); + } } -} - -ColorCopyFunction GetFastCopyFunction(DXGI_FORMAT sourceFormat, GLenum destFormat, GLenum destType) -{ - static const D3D11FastCopyMap fastCopyMap = BuildFastCopyMap(); - D3D11FastCopyMap::const_iterator iter = fastCopyMap.find(D3D11FastCopyFormat(sourceFormat, destFormat, destType)); - return (iter != fastCopyMap.end()) ? iter->second : NULL; -} + map->insert(std::make_pair(internalFormat, info)); } -namespace gl_d3d11 +static D3D11ES3FormatMap BuildD3D11FormatMap() { + D3D11ES3FormatMap map; -DXGI_FORMAT GetTexFormat(GLenum internalFormat) -{ - D3D11FormatInfo d3d11FormatInfo; - if (GetD3D11FormatInfo(internalFormat, &d3d11FormatInfo)) - { - return d3d11FormatInfo.mTexFormat; - } - else - { - UNREACHABLE(); - return DXGI_FORMAT_UNKNOWN; - } -} + // | 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); -DXGI_FORMAT GetSRVFormat(GLenum internalFormat) -{ - D3D11FormatInfo d3d11FormatInfo; - if (GetD3D11FormatInfo(internalFormat, &d3d11FormatInfo)) - { - return d3d11FormatInfo.mSRVFormat; - } - else - { - UNREACHABLE(); - return 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); -DXGI_FORMAT GetRTVFormat(GLenum internalFormat) -{ - D3D11FormatInfo d3d11FormatInfo; - if (GetD3D11FormatInfo(internalFormat, &d3d11FormatInfo)) - { - return d3d11FormatInfo.mRTVFormat; - } - else - { - UNREACHABLE(); - return 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_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_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 ); -DXGI_FORMAT GetDSVFormat(GLenum internalFormat) -{ - D3D11FormatInfo d3d11FormatInfo; - if (GetD3D11FormatInfo(internalFormat, &d3d11FormatInfo)) - { - return d3d11FormatInfo.mDSVFormat; - } - else - { - return 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 ); -// Given a GL internal format, this function returns the DSV format if it is depth- or stencil-renderable, -// the RTV format if it is color-renderable, and the (nonrenderable) texture format otherwise. -DXGI_FORMAT GetRenderableFormat(GLenum internalFormat) -{ - DXGI_FORMAT targetFormat = GetDSVFormat(internalFormat); - if (targetFormat == DXGI_FORMAT_UNKNOWN) - targetFormat = GetRTVFormat(internalFormat); - if (targetFormat == DXGI_FORMAT_UNKNOWN) - targetFormat = GetTexFormat(internalFormat); + // 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); - return targetFormat; -} + // 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); -DXGI_FORMAT GetSwizzleTexFormat(GLint internalFormat) -{ - if (GetRTVFormat(internalFormat) == DXGI_FORMAT_UNKNOWN || gl::GetComponentCount(internalFormat) != 4) - { - const SwizzleFormatInfo &swizzleInfo = GetSwizzleFormatInfo(internalFormat); - return swizzleInfo.mTexFormat; - } - else - { - return GetTexFormat(internalFormat); - } -} + // 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); -DXGI_FORMAT GetSwizzleSRVFormat(GLint internalFormat) -{ - if (GetRTVFormat(internalFormat) == DXGI_FORMAT_UNKNOWN || gl::GetComponentCount(internalFormat) != 4) - { - const SwizzleFormatInfo &swizzleInfo = GetSwizzleFormatInfo(internalFormat); - return swizzleInfo.mSRVFormat; - } - else - { - return GetSRVFormat(internalFormat); - } -} + // 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); -DXGI_FORMAT GetSwizzleRTVFormat(GLint internalFormat) -{ - if (GetRTVFormat(internalFormat) == DXGI_FORMAT_UNKNOWN || gl::GetComponentCount(internalFormat) != 4) - { - const SwizzleFormatInfo &swizzleInfo = GetSwizzleFormatInfo(internalFormat); - return swizzleInfo.mRTVFormat; - } - else - { - return GetRTVFormat(internalFormat); - } -} + // 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); -bool RequiresTextureDataInitialization(GLint internalFormat) -{ - const InternalFormatInitializerMap &map = GetInternalFormatInitializerMap(); - return map.find(internalFormat) != map.end(); + return map; } -InitializeTextureDataFunction GetTextureDataInitializationFunction(GLint internalFormat) +const TextureFormat &GetTextureFormatInfo(GLenum internalFormat) { - const InternalFormatInitializerMap &map = GetInternalFormatInitializerMap(); - InternalFormatInitializerMap::const_iterator iter = map.find(internalFormat); - if (iter != map.end()) + static const D3D11ES3FormatMap formatMap = BuildD3D11FormatMap(); + D3D11ES3FormatMap::const_iterator iter = formatMap.find(internalFormat); + if (iter != formatMap.end()) { return iter->second; } else { - UNREACHABLE(); - return NULL; + static const TextureFormat defaultInfo; + return defaultInfo; } } -struct D3D11VertexFormatInfo -{ - rx::VertexConversionType mConversionType; - DXGI_FORMAT mNativeFormat; - VertexCopyFunction mCopyFunction; - - D3D11VertexFormatInfo() - : mConversionType(VERTEX_CONVERT_NONE), - mNativeFormat(DXGI_FORMAT_UNKNOWN), - mCopyFunction(NULL) - {} - - D3D11VertexFormatInfo(VertexConversionType conversionType, DXGI_FORMAT nativeFormat, VertexCopyFunction copyFunction) - : mConversionType(conversionType), - mNativeFormat(nativeFormat), - mCopyFunction(copyFunction) - {} -}; +typedef std::map<gl::VertexFormat, VertexFormat> D3D11VertexFormatInfoMap; +typedef std::pair<gl::VertexFormat, VertexFormat> D3D11VertexFormatPair; -typedef std::map<gl::VertexFormat, D3D11VertexFormatInfo> D3D11VertexFormatInfoMap; - -typedef std::pair<gl::VertexFormat, D3D11VertexFormatInfo> D3D11VertexFormatPair; +VertexFormat::VertexFormat() + : conversionType(VERTEX_CONVERT_NONE), + nativeFormat(DXGI_FORMAT_UNKNOWN), + copyFunction(NULL) +{ +} -static void addVertexFormatInfo(D3D11VertexFormatInfoMap *map, GLenum inputType, GLboolean normalized, GLuint componentCount, +static void AddVertexFormatInfo(D3D11VertexFormatInfoMap *map, GLenum inputType, GLboolean normalized, GLuint componentCount, VertexConversionType conversionType, DXGI_FORMAT nativeFormat, VertexCopyFunction copyFunction) { gl::VertexFormat inputFormat(inputType, normalized, componentCount, false); - map->insert(D3D11VertexFormatPair(inputFormat, D3D11VertexFormatInfo(conversionType, nativeFormat, copyFunction))); + + 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, +static void AddIntegerVertexFormatInfo(D3D11VertexFormatInfoMap *map, GLenum inputType, GLuint componentCount, VertexConversionType conversionType, DXGI_FORMAT nativeFormat, VertexCopyFunction copyFunction) { gl::VertexFormat inputFormat(inputType, GL_FALSE, componentCount, true); - map->insert(D3D11VertexFormatPair(inputFormat, D3D11VertexFormatInfo(conversionType, nativeFormat, copyFunction))); + + VertexFormat info; + info.conversionType = conversionType; + info.nativeFormat = nativeFormat; + info.copyFunction = copyFunction; + + map->insert(D3D11VertexFormatPair(inputFormat, info)); } static D3D11VertexFormatInfoMap BuildD3D11VertexFormatInfoMap() @@ -1211,245 +908,165 @@ static D3D11VertexFormatInfoMap BuildD3D11VertexFormatInfoMap() // // GL_BYTE -- un-normalized - addVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_SINT, ©VertexData<GLbyte, 1, 0>); - addVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_SINT, ©VertexData<GLbyte, 2, 0>); - addVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_SINT, ©VertexData<GLbyte, 3, 1>); - addVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_SINT, ©VertexData<GLbyte, 4, 0>); + AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_SINT, &CopyNativeVertexData<GLbyte, 1, 0>); + AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_SINT, &CopyNativeVertexData<GLbyte, 2, 0>); + AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<GLbyte, 3, 1>); + AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<GLbyte, 4, 0>); // GL_BYTE -- normalized - addVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SNORM, ©VertexData<GLbyte, 1, 0>); - addVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SNORM, ©VertexData<GLbyte, 2, 0>); - addVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SNORM, ©VertexData<GLbyte, 3, INT8_MAX>); - addVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SNORM, ©VertexData<GLbyte, 4, 0>); + AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SNORM, &CopyNativeVertexData<GLbyte, 1, 0>); + AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SNORM, &CopyNativeVertexData<GLbyte, 2, 0>); + AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SNORM, &CopyNativeVertexData<GLbyte, 3, INT8_MAX>); + AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SNORM, &CopyNativeVertexData<GLbyte, 4, 0>); // GL_UNSIGNED_BYTE -- un-normalized - addVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_UINT, ©VertexData<GLubyte, 1, 0>); - addVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_UINT, ©VertexData<GLubyte, 2, 0>); - addVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT, ©VertexData<GLubyte, 3, 1>); - addVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_UINT, ©VertexData<GLubyte, 4, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_UINT, &CopyNativeVertexData<GLubyte, 1, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_UINT, &CopyNativeVertexData<GLubyte, 2, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 3, 1>); + AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 4, 0>); // GL_UNSIGNED_BYTE -- normalized - addVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UNORM, ©VertexData<GLubyte, 1, 0>); - addVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UNORM, ©VertexData<GLubyte, 2, 0>); - addVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM, ©VertexData<GLubyte, 3, UINT8_MAX>); - addVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UNORM, ©VertexData<GLubyte, 4, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UNORM, &CopyNativeVertexData<GLubyte, 1, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UNORM, &CopyNativeVertexData<GLubyte, 2, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM, &CopyNativeVertexData<GLubyte, 3, UINT8_MAX>); + AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UNORM, &CopyNativeVertexData<GLubyte, 4, 0>); // GL_SHORT -- un-normalized - addVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_SINT, ©VertexData<GLshort, 1, 0>); - addVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_SINT, ©VertexData<GLshort, 2, 0>); - addVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT, ©VertexData<GLshort, 4, 1>); - addVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_SINT, ©VertexData<GLshort, 4, 0>); + AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_SINT, &CopyNativeVertexData<GLshort, 1, 0>); + AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_SINT, &CopyNativeVertexData<GLshort, 2, 0>); + AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 4, 1>); + AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 4, 0>); // GL_SHORT -- normalized - addVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SNORM, ©VertexData<GLshort, 1, 0>); - addVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SNORM, ©VertexData<GLshort, 2, 0>); - addVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM, ©VertexData<GLshort, 3, INT16_MAX>); - addVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SNORM, ©VertexData<GLshort, 4, 0>); + AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SNORM, &CopyNativeVertexData<GLshort, 1, 0>); + AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SNORM, &CopyNativeVertexData<GLshort, 2, 0>); + AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM, &CopyNativeVertexData<GLshort, 3, INT16_MAX>); + AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SNORM, &CopyNativeVertexData<GLshort, 4, 0>); // GL_UNSIGNED_SHORT -- un-normalized - addVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_UINT, ©VertexData<GLushort, 1, 0>); - addVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_UINT, ©VertexData<GLushort, 2, 0>); - addVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_UINT, ©VertexData<GLushort, 3, 1>); - addVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_UINT, ©VertexData<GLushort, 4, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_UINT, &CopyNativeVertexData<GLushort, 1, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_UINT, &CopyNativeVertexData<GLushort, 2, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 3, 1>); + AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 4, 0>); // GL_UNSIGNED_SHORT -- normalized - addVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UNORM, ©VertexData<GLushort, 1, 0>); - addVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UNORM, ©VertexData<GLushort, 2, 0>); - addVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UNORM, ©VertexData<GLushort, 3, UINT16_MAX>); - addVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UNORM, ©VertexData<GLushort, 4, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UNORM, &CopyNativeVertexData<GLushort, 1, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UNORM, &CopyNativeVertexData<GLushort, 2, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UNORM, &CopyNativeVertexData<GLushort, 3, UINT16_MAX>); + AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UNORM, &CopyNativeVertexData<GLushort, 4, 0>); // GL_INT -- un-normalized - addVertexFormatInfo(&map, GL_INT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_SINT, ©VertexData<GLint, 1, 0>); - addVertexFormatInfo(&map, GL_INT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_SINT, ©VertexData<GLint, 2, 0>); - addVertexFormatInfo(&map, GL_INT, GL_FALSE, 3, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_SINT, ©VertexData<GLint, 3, 0>); - addVertexFormatInfo(&map, GL_INT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_SINT, ©VertexData<GLint, 4, 0>); + AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData<GLint, 1, 0>); + AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData<GLint, 2, 0>); + AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 3, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData<GLint, 3, 0>); + AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData<GLint, 4, 0>); // GL_INT -- normalized - addVertexFormatInfo(&map, GL_INT, GL_TRUE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, ©ToFloatVertexData<GLint, 1, true>); - addVertexFormatInfo(&map, GL_INT, GL_TRUE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, ©ToFloatVertexData<GLint, 2, true>); - addVertexFormatInfo(&map, GL_INT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, ©ToFloatVertexData<GLint, 3, true>); - addVertexFormatInfo(&map, GL_INT, GL_TRUE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, ©ToFloatVertexData<GLint, 4, true>); + AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, &CopyTo32FVertexData<GLint, 1, true>); + AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData<GLint, 2, true>); + AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &CopyTo32FVertexData<GLint, 3, true>); + AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData<GLint, 4, true>); // GL_UNSIGNED_INT -- un-normalized - addVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_UINT, ©VertexData<GLuint, 1, 0>); - addVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_UINT, ©VertexData<GLuint, 2, 0>); - addVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 3, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_UINT, ©VertexData<GLuint, 3, 0>); - addVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_UINT, ©VertexData<GLuint, 4, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_UINT, &CopyNativeVertexData<GLuint, 1, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_UINT, &CopyNativeVertexData<GLuint, 2, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 3, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_UINT, &CopyNativeVertexData<GLuint, 3, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_UINT, &CopyNativeVertexData<GLuint, 4, 0>); // GL_UNSIGNED_INT -- normalized - addVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, ©ToFloatVertexData<GLuint, 1, true>); - addVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, ©ToFloatVertexData<GLuint, 2, true>); - addVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, ©ToFloatVertexData<GLuint, 3, true>); - addVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, ©ToFloatVertexData<GLuint, 4, true>); + AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, &CopyTo32FVertexData<GLuint, 1, true>); + AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData<GLuint, 2, true>); + AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &CopyTo32FVertexData<GLuint, 3, true>); + AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData<GLuint, 4, true>); // GL_FIXED - addVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, ©FixedVertexData<1>); - addVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, ©FixedVertexData<2>); - addVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, ©FixedVertexData<3>); - addVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, ©FixedVertexData<4>); + AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, &Copy32FixedTo32FVertexData<1>); + AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &Copy32FixedTo32FVertexData<2>); + AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &Copy32FixedTo32FVertexData<3>); + AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &Copy32FixedTo32FVertexData<4>); // GL_HALF_FLOAT - addVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_FLOAT, ©VertexData<GLhalf, 1, 0>); - addVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_FLOAT, ©VertexData<GLhalf, 2, 0>); - addVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_FLOAT, ©VertexData<GLhalf, 3, gl::Float16One>); - addVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_FLOAT, ©VertexData<GLhalf, 4, 0>); + AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_FLOAT, &CopyNativeVertexData<GLhalf, 1, 0>); + AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_FLOAT, &CopyNativeVertexData<GLhalf, 2, 0>); + AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_FLOAT, &CopyNativeVertexData<GLhalf, 3, gl::Float16One>); + AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_FLOAT, &CopyNativeVertexData<GLhalf, 4, 0>); // GL_FLOAT - addVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, ©VertexData<GLfloat, 1, 0>); - addVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, ©VertexData<GLfloat, 2, 0>); - addVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_FLOAT, ©VertexData<GLfloat, 3, 0>); - addVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, ©VertexData<GLfloat, 4, 0>); + AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, &CopyNativeVertexData<GLfloat, 1, 0>); + AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, &CopyNativeVertexData<GLfloat, 2, 0>); + AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_FLOAT, &CopyNativeVertexData<GLfloat, 3, 0>); + AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyNativeVertexData<GLfloat, 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, ©PackedVertexData<true, false, true>); - addVertexFormatInfo(&map, GL_INT_2_10_10_10_REV, GL_TRUE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, ©PackedVertexData<true, true, true>); + 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, ©PackedVertexData<false, false, true>); - addVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UNORM, ©PackedUnsignedVertexData); + 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, 0>); // // Integer Formats // // GL_BYTE - addIntegerVertexFormatInfo(&map, GL_BYTE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SINT, ©VertexData<GLbyte, 1, 0>); - addIntegerVertexFormatInfo(&map, GL_BYTE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SINT, ©VertexData<GLbyte, 2, 0>); - addIntegerVertexFormatInfo(&map, GL_BYTE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SINT, ©VertexData<GLbyte, 3, 1>); - addIntegerVertexFormatInfo(&map, GL_BYTE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SINT, ©VertexData<GLbyte, 4, 0>); + AddIntegerVertexFormatInfo(&map, GL_BYTE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SINT, &CopyNativeVertexData<GLbyte, 1, 0>); + AddIntegerVertexFormatInfo(&map, GL_BYTE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SINT, &CopyNativeVertexData<GLbyte, 2, 0>); + AddIntegerVertexFormatInfo(&map, GL_BYTE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<GLbyte, 3, 1>); + AddIntegerVertexFormatInfo(&map, GL_BYTE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<GLbyte, 4, 0>); // GL_UNSIGNED_BYTE - addIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UINT, ©VertexData<GLubyte, 1, 0>); - addIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UINT, ©VertexData<GLubyte, 2, 0>); - addIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UINT, ©VertexData<GLubyte, 3, 1>); - addIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UINT, ©VertexData<GLubyte, 4, 0>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UINT, &CopyNativeVertexData<GLubyte, 1, 0>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UINT, &CopyNativeVertexData<GLubyte, 2, 0>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 3, 1>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 4, 0>); // GL_SHORT - addIntegerVertexFormatInfo(&map, GL_SHORT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SINT, ©VertexData<GLshort, 1, 0>); - addIntegerVertexFormatInfo(&map, GL_SHORT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SINT, ©VertexData<GLshort, 2, 0>); - addIntegerVertexFormatInfo(&map, GL_SHORT, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, ©VertexData<GLshort, 3, 1>); - addIntegerVertexFormatInfo(&map, GL_SHORT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SINT, ©VertexData<GLshort, 4, 0>); + AddIntegerVertexFormatInfo(&map, GL_SHORT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SINT, &CopyNativeVertexData<GLshort, 1, 0>); + AddIntegerVertexFormatInfo(&map, GL_SHORT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SINT, &CopyNativeVertexData<GLshort, 2, 0>); + AddIntegerVertexFormatInfo(&map, GL_SHORT, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 3, 1>); + AddIntegerVertexFormatInfo(&map, GL_SHORT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 4, 0>); // GL_UNSIGNED_SHORT - addIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UINT, ©VertexData<GLushort, 1, 0>); - addIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UINT, ©VertexData<GLushort, 2, 0>); - addIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UINT, ©VertexData<GLushort, 3, 1>); - addIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UINT, ©VertexData<GLushort, 4, 0>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UINT, &CopyNativeVertexData<GLushort, 1, 0>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UINT, &CopyNativeVertexData<GLushort, 2, 0>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 3, 1>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 4, 0>); // GL_INT - addIntegerVertexFormatInfo(&map, GL_INT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, ©VertexData<GLint, 1, 0>); - addIntegerVertexFormatInfo(&map, GL_INT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, ©VertexData<GLint, 2, 0>); - addIntegerVertexFormatInfo(&map, GL_INT, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, ©VertexData<GLint, 3, 0>); - addIntegerVertexFormatInfo(&map, GL_INT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, ©VertexData<GLint, 4, 0>); + AddIntegerVertexFormatInfo(&map, GL_INT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData<GLint, 1, 0>); + AddIntegerVertexFormatInfo(&map, GL_INT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData<GLint, 2, 0>); + AddIntegerVertexFormatInfo(&map, GL_INT, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData<GLint, 3, 0>); + AddIntegerVertexFormatInfo(&map, GL_INT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData<GLint, 4, 0>); // GL_UNSIGNED_INT - addIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, ©VertexData<GLuint, 1, 0>); - addIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, ©VertexData<GLuint, 2, 0>); - addIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, ©VertexData<GLuint, 3, 0>); - addIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, ©VertexData<GLuint, 4, 0>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData<GLuint, 1, 0>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData<GLuint, 2, 0>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData<GLuint, 3, 0>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData<GLuint, 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, ©PackedVertexData<true, true, false>); + 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, ©PackedUnsignedVertexData); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UINT, &CopyNativeVertexData<GLuint, 1, 0>); return map; } -static bool GetD3D11VertexFormatInfo(const gl::VertexFormat &vertexFormat, D3D11VertexFormatInfo *outVertexFormatInfo) +const VertexFormat &GetVertexFormatInfo(const gl::VertexFormat &vertexFormat) { static const D3D11VertexFormatInfoMap vertexFormatMap = BuildD3D11VertexFormatInfoMap(); D3D11VertexFormatInfoMap::const_iterator iter = vertexFormatMap.find(vertexFormat); if (iter != vertexFormatMap.end()) { - if (outVertexFormatInfo) - { - *outVertexFormatInfo = iter->second; - } - return true; - } - else - { - return false; - } -} - -VertexCopyFunction GetVertexCopyFunction(const gl::VertexFormat &vertexFormat) -{ - D3D11VertexFormatInfo vertexFormatInfo; - if (GetD3D11VertexFormatInfo(vertexFormat, &vertexFormatInfo)) - { - return vertexFormatInfo.mCopyFunction; - } - else - { - UNREACHABLE(); - return NULL; - } -} - -size_t GetVertexElementSize(const gl::VertexFormat &vertexFormat) -{ - D3D11VertexFormatInfo vertexFormatInfo; - if (GetD3D11VertexFormatInfo(vertexFormat, &vertexFormatInfo)) - { - // FIXME: should not need a client version, and is not a pixel! - return d3d11::GetFormatPixelBytes(vertexFormatInfo.mNativeFormat); - } - else - { - UNREACHABLE(); - return 0; - } -} - -rx::VertexConversionType GetVertexConversionType(const gl::VertexFormat &vertexFormat) -{ - D3D11VertexFormatInfo vertexFormatInfo; - if (GetD3D11VertexFormatInfo(vertexFormat, &vertexFormatInfo)) - { - return vertexFormatInfo.mConversionType; - } - else - { - UNREACHABLE(); - return VERTEX_CONVERT_NONE; - } -} - -DXGI_FORMAT GetNativeVertexFormat(const gl::VertexFormat &vertexFormat) -{ - D3D11VertexFormatInfo vertexFormatInfo; - if (GetD3D11VertexFormatInfo(vertexFormat, &vertexFormatInfo)) - { - return vertexFormatInfo.mNativeFormat; - } - else - { - UNREACHABLE(); - return DXGI_FORMAT_UNKNOWN; - } -} - -} - -namespace d3d11_gl -{ - -GLenum GetInternalFormat(DXGI_FORMAT format) -{ - const DXGIToESFormatMap &formatMap = GetDXGIToESFormatMap(); - DXGIToESFormatMap::const_iterator iter = formatMap.find(format); - if (iter != formatMap.end()) - { return iter->second; } else { - UNREACHABLE(); - return GL_NONE; + static const VertexFormat defaultInfo; + return defaultInfo; } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.h index d77fccfe9c..ea11aaa74c 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.h @@ -12,65 +12,70 @@ #include "libGLESv2/formatutils.h" +#include <map> + namespace rx { -class Renderer; - namespace d3d11 { -typedef std::set<DXGI_FORMAT> DXGIFormatSet; +typedef std::map<std::pair<GLenum, GLenum>, ColorCopyFunction> FastCopyFunctionMap; -MipGenerationFunction GetMipGenerationFunction(DXGI_FORMAT format); -LoadImageFunction GetImageLoadFunction(GLenum internalFormat, GLenum type); +struct DXGIFormat +{ + DXGIFormat(); -GLuint GetFormatPixelBytes(DXGI_FORMAT format); -GLuint GetBlockWidth(DXGI_FORMAT format); -GLuint GetBlockHeight(DXGI_FORMAT format); -GLenum GetComponentType(DXGI_FORMAT format); + GLuint pixelBytes; + GLuint blockWidth; + GLuint blockHeight; -GLuint GetDepthBits(DXGI_FORMAT format); -GLuint GetDepthOffset(DXGI_FORMAT format); -GLuint GetStencilBits(DXGI_FORMAT format); -GLuint GetStencilOffset(DXGI_FORMAT format); + GLuint depthBits; + GLuint depthOffset; + GLuint stencilBits; + GLuint stencilOffset; -void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset); + GLenum internalFormat; + GLenum componentType; -const DXGIFormatSet &GetAllUsedDXGIFormats(); + MipGenerationFunction mipGenerationFunction; + ColorReadFunction colorReadFunction; -ColorReadFunction GetColorReadFunction(DXGI_FORMAT format); -ColorCopyFunction GetFastCopyFunction(DXGI_FORMAT sourceFormat, GLenum destFormat, GLenum destType); + FastCopyFunctionMap fastCopyFunctions; + ColorCopyFunction getFastCopyFunction(GLenum format, GLenum type) const; +}; +const DXGIFormat &GetDXGIFormatInfo(DXGI_FORMAT format); -} - -namespace gl_d3d11 +struct TextureFormat { + TextureFormat(); -DXGI_FORMAT GetTexFormat(GLenum internalFormat); -DXGI_FORMAT GetSRVFormat(GLenum internalFormat); -DXGI_FORMAT GetRTVFormat(GLenum internalFormat); -DXGI_FORMAT GetDSVFormat(GLenum internalFormat); -DXGI_FORMAT GetRenderableFormat(GLenum internalFormat); - -DXGI_FORMAT GetSwizzleTexFormat(GLint internalFormat); -DXGI_FORMAT GetSwizzleSRVFormat(GLint internalFormat); -DXGI_FORMAT GetSwizzleRTVFormat(GLint internalFormat); + DXGI_FORMAT texFormat; + DXGI_FORMAT srvFormat; + DXGI_FORMAT rtvFormat; + DXGI_FORMAT dsvFormat; + DXGI_FORMAT renderFormat; -bool RequiresTextureDataInitialization(GLint internalFormat); -InitializeTextureDataFunction GetTextureDataInitializationFunction(GLint internalFormat); + DXGI_FORMAT swizzleTexFormat; + DXGI_FORMAT swizzleSRVFormat; + DXGI_FORMAT swizzleRTVFormat; -VertexCopyFunction GetVertexCopyFunction(const gl::VertexFormat &vertexFormat); -size_t GetVertexElementSize(const gl::VertexFormat &vertexFormat); -VertexConversionType GetVertexConversionType(const gl::VertexFormat &vertexFormat); -DXGI_FORMAT GetNativeVertexFormat(const gl::VertexFormat &vertexFormat); + InitializeTextureDataFunction dataInitializerFunction; -} + typedef std::map<GLenum, LoadImageFunction> LoadFunctionMap; + LoadFunctionMap loadFunctions; +}; +const TextureFormat &GetTextureFormatInfo(GLenum internalFormat); -namespace d3d11_gl +struct VertexFormat { + VertexFormat(); -GLenum GetInternalFormat(DXGI_FORMAT format); + VertexConversionType conversionType; + DXGI_FORMAT nativeFormat; + VertexCopyFunction copyFunction; +}; +const VertexFormat &GetVertexFormatInfo(const gl::VertexFormat &vertexFormat); } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp index d914a8201b..2af97e73f0 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -10,8 +9,14 @@ #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" +#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h" +#include "libGLESv2/ProgramBinary.h" +#include "libGLESv2/Framebuffer.h" + #include "common/debug.h" +#include <algorithm> + #ifndef D3D_FL9_1_DEFAULT_MAX_ANISOTROPY # define D3D_FL9_1_DEFAULT_MAX_ANISOTROPY 2 #endif @@ -21,6 +26,12 @@ #ifndef D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT # define D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT 4 #endif +#ifndef D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT +# define D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT 65535 +#endif +#ifndef D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT +# define D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT 1048575 +#endif #ifndef D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION # define D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION 512 #endif @@ -45,6 +56,48 @@ #ifndef D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION # define D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION 2048 #endif +#ifndef D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP +# define D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP 32 +#endif +#ifndef D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP +# define D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP 32 +#endif +#ifndef D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT +# define D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT 32 +#endif +#ifndef D3D11_STANDARD_VERTEX_ELEMENT_COUNT +# define D3D11_STANDARD_VERTEX_ELEMENT_COUNT 32 +#endif +#ifndef D3D10_1_SO_BUFFER_SLOT_COUNT +# define D3D10_1_SO_BUFFER_SLOT_COUNT 4 +#endif +#ifndef D3D11_SO_BUFFER_SLOT_COUNT +# define D3D11_SO_BUFFER_SLOT_COUNT 4 +#endif +#ifndef D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT +# define D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT 14 +#endif +#ifndef D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT +# define D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT 16 +#endif +#ifndef D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE +# define D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE -8 +#endif +#ifndef D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE +# define D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE 7 +#endif +#ifndef D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT +# define D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT 4096 +#endif +#ifndef D3D11_PS_INPUT_REGISTER_COUNT +# define D3D11_PS_INPUT_REGISTER_COUNT 32 +#endif +#ifndef D3D10_1_VS_OUTPUT_REGISTER_COUNT +# define D3D10_1_VS_OUTPUT_REGISTER_COUNT 32 +#endif +#ifndef D3D11_VS_OUTPUT_REGISTER_COUNT +# define D3D11_VS_OUTPUT_REGISTER_COUNT 32 +#endif namespace rx { @@ -258,16 +311,13 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, ID3D11De { gl::TextureCaps textureCaps; - DXGI_FORMAT textureFormat = gl_d3d11::GetTexFormat(internalFormat); - DXGI_FORMAT srvFormat = gl_d3d11::GetSRVFormat(internalFormat); - DXGI_FORMAT rtvFormat = gl_d3d11::GetRTVFormat(internalFormat); - DXGI_FORMAT dsvFormat = gl_d3d11::GetDSVFormat(internalFormat); - DXGI_FORMAT renderFormat = gl_d3d11::GetRenderableFormat(internalFormat); + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat); UINT formatSupport; - if (SUCCEEDED(device->CheckFormatSupport(textureFormat, &formatSupport))) + if (SUCCEEDED(device->CheckFormatSupport(formatInfo.texFormat, &formatSupport))) { - if (gl::GetDepthBits(internalFormat) > 0 || gl::GetStencilBits(internalFormat) > 0) + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); + if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) { textureCaps.texturable = ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0); } @@ -279,13 +329,13 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, ID3D11De } } - if (SUCCEEDED(device->CheckFormatSupport(renderFormat, &formatSupport)) && + if (SUCCEEDED(device->CheckFormatSupport(formatInfo.renderFormat, &formatSupport)) && ((formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET) != 0)) { for (size_t sampleCount = 1; sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount++) { UINT qualityCount = 0; - if (SUCCEEDED(device->CheckMultisampleQualityLevels(renderFormat, sampleCount, &qualityCount)) && + if (SUCCEEDED(device->CheckMultisampleQualityLevels(formatInfo.renderFormat, sampleCount, &qualityCount)) && qualityCount > 0) { textureCaps.sampleCounts.insert(sampleCount); @@ -293,11 +343,11 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, ID3D11De } } - textureCaps.filterable = SUCCEEDED(device->CheckFormatSupport(srvFormat, &formatSupport)) && + textureCaps.filterable = SUCCEEDED(device->CheckFormatSupport(formatInfo.srvFormat, &formatSupport)) && ((formatSupport & D3D11_FORMAT_SUPPORT_SHADER_SAMPLE)) != 0; - textureCaps.renderable = (SUCCEEDED(device->CheckFormatSupport(rtvFormat, &formatSupport)) && + textureCaps.renderable = (SUCCEEDED(device->CheckFormatSupport(formatInfo.rtvFormat, &formatSupport)) && ((formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET)) != 0) || - (SUCCEEDED(device->CheckFormatSupport(dsvFormat, &formatSupport)) && + (SUCCEEDED(device->CheckFormatSupport(formatInfo.dsvFormat, &formatSupport)) && ((formatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL) != 0)); return textureCaps; @@ -317,7 +367,7 @@ static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel) // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx case D3D_FEATURE_LEVEL_9_3: case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return false; + case D3D_FEATURE_LEVEL_9_1: return true; // Provided that mipmaps & wrap modes are not used default: UNREACHABLE(); return false; } @@ -441,9 +491,8 @@ static size_t GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; - // FIXME(geofflang): Work around NVIDIA driver bug by repacking buffers case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return 1; /* D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; */ + case D3D_FEATURE_LEVEL_10_0: return D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT; case D3D_FEATURE_LEVEL_9_2: @@ -554,13 +603,412 @@ static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel) } } +static size_t GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel) +{ + // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since that's what's + // returned from glGetInteger + META_ASSERT(D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32); + META_ASSERT(D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32); + + switch (featureLevel) + { +#if _MSC_VER >= 1700 + 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(); + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT; + case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT; + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel) +{ + // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since that's what's + // returned from glGetInteger + META_ASSERT(D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32); + META_ASSERT(D3D10_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32); + + switch (featureLevel) + { +#if _MSC_VER >= 1700 + 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(); + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT; + case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT; + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { +#if _MSC_VER >= 1700 + 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; + case D3D_FEATURE_LEVEL_10_0: return D3D10_STANDARD_VERTEX_ELEMENT_COUNT; + + // From http://http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx "Max Input Slots" + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 16; + + default: UNREACHABLE(); return 0; + } +} + +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 _MSC_VER >= 1700 + 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: + case D3D_FEATURE_LEVEL_10_0: return 1024; // D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; + + // 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; + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetReservedVertexUniformBuffers() +{ + // Reserve one buffer for the application uniforms, and one for driver uniforms + return 2; +} + +static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { +#if _MSC_VER >= 1700 + 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: + case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers(); + + // Uniform blocks not supported in D3D9 feature levels + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 0; + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetReservedVertexOutputVectors() +{ + // We potentially reserve varyings for gl_Position, dx_Position, gl_FragCoord and gl_PointSize + return 4; +} + +static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel) +{ + META_ASSERT(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT); + + switch (featureLevel) + { +#if _MSC_VER >= 1700 + case D3D_FEATURE_LEVEL_11_1: +#endif + case D3D_FEATURE_LEVEL_11_0: return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); + + case D3D_FEATURE_LEVEL_10_1: return D3D10_1_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); + case D3D_FEATURE_LEVEL_10_0: return D3D10_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); + + // Use D3D9 SM3 and SM2 limits + case D3D_FEATURE_LEVEL_9_3: return 10 - GetReservedVertexOutputVectors(); + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 8 - GetReservedVertexOutputVectors(); + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { +#if _MSC_VER >= 1700 + 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: + case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; + + // Vertex textures not supported in D3D9 feature levels according to + // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx + // ID3D11DeviceContext::VSSetSamplers and ID3D11DeviceContext::VSSetShaderResources + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 0; + + default: UNREACHABLE(); return 0; + } +} + +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 _MSC_VER >= 1700 + 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: + case D3D_FEATURE_LEVEL_10_0: return 1024; // D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; + + // 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; + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetReservedPixelUniformBuffers() +{ + // Reserve one buffer for the application uniforms, and one for driver uniforms + return 2; +} + +static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { +#if _MSC_VER >= 1700 + 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: + case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers(); + + // Uniform blocks not supported in D3D9 feature levels + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 0; + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { +#if _MSC_VER >= 1700 + case D3D_FEATURE_LEVEL_11_1: +#endif + case D3D_FEATURE_LEVEL_11_0: return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: return D3D10_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); + + // Use D3D9 SM3 and SM2 limits + case D3D_FEATURE_LEVEL_9_3: return 10 - GetReservedVertexOutputVectors(); + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 8 - GetReservedVertexOutputVectors(); + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { +#if _MSC_VER >= 1700 + 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: + case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; + + // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::PSSetShaderResources + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 16; + + default: UNREACHABLE(); return 0; + } +} + +static int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { +#if _MSC_VER >= 1700 + 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: + case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE; + + // Sampling functions with offsets are not available below shader model 4.0. + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 0; + + default: UNREACHABLE(); return 0; + } +} + +static int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { +#if _MSC_VER >= 1700 + 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; + + // Sampling functions with offsets are not available below shader model 4.0. + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 0; + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel) +{ + // Returns a size_t despite the limit being a GLuint64 because size_t is the maximum size of + // any buffer that could be allocated. + + const size_t bytesPerComponent = 4 * sizeof(float); + + switch (featureLevel) + { +#if _MSC_VER >= 1700 + 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: + case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent; + + // Limits from http://msdn.microsoft.com/en-us/library/windows/desktop/ff476501.aspx remarks section + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 4096 * bytesPerComponent; + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { +#if _MSC_VER >= 1700 + 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; + case D3D_FEATURE_LEVEL_10_0: return D3D10_SO_BUFFER_SLOT_COUNT; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 0; + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetMaximumStreamOutputInterleavedComponenets(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { +#if _MSC_VER >= 1700 + 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 GetMaximumVertexOutputVectors(featureLevel) * 4; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 0; + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetMaximumStreamOutputSeparateCompeonents(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { +#if _MSC_VER >= 1700 + case D3D_FEATURE_LEVEL_11_1: +#endif + case D3D_FEATURE_LEVEL_11_0: return GetMaximumStreamOutputInterleavedComponenets(featureLevel) / + GetMaximumStreamOutputBuffers(featureLevel); + + + // D3D 10 and 10.1 only allow one output per output slot if an output slot other than zero is used. + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: return 4; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 0; + + default: UNREACHABLE(); return 0; + } +} + void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions) { + GLuint maxSamples = 0; const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats(); for (gl::FormatSet::const_iterator internalFormat = allFormats.begin(); internalFormat != allFormats.end(); ++internalFormat) { gl::TextureCaps textureCaps = GenerateTextureFormatCaps(*internalFormat, device); textureCapsMap->insert(*internalFormat, textureCaps); + + maxSamples = std::max(maxSamples, textureCaps.getMaxSamples()); + + if (gl::GetInternalFormatInfo(*internalFormat).compressed) + { + caps->compressedTextureFormats.push_back(*internalFormat); + } } D3D_FEATURE_LEVEL featureLevel = device->GetFeatureLevel(); @@ -595,6 +1043,54 @@ void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *text caps->minAliasedLineWidth = 1.0f; caps->maxAliasedLineWidth = 1.0f; + // Primitive count limits + caps->maxElementsIndices = GetMaximumDrawIndexedIndexCount(featureLevel); + caps->maxElementsVertices = GetMaximumDrawVertexCount(featureLevel); + + // Program and shader binary formats (no supported shader binary formats) + caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE); + + // We do not wait for server fence objects internally, so report a max timeout of zero. + 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); + + // 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->minProgramTexelOffset = GetMinimumTexelOffset(featureLevel); + caps->maxProgramTexelOffset = GetMaximumTexelOffset(featureLevel); + + // Aggregate shader limits + 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()); + + 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->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxTextureImageUnits; + + // Transform feedback limits + caps->maxTransformFeedbackInterleavedComponents = GetMaximumStreamOutputInterleavedComponenets(featureLevel); + caps->maxTransformFeedbackSeparateAttributes = GetMaximumStreamOutputBuffers(featureLevel); + caps->maxTransformFeedbackSeparateComponents = GetMaximumStreamOutputSeparateCompeonents(featureLevel); + // GL extension support extensions->setTextureExtensionSupport(*textureCapsMap); extensions->elementIndexUint = true; @@ -617,6 +1113,7 @@ void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *text extensions->blendMinMax = true; extensions->framebufferBlit = true; extensions->framebufferMultisample = true; + extensions->maxSamples = maxSamples; extensions->instancedArrays = GetInstancingSupport(featureLevel); extensions->packReverseRowOrder = true; extensions->standardDerivatives = GetDerivativeInstructionSupport(featureLevel); @@ -631,12 +1128,33 @@ void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *text namespace d3d11 { +void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset) +{ + const DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format); + + int upsampleCount = 0; + // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already. + if (isImage || *requestWidth < static_cast<GLsizei>(dxgiFormatInfo.blockWidth) || + *requestHeight < static_cast<GLsizei>(dxgiFormatInfo.blockHeight)) + { + while (*requestWidth % dxgiFormatInfo.blockWidth != 0 || *requestHeight % dxgiFormatInfo.blockHeight != 0) + { + *requestWidth <<= 1; + *requestHeight <<= 1; + upsampleCount++; + } + } + *levelOffset = upsampleCount; +} + void GenerateInitialTextureData(GLint internalFormat, GLuint width, GLuint height, GLuint depth, GLuint mipLevels, std::vector<D3D11_SUBRESOURCE_DATA> *outSubresourceData, std::vector< std::vector<BYTE> > *outData) { - InitializeTextureDataFunction initializeFunc = gl_d3d11::GetTextureDataInitializationFunction(internalFormat); - DXGI_FORMAT dxgiFormat = gl_d3d11::GetTexFormat(internalFormat); + const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(internalFormat); + ASSERT(d3dFormatInfo.dataInitializerFunction != NULL); + + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3dFormatInfo.texFormat); outSubresourceData->resize(mipLevels); outData->resize(mipLevels); @@ -647,11 +1165,11 @@ void GenerateInitialTextureData(GLint internalFormat, GLuint width, GLuint heigh unsigned int mipHeight = std::max(height >> i, 1U); unsigned int mipDepth = std::max(depth >> i, 1U); - unsigned int rowWidth = d3d11::GetFormatPixelBytes(dxgiFormat) * mipWidth; + unsigned int rowWidth = dxgiFormatInfo.pixelBytes * mipWidth; unsigned int imageSize = rowWidth * height; outData->at(i).resize(rowWidth * mipHeight * mipDepth); - initializeFunc(mipWidth, mipHeight, mipDepth, outData->at(i).data(), rowWidth, imageSize); + d3dFormatInfo.dataInitializerFunction(mipWidth, mipHeight, mipDepth, outData->at(i).data(), rowWidth, imageSize); outSubresourceData->at(i).pSysMem = outData->at(i).data(); outSubresourceData->at(i).SysMemPitch = rowWidth; @@ -687,6 +1205,12 @@ HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name) #endif } +RenderTarget11 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment) +{ + RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment); + return RenderTarget11::makeRenderTarget11(renderTarget); +} + } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h index 4de9bfa86d..4c05eb9256 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h @@ -13,8 +13,16 @@ #include "libGLESv2/angletypes.h" #include "libGLESv2/Caps.h" +#include <vector> + +namespace gl +{ +class FramebufferAttachment; +} + namespace rx { +class RenderTarget11; namespace gl_d3d11 { @@ -47,6 +55,8 @@ void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *text namespace d3d11 { +void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset); + void GenerateInitialTextureData(GLint internalFormat, GLuint width, GLuint height, GLuint depth, GLuint mipLevels, std::vector<D3D11_SUBRESOURCE_DATA> *outSubresourceData, std::vector< std::vector<BYTE> > *outData); @@ -166,6 +176,8 @@ inline void SetBufferData(ID3D11DeviceContext *context, ID3D11Buffer *constantBu context->Unmap(constantBuffer, 0); } +RenderTarget11 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment); + } } |