diff options
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11')
32 files changed, 3044 insertions, 2396 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 d43e65ea78..06aea9befe 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp @@ -172,7 +172,7 @@ static void Write3DVertices(const gl::Box &sourceArea, const gl::Extents &source *outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; } -Blit11::Blit11(rx::Renderer11 *renderer) +Blit11::Blit11(Renderer11 *renderer) : mRenderer(renderer), mBlitShaderMap(compareBlitParameters), mSwizzleShaderMap(compareSwizzleParameters), mVertexBuffer(NULL), mPointSampler(NULL), mLinearSampler(NULL), mScissorEnabledRasterizerState(NULL), mScissorDisabledRasterizerState(NULL), mDepthStencilState(NULL), @@ -209,7 +209,7 @@ Blit11::Blit11(rx::Renderer11 *renderer) pointSamplerDesc.BorderColor[2] = 0.0f; pointSamplerDesc.BorderColor[3] = 0.0f; pointSamplerDesc.MinLOD = 0.0f; - pointSamplerDesc.MaxLOD = mRenderer->isLevel9() ? FLT_MAX : 0.0f; + pointSamplerDesc.MaxLOD = mRenderer->isLevel9() ? D3D11_FLOAT32_MAX : 0.0f; result = device->CreateSamplerState(&pointSamplerDesc, &mPointSampler); ASSERT(SUCCEEDED(result)); @@ -228,7 +228,7 @@ Blit11::Blit11(rx::Renderer11 *renderer) linearSamplerDesc.BorderColor[2] = 0.0f; linearSamplerDesc.BorderColor[3] = 0.0f; linearSamplerDesc.MinLOD = 0.0f; - linearSamplerDesc.MaxLOD = mRenderer->isLevel9() ? FLT_MAX : 0.0f; + linearSamplerDesc.MaxLOD = mRenderer->isLevel9() ? D3D11_FLOAT32_MAX : 0.0f; result = device->CreateSamplerState(&linearSamplerDesc, &mLinearSampler); ASSERT(SUCCEEDED(result)); @@ -468,8 +468,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT deviceContext->GSSetShader(shader.mGeometryShader, NULL, 0); // Unset the currently bound shader resource to avoid conflicts - ID3D11ShaderResourceView *const nullSRV = NULL; - deviceContext->PSSetShaderResources(0, 1, &nullSRV); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); // Apply render target mRenderer->setOneTimeRenderTarget(dest); @@ -485,7 +484,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT deviceContext->RSSetViewports(1, &viewport); // Apply textures - deviceContext->PSSetShaderResources(0, 1, &source); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source); // Apply samplers deviceContext->PSSetSamplers(0, 1, &mPointSampler); @@ -494,7 +493,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT deviceContext->Draw(drawCount, 0); // Unbind textures and render targets and vertex buffer - deviceContext->PSSetShaderResources(0, 1, &nullSRV); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); mRenderer->unapplyRenderTargets(); @@ -507,9 +506,9 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT return gl::Error(GL_NO_ERROR); } -bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize, - const gl::Rectangle *scissor, GLenum destFormat, GLenum filter) +gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor, GLenum destFormat, GLenum filter) { HRESULT result; ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); @@ -531,7 +530,7 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source if (i == mBlitShaderMap.end()) { UNREACHABLE(); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Could not find appropriate shader for internal texture blit."); } const Shader& shader = i->second; @@ -541,8 +540,7 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); if (FAILED(result)) { - ERR("Failed to map vertex buffer for texture copy, HRESULT: 0x%X.", result); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer for texture copy, HRESULT: 0x%X.", result); } UINT stride = 0; @@ -587,8 +585,7 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source deviceContext->GSSetShader(shader.mGeometryShader, NULL, 0); // Unset the currently bound shader resource to avoid conflicts - ID3D11ShaderResourceView *const nullSRV = NULL; - deviceContext->PSSetShaderResources(0, 1, &nullSRV); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); // Apply render target mRenderer->setOneTimeRenderTarget(dest); @@ -604,7 +601,7 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source deviceContext->RSSetViewports(1, &viewport); // Apply textures - deviceContext->PSSetShaderResources(0, 1, &source); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source); // Apply samplers ID3D11SamplerState *sampler = NULL; @@ -612,7 +609,10 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source { case GL_NEAREST: sampler = mPointSampler; break; case GL_LINEAR: sampler = mLinearSampler; break; - default: UNREACHABLE(); return false; + + default: + UNREACHABLE(); + return gl::Error(GL_OUT_OF_MEMORY, "Internal error, unknown blit filter mode."); } deviceContext->PSSetSamplers(0, 1, &sampler); @@ -620,7 +620,7 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source deviceContext->Draw(drawCount, 0); // Unbind textures and render targets and vertex buffer - deviceContext->PSSetShaderResources(0, 1, &nullSRV); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); mRenderer->unapplyRenderTargets(); @@ -630,21 +630,21 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source mRenderer->markAllStateDirty(); - return true; + return gl::Error(GL_NO_ERROR); } -bool Blit11::copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, - const gl::Rectangle *scissor) +gl::Error Blit11::copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor) { return copyDepthStencil(source, sourceSubresource, sourceArea, sourceSize, dest, destSubresource, destArea, destSize, scissor, true); } -bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize, - const gl::Rectangle *scissor) +gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor) { HRESULT result; ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); @@ -654,8 +654,7 @@ bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceAr result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); if (FAILED(result)) { - ERR("Failed to map vertex buffer for texture copy, HRESULT: 0x%X.", result); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer for texture copy, HRESULT: 0x%X.", result); } UINT stride = 0; @@ -700,8 +699,7 @@ bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceAr deviceContext->GSSetShader(NULL, NULL, 0); // Unset the currently bound shader resource to avoid conflicts - ID3D11ShaderResourceView *const nullSRV = NULL; - deviceContext->PSSetShaderResources(0, 1, &nullSRV); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); // Apply render target deviceContext->OMSetRenderTargets(0, NULL, dest); @@ -717,7 +715,7 @@ bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceAr deviceContext->RSSetViewports(1, &viewport); // Apply textures - deviceContext->PSSetShaderResources(0, 1, &source); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source); // Apply samplers deviceContext->PSSetSamplers(0, 1, &mPointSampler); @@ -726,7 +724,7 @@ bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceAr deviceContext->Draw(drawCount, 0); // Unbind textures and render targets and vertex buffer - deviceContext->PSSetShaderResources(0, 1, &nullSRV); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); mRenderer->unapplyRenderTargets(); @@ -736,21 +734,21 @@ bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceAr mRenderer->markAllStateDirty(); - return true; + return gl::Error(GL_NO_ERROR); } -bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, - const gl::Rectangle *scissor) +gl::Error Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor) { return copyDepthStencil(source, sourceSubresource, sourceArea, sourceSize, dest, destSubresource, destArea, destSize, scissor, false); } -bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, - const gl::Rectangle *scissor, bool stencilOnly) +gl::Error Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor, bool stencilOnly) { ID3D11Device *device = mRenderer->getDevice(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); @@ -764,7 +762,7 @@ bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubreso { SafeRelease(sourceStaging); SafeRelease(destStaging); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal staging textures for depth stencil blit."); } DXGI_FORMAT format = GetTextureFormat(source); @@ -785,23 +783,23 @@ bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubreso dxgiFormatInfo.depthBits % 8 == 0); } - D3D11_MAPPED_SUBRESOURCE sourceMapping, destMapping; - deviceContext->Map(sourceStaging, 0, D3D11_MAP_READ, 0, &sourceMapping); - deviceContext->Map(destStaging, 0, D3D11_MAP_WRITE, 0, &destMapping); + D3D11_MAPPED_SUBRESOURCE sourceMapping; + HRESULT result = deviceContext->Map(sourceStaging, 0, D3D11_MAP_READ, 0, &sourceMapping); + if (FAILED(result)) + { + SafeRelease(sourceStaging); + SafeRelease(destStaging); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal source staging texture for depth stencil blit, HRESULT: 0x%X.", result); + } - if (!sourceMapping.pData || !destMapping.pData) + D3D11_MAPPED_SUBRESOURCE destMapping; + result = deviceContext->Map(destStaging, 0, D3D11_MAP_WRITE, 0, &destMapping); + if (FAILED(result)) { - if (!sourceMapping.pData) - { - deviceContext->Unmap(sourceStaging, 0); - } - if (!destMapping.pData) - { - deviceContext->Unmap(destStaging, 0); - } + deviceContext->Unmap(sourceStaging, 0); SafeRelease(sourceStaging); SafeRelease(destStaging); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal destination staging texture for depth stencil blit, HRESULT: 0x%X.", result); } gl::Rectangle clippedDestArea(destArea.x, destArea.y, destArea.width, destArea.height); @@ -880,7 +878,7 @@ bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubreso SafeRelease(sourceStaging); SafeRelease(destStaging); - return true; + return gl::Error(GL_NO_ERROR); } bool Blit11::compareBlitParameters(const Blit11::BlitParameters &a, const Blit11::BlitParameters &b) @@ -1001,12 +999,12 @@ void Blit11::buildShaderMap() 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_RED, false, d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R pixel shader" )); + add3DBlitShaderToMap(GL_RG, false, d3d11::CompilePS(device, g_PS_PassthroughRG3D, "Blit11 3D RG pixel shader" )); add3DBlitShaderToMap(GL_RG_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRG3DUI, "Blit11 3D RG UI pixel shader" )); add3DBlitShaderToMap(GL_RG_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRG3DI, "Blit11 3D RG I pixel shader" )); + add3DBlitShaderToMap(GL_RED, false, d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R pixel shader" )); add3DBlitShaderToMap(GL_RED_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughR3DUI, "Blit11 3D R UI pixel shader" )); add3DBlitShaderToMap(GL_RED_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughR3DI, "Blit11 3D R I pixel shader" )); add3DBlitShaderToMap(GL_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D alpha pixel shader" )); 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 d6a0b795f4..821fa9d0cc 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h @@ -19,12 +19,6 @@ namespace rx { class Renderer11; -enum Filter -{ - Point, - Linear, -}; - class Blit11 { public: @@ -34,24 +28,24 @@ class Blit11 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, - const gl::Rectangle *scissor, GLenum destFormat, GLenum filter); - - bool copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, - const gl::Rectangle *scissor); + gl::Error copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor, GLenum destFormat, GLenum filter); - bool copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize, - const gl::Rectangle *scissor); - - bool copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, + gl::Error copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, const gl::Rectangle *scissor); + gl::Error copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor); + + gl::Error copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor); + private: - rx::Renderer11 *mRenderer; + Renderer11 *mRenderer; struct BlitParameters { @@ -60,9 +54,9 @@ class Blit11 bool m3DBlit; }; - bool copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, - const gl::Rectangle *scissor, bool stencilOnly); + gl::Error copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor, bool stencilOnly); static bool compareBlitParameters(const BlitParameters &a, const BlitParameters &b); 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 ecd4d4672b..5aab37938f 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp @@ -86,7 +86,7 @@ class Buffer11::BufferStorage11 virtual bool copyFromStorage(BufferStorage11 *source, size_t sourceOffset, size_t size, size_t destOffset) = 0; - virtual bool resize(size_t size, bool preserveData) = 0; + virtual gl::Error resize(size_t size, bool preserveData) = 0; virtual void *map(size_t offset, size_t length, GLbitfield access) = 0; virtual void unmap() = 0; @@ -112,17 +112,17 @@ class Buffer11::NativeBuffer11 : public Buffer11::BufferStorage11 virtual bool copyFromStorage(BufferStorage11 *source, size_t sourceOffset, size_t size, size_t destOffset); - virtual bool resize(size_t size, bool preserveData); + virtual gl::Error resize(size_t size, bool preserveData); 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); + gl::Error setData(D3D11_MAP mapMode, const uint8_t *data, size_t size, size_t offset); private: ID3D11Buffer *mNativeBuffer; - static void fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer, BufferUsage usage, unsigned int bufferSize); + static void fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer11 *renderer, BufferUsage usage, unsigned int bufferSize); }; // Pack storage represents internal storage for pack buffers. We implement pack buffers @@ -135,7 +135,7 @@ class Buffer11::PackStorage11 : public Buffer11::BufferStorage11 virtual bool copyFromStorage(BufferStorage11 *source, size_t sourceOffset, size_t size, size_t destOffset); - virtual bool resize(size_t size, bool preserveData); + virtual gl::Error resize(size_t size, bool preserveData); virtual void *map(size_t offset, size_t length, GLbitfield access); virtual void unmap(); @@ -144,7 +144,7 @@ class Buffer11::PackStorage11 : public Buffer11::BufferStorage11 private: - void flushQueuedPackCommand(); + gl::Error flushQueuedPackCommand(); ID3D11Texture2D *mStagingTexture; DXGI_FORMAT mTextureFormat; @@ -195,14 +195,14 @@ gl::Error Buffer11::setData(const void *data, size_t size, GLenum usage) return error; } -void *Buffer11::getData() +gl::Error Buffer11::getData(const uint8_t **outData) { NativeBuffer11 *stagingBuffer = getStagingBuffer(); if (!stagingBuffer) { // Out-of-memory - return NULL; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to get internal staging buffer."); } if (stagingBuffer->getDataRevision() > mResolvedDataRevision) @@ -211,7 +211,7 @@ void *Buffer11::getData() { if (!mResolvedData.resize(stagingBuffer->getSize())) { - return gl::error(GL_OUT_OF_MEMORY, (void*)NULL); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize data resolve buffer."); } } @@ -221,7 +221,7 @@ void *Buffer11::getData() HRESULT result = context->Map(stagingBuffer->getNativeBuffer(), 0, D3D11_MAP_READ, 0, &mappedResource); if (FAILED(result)) { - return gl::error(GL_OUT_OF_MEMORY, (void*)NULL); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer, result: 0x%X.", result); } memcpy(mResolvedData.data(), mappedResource.pData, stagingBuffer->getSize()); @@ -238,13 +238,14 @@ void *Buffer11::getData() { if (!mResolvedData.resize(mSize)) { - return gl::error(GL_OUT_OF_MEMORY, (void*)NULL); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize data resolve buffer."); } } ASSERT(mResolvedData.size() >= mSize); - return mResolvedData.data(); + *outData = mResolvedData.data(); + return gl::Error(GL_NO_ERROR); } gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset) @@ -265,15 +266,17 @@ gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset) if (stagingBuffer->getSize() < requiredSize) { bool preserveData = (offset > 0); - if (!stagingBuffer->resize(requiredSize, preserveData)) + gl::Error error = stagingBuffer->resize(requiredSize, preserveData); + if (error.isError()) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal staging buffer."); + return error; } } - if (!stagingBuffer->setData(D3D11_MAP_WRITE, reinterpret_cast<const uint8_t *>(data), size, offset)) + gl::Error error = stagingBuffer->setData(D3D11_MAP_WRITE, reinterpret_cast<const uint8_t *>(data), size, offset); + if (error.isError()) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to set data on internal staging buffer."); + return error; } stagingBuffer->setDataRevision(stagingBuffer->getDataRevision() + 1); @@ -411,7 +414,7 @@ void Buffer11::markBufferUsage() } } -Renderer* Buffer11::getRenderer() +RendererD3D* Buffer11::getRenderer() { return mRenderer; } @@ -527,7 +530,7 @@ Buffer11::BufferStorage11 *Buffer11::getBufferStorage(BufferUsage usage) // resize buffer if (directBuffer->getSize() < mSize) { - if (!directBuffer->resize(mSize, true)) + if (directBuffer->resize(mSize, true).isError()) { // Out of memory error return NULL; @@ -667,6 +670,9 @@ bool Buffer11::NativeBuffer11::copyFromStorage(BufferStorage11 *source, size_t s // Offset bounds are validated at the API layer ASSERT(sourceOffset + size <= destOffset + mBufferSize); memcpy(destPointer, sourcePointer, size); + + context->Unmap(mNativeBuffer, 0); + source->unmap(); } else { @@ -689,7 +695,7 @@ bool Buffer11::NativeBuffer11::copyFromStorage(BufferStorage11 *source, size_t s return createBuffer; } -bool Buffer11::NativeBuffer11::resize(size_t size, bool preserveData) +gl::Error Buffer11::NativeBuffer11::resize(size_t size, bool preserveData) { ID3D11Device *device = mRenderer->getDevice(); ID3D11DeviceContext *context = mRenderer->getDeviceContext(); @@ -702,7 +708,7 @@ bool Buffer11::NativeBuffer11::resize(size_t size, bool preserveData) if (FAILED(result)) { - return gl::error(GL_OUT_OF_MEMORY, false); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer, result: 0x%X.", result); } if (mNativeBuffer && preserveData) @@ -727,10 +733,10 @@ bool Buffer11::NativeBuffer11::resize(size_t size, bool preserveData) mBufferSize = bufferDesc.ByteWidth; - return true; + return gl::Error(GL_NO_ERROR); } -void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer, +void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer11 *renderer, BufferUsage usage, unsigned int bufferSize) { bufferDesc->ByteWidth = bufferSize; @@ -748,7 +754,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 (!static_cast<Renderer11 *>(renderer)->isLevel9()) + if (!renderer->isLevel9()) bufferDesc->BindFlags |= D3D11_BIND_STREAM_OUTPUT; bufferDesc->CPUAccessFlags = 0; break; @@ -797,7 +803,7 @@ 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) +gl::Error Buffer11::NativeBuffer11::setData(D3D11_MAP mapMode, const uint8_t *data, size_t size, size_t offset) { ID3D11DeviceContext *context = mRenderer->getDeviceContext(); @@ -805,7 +811,7 @@ bool Buffer11::NativeBuffer11::setData(D3D11_MAP mapMode, const uint8_t *data, s HRESULT result = context->Map(mNativeBuffer, 0, mapMode, 0, &mappedResource); if (FAILED(result)) { - return gl::error(GL_OUT_OF_MEMORY, false); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer, result: 0x%X.", result); } uint8_t *offsetBufferPointer = reinterpret_cast<uint8_t *>(mappedResource.pData) + offset; @@ -813,7 +819,7 @@ bool Buffer11::NativeBuffer11::setData(D3D11_MAP mapMode, const uint8_t *data, s context->Unmap(mNativeBuffer, 0); - return true; + return gl::Error(GL_NO_ERROR); } void Buffer11::NativeBuffer11::unmap() @@ -847,18 +853,18 @@ bool Buffer11::PackStorage11::copyFromStorage(BufferStorage11 *source, size_t so return false; } -bool Buffer11::PackStorage11::resize(size_t size, bool preserveData) +gl::Error Buffer11::PackStorage11::resize(size_t size, bool preserveData) { if (size != mBufferSize) { if (!mMemoryBuffer.resize(size)) { - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal buffer storage."); } mBufferSize = size; } - return true; + return gl::Error(GL_NO_ERROR); } void *Buffer11::PackStorage11::map(size_t offset, size_t length, GLbitfield access) @@ -869,7 +875,12 @@ void *Buffer11::PackStorage11::map(size_t offset, size_t length, GLbitfield acce // and if D3D packs the staging texture memory identically to how we would fill // the pack buffer according to the current pack state. - flushQueuedPackCommand(); + gl::Error error = flushQueuedPackCommand(); + if (error.isError()) + { + return NULL; + } + mDataModified = (mDataModified || (access & GL_MAP_WRITE_BIT) != 0); return mMemoryBuffer.data() + offset; @@ -882,7 +893,12 @@ void Buffer11::PackStorage11::unmap() gl::Error Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams ¶ms) { - flushQueuedPackCommand(); + gl::Error error = flushQueuedPackCommand(); + if (error.isError()) + { + return error; + } + mQueuedPackCommand = new PackPixelsParams(params); D3D11_TEXTURE2D_DESC textureDesc; @@ -947,15 +963,21 @@ gl::Error Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT s return gl::Error(GL_NO_ERROR); } -void Buffer11::PackStorage11::flushQueuedPackCommand() +gl::Error Buffer11::PackStorage11::flushQueuedPackCommand() { ASSERT(mMemoryBuffer.size() > 0); if (mQueuedPackCommand) { - mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, mMemoryBuffer.data()); + gl::Error error = mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, mMemoryBuffer.data()); SafeDelete(mQueuedPackCommand); + if (error.isError()) + { + return error; + } } + + return gl::Error(GL_NO_ERROR); } } 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 5f24fb4e2d..1c06bbf88a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h @@ -47,7 +47,7 @@ typedef size_t DataRevision; class Buffer11 : public BufferD3D { public: - Buffer11(rx::Renderer11 *renderer); + Buffer11(Renderer11 *renderer); virtual ~Buffer11(); static Buffer11 *makeBuffer11(BufferImpl *buffer); @@ -60,11 +60,11 @@ class Buffer11 : public BufferD3D // BufferD3D implementation virtual size_t getSize() const { return mSize; } virtual bool supportsDirectBinding() const; - virtual Renderer* getRenderer(); + RendererD3D *getRenderer() override; // BufferImpl implementation virtual gl::Error setData(const void* data, size_t size, GLenum usage); - virtual void *getData(); + gl::Error getData(const uint8_t **outData) override; virtual gl::Error setSubData(const void* data, size_t size, size_t offset); virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr); @@ -78,7 +78,7 @@ class Buffer11 : public BufferD3D class NativeBuffer11; class PackStorage11; - rx::Renderer11 *mRenderer; + Renderer11 *mRenderer; size_t mSize; BufferStorage11 *mMappedStorage; 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 765d34fd3f..7185a05506 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp @@ -104,7 +104,7 @@ Clear11::Clear11(Renderer11 *renderer) rsDesc.DepthBias = 0; rsDesc.DepthBiasClamp = 0.0f; rsDesc.SlopeScaledDepthBias = 0.0f; - rsDesc.DepthClipEnable = mRenderer->isLevel9(); + rsDesc.DepthClipEnable = renderer->isLevel9(); rsDesc.ScissorEnable = FALSE; rsDesc.MultisampleEnable = FALSE; rsDesc.AntialiasedLineEnable = FALSE; @@ -119,7 +119,6 @@ Clear11::Clear11(Renderer11 *renderer) memset(&mIntClearShader, 0, sizeof(ClearShader)); return; } - mUintClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_UINT, g_VS_ClearUint, g_PS_ClearUint ); mIntClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_SINT, g_VS_ClearSint, g_PS_ClearSint ); } @@ -154,7 +153,7 @@ Clear11::~Clear11() SafeRelease(mRasterizerState); } -gl::Error Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) +gl::Error Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer) { // First determine if a scissored clear is needed, this will always require drawing a quad. // @@ -217,10 +216,11 @@ gl::Error Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl:: gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(colorAttachment); if (attachment) { - RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(attachment); - if (!renderTarget) + RenderTarget11 *renderTarget = NULL; + gl::Error error = d3d11::GetAttachmentRenderTarget(attachment, &renderTarget); + if (error.isError()) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null."); + return error; } const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment->getInternalFormat()); @@ -290,10 +290,11 @@ gl::Error Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl:: gl::FramebufferAttachment *attachment = frameBuffer->getDepthOrStencilbuffer(); if (attachment) { - RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(attachment); - if (!renderTarget) + RenderTarget11 *renderTarget = NULL; + gl::Error error = d3d11::GetAttachmentRenderTarget(attachment, &renderTarget); + if (error.isError()) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil view pointer unexpectedly null."); + return error; } const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(attachment->getActualFormat()); 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 be8e187c40..a7e8fea56a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h @@ -32,7 +32,7 @@ class Clear11 ~Clear11(); // Clears the framebuffer with the supplied clear parameters, assumes that the framebuffer is currently applied. - gl::Error clearFramebuffer(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); + gl::Error clearFramebuffer(const gl::ClearParameters &clearParams, const 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 a841b52862..f44d934056 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp @@ -4,67 +4,229 @@ // found in the LICENSE file. // -// Fence11.cpp: Defines the rx::Fence11 class which implements rx::FenceImpl. +// Fence11.cpp: Defines the rx::FenceNV11 and rx::FenceSync11 classes which implement rx::FenceNVImpl and rx::FenceSyncImpl. #include "libGLESv2/renderer/d3d/d3d11/Fence11.h" #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #include "libGLESv2/main.h" +#include "common/utilities.h" + namespace rx { -Fence11::Fence11(rx::Renderer11 *renderer) +// +// Template helpers for set and test operations. +// + +template<class FenceClass> +gl::Error FenceSetHelper(FenceClass *fence) { - mRenderer = renderer; - mQuery = NULL; + if (!fence->mQuery) + { + D3D11_QUERY_DESC queryDesc; + queryDesc.Query = D3D11_QUERY_EVENT; + queryDesc.MiscFlags = 0; + + HRESULT result = fence->mRenderer->getDevice()->CreateQuery(&queryDesc, &fence->mQuery); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create event query, result: 0x%X.", result); + } + } + + fence->mRenderer->getDeviceContext()->End(fence->mQuery); + return gl::Error(GL_NO_ERROR); } -Fence11::~Fence11() +template <class FenceClass> +gl::Error FenceTestHelper(FenceClass *fence, bool flushCommandBuffer, GLboolean *outFinished) +{ + ASSERT(fence->mQuery); + + UINT getDataFlags = (flushCommandBuffer ? 0 : D3D11_ASYNC_GETDATA_DONOTFLUSH); + HRESULT result = fence->mRenderer->getDeviceContext()->GetData(fence->mQuery, NULL, 0, getDataFlags); + + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to get query data, result: 0x%X.", result); + } + else if (fence->mRenderer->isDeviceLost()) + { + return gl::Error(GL_OUT_OF_MEMORY, "Device was lost while querying result of an event query."); + } + + ASSERT(result == S_OK || result == S_FALSE); + *outFinished = ((result == S_OK) ? GL_TRUE : GL_FALSE); + return gl::Error(GL_NO_ERROR); +} + +// +// FenceNV11 +// + +FenceNV11::FenceNV11(Renderer11 *renderer) + : FenceNVImpl(), + mRenderer(renderer), + mQuery(NULL) +{ +} + +FenceNV11::~FenceNV11() { SafeRelease(mQuery); } -bool Fence11::isSet() const +gl::Error FenceNV11::set() { - return mQuery != NULL; + return FenceSetHelper(this); } -void Fence11::set() +gl::Error FenceNV11::test(bool flushCommandBuffer, GLboolean *outFinished) { - if (!mQuery) - { - D3D11_QUERY_DESC queryDesc; - queryDesc.Query = D3D11_QUERY_EVENT; - queryDesc.MiscFlags = 0; + return FenceTestHelper(this, flushCommandBuffer, outFinished); +} + +gl::Error FenceNV11::finishFence(GLboolean *outFinished) +{ + ASSERT(outFinished); - if (FAILED(mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery))) + while (*outFinished != GL_TRUE) + { + gl::Error error = test(true, outFinished); + if (error.isError()) { - return gl::error(GL_OUT_OF_MEMORY); + return error; } + + Sleep(0); } - mRenderer->getDeviceContext()->End(mQuery); + return gl::Error(GL_NO_ERROR); } -bool Fence11::test(bool flushCommandBuffer) +// +// FenceSync11 +// + +// Important note on accurate timers in Windows: +// +// QueryPerformanceCounter has a few major issues, including being 10x as expensive to call +// as timeGetTime on laptops and "jumping" during certain hardware events. +// +// See the comments at the top of the Chromium source file "chromium/src/base/time/time_win.cc" +// https://code.google.com/p/chromium/codesearch#chromium/src/base/time/time_win.cc +// +// We still opt to use QPC. In the present and moving forward, most newer systems will not suffer +// from buggy implementations. + +FenceSync11::FenceSync11(Renderer11 *renderer) + : FenceSyncImpl(), + mRenderer(renderer), + mQuery(NULL) { - ASSERT(mQuery); + LARGE_INTEGER counterFreqency = { 0 }; + BOOL success = QueryPerformanceFrequency(&counterFreqency); + UNUSED_ASSERTION_VARIABLE(success); + ASSERT(success); - UINT getDataFlags = (flushCommandBuffer ? 0 : D3D11_ASYNC_GETDATA_DONOTFLUSH); - HRESULT result = mRenderer->getDeviceContext()->GetData(mQuery, NULL, 0, getDataFlags); + mCounterFrequency = counterFreqency.QuadPart; +} - if (mRenderer->isDeviceLost()) +FenceSync11::~FenceSync11() +{ + SafeRelease(mQuery); +} + +gl::Error FenceSync11::set() +{ + return FenceSetHelper(this); +} + +gl::Error FenceSync11::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult) +{ + ASSERT(outResult); + + bool flushCommandBuffer = ((flags & GL_SYNC_FLUSH_COMMANDS_BIT) != 0); + + GLboolean result = GL_FALSE; + gl::Error error = FenceTestHelper(this, flushCommandBuffer, &result); + if (error.isError()) { - return gl::error(GL_OUT_OF_MEMORY, true); + *outResult = GL_WAIT_FAILED; + return error; } - ASSERT(result == S_OK || result == S_FALSE); - return (result == S_OK); + if (result == GL_TRUE) + { + *outResult = GL_ALREADY_SIGNALED; + return gl::Error(GL_NO_ERROR); + } + + if (timeout == 0) + { + *outResult = GL_TIMEOUT_EXPIRED; + return gl::Error(GL_NO_ERROR); + } + + LARGE_INTEGER currentCounter = { 0 }; + BOOL success = QueryPerformanceCounter(¤tCounter); + UNUSED_ASSERTION_VARIABLE(success); + ASSERT(success); + + LONGLONG timeoutInSeconds = static_cast<LONGLONG>(timeout) * static_cast<LONGLONG>(1000000ll); + LONGLONG endCounter = currentCounter.QuadPart + mCounterFrequency * timeoutInSeconds; + + while (currentCounter.QuadPart < endCounter && !result) + { + Sleep(0); + BOOL success = QueryPerformanceCounter(¤tCounter); + UNUSED_ASSERTION_VARIABLE(success); + ASSERT(success); + + error = FenceTestHelper(this, flushCommandBuffer, &result); + if (error.isError()) + { + *outResult = GL_WAIT_FAILED; + return error; + } + } + + if (currentCounter.QuadPart >= endCounter) + { + *outResult = GL_TIMEOUT_EXPIRED; + } + else + { + *outResult = GL_CONDITION_SATISFIED; + } + + return gl::Error(GL_NO_ERROR); } -bool Fence11::hasError() const +gl::Error FenceSync11::serverWait(GLbitfield flags, GLuint64 timeout) { - return mRenderer->isDeviceLost(); + // Because our API is currently designed to be called from a single thread, we don't need to do + // extra work for a server-side fence. GPU commands issued after the fence is created will always + // be processed after the fence is signaled. + return gl::Error(GL_NO_ERROR); } +gl::Error FenceSync11::getStatus(GLint *outResult) +{ + GLboolean result = GL_FALSE; + gl::Error error = FenceTestHelper(this, false, &result); + if (error.isError()) + { + // The spec does not specify any way to report errors during the status test (e.g. device lost) + // so we report the fence is unblocked in case of error or signaled. + *outResult = GL_SIGNALED; + + return error; + } + + *outResult = (result ? GL_SIGNALED : GL_UNSIGNALED); + return gl::Error(GL_NO_ERROR); } + +} // namespace rx diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.h index 50c7621776..1223a53b90 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.h @@ -4,10 +4,10 @@ // found in the LICENSE file. // -// Fence11.h: Defines the rx::Fence11 class which implements rx::FenceImpl. +// Fence11.h: Defines the rx::FenceNV11 and rx::FenceSync11 classes which implement rx::FenceNVImpl and rx::FenceSyncImpl. -#ifndef LIBGLESV2_RENDERER_Fence11_H_ -#define LIBGLESV2_RENDERER_Fence11_H_ +#ifndef LIBGLESV2_RENDERER_FENCE11_H_ +#define LIBGLESV2_RENDERER_FENCE11_H_ #include "libGLESv2/renderer/FenceImpl.h" @@ -15,22 +15,46 @@ namespace rx { class Renderer11; -class Fence11 : public FenceImpl +class FenceNV11 : public FenceNVImpl { public: - explicit Fence11(rx::Renderer11 *renderer); - virtual ~Fence11(); + explicit FenceNV11(Renderer11 *renderer); + virtual ~FenceNV11(); - bool isSet() const; - void set(); - bool test(bool flushCommandBuffer); - bool hasError() const; + gl::Error set(); + gl::Error test(bool flushCommandBuffer, GLboolean *outFinished); + gl::Error finishFence(GLboolean *outFinished); private: - DISALLOW_COPY_AND_ASSIGN(Fence11); + DISALLOW_COPY_AND_ASSIGN(FenceNV11); - rx::Renderer11 *mRenderer; + template<class T> friend gl::Error FenceSetHelper(T *fence); + template<class T> friend gl::Error FenceTestHelper(T *fence, bool flushCommandBuffer, GLboolean *outFinished); + + Renderer11 *mRenderer; + ID3D11Query *mQuery; +}; + +class FenceSync11 : public FenceSyncImpl +{ + public: + explicit FenceSync11(Renderer11 *renderer); + virtual ~FenceSync11(); + + gl::Error set(); + gl::Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult); + gl::Error serverWait(GLbitfield flags, GLuint64 timeout); + gl::Error getStatus(GLint *outResult); + + private: + DISALLOW_COPY_AND_ASSIGN(FenceSync11); + + template<class T> friend gl::Error FenceSetHelper(T *fence); + template<class T> friend gl::Error FenceTestHelper(T *fence, bool flushCommandBuffer, GLboolean *outFinished); + + Renderer11 *mRenderer; ID3D11Query *mQuery; + LONGLONG mCounterFrequency; }; } 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 7536713af4..e6f3e90683 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp @@ -9,6 +9,7 @@ #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #include "libGLESv2/renderer/d3d/d3d11/Image11.h" +#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h" #include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" @@ -22,15 +23,16 @@ namespace rx { Image11::Image11() + : mRenderer(NULL), + mDXGIFormat(DXGI_FORMAT_UNKNOWN), + mStagingTexture(NULL), + mStagingSubresource(0), + mRecoverFromStorage(false), + mAssociatedStorage(NULL), + mAssociatedImageIndex(gl::ImageIndex::MakeInvalid()), + mRecoveredFromStorageCount(0) + { - mStagingTexture = NULL; - mRenderer = NULL; - mDXGIFormat = DXGI_FORMAT_UNKNOWN; - mRecoverFromStorage = false; - mAssociatedStorage = NULL; - mAssociatedStorageLevel = 0; - mAssociatedStorageLayerTarget = 0; - mRecoveredFromStorageCount = 0; } Image11::~Image11() @@ -41,11 +43,11 @@ Image11::~Image11() Image11 *Image11::makeImage11(Image *img) { - ASSERT(HAS_DYNAMIC_TYPE(rx::Image11*, img)); - return static_cast<rx::Image11*>(img); + ASSERT(HAS_DYNAMIC_TYPE(Image11*, img)); + return static_cast<Image11*>(img); } -void Image11::generateMipmap(Image11 *dest, Image11 *src) +gl::Error Image11::generateMipmap(Image11 *dest, Image11 *src) { ASSERT(src->getDXGIFormat() == dest->getDXGIFormat()); ASSERT(src->getWidth() == 1 || src->getWidth() / 2 == dest->getWidth()); @@ -55,21 +57,18 @@ void Image11::generateMipmap(Image11 *dest, Image11 *src) ASSERT(dxgiFormatInfo.mipGenerationFunction != NULL); D3D11_MAPPED_SUBRESOURCE destMapped; - HRESULT destMapResult = dest->map(D3D11_MAP_WRITE, &destMapped); - if (FAILED(destMapResult)) + gl::Error error = dest->map(D3D11_MAP_WRITE, &destMapped); + if (error.isError()) { - ERR("Failed to map destination image for mip map generation. HRESULT:0x%X", destMapResult); - return; + return error; } D3D11_MAPPED_SUBRESOURCE srcMapped; - HRESULT srcMapResult = src->map(D3D11_MAP_READ, &srcMapped); - if (FAILED(srcMapResult)) + error = src->map(D3D11_MAP_READ, &srcMapped); + if (error.isError()) { - ERR("Failed to map source image for mip map generation. HRESULT:0x%X", srcMapResult); - dest->unmap(); - return; + return error; } const uint8_t *sourceData = reinterpret_cast<const uint8_t*>(srcMapped.pData); @@ -83,6 +82,8 @@ void Image11::generateMipmap(Image11 *dest, Image11 *src) src->unmap(); dest->markDirty(); + + return gl::Error(GL_NO_ERROR); } bool Image11::isDirty() const @@ -99,32 +100,10 @@ bool Image11::isDirty() const return mDirty; } -bool Image11::copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +gl::Error Image11::copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box ®ion) { - TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage); - return copyToStorageImpl(storage11, level, 0, xoffset, yoffset, width, height); -} + TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(storage); -bool Image11::copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) -{ - TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage); - return copyToStorageImpl(storage11, level, face, xoffset, yoffset, width, height); -} - -bool Image11::copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) -{ - TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage); - return copyToStorageImpl(storage11, level, 0, xoffset, yoffset, width, height); -} - -bool Image11::copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint arrayLayer, GLsizei width, GLsizei height) -{ - TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage); - return copyToStorageImpl(storage11, level, arrayLayer, xoffset, yoffset, width, height); -} - -bool Image11::copyToStorageImpl(TextureStorage11 *storage11, int level, int layerTarget, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) -{ // 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. @@ -134,23 +113,38 @@ bool Image11::copyToStorageImpl(TextureStorage11 *storage11, int level, int laye 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); + gl::Error error = storage11->releaseAssociatedImage(index, this); + if (error.isError()) + { + return error; + } + } + + ID3D11Resource *stagingTexture = NULL; + unsigned int stagingSubresourceIndex = 0; + gl::Error error = getStagingTexture(&stagingTexture, &stagingSubresourceIndex); + if (error.isError()) + { + return error; } - bool updateSubresourceSuccess = storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, layerTarget, xoffset, yoffset, 0, width, height, 1); + error = storage11->updateSubresourceLevel(stagingTexture, stagingSubresourceIndex, index, region); + if (error.isError()) + { + return error; + } // Once the image data has been copied into the Storage, we can release it locally. - if (attemptToReleaseStagingTexture && updateSubresourceSuccess) + if (attemptToReleaseStagingTexture) { - storage11->associateImage(this, level, layerTarget); + storage11->associateImage(this, index); releaseStagingTexture(); mRecoverFromStorage = true; mAssociatedStorage = storage11; - mAssociatedStorageLevel = level; - mAssociatedStorageLayerTarget = layerTarget; + mAssociatedImageIndex = index; } - return updateSubresourceSuccess; + return gl::Error(GL_NO_ERROR); } bool Image11::isAssociatedStorageValid(TextureStorage11* textureStorage) const @@ -158,13 +152,17 @@ bool Image11::isAssociatedStorageValid(TextureStorage11* textureStorage) const return (mAssociatedStorage == textureStorage); } -bool Image11::recoverFromAssociatedStorage() +gl::Error Image11::recoverFromAssociatedStorage() { if (mRecoverFromStorage) { - createStagingTexture(); + gl::Error error = createStagingTexture(); + if (error.isError()) + { + return error; + } - bool textureStorageCorrect = mAssociatedStorage->isAssociatedImageValid(mAssociatedStorageLevel, mAssociatedStorageLayerTarget, this); + bool textureStorageCorrect = mAssociatedStorage->isAssociatedImageValid(mAssociatedImageIndex, 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. @@ -173,17 +171,21 @@ bool Image11::recoverFromAssociatedStorage() if (textureStorageCorrect) { // CopySubResource from the Storage to the Staging texture - mAssociatedStorage->copySubresourceLevel(mStagingTexture, mStagingSubresource, mAssociatedStorageLevel, mAssociatedStorageLayerTarget, 0, 0, 0, mWidth, mHeight, mDepth); + gl::Box region(0, 0, 0, mWidth, mHeight, mDepth); + error = mAssociatedStorage->copySubresourceLevel(mStagingTexture, mStagingSubresource, mAssociatedImageIndex, region); + if (error.isError()) + { + return error; + } + mRecoveredFromStorageCount += 1; } // Reset all the recovery parameters, even if the texture storage association is broken. disassociateStorage(); - - return textureStorageCorrect; } - return false; + return gl::Error(GL_NO_ERROR); } void Image11::disassociateStorage() @@ -191,16 +193,15 @@ void Image11::disassociateStorage() if (mRecoverFromStorage) { // Make the texturestorage release the Image11 too - mAssociatedStorage->disassociateImage(mAssociatedStorageLevel, mAssociatedStorageLayerTarget, this); + mAssociatedStorage->disassociateImage(mAssociatedImageIndex, this); mRecoverFromStorage = false; mAssociatedStorage = NULL; - mAssociatedStorageLevel = 0; - mAssociatedStorageLayerTarget = 0; + mAssociatedImageIndex = gl::ImageIndex::MakeInvalid(); } } -bool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) +bool Image11::redefine(RendererD3D *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) { if (mWidth != width || mHeight != height || @@ -227,7 +228,7 @@ bool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat, mActualFormat = dxgiFormatInfo.internalFormat; mRenderable = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN); - SafeRelease(mStagingTexture); + releaseStagingTexture(); mDirty = (formatInfo.dataInitializerFunction != NULL); return true; @@ -247,8 +248,8 @@ DXGI_FORMAT Image11::getDXGIFormat() const // Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input // into the target pixel rectangle. -void Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - GLint unpackAlignment, GLenum type, const void *input) +gl::Error Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLint unpackAlignment, GLenum type, const void *input) { const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); GLsizei inputRowPitch = formatInfo.computeRowPitch(type, width, unpackAlignment); @@ -261,11 +262,10 @@ void Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei widt LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(type); D3D11_MAPPED_SUBRESOURCE mappedImage; - HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); - if (FAILED(result)) + gl::Error error = map(D3D11_MAP_WRITE, &mappedImage); + if (error.isError()) { - ERR("Could not map image for loading."); - return; + return error; } uint8_t* offsetMappedData = (reinterpret_cast<uint8_t*>(mappedImage.pData) + (yoffset * mappedImage.RowPitch + xoffset * outputPixelSize + zoffset * mappedImage.DepthPitch)); @@ -274,10 +274,12 @@ void Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei widt offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch); unmap(); + + return gl::Error(GL_NO_ERROR); } -void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - const void *input) +gl::Error Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + const void *input) { const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, width, 1); @@ -295,11 +297,10 @@ void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GL LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(GL_UNSIGNED_BYTE); D3D11_MAPPED_SUBRESOURCE mappedImage; - HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); - if (FAILED(result)) + gl::Error error = map(D3D11_MAP_WRITE, &mappedImage); + if (error.isError()) { - ERR("Could not map image for loading."); - return; + return error; } uint8_t* offsetMappedData = reinterpret_cast<uint8_t*>(mappedImage.pData) + ((yoffset / outputBlockHeight) * mappedImage.RowPitch + @@ -311,81 +312,130 @@ void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GL offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch); unmap(); + + return gl::Error(GL_NO_ERROR); } -void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) +gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source) { - gl::FramebufferAttachment *colorbuffer = source->getReadColorbuffer(); + RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(source); + ASSERT(sourceRenderTarget->getTexture()); - if (colorbuffer && colorbuffer->getActualFormat() == mActualFormat) + UINT subresourceIndex = sourceRenderTarget->getSubresourceIndex(); + ID3D11Texture2D *sourceTexture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(sourceRenderTarget->getTexture()); + + if (!sourceTexture2D) { - // No conversion needed-- use copyback fastpath - ID3D11Texture2D *colorBufferTexture = NULL; - unsigned int subresourceIndex = 0; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the ID3D11Texture2D from the source RenderTarget."); + } + + gl::Error error = copy(xoffset, yoffset, zoffset, sourceArea, sourceTexture2D, subresourceIndex); + + SafeRelease(sourceTexture2D); + + return error; +} + +gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, const gl::ImageIndex &sourceIndex, TextureStorage *source) +{ + TextureStorage11 *sourceStorage11 = TextureStorage11::makeTextureStorage11(source); + + UINT subresourceIndex = sourceStorage11->getSubresourceIndex(sourceIndex); + ID3D11Resource *resource = NULL; + gl::Error error = sourceStorage11->getResource(&resource); + if (error.isError()) + { + return error; + } + + ID3D11Texture2D *sourceTexture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(resource); + + if (!sourceTexture2D) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the ID3D11Texture2D from the source TextureStorage."); + } + + error = copy(xoffset, yoffset, zoffset, sourceArea, sourceTexture2D, subresourceIndex); + + SafeRelease(sourceTexture2D); + + return error; +} + +gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, ID3D11Texture2D *source, UINT sourceSubResource) +{ + D3D11_TEXTURE2D_DESC textureDesc; + source->GetDesc(&textureDesc); - if (mRenderer->getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture)) + if (textureDesc.Format == mDXGIFormat) + { + // No conversion needed-- use copyback fastpath + ID3D11Resource *stagingTexture = NULL; + unsigned int stagingSubresourceIndex = 0; + gl::Error error = getStagingTexture(&stagingTexture, &stagingSubresourceIndex); + if (error.isError()) { - D3D11_TEXTURE2D_DESC textureDesc; - colorBufferTexture->GetDesc(&textureDesc); + return error; + } - ID3D11Device *device = mRenderer->getDevice(); - ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + ID3D11Device *device = mRenderer->getDevice(); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - ID3D11Texture2D* srcTex = NULL; - if (textureDesc.SampleDesc.Count > 1) - { - D3D11_TEXTURE2D_DESC resolveDesc; - resolveDesc.Width = textureDesc.Width; - resolveDesc.Height = textureDesc.Height; - resolveDesc.MipLevels = 1; - resolveDesc.ArraySize = 1; - resolveDesc.Format = textureDesc.Format; - resolveDesc.SampleDesc.Count = 1; - resolveDesc.SampleDesc.Quality = 0; - resolveDesc.Usage = D3D11_USAGE_DEFAULT; - resolveDesc.BindFlags = 0; - resolveDesc.CPUAccessFlags = 0; - resolveDesc.MiscFlags = 0; - - HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex); - if (FAILED(result)) - { - ERR("Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result); - return; - } - - deviceContext->ResolveSubresource(srcTex, 0, colorBufferTexture, subresourceIndex, textureDesc.Format); - subresourceIndex = 0; - } - else + UINT subresourceAfterResolve = sourceSubResource; + + ID3D11Texture2D* srcTex = NULL; + if (textureDesc.SampleDesc.Count > 1) + { + D3D11_TEXTURE2D_DESC resolveDesc; + resolveDesc.Width = textureDesc.Width; + resolveDesc.Height = textureDesc.Height; + resolveDesc.MipLevels = 1; + resolveDesc.ArraySize = 1; + resolveDesc.Format = textureDesc.Format; + resolveDesc.SampleDesc.Count = 1; + resolveDesc.SampleDesc.Quality = 0; + resolveDesc.Usage = D3D11_USAGE_DEFAULT; + resolveDesc.BindFlags = 0; + resolveDesc.CPUAccessFlags = 0; + resolveDesc.MiscFlags = 0; + + HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex); + if (FAILED(result)) { - srcTex = colorBufferTexture; - srcTex->AddRef(); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result); } - D3D11_BOX srcBox; - srcBox.left = x; - srcBox.right = x + width; - srcBox.top = y; - srcBox.bottom = y + height; - srcBox.front = 0; - srcBox.back = 1; + deviceContext->ResolveSubresource(srcTex, 0, source, sourceSubResource, textureDesc.Format); + subresourceAfterResolve = 0; + } + else + { + srcTex = source; + } - deviceContext->CopySubresourceRegion(mStagingTexture, 0, xoffset, yoffset, zoffset, srcTex, subresourceIndex, &srcBox); + D3D11_BOX srcBox; + srcBox.left = sourceArea.x; + srcBox.right = sourceArea.x + sourceArea.width; + srcBox.top = sourceArea.y; + srcBox.bottom = sourceArea.y + sourceArea.height; + srcBox.front = 0; + srcBox.back = 1; + deviceContext->CopySubresourceRegion(stagingTexture, stagingSubresourceIndex, xoffset, yoffset, zoffset, srcTex, subresourceAfterResolve, &srcBox); + + if (textureDesc.SampleDesc.Count > 1) + { SafeRelease(srcTex); - SafeRelease(colorBufferTexture); } } else { // This format requires conversion, so we must copy the texture to staging and manually convert via readPixels D3D11_MAPPED_SUBRESOURCE mappedImage; - HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); - if (FAILED(result)) + gl::Error error = map(D3D11_MAP_WRITE, &mappedImage); + if (error.isError()) { - ERR("Failed to map texture for Image11::copy, HRESULT: 0x%X.", result); - return; + return error; } // determine the offset coordinate into the destination buffer @@ -394,17 +444,32 @@ void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); - mRenderer->readPixels(source, x, y, width, height, formatInfo.format, formatInfo.type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset); + error = mRenderer->readTextureData(source, sourceSubResource, sourceArea, formatInfo.format, formatInfo.type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset); unmap(); + + if (error.isError()) + { + return error; + } } + + mDirty = true; + + return gl::Error(GL_NO_ERROR); } -ID3D11Resource *Image11::getStagingTexture() +gl::Error Image11::getStagingTexture(ID3D11Resource **outStagingTexture, unsigned int *outSubresourceIndex) { - createStagingTexture(); + gl::Error error = createStagingTexture(); + if (error.isError()) + { + return error; + } - return mStagingTexture; + *outStagingTexture = mStagingTexture; + *outSubresourceIndex = mStagingSubresource; + return gl::Error(GL_NO_ERROR); } void Image11::releaseStagingTexture() @@ -412,149 +477,149 @@ void Image11::releaseStagingTexture() SafeRelease(mStagingTexture); } -unsigned int Image11::getStagingSubresource() -{ - createStagingTexture(); - - return mStagingSubresource; -} - -void Image11::createStagingTexture() +gl::Error Image11::createStagingTexture() { if (mStagingTexture) { - return; + return gl::Error(GL_NO_ERROR); } + ASSERT(mWidth > 0 && mHeight > 0 && mDepth > 0); + const DXGI_FORMAT dxgiFormat = getDXGIFormat(); - if (mWidth > 0 && mHeight > 0 && mDepth > 0) - { - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result; + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result; - int lodOffset = 1; - GLsizei width = mWidth; - GLsizei height = mHeight; + int lodOffset = 1; + GLsizei width = mWidth; + GLsizei height = mHeight; - // adjust size if needed for compressed textures - d3d11::MakeValidSize(false, dxgiFormat, &width, &height, &lodOffset); + // adjust size if needed for compressed textures + d3d11::MakeValidSize(false, dxgiFormat, &width, &height, &lodOffset); - if (mTarget == GL_TEXTURE_3D) + if (mTarget == GL_TEXTURE_3D) + { + ID3D11Texture3D *newTexture = NULL; + + D3D11_TEXTURE3D_DESC desc; + desc.Width = width; + desc.Height = height; + desc.Depth = mDepth; + desc.MipLevels = lodOffset + 1; + desc.Format = dxgiFormat; + desc.Usage = D3D11_USAGE_STAGING; + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + desc.MiscFlags = 0; + + if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) { - ID3D11Texture3D *newTexture = NULL; - - D3D11_TEXTURE3D_DESC desc; - desc.Width = width; - desc.Height = height; - desc.Depth = mDepth; - desc.MipLevels = lodOffset + 1; - desc.Format = dxgiFormat; - desc.Usage = D3D11_USAGE_STAGING; - desc.BindFlags = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; - desc.MiscFlags = 0; - - if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) - { - std::vector<D3D11_SUBRESOURCE_DATA> initialData; - std::vector< std::vector<BYTE> > textureData; - d3d11::GenerateInitialTextureData(mInternalFormat, width, height, mDepth, - lodOffset + 1, &initialData, &textureData); + std::vector<D3D11_SUBRESOURCE_DATA> initialData; + std::vector< std::vector<BYTE> > textureData; + d3d11::GenerateInitialTextureData(mInternalFormat, width, height, mDepth, + lodOffset + 1, &initialData, &textureData); - result = device->CreateTexture3D(&desc, initialData.data(), &newTexture); - } - else - { - result = device->CreateTexture3D(&desc, NULL, &newTexture); - } - - if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - ERR("Creating image failed."); - return gl::error(GL_OUT_OF_MEMORY); - } - - mStagingTexture = newTexture; - mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); + result = device->CreateTexture3D(&desc, initialData.data(), &newTexture); } - else if (mTarget == GL_TEXTURE_2D || mTarget == GL_TEXTURE_2D_ARRAY || mTarget == GL_TEXTURE_CUBE_MAP) + else { - ID3D11Texture2D *newTexture = NULL; - - D3D11_TEXTURE2D_DESC desc; - desc.Width = width; - desc.Height = height; - desc.MipLevels = lodOffset + 1; - desc.ArraySize = 1; - desc.Format = dxgiFormat; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_STAGING; - desc.BindFlags = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; - desc.MiscFlags = 0; - - if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) - { - std::vector<D3D11_SUBRESOURCE_DATA> initialData; - std::vector< std::vector<BYTE> > textureData; - d3d11::GenerateInitialTextureData(mInternalFormat, width, height, 1, - lodOffset + 1, &initialData, &textureData); + result = device->CreateTexture3D(&desc, NULL, &newTexture); + } - result = device->CreateTexture2D(&desc, initialData.data(), &newTexture); - } - else - { - result = device->CreateTexture2D(&desc, NULL, &newTexture); - } + if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create staging texture, result: 0x%X.", result); + } - if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - ERR("Creating image failed."); - return gl::error(GL_OUT_OF_MEMORY); - } + mStagingTexture = newTexture; + mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); + } + else if (mTarget == GL_TEXTURE_2D || mTarget == GL_TEXTURE_2D_ARRAY || mTarget == GL_TEXTURE_CUBE_MAP) + { + ID3D11Texture2D *newTexture = NULL; + + D3D11_TEXTURE2D_DESC desc; + desc.Width = width; + desc.Height = height; + desc.MipLevels = lodOffset + 1; + desc.ArraySize = 1; + desc.Format = dxgiFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_STAGING; + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + desc.MiscFlags = 0; + + if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) + { + std::vector<D3D11_SUBRESOURCE_DATA> initialData; + std::vector< std::vector<BYTE> > textureData; + d3d11::GenerateInitialTextureData(mInternalFormat, width, height, 1, + lodOffset + 1, &initialData, &textureData); - mStagingTexture = newTexture; - mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); + result = device->CreateTexture2D(&desc, initialData.data(), &newTexture); } else { - UNREACHABLE(); + result = device->CreateTexture2D(&desc, NULL, &newTexture); } + + if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create staging texture, result: 0x%X.", result); + } + + mStagingTexture = newTexture; + mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); + } + else + { + UNREACHABLE(); } mDirty = false; + return gl::Error(GL_NO_ERROR); } -HRESULT Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map) +gl::Error 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; + gl::Error error = recoverFromAssociatedStorage(); + if (error.isError()) + { + return error; + } - if (mStagingTexture) + ID3D11Resource *stagingTexture = NULL; + unsigned int subresourceIndex = 0; + error = getStagingTexture(&stagingTexture, &subresourceIndex); + if (error.isError()) { - ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - result = deviceContext->Map(mStagingTexture, mStagingSubresource, mapType, 0, map); + return error; + } - // this can fail if the device is removed (from TDR) - if (d3d11::isDeviceLostError(result)) - { - mRenderer->notifyDeviceLost(); - } - else if (SUCCEEDED(result)) - { - mDirty = true; - } + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + ASSERT(mStagingTexture); + HRESULT result = deviceContext->Map(stagingTexture, subresourceIndex, mapType, 0, map); + + // this can fail if the device is removed (from TDR) + if (d3d11::isDeviceLostError(result)) + { + mRenderer->notifyDeviceLost(); + } + else if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map staging texture, result: 0x%X.", result); } - return result; + mDirty = true; + + return gl::Error(GL_NO_ERROR); } void Image11::unmap() 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 a76a61f036..a936e6d7b2 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h @@ -11,6 +11,7 @@ #define LIBGLESV2_RENDERER_IMAGE11_H_ #include "libGLESv2/renderer/d3d/ImageD3D.h" +#include "libGLESv2/ImageIndex.h" #include "common/debug.h" @@ -21,7 +22,6 @@ class Framebuffer; namespace rx { -class Renderer; class Renderer11; class TextureStorage11; @@ -33,42 +33,41 @@ class Image11 : public ImageD3D static Image11 *makeImage11(Image *img); - static void generateMipmap(Image11 *dest, Image11 *src); + static gl::Error generateMipmap(Image11 *dest, Image11 *src); virtual bool isDirty() const; - 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 gl::Error copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box ®ion); - virtual bool redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease); + bool redefine(RendererD3D *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) override; DXGI_FORMAT getDXGIFormat() const; - - virtual void loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - GLint unpackAlignment, GLenum type, const void *input); - virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - const void *input); - virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); + virtual gl::Error loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLint unpackAlignment, GLenum type, const void *input); + virtual gl::Error loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + const void *input); - bool recoverFromAssociatedStorage(); + virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source); + virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, + const gl::ImageIndex &sourceIndex, TextureStorage *source); + + gl::Error recoverFromAssociatedStorage(); bool isAssociatedStorageValid(TextureStorage11* textureStorage) const; void disassociateStorage(); protected: - HRESULT map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map); + gl::Error map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map); void unmap(); private: DISALLOW_COPY_AND_ASSIGN(Image11); - bool copyToStorageImpl(TextureStorage11 *storage11, int level, int layerTarget, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + gl::Error copyToStorageImpl(TextureStorage11 *storage11, const gl::ImageIndex &index, const gl::Box ®ion); + gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, ID3D11Texture2D *source, UINT sourceSubResource); - ID3D11Resource *getStagingTexture(); - unsigned int getStagingSubresource(); - void createStagingTexture(); + gl::Error getStagingTexture(ID3D11Resource **outStagingTexture, unsigned int *outSubresourceIndex); + gl::Error createStagingTexture(); void releaseStagingTexture(); Renderer11 *mRenderer; @@ -79,8 +78,7 @@ class Image11 : public ImageD3D bool mRecoverFromStorage; TextureStorage11 *mAssociatedStorage; - int mAssociatedStorageLevel; - int mAssociatedStorageLayerTarget; + gl::ImageIndex mAssociatedImageIndex; unsigned int mRecoveredFromStorageCount; }; 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 f7c2b38e7e..3351df5ec1 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h @@ -40,7 +40,7 @@ class IndexBuffer11 : public IndexBuffer private: DISALLOW_COPY_AND_ASSIGN(IndexBuffer11); - rx::Renderer11 *const mRenderer; + Renderer11 *const mRenderer; ID3D11Buffer *mBuffer; unsigned int mBufferSize; 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 d835e4fa68..ff90a6a69a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp @@ -12,6 +12,7 @@ #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/ProgramD3D.h" #include "libGLESv2/renderer/d3d/VertexDataManager.h" #include "libGLESv2/ProgramBinary.h" #include "libGLESv2/VertexAttribute.h" @@ -137,7 +138,16 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl { gl::VertexFormat shaderInputLayout[gl::MAX_VERTEX_ATTRIBS]; GetInputLayout(attributes, shaderInputLayout); - ShaderExecutable11 *shader = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutableForInputLayout(shaderInputLayout)); + ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary->getImplementation()); + + ShaderExecutable *shader = NULL; + gl::Error error = programD3D->getVertexExecutableForInputLayout(shaderInputLayout, &shader); + if (error.isError()) + { + return error; + } + + ShaderExecutable *shader11 = ShaderExecutable11::makeShaderExecutable11(shader); D3D11_INPUT_ELEMENT_DESC descs[gl::MAX_VERTEX_ATTRIBS]; for (unsigned int j = 0; j < ilKey.elementCount; ++j) @@ -145,7 +155,7 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl descs[j] = ilKey.elements[j].desc; } - HRESULT result = mDevice->CreateInputLayout(descs, ilKey.elementCount, shader->getFunction(), shader->getLength(), &inputLayout); + HRESULT result = mDevice->CreateInputLayout(descs, ilKey.elementCount, shader11->getFunction(), shader11->getLength(), &inputLayout); if (FAILED(result)) { return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal input layout, HRESULT: 0x%08x", result); 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 a4e84f91c2..6a3d3475ee 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp @@ -33,12 +33,38 @@ namespace rx PixelTransfer11::PixelTransfer11(Renderer11 *renderer) : mRenderer(renderer), + mResourcesLoaded(false), mBufferToTextureVS(NULL), mBufferToTextureGS(NULL), mParamsConstantBuffer(NULL), mCopyRasterizerState(NULL), mCopyDepthStencilState(NULL) { +} + +PixelTransfer11::~PixelTransfer11() +{ + for (auto shaderMapIt = mBufferToTexturePSMap.begin(); shaderMapIt != mBufferToTexturePSMap.end(); shaderMapIt++) + { + SafeRelease(shaderMapIt->second); + } + + mBufferToTexturePSMap.clear(); + + SafeRelease(mBufferToTextureVS); + SafeRelease(mBufferToTextureGS); + SafeRelease(mParamsConstantBuffer); + SafeRelease(mCopyRasterizerState); + SafeRelease(mCopyDepthStencilState); +} + +gl::Error PixelTransfer11::loadResources() +{ + if (mResourcesLoaded) + { + return gl::Error(GL_NO_ERROR); + } + HRESULT result = S_OK; ID3D11Device *device = mRenderer->getDevice(); @@ -56,6 +82,10 @@ PixelTransfer11::PixelTransfer11(Renderer11 *renderer) result = device->CreateRasterizerState(&rasterDesc, &mCopyRasterizerState); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal pixel transfer rasterizer state, result: 0x%X.", result); + } D3D11_DEPTH_STENCIL_DESC depthStencilDesc; depthStencilDesc.DepthEnable = true; @@ -75,9 +105,13 @@ PixelTransfer11::PixelTransfer11(Renderer11 *renderer) result = device->CreateDepthStencilState(&depthStencilDesc, &mCopyDepthStencilState); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal pixel transfer depth stencil state, result: 0x%X.", result); + } D3D11_BUFFER_DESC constantBufferDesc = { 0 }; - constantBufferDesc.ByteWidth = rx::roundUp<UINT>(sizeof(CopyShaderParams), 32u); + constantBufferDesc.ByteWidth = roundUp<UINT>(sizeof(CopyShaderParams), 32u); constantBufferDesc.Usage = D3D11_USAGE_DYNAMIC; constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; constantBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; @@ -86,34 +120,39 @@ PixelTransfer11::PixelTransfer11(Renderer11 *renderer) result = device->CreateBuffer(&constantBufferDesc, NULL, &mParamsConstantBuffer); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal pixel transfer constant buffer, result: 0x%X.", result); + } d3d11::SetDebugName(mParamsConstantBuffer, "PixelTransfer11 constant buffer"); - StructZero(&mParamsData); - // init shaders - if (mRenderer->isLevel9()) - return; - mBufferToTextureVS = d3d11::CompileVS(device, g_VS_BufferToTexture, "BufferToTexture VS"); - mBufferToTextureGS = d3d11::CompileGS(device, g_GS_BufferToTexture, "BufferToTexture GS"); + if (!mBufferToTextureVS) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture vertex shader."); + } - buildShaderMap(); -} + if (!mRenderer->isLevel9()) + { + mBufferToTextureGS = d3d11::CompileGS(device, g_GS_BufferToTexture, "BufferToTexture GS"); + if (!mBufferToTextureGS) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture geometry shader."); + } + } -PixelTransfer11::~PixelTransfer11() -{ - for (auto shaderMapIt = mBufferToTexturePSMap.begin(); shaderMapIt != mBufferToTexturePSMap.end(); shaderMapIt++) + gl::Error error = buildShaderMap(); + if (error.isError()) { - SafeRelease(shaderMapIt->second); + return error; } - mBufferToTexturePSMap.clear(); + StructZero(&mParamsData); - SafeRelease(mBufferToTextureVS); - SafeRelease(mBufferToTextureGS); - SafeRelease(mParamsConstantBuffer); - SafeRelease(mCopyRasterizerState); - SafeRelease(mCopyDepthStencilState); + mResourcesLoaded = true; + + return gl::Error(GL_NO_ERROR); } void PixelTransfer11::setBufferToTextureCopyParams(const gl::Box &destArea, const gl::Extents &destSize, GLenum internalFormat, @@ -138,18 +177,21 @@ void PixelTransfer11::setBufferToTextureCopyParams(const gl::Box &destArea, cons parametersOut->PositionScale[1] = -2.0f / static_cast<float>(destSize.height); } -bool PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) +gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, + GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) { - gl::Extents destSize = destRenderTarget->getExtents(); - - if (destArea.x < 0 || destArea.x + destArea.width > destSize.width || - destArea.y < 0 || destArea.y + destArea.height > destSize.height || - destArea.z < 0 || destArea.z + destArea.depth > destSize.depth ) + gl::Error error = loadResources(); + if (error.isError()) { - return false; + return error; } + gl::Extents destSize = destRenderTarget->getExtents(); + + ASSERT(destArea.x >= 0 && destArea.x + destArea.width <= destSize.width && + destArea.y >= 0 && destArea.y + destArea.height <= destSize.height && + destArea.z >= 0 && destArea.z + destArea.depth <= destSize.depth ); + const gl::Buffer &sourceBuffer = *unpack.pixelBuffer.get(); ASSERT(mRenderer->supportsFastCopyBufferToTexture(destinationFormat)); @@ -177,7 +219,6 @@ bool PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, un ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - ID3D11ShaderResourceView *nullSRV = NULL; ID3D11Buffer *nullBuffer = NULL; UINT zero = 0; @@ -187,7 +228,7 @@ bool PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, un deviceContext->VSSetShader(mBufferToTextureVS, NULL, 0); deviceContext->GSSetShader(geometryShader, NULL, 0); deviceContext->PSSetShader(pixelShader, NULL, 0); - deviceContext->PSSetShaderResources(0, 1, &bufferSRV); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, bufferSRV); deviceContext->IASetInputLayout(NULL); deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); @@ -220,21 +261,32 @@ bool PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, un deviceContext->Draw(numPixels, 0); // Unbind textures and render targets and vertex buffer - deviceContext->PSSetShaderResources(0, 1, &nullSRV); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); deviceContext->VSSetConstantBuffers(0, 1, &nullBuffer); mRenderer->markAllStateDirty(); - return true; + return gl::Error(GL_NO_ERROR); } -void PixelTransfer11::buildShaderMap() +gl::Error PixelTransfer11::buildShaderMap() { ID3D11Device *device = mRenderer->getDevice(); mBufferToTexturePSMap[GL_FLOAT] = d3d11::CompilePS(device, g_PS_BufferToTexture_4F, "BufferToTexture RGBA ps"); mBufferToTexturePSMap[GL_INT] = d3d11::CompilePS(device, g_PS_BufferToTexture_4I, "BufferToTexture RGBA-I ps"); mBufferToTexturePSMap[GL_UNSIGNED_INT] = d3d11::CompilePS(device, g_PS_BufferToTexture_4UI, "BufferToTexture RGBA-UI ps"); + + // Check that all the shaders were created successfully + for (auto shaderMapIt = mBufferToTexturePSMap.begin(); shaderMapIt != mBufferToTexturePSMap.end(); shaderMapIt++) + { + if (shaderMapIt->second == NULL) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture pixel shader."); + } + } + + return gl::Error(GL_NO_ERROR); } ID3D11PixelShader *PixelTransfer11::findBufferToTexturePS(GLenum internalFormat) const 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 ed1a3ae1d0..29552140bb 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h @@ -11,6 +11,8 @@ #ifndef LIBGLESV2_PIXELTRANSFER11_H_ #define LIBGLESV2_PIXELTRANSFER11_H_ +#include "libGLESv2/Error.h" + #include "common/platform.h" #include <GLES2/gl2.h> @@ -38,15 +40,13 @@ class PixelTransfer11 explicit PixelTransfer11(Renderer11 *renderer); ~PixelTransfer11(); - static bool supportsBufferToTextureCopy(GLenum internalFormat); - // unpack: the source buffer is stored in the unpack state, and buffer strides // offset: the start of the data within the unpack buffer // destRenderTarget: individual slice/layer of a target texture // destinationFormat/sourcePixelsType: determines shaders + shader parameters // destArea: the sub-section of destRenderTarget to copy to - bool copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); + gl::Error copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, + GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); private: @@ -65,11 +65,13 @@ class PixelTransfer11 static void setBufferToTextureCopyParams(const gl::Box &destArea, const gl::Extents &destSize, GLenum internalFormat, const gl::PixelUnpackState &unpack, unsigned int offset, CopyShaderParams *parametersOut); - void buildShaderMap(); + gl::Error loadResources(); + gl::Error buildShaderMap(); ID3D11PixelShader *findBufferToTexturePS(GLenum internalFormat) const; Renderer11 *mRenderer; + bool mResourcesLoaded; std::map<GLenum, ID3D11PixelShader *> mBufferToTexturePSMap; ID3D11VertexShader *mBufferToTextureVS; ID3D11GeometryShader *mBufferToTextureGS; 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 7109be3e28..17ab1f8ab3 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp @@ -10,13 +10,14 @@ #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/main.h" +#include "common/utilities.h" #include <GLES2/gl2ext.h> namespace rx { -Query11::Query11(rx::Renderer11 *renderer, GLenum type) +Query11::Query11(Renderer11 *renderer, GLenum type) : QueryImpl(type), mResult(0), mQueryFinished(false), 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 822f2542ee..f9ff467873 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h @@ -18,7 +18,7 @@ class Renderer11; class Query11 : public QueryImpl { public: - Query11(rx::Renderer11 *renderer, GLenum type); + Query11(Renderer11 *renderer, GLenum type); virtual ~Query11(); virtual gl::Error begin(); @@ -35,7 +35,7 @@ class Query11 : public QueryImpl bool mQueryFinished; - rx::Renderer11 *mRenderer; + 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 71b931f27e..ab4f60bd98 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp @@ -38,11 +38,14 @@ const unsigned int RenderStateCache::kMaxRasterizerStates = 4096; const unsigned int RenderStateCache::kMaxDepthStencilStates = 4096; const unsigned int RenderStateCache::kMaxSamplerStates = 4096; -RenderStateCache::RenderStateCache() : mDevice(NULL), mCounter(0), - mBlendStateCache(kMaxBlendStates, hashBlendState, compareBlendStates), - mRasterizerStateCache(kMaxRasterizerStates, hashRasterizerState, compareRasterizerStates), - mDepthStencilStateCache(kMaxDepthStencilStates, hashDepthStencilState, compareDepthStencilStates), - mSamplerStateCache(kMaxSamplerStates, hashSamplerState, compareSamplerStates) +RenderStateCache::RenderStateCache(Renderer11 *renderer) + : mRenderer(renderer), + mDevice(NULL), + mCounter(0), + mBlendStateCache(kMaxBlendStates, hashBlendState, compareBlendStates), + mRasterizerStateCache(kMaxRasterizerStates, hashRasterizerState, compareRasterizerStates), + mDepthStencilStateCache(kMaxDepthStencilStates, hashDepthStencilState, compareDepthStencilStates), + mSamplerStateCache(kMaxSamplerStates, hashSamplerState, compareSamplerStates) { } @@ -89,7 +92,7 @@ gl::Error RenderStateCache::getBlendState(const gl::Framebuffer *framebuffer, co bool mrt = false; - const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender(); + const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender(mRenderer->getWorkarounds()); BlendStateKey key = { 0 }; key.blendState = blendState; 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 d5471a3061..dfd1d84265 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h @@ -28,7 +28,7 @@ class Renderer11; class RenderStateCache { public: - RenderStateCache(); + RenderStateCache(Renderer11 *renderer); virtual ~RenderStateCache(); void initialize(ID3D11Device *device); @@ -42,6 +42,7 @@ class RenderStateCache private: DISALLOW_COPY_AND_ASSIGN(RenderStateCache); + Renderer11 *mRenderer; unsigned long long mCounter; // Blend state cache 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 3041f21faa..aff3453492 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp @@ -10,6 +10,7 @@ #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/SwapChain11.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" #include "libGLESv2/main.h" @@ -176,276 +177,228 @@ static unsigned int getDSVSubresourceIndex(ID3D11Resource *resource, ID3D11Depth return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels); } -RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Resource *resource, - ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth) +RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target) +{ + ASSERT(HAS_DYNAMIC_TYPE(RenderTarget11*, target)); + return static_cast<RenderTarget11*>(target); +} + +void RenderTarget11::invalidate(GLint x, GLint y, GLsizei width, GLsizei height) { - mRenderer = Renderer11::makeRenderer11(renderer); + // Currently a no-op +} - mTexture = resource; +TextureRenderTarget11::TextureRenderTarget11(ID3D11RenderTargetView *rtv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, + GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples) + : mWidth(width), + mHeight(height), + mDepth(depth), + mInternalFormat(internalFormat), + mActualFormat(internalFormat), + mSamples(samples), + mSubresourceIndex(0), + mTexture(resource), + mRenderTarget(rtv), + mDepthStencil(NULL), + mShaderResource(srv) +{ if (mTexture) { mTexture->AddRef(); } - mRenderTarget = rtv; if (mRenderTarget) { mRenderTarget->AddRef(); } - mDepthStencil = NULL; - - mShaderResource = srv; if (mShaderResource) { mShaderResource->AddRef(); } - mSubresourceIndex = 0; - if (mRenderTarget && mTexture) { + mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget); + D3D11_RENDER_TARGET_VIEW_DESC desc; mRenderTarget->GetDesc(&desc); - unsigned int mipLevels, samples; - getTextureProperties(mTexture, &mipLevels, &samples); - - mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget); - mWidth = width; - mHeight = height; - mDepth = depth; - mSamples = samples; - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format); - mInternalFormat = dxgiFormatInfo.internalFormat; mActualFormat = dxgiFormatInfo.internalFormat; } } -RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Resource *resource, - ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth) +TextureRenderTarget11::TextureRenderTarget11(ID3D11DepthStencilView *dsv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, + GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples) + : mWidth(width), + mHeight(height), + mDepth(depth), + mInternalFormat(internalFormat), + mActualFormat(internalFormat), + mSamples(samples), + mSubresourceIndex(0), + mTexture(resource), + mRenderTarget(NULL), + mDepthStencil(dsv), + mShaderResource(srv) { - mRenderer = Renderer11::makeRenderer11(renderer); - - mTexture = resource; if (mTexture) { mTexture->AddRef(); } - mRenderTarget = NULL; - - mDepthStencil = dsv; if (mDepthStencil) { mDepthStencil->AddRef(); } - mShaderResource = srv; if (mShaderResource) { mShaderResource->AddRef(); } - mSubresourceIndex = 0; - if (mDepthStencil && mTexture) { + mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil); + D3D11_DEPTH_STENCIL_VIEW_DESC desc; mDepthStencil->GetDesc(&desc); - unsigned int mipLevels, samples; - getTextureProperties(mTexture, &mipLevels, &samples); - - mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil); - mWidth = width; - mHeight = height; - mDepth = depth; - mSamples = samples; - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format); - mInternalFormat = dxgiFormatInfo.internalFormat; mActualFormat = dxgiFormatInfo.internalFormat; } } -RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples) +TextureRenderTarget11::~TextureRenderTarget11() { - mRenderer = Renderer11::makeRenderer11(renderer); - mTexture = NULL; - mRenderTarget = NULL; - mDepthStencil = NULL; - mShaderResource = NULL; + SafeRelease(mTexture); + SafeRelease(mRenderTarget); + SafeRelease(mDepthStencil); + SafeRelease(mShaderResource); +} - const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(formatInfo.texFormat); +ID3D11Resource *TextureRenderTarget11::getTexture() const +{ + return mTexture; +} - const gl::TextureCaps &textureCaps = mRenderer->getRendererTextureCaps().get(internalFormat); - GLuint supportedSamples = textureCaps.getNearestSamples(samples); +ID3D11RenderTargetView *TextureRenderTarget11::getRenderTargetView() const +{ + return mRenderTarget; +} - if (width > 0 && height > 0) - { - // Create texture resource - D3D11_TEXTURE2D_DESC desc; - desc.Width = width; - desc.Height = height; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Format = formatInfo.texFormat; - desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples; - desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; - - // If a rendertarget or depthstencil format exists for this texture format, - // 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 = (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 = !(formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN && desc.SampleDesc.Count > 1); - } - - desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET : 0) | - (bindDSV ? D3D11_BIND_DEPTH_STENCIL : 0) | - (bindSRV ? D3D11_BIND_SHADER_RESOURCE : 0); - - ID3D11Device *device = mRenderer->getDevice(); - ID3D11Texture2D *texture = NULL; - HRESULT result = device->CreateTexture2D(&desc, NULL, &texture); - mTexture = texture; - - if (result == E_OUTOFMEMORY) - { - gl::error(GL_OUT_OF_MEMORY); - return; - } - ASSERT(SUCCEEDED(result)); - - if (bindSRV) - { - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = formatInfo.srvFormat; - srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS; - srvDesc.Texture2D.MostDetailedMip = 0; - srvDesc.Texture2D.MipLevels = 1; - result = device->CreateShaderResourceView(mTexture, &srvDesc, &mShaderResource); - - if (result == E_OUTOFMEMORY) - { - SafeRelease(mTexture); - gl::error(GL_OUT_OF_MEMORY); - return; - } - ASSERT(SUCCEEDED(result)); - } - - if (bindDSV) - { - D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = formatInfo.dsvFormat; - dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS; - dsvDesc.Texture2D.MipSlice = 0; - dsvDesc.Flags = 0; - result = device->CreateDepthStencilView(mTexture, &dsvDesc, &mDepthStencil); - - if (result == E_OUTOFMEMORY) - { - SafeRelease(mTexture); - SafeRelease(mShaderResource); - gl::error(GL_OUT_OF_MEMORY); - return; - } - ASSERT(SUCCEEDED(result)); - } - - if (bindRTV) - { - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - 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); - - if (result == E_OUTOFMEMORY) - { - SafeRelease(mTexture); - SafeRelease(mShaderResource); - SafeRelease(mDepthStencil); - gl::error(GL_OUT_OF_MEMORY); - return; - } - ASSERT(SUCCEEDED(result)); - - if (formatInfo.dataInitializerFunction != NULL) - { - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - - const float clearValues[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; - context->ClearRenderTargetView(mRenderTarget, clearValues); - } - } - } +ID3D11DepthStencilView *TextureRenderTarget11::getDepthStencilView() const +{ + return mDepthStencil; +} +ID3D11ShaderResourceView *TextureRenderTarget11::getShaderResourceView() const +{ + return mShaderResource; +} - mWidth = width; - mHeight = height; - mDepth = 1; - mInternalFormat = internalFormat; - mSamples = supportedSamples; - mActualFormat = dxgiFormatInfo.internalFormat; - mSubresourceIndex = D3D11CalcSubresource(0, 0, 1); +GLsizei TextureRenderTarget11::getWidth() const +{ + return mWidth; } -RenderTarget11::~RenderTarget11() +GLsizei TextureRenderTarget11::getHeight() const { - SafeRelease(mTexture); - SafeRelease(mRenderTarget); - SafeRelease(mDepthStencil); - SafeRelease(mShaderResource); + return mHeight; } -RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target) +GLsizei TextureRenderTarget11::getDepth() const { - ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget11*, target)); - return static_cast<rx::RenderTarget11*>(target); + return mDepth; } -void RenderTarget11::invalidate(GLint x, GLint y, GLsizei width, GLsizei height) +GLenum TextureRenderTarget11::getInternalFormat() const { - // Currently a no-op + return mInternalFormat; } -ID3D11Resource *RenderTarget11::getTexture() const +GLenum TextureRenderTarget11::getActualFormat() const { - return mTexture; + return mActualFormat; } -ID3D11RenderTargetView *RenderTarget11::getRenderTargetView() const +GLsizei TextureRenderTarget11::getSamples() const { - return mRenderTarget; + return mSamples; } -ID3D11DepthStencilView *RenderTarget11::getDepthStencilView() const +unsigned int TextureRenderTarget11::getSubresourceIndex() const { - return mDepthStencil; + return mSubresourceIndex; } -ID3D11ShaderResourceView *RenderTarget11::getShaderResourceView() const + +SurfaceRenderTarget11::SurfaceRenderTarget11(SwapChain11 *swapChain, bool depth) + : mSwapChain(swapChain), + mDepth(depth) { - return mShaderResource; + ASSERT(mSwapChain); } -unsigned int RenderTarget11::getSubresourceIndex() const +SurfaceRenderTarget11::~SurfaceRenderTarget11() { - return mSubresourceIndex; +} + +GLsizei SurfaceRenderTarget11::getWidth() const +{ + return mSwapChain->getWidth(); +} + +GLsizei SurfaceRenderTarget11::getHeight() const +{ + return mSwapChain->getHeight(); +} + +GLsizei SurfaceRenderTarget11::getDepth() const +{ + return 1; +} + +GLenum SurfaceRenderTarget11::getInternalFormat() const +{ + return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetBackBufferInternalFormat()); +} + +GLenum SurfaceRenderTarget11::getActualFormat() const +{ + return d3d11::GetDXGIFormatInfo(d3d11::GetTextureFormatInfo(getInternalFormat()).texFormat).internalFormat; +} + +GLsizei SurfaceRenderTarget11::getSamples() const +{ + // Our EGL surfaces do not support multisampling. + return 0; +} + +ID3D11Resource *SurfaceRenderTarget11::getTexture() const +{ + return (mDepth ? mSwapChain->getDepthStencilTexture() : mSwapChain->getOffscreenTexture()); +} + +ID3D11RenderTargetView *SurfaceRenderTarget11::getRenderTargetView() const +{ + return (mDepth ? NULL : mSwapChain->getRenderTarget()); +} + +ID3D11DepthStencilView *SurfaceRenderTarget11::getDepthStencilView() const +{ + return (mDepth ? mSwapChain->getDepthStencil() : NULL); +} + +ID3D11ShaderResourceView *SurfaceRenderTarget11::getShaderResourceView() const +{ + return (mDepth ? mSwapChain->getDepthStencilShaderResource() : mSwapChain->getRenderTargetShaderResource()); +} + +unsigned int SurfaceRenderTarget11::getSubresourceIndex() const +{ + return 0; } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h index 82182957af..c7babdda3f 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h @@ -14,39 +14,95 @@ namespace rx { -class Renderer; -class Renderer11; +class SwapChain11; class RenderTarget11 : public RenderTarget { public: - // RenderTarget11 takes ownership of any D3D11 resources it is given and will AddRef them - RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth); - RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth); - RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples); - virtual ~RenderTarget11(); + RenderTarget11() { } + virtual ~RenderTarget11() { } static RenderTarget11 *makeRenderTarget11(RenderTarget *renderTarget); - virtual void invalidate(GLint x, GLint y, GLsizei width, GLsizei height); + void invalidate(GLint x, GLint y, GLsizei width, GLsizei height) override; - ID3D11Resource *getTexture() const; - ID3D11RenderTargetView *getRenderTargetView() const; - ID3D11DepthStencilView *getDepthStencilView() const; - ID3D11ShaderResourceView *getShaderResourceView() const; + virtual ID3D11Resource *getTexture() const = 0; + virtual ID3D11RenderTargetView *getRenderTargetView() const = 0; + virtual ID3D11DepthStencilView *getDepthStencilView() const = 0; + virtual ID3D11ShaderResourceView *getShaderResourceView() const = 0; - unsigned int getSubresourceIndex() const; + virtual unsigned int getSubresourceIndex() const = 0; private: DISALLOW_COPY_AND_ASSIGN(RenderTarget11); +}; + +class TextureRenderTarget11 : public RenderTarget11 +{ + public: + // TextureRenderTarget11 takes ownership of any D3D11 resources it is given and will AddRef them + TextureRenderTarget11(ID3D11RenderTargetView *rtv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, + GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples); + TextureRenderTarget11(ID3D11DepthStencilView *dsv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, + GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples); + virtual ~TextureRenderTarget11(); + + GLsizei getWidth() const override; + GLsizei getHeight() const override; + GLsizei getDepth() const override; + GLenum getInternalFormat() const override; + GLenum getActualFormat() const override; + GLsizei getSamples() const override; + + ID3D11Resource *getTexture() const override; + ID3D11RenderTargetView *getRenderTargetView() const override; + ID3D11DepthStencilView *getDepthStencilView() const override; + ID3D11ShaderResourceView *getShaderResourceView() const override; + + unsigned int getSubresourceIndex() const override; + + private: + DISALLOW_COPY_AND_ASSIGN(TextureRenderTarget11); + + GLsizei mWidth; + GLsizei mHeight; + GLsizei mDepth; + GLenum mInternalFormat; + GLenum mActualFormat; + GLsizei mSamples; unsigned int mSubresourceIndex; ID3D11Resource *mTexture; ID3D11RenderTargetView *mRenderTarget; ID3D11DepthStencilView *mDepthStencil; ID3D11ShaderResourceView *mShaderResource; +}; + +class SurfaceRenderTarget11 : public RenderTarget11 +{ + public: + SurfaceRenderTarget11(SwapChain11 *swapChain, bool depth); + virtual ~SurfaceRenderTarget11(); + + GLsizei getWidth() const override; + GLsizei getHeight() const override; + GLsizei getDepth() const override; + GLenum getInternalFormat() const override; + GLenum getActualFormat() const override; + GLsizei getSamples() const override; + + ID3D11Resource *getTexture() const override; + ID3D11RenderTargetView *getRenderTargetView() const override; + ID3D11DepthStencilView *getDepthStencilView() const override; + ID3D11ShaderResourceView *getShaderResourceView() const override; + + unsigned int getSubresourceIndex() const override; + + private: + DISALLOW_COPY_AND_ASSIGN(SurfaceRenderTarget11); - Renderer11 *mRenderer; + SwapChain11 *mSwapChain; + bool mDepth; }; } 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 b29b2ef910..e6d7f3025b 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp @@ -6,12 +6,12 @@ // Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer. -#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/State.h" #include "libGLESv2/renderer/d3d/ProgramD3D.h" #include "libGLESv2/renderer/d3d/ShaderD3D.h" #include "libGLESv2/renderer/d3d/TextureD3D.h" @@ -36,10 +36,12 @@ #include "libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h" #include "libGLESv2/renderer/d3d/d3d11/VertexArray11.h" #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h" +#include "libGLESv2/renderer/d3d/RenderbufferD3D.h" #include "libEGL/Display.h" #include "common/utilities.h" +#include "common/tls.h" #include <EGL/eglext.h> @@ -59,6 +61,9 @@ namespace rx { + +namespace +{ static const DXGI_FORMAT RenderTargetFormats[] = { DXGI_FORMAT_B8G8R8A8_UNORM, @@ -77,10 +82,22 @@ enum MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16 }; -Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, EGLint requestedDisplay) - : Renderer(display), +// Does *not* increment the resource ref count!! +ID3D11Resource *GetSRVResource(ID3D11ShaderResourceView *srv) +{ + ID3D11Resource *resource = NULL; + ASSERT(srv); + srv->GetResource(&resource); + resource->Release(); + return resource; +} + +} + +Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, const egl::AttributeMap &attributes) + : RendererD3D(display), mDc(hDc), - mRequestedDisplay(requestedDisplay) + mStateCache(this) { mVertexDataManager = NULL; mIndexDataManager = NULL; @@ -112,6 +129,50 @@ Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, EGLint r mAppliedGeometryShader = NULL; mCurPointGeometryShader = NULL; mAppliedPixelShader = NULL; + + EGLint requestedMajorVersion = attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, EGL_DONT_CARE); + EGLint requestedMinorVersion = attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, EGL_DONT_CARE); + + if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 11) + { + if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 0) + { + mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_11_0); + } + } + + if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 10) + { + if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 1) + { + mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_10_1); + } + if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 0) + { + mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_10_0); + } + } + +#if !defined(ANGLE_ENABLE_D3D9) + if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 9) + { + if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 3) + { + mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_3); + } + if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 2) + { + mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_2); + } + if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 1) + { + mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_1); + } + } +#endif + + mDriverType = (attributes.get(EGL_PLATFORM_ANGLE_USE_WARP_ANGLE, EGL_FALSE) == EGL_TRUE) ? D3D_DRIVER_TYPE_WARP + : D3D_DRIVER_TYPE_HARDWARE; } Renderer11::~Renderer11() @@ -121,8 +182,8 @@ Renderer11::~Renderer11() Renderer11 *Renderer11::makeRenderer11(Renderer *renderer) { - ASSERT(HAS_DYNAMIC_TYPE(rx::Renderer11*, renderer)); - return static_cast<rx::Renderer11*>(renderer); + ASSERT(HAS_DYNAMIC_TYPE(Renderer11*, renderer)); + return static_cast<Renderer11*>(renderer); } #ifndef __d3d11_1_h__ @@ -136,7 +197,7 @@ EGLint Renderer11::initialize() return EGL_NOT_INITIALIZED; } -#if !defined(ANGLE_PLATFORM_WINRT) +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) mDxgiModule = LoadLibrary(TEXT("dxgi.dll")); mD3d11Module = LoadLibrary(TEXT("d3d11.dll")); @@ -157,33 +218,14 @@ EGLint Renderer11::initialize() } #endif - D3D_FEATURE_LEVEL featureLevels[] = - { - D3D_FEATURE_LEVEL_11_0, - D3D_FEATURE_LEVEL_10_1, - D3D_FEATURE_LEVEL_10_0, -#if !defined(ANGLE_ENABLE_D3D9) - D3D_FEATURE_LEVEL_9_3, - D3D_FEATURE_LEVEL_9_2, - D3D_FEATURE_LEVEL_9_1, -#endif - }; - - D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_HARDWARE; - if (mRequestedDisplay == EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE) - { - driverType = D3D_DRIVER_TYPE_WARP; - } - HRESULT result = S_OK; - #ifdef _DEBUG result = D3D11CreateDevice(NULL, - driverType, + mDriverType, NULL, D3D11_CREATE_DEVICE_DEBUG, - featureLevels, - ArraySize(featureLevels), + mAvailableFeatureLevels.data(), + mAvailableFeatureLevels.size(), D3D11_SDK_VERSION, &mDevice, &mFeatureLevel, @@ -198,11 +240,11 @@ EGLint Renderer11::initialize() #endif { result = D3D11CreateDevice(NULL, - driverType, + mDriverType, NULL, 0, - featureLevels, - ArraySize(featureLevels), + mAvailableFeatureLevels.data(), + mAvailableFeatureLevels.size(), D3D11_SDK_VERSION, &mDevice, &mFeatureLevel, @@ -215,7 +257,18 @@ EGLint Renderer11::initialize() } } -#if !ANGLE_SKIP_DXGI_1_2_CHECK && !defined(ANGLE_PLATFORM_WINRT) +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) + static wchar_t *qt_d3dcreate_multihreaded_var = _wgetenv(L"QT_D3DCREATE_MULTITHREADED"); + if (qt_d3dcreate_multihreaded_var && wcsstr(qt_d3dcreate_multihreaded_var, L"1")) + { + ID3D10Multithread *multithread; + result = mDevice->QueryInterface(IID_PPV_ARGS(&multithread)); + ASSERT(SUCCEEDED(result)); + result = multithread->SetMultithreadProtected(true); + ASSERT(SUCCEEDED(result)); + multithread->Release(); + } +#if !ANGLE_SKIP_DXGI_1_2_CHECK // In order to create a swap chain for an HWND owned by another process, DXGI 1.2 is required. // The easiest way to check is to query for a IDXGIDevice2. bool requireDXGI1_2 = false; @@ -244,13 +297,10 @@ EGLint Renderer11::initialize() SafeRelease(dxgiDevice2); } #endif +#endif -#if !defined(ANGLE_PLATFORM_WINRT) IDXGIDevice *dxgiDevice = NULL; -#else - IDXGIDevice1 *dxgiDevice = NULL; -#endif - result = mDevice->QueryInterface(IID_PPV_ARGS(&dxgiDevice)); + result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); if (FAILED(result)) { @@ -281,9 +331,9 @@ EGLint Renderer11::initialize() } // Disable some spurious D3D11 debug warnings to prevent them from flooding the output log -#if !defined(__MINGW32__) && defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG) +#if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG) ID3D11InfoQueue *infoQueue; - result = mDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&infoQueue); + result = mDevice->QueryInterface(IID_ID3D11InfoQueue, (void **)&infoQueue); if (SUCCEEDED(result)) { @@ -301,19 +351,6 @@ EGLint Renderer11::initialize() } #endif -#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")) - { - ID3D10Multithread *multithread; - result = mDevice->QueryInterface(IID_PPV_ARGS(&multithread)); - ASSERT(SUCCEEDED(result)); - result = multithread->SetMultithreadProtected(true); - ASSERT(SUCCEEDED(result)); - multithread->Release(); - } -#endif - initializeDevice(); return EGL_SUCCESS; @@ -394,7 +431,7 @@ void Renderer11::deleteConfigs(ConfigDesc *configDescList) delete [] (configDescList); } -void Renderer11::sync(bool block) +gl::Error Renderer11::sync(bool block) { if (block) { @@ -408,6 +445,10 @@ void Renderer11::sync(bool block) result = mDevice->CreateQuery(&queryDesc, &mSyncQuery); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create event query, result: 0x%X.", result); + } } mDeviceContext->End(mSyncQuery); @@ -416,13 +457,17 @@ void Renderer11::sync(bool block) do { result = mDeviceContext->GetData(mSyncQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result); + } // Keep polling, but allow other threads to do something useful first Sleep(0); if (testDeviceLost(true)) { - return; + return gl::Error(GL_OUT_OF_MEMORY, "Device was lost while waiting for sync."); } } while (result == S_FALSE); @@ -431,22 +476,26 @@ void Renderer11::sync(bool block) { mDeviceContext->Flush(); } + + return gl::Error(GL_NO_ERROR); } -SwapChain *Renderer11::createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) +SwapChain *Renderer11::createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) { - return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat); + return new SwapChain11(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat); } gl::Error Renderer11::generateSwizzle(gl::Texture *texture) { if (texture) { - TextureStorage *texStorage = texture->getNativeTexture(); + TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation()); + ASSERT(textureD3D); + + TextureStorage *texStorage = textureD3D->getNativeTexture(); if (texStorage) { TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage); - gl::Error error = storage11->generateSwizzles(texture->getSamplerState().swizzleRed, texture->getSamplerState().swizzleGreen, texture->getSamplerState().swizzleBlue, @@ -461,16 +510,21 @@ gl::Error Renderer11::generateSwizzle(gl::Texture *texture) return gl::Error(GL_NO_ERROR); } -gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState) +gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &samplerStateParam) { + // Make sure to add the level offset for our tiny compressed texture workaround + TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation()); + gl::SamplerState samplerStateInternal = samplerStateParam; + samplerStateInternal.baseLevel += textureD3D->getNativeTexture()->getTopLevel(); + if (type == gl::SAMPLER_PIXEL) { ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits); - if (mForceSetPixelSamplerStates[index] || memcmp(&samplerState, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0) + if (mForceSetPixelSamplerStates[index] || memcmp(&samplerStateInternal, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0) { ID3D11SamplerState *dxSamplerState = NULL; - gl::Error error = mStateCache.getSamplerState(samplerState, &dxSamplerState); + gl::Error error = mStateCache.getSamplerState(samplerStateInternal, &dxSamplerState); if (error.isError()) { return error; @@ -479,7 +533,7 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, const gl: ASSERT(dxSamplerState != NULL); mDeviceContext->PSSetSamplers(index, 1, &dxSamplerState); - mCurPixelSamplerStates[index] = samplerState; + mCurPixelSamplerStates[index] = samplerStateInternal; } mForceSetPixelSamplerStates[index] = false; @@ -488,10 +542,10 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, const gl: { ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits); - if (mForceSetVertexSamplerStates[index] || memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0) + if (mForceSetVertexSamplerStates[index] || memcmp(&samplerStateInternal, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0) { ID3D11SamplerState *dxSamplerState = NULL; - gl::Error error = mStateCache.getSamplerState(samplerState, &dxSamplerState); + gl::Error error = mStateCache.getSamplerState(samplerStateInternal, &dxSamplerState); if (error.isError()) { return error; @@ -500,7 +554,7 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, const gl: ASSERT(dxSamplerState != NULL); mDeviceContext->VSSetSamplers(index, 1, &dxSamplerState); - mCurVertexSamplerStates[index] = samplerState; + mCurVertexSamplerStates[index] = samplerStateInternal; } mForceSetVertexSamplerStates[index] = false; @@ -513,50 +567,36 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, const gl: gl::Error Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture) { ID3D11ShaderResourceView *textureSRV = NULL; - bool forceSetTexture = false; if (texture) { - TextureD3D* textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation()); + 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); + + // Make sure to add the level offset for our tiny compressed texture workaround + gl::SamplerState samplerState = texture->getSamplerState(); + samplerState.baseLevel += storage11->getTopLevel(); + + gl::Error error = storage11->getSRV(samplerState, &textureSRV); + if (error.isError()) + { + return error; + } // 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 = textureImpl->hasDirtyImages(); textureImpl->resetDirty(); } - if (type == gl::SAMPLER_PIXEL) - { - ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits); - - if (forceSetTexture || mCurPixelSRVs[index] != textureSRV) - { - mDeviceContext->PSSetShaderResources(index, 1, &textureSRV); - } - - mCurPixelSRVs[index] = textureSRV; - } - else if (type == gl::SAMPLER_VERTEX) - { - ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits); - - if (forceSetTexture || mCurVertexSRVs[index] != textureSRV) - { - mDeviceContext->VSSetShaderResources(index, 1, &textureSRV); - } + ASSERT((type == gl::SAMPLER_PIXEL && static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits) || + (type == gl::SAMPLER_VERTEX && static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits)); - mCurVertexSRVs[index] = textureSRV; - } - else UNREACHABLE(); + setShaderResource(type, index, textureSRV); return gl::Error(GL_NO_ERROR); } @@ -631,7 +671,7 @@ gl::Error Renderer11::setRasterizerState(const gl::RasterizerState &rasterState) return gl::Error(GL_NO_ERROR); } -gl::Error Renderer11::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, +gl::Error Renderer11::setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, unsigned int sampleMask) { if (mForceSetBlendState || @@ -831,7 +871,22 @@ bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count) return count >= minCount; } -gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) +void Renderer11::unsetSRVsWithResource(gl::SamplerType samplerType, const ID3D11Resource *resource) +{ + std::vector<ID3D11ShaderResourceView *> ¤tSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs); + + for (size_t resourceIndex = 0; resourceIndex < currentSRVs.size(); ++resourceIndex) + { + ID3D11ShaderResourceView *srv = currentSRVs[resourceIndex]; + + if (srv && GetSRVResource(srv) == resource) + { + setShaderResource(samplerType, static_cast<UINT>(resourceIndex), NULL); + } + } +} + +gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer) { // Get the color render buffer and serial // Also extract the render target dimensions and view @@ -842,7 +897,7 @@ gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) ID3D11RenderTargetView* framebufferRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL}; bool missingColorRenderTarget = true; - const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender(); + const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender(getWorkarounds()); for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment) { @@ -863,17 +918,16 @@ gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) renderTargetSerials[colorAttachment] = GetAttachmentSerial(colorbuffer); // Extract the render target dimensions and view - RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); - if (!renderTarget) + RenderTarget11 *renderTarget = NULL; + gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &renderTarget); + if (error.isError()) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal render target pointer unexpectedly null."); + return error; } + ASSERT(renderTarget); framebufferRTVs[colorAttachment] = renderTarget->getRenderTargetView(); - if (!framebufferRTVs[colorAttachment]) - { - return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null."); - } + ASSERT(framebufferRTVs[colorAttachment]); if (missingColorRenderTarget) { @@ -883,8 +937,12 @@ gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) missingColorRenderTarget = false; } - // TODO: Detect if this color buffer is already bound as a texture and unbind it first to prevent - // D3D11 warnings. +#if !defined(NDEBUG) + // Unbind render target SRVs from the shader here to prevent D3D11 warnings. + ID3D11Resource *renderTargetResource = renderTarget->getTexture(); + unsetSRVsWithResource(gl::SAMPLER_VERTEX, renderTargetResource); + unsetSRVsWithResource(gl::SAMPLER_PIXEL, renderTargetResource); +#endif } } @@ -905,19 +963,17 @@ gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) ID3D11DepthStencilView* framebufferDSV = NULL; if (depthStencil) { - RenderTarget11 *depthStencilRenderTarget = d3d11::GetAttachmentRenderTarget(depthStencil); - if (!depthStencilRenderTarget) + RenderTarget11 *depthStencilRenderTarget = NULL; + gl::Error error = d3d11::GetAttachmentRenderTarget(depthStencil, &depthStencilRenderTarget); + if (error.isError()) { SafeRelease(framebufferRTVs); - return gl::Error(GL_OUT_OF_MEMORY, "Internal render target pointer unexpectedly null."); + return error; } + ASSERT(depthStencilRenderTarget); framebufferDSV = depthStencilRenderTarget->getDepthStencilView(); - if (!framebufferDSV) - { - SafeRelease(framebufferRTVs); - return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil view pointer unexpectedly null."); - } + ASSERT(framebufferDSV); // If there is no render buffer, the width, height and format values come from // the depth stencil @@ -964,17 +1020,16 @@ gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) return gl::Error(GL_NO_ERROR); } -gl::Error Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], - GLint first, GLsizei count, GLsizei instances) +gl::Error Renderer11::applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances) { TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS]; - gl::Error error = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances); + gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, attributes, instances); if (error.isError()) { return error; } - return mInputLayoutCache.applyVertexBuffers(attributes, programBinary); + return mInputLayoutCache.applyVertexBuffers(attributes, state.getCurrentProgramBinary()); } gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) @@ -1011,28 +1066,25 @@ gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elemen return gl::Error(GL_NO_ERROR); } -void Renderer11::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]) +void Renderer11::applyTransformFeedbackBuffers(const gl::State& state) { - ID3D11Buffer* d3dBuffers[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; - UINT d3dOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; + size_t numXFBBindings = state.getTransformFeedbackBufferIndexRange(); + ASSERT(numXFBBindings <= gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS); + bool requiresUpdate = false; - for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) + for (size_t i = 0; i < numXFBBindings; i++) { - if (transformFeedbackBuffers[i]) + gl::Buffer *curXFBBuffer = state.getIndexedTransformFeedbackBuffer(i); + GLintptr curXFBOffset = state.getIndexedTransformFeedbackBufferOffset(i); + ID3D11Buffer *d3dBuffer = NULL; + if (curXFBBuffer) { - Buffer11 *storage = Buffer11::makeBuffer11(transformFeedbackBuffers[i]->getImplementation()); - ID3D11Buffer *buffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); - - d3dBuffers[i] = buffer; - d3dOffsets[i] = (mAppliedTFBuffers[i] != buffer) ? static_cast<UINT>(offsets[i]) : -1; - } - else - { - d3dBuffers[i] = NULL; - d3dOffsets[i] = 0; + Buffer11 *storage = Buffer11::makeBuffer11(curXFBBuffer->getImplementation()); + d3dBuffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); } - if (d3dBuffers[i] != mAppliedTFBuffers[i] || offsets[i] != mAppliedTFOffsets[i]) + // TODO: mAppliedTFBuffers and friends should also be kept in a vector. + if (d3dBuffer != mAppliedTFBuffers[i] || curXFBOffset != mAppliedTFOffsets[i]) { requiresUpdate = true; } @@ -1040,12 +1092,29 @@ void Renderer11::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuff if (requiresUpdate) { - mDeviceContext->SOSetTargets(ArraySize(d3dBuffers), d3dBuffers, d3dOffsets); - for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) + for (size_t i = 0; i < numXFBBindings; ++i) { - mAppliedTFBuffers[i] = d3dBuffers[i]; - mAppliedTFOffsets[i] = offsets[i]; + gl::Buffer *curXFBBuffer = state.getIndexedTransformFeedbackBuffer(i); + GLintptr curXFBOffset = state.getIndexedTransformFeedbackBufferOffset(i); + + if (curXFBBuffer) + { + Buffer11 *storage = Buffer11::makeBuffer11(curXFBBuffer->getImplementation()); + ID3D11Buffer *d3dBuffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); + + mCurrentD3DOffsets[i] = (mAppliedTFBuffers[i] != d3dBuffer && mAppliedTFOffsets[i] != curXFBOffset) ? + static_cast<UINT>(curXFBOffset) : -1; + mAppliedTFBuffers[i] = d3dBuffer; + } + else + { + mAppliedTFBuffers[i] = NULL; + mCurrentD3DOffsets[i] = 0; + } + mAppliedTFOffsets[i] = curXFBOffset; } + + mDeviceContext->SOSetTargets(numXFBBindings, mAppliedTFBuffers, mCurrentD3DOffsets); } } @@ -1129,7 +1198,6 @@ gl::Error Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, cons return gl::Error(GL_NO_ERROR); } } - template<typename T> static void fillLineLoopIndices(GLenum type, GLsizei count, const GLvoid *indices, T *data) { @@ -1213,10 +1281,17 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind // Get the raw indices for an indexed draw if (type != GL_NONE && elementArrayBuffer) { - gl::Buffer *indexBuffer = elementArrayBuffer; - BufferImpl *storage = indexBuffer->getImplementation(); + BufferD3D *storage = BufferD3D::makeFromBuffer(elementArrayBuffer); intptr_t offset = reinterpret_cast<intptr_t>(indices); - indices = static_cast<const GLubyte*>(storage->getData()) + offset; + + const uint8_t *bufferData = NULL; + gl::Error error = storage->getData(&bufferData); + if (error.isError()) + { + return error; + } + + indices = bufferData + offset; } // TODO: some level 9 hardware supports 32-bit indices; test and store support instead @@ -1291,10 +1366,17 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid * // Get the raw indices for an indexed draw if (type != GL_NONE && elementArrayBuffer) { - gl::Buffer *indexBuffer = elementArrayBuffer; - BufferImpl *storage = indexBuffer->getImplementation(); + BufferD3D *storage = BufferD3D::makeFromBuffer(elementArrayBuffer); intptr_t offset = reinterpret_cast<intptr_t>(indices); - indices = static_cast<const GLubyte*>(storage->getData()) + offset; + + const uint8_t *bufferData = NULL; + gl::Error error = storage->getData(&bufferData); + if (error.isError()) + { + return error; + } + + indices = bufferData + offset; } const int indexType = isLevel9() ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT; @@ -1376,9 +1458,23 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid * 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); - ShaderExecutable *geometryExe = programBinary->getGeometryExecutable(); + ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary->getImplementation()); + + ShaderExecutable *vertexExe = NULL; + gl::Error error = programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe); + if (error.isError()) + { + return error; + } + + ShaderExecutable *pixelExe = NULL; + error = programD3D->getPixelExecutableForFramebuffer(framebuffer, &pixelExe); + if (error.isError()) + { + return error; + } + + ShaderExecutable *geometryExe = programD3D->getGeometryExecutable(); ID3D11VertexShader *vertexShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader() : NULL); @@ -1433,16 +1529,14 @@ gl::Error Renderer11::applyShaders(gl::ProgramBinary *programBinary, const gl::V if (dirtyUniforms) { - programBinary->dirtyAllUniforms(); + programD3D->dirtyAllUniforms(); } return gl::Error(GL_NO_ERROR); } -gl::Error Renderer11::applyUniforms(const gl::ProgramBinary &programBinary) +gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray) { - const std::vector<gl::LinkedUniform*> &uniformArray = programBinary.getUniforms(); - unsigned int totalRegisterCountVS = 0; unsigned int totalRegisterCountPS = 0; @@ -1466,7 +1560,7 @@ gl::Error Renderer11::applyUniforms(const gl::ProgramBinary &programBinary) } } - const ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary.getImplementation()); + const ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(&program); const UniformStorage11 *vertexUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getVertexUniformStorage()); const UniformStorage11 *fragmentUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getFragmentUniformStorage()); ASSERT(vertexUniformStorage); @@ -1598,7 +1692,7 @@ gl::Error Renderer11::applyUniforms(const gl::ProgramBinary &programBinary) return gl::Error(GL_NO_ERROR); } -gl::Error Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) +gl::Error Renderer11::clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer) { gl::Error error = mClear->clearFramebuffer(clearParams, frameBuffer); if (error.isError()) @@ -1626,14 +1720,12 @@ void Renderer11::markAllStateDirty() for (size_t vsamplerId = 0; vsamplerId < mForceSetVertexSamplerStates.size(); ++vsamplerId) { mForceSetVertexSamplerStates[vsamplerId] = true; - mCurVertexSRVs[vsamplerId] = NULL; } ASSERT(mForceSetPixelSamplerStates.size() == mCurPixelSRVs.size()); for (size_t fsamplerId = 0; fsamplerId < mForceSetPixelSamplerStates.size(); ++fsamplerId) { mForceSetPixelSamplerStates[fsamplerId] = true; - mCurPixelSRVs[fsamplerId] = NULL; } mForceSetBlendState = true; @@ -1746,32 +1838,20 @@ bool Renderer11::testDeviceResettable() return false; } - D3D_FEATURE_LEVEL featureLevels[] = - { - D3D_FEATURE_LEVEL_11_0, - D3D_FEATURE_LEVEL_10_1, - D3D_FEATURE_LEVEL_10_0, -#if !defined(ANGLE_ENABLE_D3D9) - D3D_FEATURE_LEVEL_9_3, - D3D_FEATURE_LEVEL_9_2, - D3D_FEATURE_LEVEL_9_1, -#endif - }; - ID3D11Device* dummyDevice; D3D_FEATURE_LEVEL dummyFeatureLevel; ID3D11DeviceContext* dummyContext; HRESULT result = D3D11CreateDevice(NULL, - D3D_DRIVER_TYPE_HARDWARE, + mDriverType, NULL, #if defined(_DEBUG) D3D11_CREATE_DEVICE_DEBUG, #else 0, #endif - featureLevels, - ArraySize(featureLevels), + mAvailableFeatureLevels.data(), + mAvailableFeatureLevels.size(), D3D11_SDK_VERSION, &dummyDevice, &dummyFeatureLevel, @@ -1939,119 +2019,37 @@ int Renderer11::getMaxSwapInterval() const return 4; } -bool Renderer11::copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source) -{ - if (source && dest) - { - TextureStorage11_2D *source11 = TextureStorage11_2D::makeTextureStorage11_2D(source); - TextureStorage11_2D *dest11 = TextureStorage11_2D::makeTextureStorage11_2D(dest); - - mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); - - dest11->invalidateSwizzleCache(); - - return true; - } - - return false; -} - -bool Renderer11::copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source) -{ - if (source && dest) - { - TextureStorage11_Cube *source11 = TextureStorage11_Cube::makeTextureStorage11_Cube(source); - TextureStorage11_Cube *dest11 = TextureStorage11_Cube::makeTextureStorage11_Cube(dest); - - mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); - - dest11->invalidateSwizzleCache(); - - return true; - } - - return false; -} - -bool Renderer11::copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source) -{ - if (source && dest) - { - TextureStorage11_3D *source11 = TextureStorage11_3D::makeTextureStorage11_3D(source); - TextureStorage11_3D *dest11 = TextureStorage11_3D::makeTextureStorage11_3D(dest); - - mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); - - dest11->invalidateSwizzleCache(); - - return true; - } - - return false; -} - -bool Renderer11::copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source) -{ - if (source && dest) - { - TextureStorage11_2DArray *source11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(source); - TextureStorage11_2DArray *dest11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(dest); - - mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); - - dest11->invalidateSwizzleCache(); - - return true; - } - - return false; -} - -bool Renderer11::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) +gl::Error 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) - { - ERR("Failed to retrieve the color buffer from the frame buffer."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ASSERT(colorbuffer); - RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); - if (!sourceRenderTarget) + RenderTarget11 *sourceRenderTarget = NULL; + gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget); + if (error.isError()) { - ERR("Failed to retrieve the render target from the frame buffer."); - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } + ASSERT(sourceRenderTarget); ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); - if (!source) - { - ERR("Failed to retrieve the render target view from the render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ASSERT(source); 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); - } + ASSERT(storage11); gl::ImageIndex index = gl::ImageIndex::Make2D(level); - RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index)); - if (!destRenderTarget) + RenderTarget *destRenderTarget = NULL; + error = storage11->getRenderTarget(index, &destRenderTarget); + if (error.isError()) { - ERR("Failed to retrieve the render target from the destination storage."); - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } + ASSERT(destRenderTarget); - ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView(); - if (!dest) - { - ERR("Failed to retrieve the render target view from the destination render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView(); + ASSERT(dest); gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1); @@ -2061,59 +2059,48 @@ bool Renderer11::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle & // Use nearest filtering because source and destination are the same size for the direct // copy - bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, - destFormat, GL_NEAREST); + mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST); + if (error.isError()) + { + return error; + } storage11->invalidateSwizzleCacheLevel(level); - return ret; + return gl::Error(GL_NO_ERROR); } -bool Renderer11::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) +gl::Error 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) - { - ERR("Failed to retrieve the color buffer from the frame buffer."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ASSERT(colorbuffer); - RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); - if (!sourceRenderTarget) + RenderTarget11 *sourceRenderTarget = NULL; + gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget); + if (error.isError()) { - ERR("Failed to retrieve the render target from the frame buffer."); - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } + ASSERT(sourceRenderTarget); ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); - if (!source) - { - ERR("Failed to retrieve the render target view from the render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ASSERT(source); 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); - } + ASSERT(storage11); gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level); - RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index)); - if (!destRenderTarget) + RenderTarget *destRenderTarget = NULL; + error = storage11->getRenderTarget(index, &destRenderTarget); + if (error.isError()) { - ERR("Failed to retrieve the render target from the destination storage."); - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } + ASSERT(destRenderTarget); - ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView(); - if (!dest) - { - ERR("Failed to retrieve the render target view from the destination render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView(); + ASSERT(dest); gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1); @@ -2123,59 +2110,48 @@ bool Renderer11::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle // Use nearest filtering because source and destination are the same size for the direct // copy - bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, - destFormat, GL_NEAREST); + error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST); + if (error.isError()) + { + return error; + } storage11->invalidateSwizzleCacheLevel(level); - return ret; + return gl::Error(GL_NO_ERROR); } -bool Renderer11::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) +gl::Error 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) - { - ERR("Failed to retrieve the color buffer from the frame buffer."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ASSERT(colorbuffer); - RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); - if (!sourceRenderTarget) + RenderTarget11 *sourceRenderTarget = NULL; + gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget); + if (error.isError()) { - ERR("Failed to retrieve the render target from the frame buffer."); - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } + ASSERT(sourceRenderTarget); ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); - if (!source) - { - ERR("Failed to retrieve the render target view from the render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ASSERT(source); 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); - } + ASSERT(storage11); gl::ImageIndex index = gl::ImageIndex::Make3D(level, zOffset); - RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index)); - if (!destRenderTarget) + RenderTarget *destRenderTarget = NULL; + error = storage11->getRenderTarget(index, &destRenderTarget); + if (error.isError()) { - ERR("Failed to retrieve the render target from the destination storage."); - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } + ASSERT(destRenderTarget); - ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView(); - if (!dest) - { - ERR("Failed to retrieve the render target view from the destination render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView(); + ASSERT(dest); gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1); @@ -2185,61 +2161,48 @@ bool Renderer11::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle & // Use nearest filtering because source and destination are the same size for the direct // copy - bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, - destFormat, GL_NEAREST); + error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST); + if (error.isError()) + { + return error; + } storage11->invalidateSwizzleCacheLevel(level); - return ret; + return gl::Error(GL_NO_ERROR); } -bool Renderer11::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) +gl::Error 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) - { - ERR("Failed to retrieve the color buffer from the frame buffer."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ASSERT(colorbuffer); - RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); - if (!sourceRenderTarget) + RenderTarget11 *sourceRenderTarget = NULL; + gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget); + if (error.isError()) { - ERR("Failed to retrieve the render target from the frame buffer."); - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } + ASSERT(sourceRenderTarget); ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); - if (!source) - { - ERR("Failed to retrieve the render target view from the render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ASSERT(source); TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage); - if (!storage11) - { - SafeRelease(source); - ERR("Failed to retrieve the texture storage from the destination."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ASSERT(storage11); gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, zOffset); - RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index)); - if (!destRenderTarget) + RenderTarget *destRenderTarget = NULL; + error = storage11->getRenderTarget(index, &destRenderTarget); + if (error.isError()) { - SafeRelease(source); - ERR("Failed to retrieve the render target from the destination storage."); - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } + ASSERT(destRenderTarget); - ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView(); - if (!dest) - { - ERR("Failed to retrieve the render target view from the destination render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView(); + ASSERT(dest); gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1); @@ -2249,12 +2212,15 @@ bool Renderer11::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectan // Use nearest filtering because source and destination are the same size for the direct // copy - bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, - destFormat, GL_NEAREST); + error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST); + if (error.isError()) + { + return error; + } storage11->invalidateSwizzleCacheLevel(level); - return ret; + return gl::Error(GL_NO_ERROR); } void Renderer11::unapplyRenderTargets() @@ -2277,39 +2243,150 @@ void Renderer11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView } } -RenderTarget *Renderer11::createRenderTarget(SwapChain *swapChain, bool depth) +gl::Error Renderer11::createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT) { SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain); - RenderTarget11 *renderTarget = NULL; + *outRT = new SurfaceRenderTarget11(swapChain11, depth); + return gl::Error(GL_NO_ERROR); +} + +gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT) +{ + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(format); - if (depth) + const gl::TextureCaps &textureCaps = getRendererTextureCaps().get(format); + GLuint supportedSamples = textureCaps.getNearestSamples(samples); + + if (width > 0 && height > 0) { - // Note: depth stencil may be NULL for 0 sized surfaces - renderTarget = new RenderTarget11(this, swapChain11->getDepthStencil(), - swapChain11->getDepthStencilTexture(), - swapChain11->getDepthStencilShaderResource(), - swapChain11->getWidth(), swapChain11->getHeight(), 1); + // Create texture resource + D3D11_TEXTURE2D_DESC desc; + desc.Width = width; + desc.Height = height; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = formatInfo.texFormat; + desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + // If a rendertarget or depthstencil format exists for this texture format, + // 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 = (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 = !(formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN && desc.SampleDesc.Count > 1); + } + + desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET : 0) | + (bindDSV ? D3D11_BIND_DEPTH_STENCIL : 0) | + (bindSRV ? D3D11_BIND_SHADER_RESOURCE : 0); + + // The format must be either an RTV or a DSV + ASSERT(bindRTV != bindDSV); + + ID3D11Texture2D *texture = NULL; + HRESULT result = mDevice->CreateTexture2D(&desc, NULL, &texture); + if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target texture, result: 0x%X.", result); + } + + ID3D11ShaderResourceView *srv = NULL; + if (bindSRV) + { + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = formatInfo.srvFormat; + srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS; + srvDesc.Texture2D.MostDetailedMip = 0; + srvDesc.Texture2D.MipLevels = 1; + + result = mDevice->CreateShaderResourceView(texture, &srvDesc, &srv); + if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + SafeRelease(texture); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target shader resource view, result: 0x%X.", result); + } + } + + if (bindDSV) + { + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Format = formatInfo.dsvFormat; + dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS; + dsvDesc.Texture2D.MipSlice = 0; + dsvDesc.Flags = 0; + + ID3D11DepthStencilView *dsv = NULL; + result = mDevice->CreateDepthStencilView(texture, &dsvDesc, &dsv); + if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + SafeRelease(texture); + SafeRelease(srv); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target depth stencil view, result: 0x%X.", result); + } + + *outRT = new TextureRenderTarget11(dsv, texture, srv, format, width, height, 1, supportedSamples); + + SafeRelease(dsv); + } + else if (bindRTV) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = formatInfo.rtvFormat; + rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS; + rtvDesc.Texture2D.MipSlice = 0; + + ID3D11RenderTargetView *rtv = NULL; + result = mDevice->CreateRenderTargetView(texture, &rtvDesc, &rtv); + if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + SafeRelease(texture); + SafeRelease(srv); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target render target view, result: 0x%X.", result); + } + + if (formatInfo.dataInitializerFunction != NULL) + { + const float clearValues[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; + mDeviceContext->ClearRenderTargetView(rtv, clearValues); + } + + *outRT = new TextureRenderTarget11(rtv, texture, srv, format, width, height, 1, supportedSamples); + + SafeRelease(rtv); + } + else + { + UNREACHABLE(); + } + + SafeRelease(texture); + SafeRelease(srv); } else { - // Note: render target may be NULL for 0 sized surfaces - renderTarget = new RenderTarget11(this, swapChain11->getRenderTarget(), - swapChain11->getOffscreenTexture(), - swapChain11->getRenderTargetShaderResource(), - swapChain11->getWidth(), swapChain11->getHeight(), 1); + *outRT = new TextureRenderTarget11(reinterpret_cast<ID3D11RenderTargetView*>(NULL), NULL, NULL, format, width, height, 1, supportedSamples); } - return renderTarget; -} -RenderTarget *Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples) -{ - RenderTarget11 *renderTarget = new RenderTarget11(this, width, height, format, samples); - return renderTarget; + return gl::Error(GL_NO_ERROR); } -ShaderImpl *Renderer11::createShader(GLenum type) +ShaderImpl *Renderer11::createShader(const gl::Data &data, GLenum type) { - return new ShaderD3D(type, this); + return new ShaderD3D(data, type, this); } ProgramImpl *Renderer11::createProgram() @@ -2322,22 +2399,23 @@ 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) +gl::Error Renderer11::loadExecutable(const void *function, size_t length, ShaderType type, + const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, + bool separatedOutputBuffers, ShaderExecutable **outExecutable) { - ShaderExecutable11 *executable = NULL; - HRESULT result; - switch (type) { - case rx::SHADER_VERTEX: + case SHADER_VERTEX: { ID3D11VertexShader *vertexShader = NULL; ID3D11GeometryShader *streamOutShader = NULL; - result = mDevice->CreateVertexShader(function, length, NULL, &vertexShader); + HRESULT result = mDevice->CreateVertexShader(function, length, NULL, &vertexShader); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create vertex shader, result: 0x%X.", result); + } if (transformFeedbackVaryings.size() > 0) { @@ -2363,99 +2441,116 @@ ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length result = mDevice->CreateGeometryShaderWithStreamOutput(function, length, soDeclaration.data(), soDeclaration.size(), NULL, 0, 0, NULL, &streamOutShader); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create steam output shader, result: 0x%X.", result); + } } - if (vertexShader) - { - executable = new ShaderExecutable11(function, length, vertexShader, streamOutShader); - } + *outExecutable = new ShaderExecutable11(function, length, vertexShader, streamOutShader); } break; - case rx::SHADER_PIXEL: + case SHADER_PIXEL: { ID3D11PixelShader *pixelShader = NULL; - result = mDevice->CreatePixelShader(function, length, NULL, &pixelShader); + HRESULT result = mDevice->CreatePixelShader(function, length, NULL, &pixelShader); ASSERT(SUCCEEDED(result)); - - if (pixelShader) + if (FAILED(result)) { - executable = new ShaderExecutable11(function, length, pixelShader); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create pixel shader, result: 0x%X.", result); } + + *outExecutable = new ShaderExecutable11(function, length, pixelShader); } break; - case rx::SHADER_GEOMETRY: + case SHADER_GEOMETRY: { ID3D11GeometryShader *geometryShader = NULL; - result = mDevice->CreateGeometryShader(function, length, NULL, &geometryShader); + HRESULT result = mDevice->CreateGeometryShader(function, length, NULL, &geometryShader); ASSERT(SUCCEEDED(result)); - - if (geometryShader) + if (FAILED(result)) { - executable = new ShaderExecutable11(function, length, geometryShader); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create geometry shader, result: 0x%X.", result); } + + *outExecutable = new ShaderExecutable11(function, length, geometryShader); } break; default: UNREACHABLE(); - break; + return gl::Error(GL_INVALID_OPERATION); } - return executable; + return gl::Error(GL_NO_ERROR); } -ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, - const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, - bool separatedOutputBuffers, D3DWorkaroundType workaround) +gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type, + const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, + bool separatedOutputBuffers, D3DWorkaroundType workaround, + ShaderExecutable **outExectuable) { const char *profileType = NULL; switch (type) { - case rx::SHADER_VERTEX: + case SHADER_VERTEX: profileType = "vs"; break; - case rx::SHADER_PIXEL: + case SHADER_PIXEL: profileType = "ps"; break; - case rx::SHADER_GEOMETRY: + case SHADER_GEOMETRY: profileType = "gs"; break; default: UNREACHABLE(); - return NULL; + return gl::Error(GL_INVALID_OPERATION); } - const char *profileVersion = NULL; + unsigned int profileMajorVersion = 0; + unsigned int profileMinorVersion = 0; + const char *profileSuffix = NULL; switch (mFeatureLevel) { case D3D_FEATURE_LEVEL_11_0: - profileVersion = "5_0"; + profileMajorVersion = 5; + profileMinorVersion = 0; break; case D3D_FEATURE_LEVEL_10_1: - profileVersion = "4_1"; + profileMajorVersion = 4; + profileMinorVersion = 1; break; case D3D_FEATURE_LEVEL_10_0: - profileVersion = "4_0"; + profileMajorVersion = 4; + profileMinorVersion = 0; break; case D3D_FEATURE_LEVEL_9_3: - profileVersion = "4_0_level_9_3"; + profileMajorVersion = 4; + profileMinorVersion = 0; + profileSuffix = "_level_9_3"; break; case D3D_FEATURE_LEVEL_9_2: - profileVersion = "4_0_level_9_2"; + profileMajorVersion = 4; + profileMinorVersion = 0; + profileSuffix = "_level_9_2"; break; case D3D_FEATURE_LEVEL_9_1: - profileVersion = "4_0_level_9_1"; + profileMajorVersion = 4; + profileMinorVersion = 0; + profileSuffix = "_level_9_1"; break; + break; default: UNREACHABLE(); - return NULL; + return gl::Error(GL_INVALID_OPERATION); } - char profile[32]; - snprintf(profile, ArraySize(profile), "%s_%s", profileType, profileVersion); + std::string profile = FormatString("%s_%u_%u", profileType, profileMajorVersion, profileMinorVersion); + if (profileSuffix) + profile += profileSuffix; - UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL0; + UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL2; if (gl::perfActive()) { @@ -2464,44 +2559,51 @@ ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const ch #endif flags |= D3DCOMPILE_DEBUG; - - std::string sourcePath = getTempPath(); - std::string sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(shaderHLSL); - writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size()); } // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options. // Try the default flags first and if compilation fails, try some alternatives. - const UINT extraFlags[] = - { - flags, - flags | D3DCOMPILE_SKIP_VALIDATION, - flags | D3DCOMPILE_SKIP_OPTIMIZATION - }; + std::vector<CompileConfig> configs; + configs.push_back(CompileConfig(flags, "default" )); + configs.push_back(CompileConfig(flags | D3DCOMPILE_SKIP_VALIDATION, "skip validation" )); + configs.push_back(CompileConfig(flags | D3DCOMPILE_SKIP_OPTIMIZATION, "skip optimization")); - const static char *extraFlagNames[] = - { - "default", - "skip validation", - "skip optimization" - }; + D3D_SHADER_MACRO loopMacros[] = { {"ANGLE_ENABLE_LOOP_FLATTEN", "1"}, {0, 0} }; - int attempts = ArraySize(extraFlags); + ID3DBlob *binary = NULL; + std::string debugInfo; + gl::Error error = mCompiler.compileToBinary(infoLog, shaderHLSL, profile, configs, loopMacros, &binary, &debugInfo); + if (error.isError()) + { + return error; + } - ID3DBlob *binary = (ID3DBlob*)mCompiler.compileToBinary(infoLog, shaderHLSL, profile, extraFlags, extraFlagNames, attempts); + // It's possible that binary is NULL if the compiler failed in all configurations. Set the executable to NULL + // and return GL_NO_ERROR to signify that there was a link error but the internal state is still OK. if (!binary) { - return NULL; + *outExectuable = NULL; + return gl::Error(GL_NO_ERROR); } - ShaderExecutable *executable = loadExecutable((DWORD *)binary->GetBufferPointer(), binary->GetBufferSize(), type, - transformFeedbackVaryings, separatedOutputBuffers); + error = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type, + transformFeedbackVaryings, separatedOutputBuffers, outExectuable); + SafeRelease(binary); + if (error.isError()) + { + return error; + } + + if (!debugInfo.empty()) + { + (*outExectuable)->appendDebugInfo(debugInfo); + } - return executable; + return gl::Error(GL_NO_ERROR); } -rx::UniformStorage *Renderer11::createUniformStorage(size_t storageSize) +UniformStorage *Renderer11::createUniformStorage(size_t storageSize) { return new UniformStorage11(this, storageSize); } @@ -2531,9 +2633,14 @@ QueryImpl *Renderer11::createQuery(GLenum type) return new Query11(this, type); } -FenceImpl *Renderer11::createFence() +FenceNVImpl *Renderer11::createFenceNV() { - return new Fence11(this); + return new FenceNV11(this); +} + +FenceSyncImpl *Renderer11::createFenceSync() +{ + return new FenceSync11(this); } TransformFeedbackImpl* Renderer11::createTransformFeedback() @@ -2576,82 +2683,77 @@ bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const return true; } -bool Renderer11::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) +gl::Error Renderer11::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, + GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) { ASSERT(supportsFastCopyBufferToTexture(destinationFormat)); return mPixelTransfer->copyBufferToTexture(unpack, offset, destRenderTarget, destinationFormat, sourcePixelsType, destArea); } -bool Renderer11::getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource) +gl::Error Renderer11::getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndexOut, ID3D11Texture2D **texture2DOut) + { - ASSERT(colorbuffer != NULL); + ASSERT(colorbuffer); - RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); - if (renderTarget) + RenderTarget11 *renderTarget = NULL; + gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &renderTarget); + if (error.isError()) { - *subresourceIndex = renderTarget->getSubresourceIndex(); + return error; + } - ID3D11RenderTargetView *colorBufferRTV = renderTarget->getRenderTargetView(); - if (colorBufferRTV) - { - ID3D11Resource *textureResource = NULL; - colorBufferRTV->GetResource(&textureResource); + ID3D11Resource *renderTargetResource = renderTarget->getTexture(); + ASSERT(renderTargetResource); - if (textureResource) - { - HRESULT result = textureResource->QueryInterface(__uuidof(ID3D11Texture2D), (void**)resource); - SafeRelease(textureResource); + *subresourceIndexOut = renderTarget->getSubresourceIndex(); + *texture2DOut = d3d11::DynamicCastComObject<ID3D11Texture2D>(renderTargetResource); - if (SUCCEEDED(result)) - { - return true; - } - else - { - ERR("Failed to extract the ID3D11Texture2D from the render target resource, " - "HRESULT: 0x%X.", result); - } - } - } + if (!(*texture2DOut)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to query the ID3D11Texture2D from a RenderTarget"); } - return false; + return gl::Error(GL_NO_ERROR); } -bool Renderer11::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) +gl::Error Renderer11::blitRect(const gl::Framebuffer *readTarget, const gl::Rectangle &readRect, + const gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, + const gl::Rectangle *scissor, bool blitRenderTarget, + bool blitDepth, bool blitStencil, GLenum filter) { if (blitRenderTarget) { gl::FramebufferAttachment *readBuffer = readTarget->getReadColorbuffer(); + ASSERT(readBuffer); - if (!readBuffer) + RenderTarget *readRenderTarget = NULL; + gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget); + if (error.isError()) { - ERR("Failed to retrieve the read buffer from the read framebuffer."); - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } - - RenderTarget *readRenderTarget = GetAttachmentRenderTarget(readBuffer); + ASSERT(readRenderTarget); for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) { if (drawTarget->isEnabledColorAttachment(colorAttachment)) { gl::FramebufferAttachment *drawBuffer = drawTarget->getColorbuffer(colorAttachment); + ASSERT(drawBuffer); - if (!drawBuffer) + RenderTarget *drawRenderTarget = NULL; + error = GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget); + if (error.isError()) { - ERR("Failed to retrieve the draw buffer from the draw framebuffer."); - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } + ASSERT(drawRenderTarget); - RenderTarget *drawRenderTarget = GetAttachmentRenderTarget(drawBuffer); - - if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, - blitRenderTarget, false, false)) + error = blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, blitRenderTarget, + false, false); + if (error.isError()) { - return false; + return error; } } } @@ -2660,78 +2762,88 @@ bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &read if (blitDepth || blitStencil) { gl::FramebufferAttachment *readBuffer = readTarget->getDepthOrStencilbuffer(); - gl::FramebufferAttachment *drawBuffer = drawTarget->getDepthOrStencilbuffer(); + ASSERT(readBuffer); - if (!readBuffer) + RenderTarget *readRenderTarget = NULL; + gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget); + if (error.isError()) { - ERR("Failed to retrieve the read depth-stencil buffer from the read framebuffer."); - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } + ASSERT(readRenderTarget); - if (!drawBuffer) + gl::FramebufferAttachment *drawBuffer = drawTarget->getDepthOrStencilbuffer(); + ASSERT(drawBuffer); + + RenderTarget *drawRenderTarget = NULL; + error = GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget); + if (error.isError()) { - ERR("Failed to retrieve the draw depth-stencil buffer from the draw framebuffer."); - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } + ASSERT(drawRenderTarget); - RenderTarget *readRenderTarget = GetAttachmentRenderTarget(readBuffer); - RenderTarget *drawRenderTarget = GetAttachmentRenderTarget(drawBuffer); - ASSERT(readRenderTarget && drawRenderTarget); - - if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, - false, blitDepth, blitStencil)) + error = blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, false, + blitDepth, blitStencil); + if (error.isError()) { - return false; + return error; } } invalidateFramebufferSwizzles(drawTarget); - return true; + return gl::Error(GL_NO_ERROR); } -gl::Error Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, +gl::Error Renderer11::readPixels(const 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; gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); + ASSERT(colorbuffer); - if (colorbuffer && getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture)) + gl::Error error = getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture); + if (error.isError()) { - gl::Rectangle area; - area.x = x; - area.y = y; - area.width = width; - area.height = height; + return error; + } - gl::Buffer *packBuffer = pack.pixelBuffer.get(); - if (packBuffer != NULL) - { - rx::Buffer11 *packBufferStorage = Buffer11::makeBuffer11(packBuffer->getImplementation()); - PackPixelsParams packParams(area, format, type, outputPitch, pack, reinterpret_cast<ptrdiff_t>(pixels)); + gl::Rectangle area; + area.x = x; + area.y = y; + area.width = width; + area.height = height; - gl::Error error = packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams); - if (error.isError()) - { - return error; - } + gl::Buffer *packBuffer = pack.pixelBuffer.get(); + if (packBuffer != NULL) + { + Buffer11 *packBufferStorage = Buffer11::makeBuffer11(packBuffer->getImplementation()); + PackPixelsParams packParams(area, format, type, outputPitch, pack, reinterpret_cast<ptrdiff_t>(pixels)); - packBuffer->getIndexRangeCache()->clear(); - } - else + error = packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams); + if (error.isError()) { - gl::Error error = readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels); - if (error.isError()) - { - return error; - } + SafeRelease(colorBufferTexture); + return error; } - SafeRelease(colorBufferTexture); + packBuffer->getIndexRangeCache()->clear(); + } + else + { + error = readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels); + if (error.isError()) + { + SafeRelease(colorBufferTexture); + return error; + } } + SafeRelease(colorBufferTexture); + return gl::Error(GL_NO_ERROR); } @@ -2740,11 +2852,11 @@ Image *Renderer11::createImage() return new Image11(); } -void Renderer11::generateMipmap(Image *dest, Image *src) +gl::Error Renderer11::generateMipmap(Image *dest, Image *src) { Image11 *dest11 = Image11::makeImage11(dest); Image11 *src11 = Image11::makeImage11(src); - Image11::generateMipmap(dest11, src11); + return Image11::generateMipmap(dest11, src11); } TextureStorage *Renderer11::createTextureStorage2D(SwapChain *swapChain) @@ -2788,6 +2900,19 @@ TextureImpl *Renderer11::createTexture(GLenum target) return NULL; } +RenderbufferImpl *Renderer11::createRenderbuffer() +{ + RenderbufferD3D *renderbuffer = new RenderbufferD3D(this); + return renderbuffer; +} + +RenderbufferImpl *Renderer11::createRenderbuffer(SwapChain *swapChain, bool depth) +{ + RenderbufferD3D *renderbuffer = new RenderbufferD3D(this); + renderbuffer->setStorage(swapChain, depth); + return renderbuffer; +} + gl::Error Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format, GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) { @@ -2882,22 +3007,25 @@ gl::Error Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int sub SafeRelease(srcTex); PackPixelsParams packParams(safeArea, format, type, outputPitch, pack, 0); - packPixels(stagingTex, packParams, pixels); + gl::Error error = packPixels(stagingTex, packParams, pixels); SafeRelease(stagingTex); - return gl::Error(GL_NO_ERROR); + return error; } -void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams ¶ms, uint8_t *pixelsOut) +gl::Error Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams ¶ms, uint8_t *pixelsOut) { D3D11_TEXTURE2D_DESC textureDesc; readTexture->GetDesc(&textureDesc); D3D11_MAPPED_SUBRESOURCE mapping; HRESULT hr = mDeviceContext->Map(readTexture, 0, D3D11_MAP_READ, 0, &mapping); - UNUSED_ASSERTION_VARIABLE(hr); - ASSERT(SUCCEEDED(hr)); + if (FAILED(hr)) + { + ASSERT(hr == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal texture for reading, result: 0x%X.", hr); + } uint8_t *source; int inputPitch; @@ -2968,24 +3096,23 @@ void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams } mDeviceContext->Unmap(readTexture, 0); + + return gl::Error(GL_NO_ERROR); } -bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget, - RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor, - bool colorBlit, bool depthBlit, bool stencilBlit) +gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget, + RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor, + bool colorBlit, bool depthBlit, bool stencilBlit) { // Since blitRenderbufferRect is called for each render buffer that needs to be blitted, // it should never be the case that both color and depth/stencil need to be blitted at // at the same time. ASSERT(colorBlit != (depthBlit || stencilBlit)); - bool result = true; - RenderTarget11 *drawRenderTarget11 = RenderTarget11::makeRenderTarget11(drawRenderTarget); if (!drawRenderTarget) { - ERR("Failed to retrieve the draw render target from the draw framebuffer."); - return gl::error(GL_OUT_OF_MEMORY, false); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal draw render target from the draw framebuffer."); } ID3D11Resource *drawTexture = drawRenderTarget11->getTexture(); @@ -2996,8 +3123,7 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R RenderTarget11 *readRenderTarget11 = RenderTarget11::makeRenderTarget11(readRenderTarget); if (!readRenderTarget) { - ERR("Failed to retrieve the read render target from the read framebuffer."); - return gl::error(GL_OUT_OF_MEMORY, false); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal read render target from the read framebuffer."); } ID3D11Resource *readTexture = NULL; @@ -3019,7 +3145,7 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R if (FAILED(hresult)) { SafeRelease(readTexture); - return gl::error(GL_OUT_OF_MEMORY, false); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create shader resource view to resolve multisampled framebuffer."); } } } @@ -3036,8 +3162,7 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R { SafeRelease(readTexture); SafeRelease(readSRV); - ERR("Failed to retrieve the read render target view from the read render target."); - return gl::error(GL_OUT_OF_MEMORY, false); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal read render target view from the read render target."); } gl::Extents readSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1); @@ -3063,6 +3188,8 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(drawRenderTarget->getActualFormat()); bool partialDSBlit = (actualFormatInfo.depthBits > 0 && depthBlit) != (actualFormatInfo.stencilBits > 0 && stencilBlit); + gl::Error result(GL_NO_ERROR); + if (readRenderTarget11->getActualFormat() == drawRenderTarget->getActualFormat() && !stretchRequired && !outOfBounds && !flipRequired && !partialDSBlit && (!(depthBlit || stencilBlit) || wholeBufferCopy)) @@ -3109,7 +3236,7 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R mDeviceContext->CopySubresourceRegion(drawTexture, drawSubresource, dstX, dstY, 0, readTexture, readSubresource, pSrcBox); - result = true; + result = gl::Error(GL_NO_ERROR); } else { @@ -3190,7 +3317,8 @@ void Renderer11::invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *atta ASSERT(attachment->isTexture()); gl::Texture *texture = attachment->getTexture(); - TextureStorage *texStorage = texture->getNativeTexture(); + TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation()); + TextureStorage *texStorage = textureD3D->getNativeTexture(); if (texStorage) { TextureStorage11 *texStorage11 = TextureStorage11::makeTextureStorage11(texStorage); @@ -3204,7 +3332,7 @@ void Renderer11::invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *atta } } -void Renderer11::invalidateFramebufferSwizzles(gl::Framebuffer *framebuffer) +void Renderer11::invalidateFramebufferSwizzles(const gl::Framebuffer *framebuffer) { for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) { @@ -3248,7 +3376,7 @@ bool Renderer11::getLUID(LUID *adapterLuid) const return true; } -rx::VertexConversionType Renderer11::getVertexConversionType(const gl::VertexFormat &vertexFormat) const +VertexConversionType Renderer11::getVertexConversionType(const gl::VertexFormat &vertexFormat) const { return d3d11::GetVertexFormatInfo(vertexFormat).conversionType; } @@ -3263,4 +3391,30 @@ void Renderer11::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureC d3d11_gl::GenerateCaps(mDevice, outCaps, outTextureCaps, outExtensions); } +Workarounds Renderer11::generateWorkarounds() const +{ + return d3d11::GenerateWorkarounds(); +} + +void Renderer11::setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, ID3D11ShaderResourceView *srv) +{ + std::vector<ID3D11ShaderResourceView *> ¤tSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs); + + ASSERT(static_cast<size_t>(resourceSlot) < currentSRVs.size()); + + if (currentSRVs[resourceSlot] != srv) + { + if (shaderType == gl::SAMPLER_VERTEX) + { + mDeviceContext->VSSetShaderResources(resourceSlot, 1, &srv); + } + else + { + mDeviceContext->PSSetShaderResources(resourceSlot, 1, &srv); + } + + currentSRVs[resourceSlot] = srv; + } +} + } 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 2a53fa1672..d44bd2fd30 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h @@ -13,12 +13,14 @@ #include "libGLESv2/angletypes.h" #include "common/mathutil.h" -#include "libGLESv2/renderer/Renderer.h" -#include "libGLESv2/renderer/d3d/HLSLCompiler.h" #include "libGLESv2/renderer/d3d/d3d11/RenderStateCache.h" #include "libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h" +#include "libGLESv2/renderer/d3d/HLSLCompiler.h" +#include "libGLESv2/renderer/d3d/RendererD3D.h" #include "libGLESv2/renderer/RenderTarget.h" +#include "libEGL/AttributeMap.h" + namespace gl { class FramebufferAttachment; @@ -33,6 +35,7 @@ class StreamingIndexBufferInterface; class Blit11; class Clear11; class PixelTransfer11; +class RenderTarget11; struct PackPixelsParams; enum @@ -41,10 +44,10 @@ enum MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 = 1024 }; -class Renderer11 : public Renderer +class Renderer11 : public RendererD3D { public: - Renderer11(egl::Display *display, EGLNativeDisplayType hDc, EGLint requestedDisplay); + Renderer11(egl::Display *display, EGLNativeDisplayType hDc, const egl::AttributeMap &attributes); virtual ~Renderer11(); static Renderer11 *makeRenderer11(Renderer *renderer); @@ -55,19 +58,19 @@ class Renderer11 : public Renderer virtual int generateConfigs(ConfigDesc **configDescList); virtual void deleteConfigs(ConfigDesc *configDescList); - virtual void sync(bool block); + virtual gl::Error sync(bool block); - virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat); + virtual SwapChain *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat); virtual gl::Error generateSwizzle(gl::Texture *texture); - virtual gl::Error setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler); + virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler); virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture); virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]); 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); + gl::Error setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, + unsigned int sampleMask) override; virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, int stencilBackRef, bool frontFaceCCW); @@ -76,32 +79,32 @@ class Renderer11 : public Renderer bool ignoreViewport); virtual bool applyPrimitiveType(GLenum mode, GLsizei count); - virtual gl::Error applyRenderTarget(gl::Framebuffer *frameBuffer); + gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override; 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 applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray); + virtual gl::Error applyVertexBuffer(const gl::State &state, 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 applyTransformFeedbackBuffers(const gl::State &state); 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 gl::Error clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); + gl::Error clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer) override; virtual void markAllStateDirty(); // lost device - void notifyDeviceLost(); - virtual bool isDeviceLost(); - virtual bool testDeviceLost(bool notify); - virtual bool testDeviceResettable(); + void notifyDeviceLost() override; + bool isDeviceLost() override; + bool testDeviceLost(bool notify) override; + bool testDeviceResettable() override; - virtual DWORD getAdapterVendor() const; - virtual std::string getRendererDescription() const; - virtual GUID getAdapterIdentifier() const; + DWORD getAdapterVendor() const override; + std::string getRendererDescription() const override; + GUID getAdapterIdentifier() const override; virtual unsigned int getReservedVertexUniformVectors() const; virtual unsigned int getReservedFragmentUniformVectors() const; @@ -115,47 +118,43 @@ class Renderer11 : public Renderer virtual int getMaxSwapInterval() const; // Pixel operations - 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, + virtual gl::Error copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level); + virtual gl::Error copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level); + virtual gl::Error copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level); + virtual gl::Error 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); + gl::Error blitRect(const gl::Framebuffer *readTarget, const gl::Rectangle &readRect, const gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, + const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter) override; - virtual gl::Error readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, + virtual gl::Error readPixels(const 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); + virtual gl::Error createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT); + virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT); // Shader creation - virtual ShaderImpl *createShader(GLenum type); + virtual ShaderImpl *createShader(const gl::Data &data, 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); - virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, - const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, - bool separatedOutputBuffers, D3DWorkaroundType workaround); + void releaseShaderCompiler() override; + virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type, + const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, + bool separatedOutputBuffers, ShaderExecutable **outExecutable); + virtual gl::Error compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type, + const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, + bool separatedOutputBuffers, D3DWorkaroundType workaround, + ShaderExecutable **outExectuable); virtual UniformStorage *createUniformStorage(size_t storageSize); // Image operations virtual Image *createImage(); - virtual void generateMipmap(Image *dest, Image *source); + gl::Error generateMipmap(Image *dest, Image *source) override; virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain); virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels); virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels); @@ -165,6 +164,10 @@ class Renderer11 : public Renderer // Texture creation virtual TextureImpl *createTexture(GLenum target); + // Renderbuffer creation + virtual RenderbufferImpl *createRenderbuffer(); + virtual RenderbufferImpl *createRenderbuffer(SwapChain *swapChain, bool depth); + // Buffer creation virtual BufferImpl *createBuffer(); virtual VertexBuffer *createVertexBuffer(); @@ -175,7 +178,8 @@ class Renderer11 : public Renderer // Query and Fence creation virtual QueryImpl *createQuery(GLenum type); - virtual FenceImpl *createFence(); + virtual FenceNVImpl *createFenceNV(); + virtual FenceSyncImpl *createFenceSync(); // Transform Feedback creation virtual TransformFeedbackImpl* createTransformFeedback(); @@ -183,48 +187,54 @@ class Renderer11 : public Renderer // D3D11-renderer specific methods ID3D11Device *getDevice() { return mDevice; } ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; }; - IDXGIFactory *getDxgiFactory() { return mDxgiFactory; }; + DXGIFactory *getDxgiFactory() { return mDxgiFactory; }; bool isLevel9() { return mFeatureLevel <= D3D_FEATURE_LEVEL_9_3; } Blit11 *getBlitter() { return mBlit; } // Buffer-to-texture and Texture-to-buffer copies virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const; - virtual bool fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); + virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, + GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); + + gl::Error getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndexOut, ID3D11Texture2D **texture2DOut); - bool getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource); void unapplyRenderTargets(); void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView); - void packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams ¶ms, uint8_t *pixelsOut); + gl::Error packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams ¶ms, uint8_t *pixelsOut); virtual bool getLUID(LUID *adapterLuid) const; - virtual rx::VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const; + virtual VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const; virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const; + gl::Error readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format, + GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels); + + void setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, ID3D11ShaderResourceView *srv); + private: DISALLOW_COPY_AND_ASSIGN(Renderer11); - virtual void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const; + void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const override; + Workarounds generateWorkarounds() const override; gl::Error drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); gl::Error drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances); - 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, - bool colorBlit, bool depthBlit, bool stencilBlit); + gl::Error blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget, + RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor, + bool colorBlit, bool depthBlit, bool stencilBlit); ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource); + void unsetSRVsWithResource(gl::SamplerType shaderType, const ID3D11Resource *resource); static void invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *attachment, int mipLevel); - static void invalidateFramebufferSwizzles(gl::Framebuffer *framebuffer); + static void invalidateFramebufferSwizzles(const gl::Framebuffer *framebuffer); HMODULE mD3d11Module; HMODULE mDxgiModule; EGLNativeDisplayType mDc; - EGLint mRequestedDisplay; + std::vector<D3D_FEATURE_LEVEL> mAvailableFeatureLevels; + D3D_DRIVER_TYPE mDriverType; HLSLCompiler mCompiler; @@ -243,7 +253,7 @@ class Renderer11 : public Renderer unsigned int mAppliedStencilbufferSerial; bool mDepthStencilInitialized; bool mRenderTargetDescInitialized; - rx::RenderTarget::Desc mRenderTargetDesc; + RenderTarget::Desc mRenderTargetDesc; // Currently applied sampler states std::vector<bool> mForceSetVertexSamplerStates; @@ -292,8 +302,14 @@ class Renderer11 : public Renderer unsigned int mAppliedIBOffset; // Currently applied transform feedback buffers - ID3D11Buffer *mAppliedTFBuffers[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; - GLintptr mAppliedTFOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; + ID3D11Buffer *mAppliedTFBuffers[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; // Tracks the current D3D buffers + // in use for streamout + GLintptr mAppliedTFOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; // Tracks the current GL-specified + // buffer offsets to transform feedback + // buffers + UINT mCurrentD3DOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; // Tracks the D3D buffer offsets, + // which may differ from GLs, due + // to different append behavior // Currently applied shaders ID3D11VertexShader *mAppliedVertexShader; @@ -339,7 +355,7 @@ class Renderer11 : public Renderer IDXGIAdapter *mDxgiAdapter; DXGI_ADAPTER_DESC mAdapterDescription; char mDescription[128]; - IDXGIFactory *mDxgiFactory; + DXGIFactory *mDxgiFactory; }; } 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 4b29be055d..52c8a81633 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp @@ -6,7 +6,6 @@ // SwapChain11.cpp: Implements a back-end specific class for the D3D11 swap chain. -#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" @@ -16,12 +15,16 @@ #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough2dvs.h" #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dps.h" +#include "common/features.h" +#include "common/NativeWindow.h" + namespace rx { -SwapChain11::SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle, +SwapChain11::SwapChain11(Renderer11 *renderer, NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) - : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat) + : mRenderer(renderer), + SwapChain(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat) { mSwapChain = NULL; mBackBufferTexture = NULL; @@ -39,8 +42,8 @@ SwapChain11::SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDL mPassThroughPS = NULL; mWidth = -1; mHeight = -1; - mViewportWidth = -1; - mViewportHeight = -1; + mRotateL = false; + mRotateR = false; mSwapInterval = 0; mAppCreatedShareHandle = mShareHandle != NULL; mPassThroughResourcesInit = false; @@ -91,11 +94,11 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei ASSERT(device != NULL); // D3D11 does not allow zero size textures - ASSERT(backbufferWidth >= 1); - ASSERT(backbufferHeight >= 1); + ASSERT(backbufferWidth != 0); + ASSERT(backbufferHeight != 0); // Preserve the render target content -#if !defined(ANGLE_PLATFORM_WINRT) +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) ID3D11Texture2D *previousOffscreenTexture = mOffscreenTexture; if (previousOffscreenTexture) { @@ -137,8 +140,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; mOffscreenTexture->GetDesc(&offscreenTextureDesc); - if (offscreenTextureDesc.Width != (UINT)backbufferWidth || - offscreenTextureDesc.Height != (UINT)backbufferHeight || + if (offscreenTextureDesc.Width != UINT(abs(backbufferWidth)) || + offscreenTextureDesc.Height != UINT(abs(backbufferHeight)) || offscreenTextureDesc.Format != backbufferFormatInfo.texFormat || offscreenTextureDesc.MipLevels != 1 || offscreenTextureDesc.ArraySize != 1) @@ -150,11 +153,11 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei } else { - const bool useSharedResource = !mWindow && mRenderer->getShareHandleSupport(); + const bool useSharedResource = !mNativeWindow.getNativeWindow() && mRenderer->getShareHandleSupport(); D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; - offscreenTextureDesc.Width = backbufferWidth; - offscreenTextureDesc.Height = backbufferHeight; + offscreenTextureDesc.Width = abs(backbufferWidth); + offscreenTextureDesc.Height = abs(backbufferHeight); offscreenTextureDesc.Format = backbufferFormatInfo.texFormat; offscreenTextureDesc.MipLevels = 1; offscreenTextureDesc.ArraySize = 1; @@ -234,8 +237,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei if (mDepthBufferFormat != GL_NONE) { D3D11_TEXTURE2D_DESC depthStencilTextureDesc; - depthStencilTextureDesc.Width = backbufferWidth; - depthStencilTextureDesc.Height = backbufferHeight; + depthStencilTextureDesc.Width = abs(backbufferWidth); + depthStencilTextureDesc.Height = abs(backbufferHeight); depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat; depthStencilTextureDesc.MipLevels = 1; depthStencilTextureDesc.ArraySize = 1; @@ -286,12 +289,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei mWidth = backbufferWidth; mHeight = backbufferHeight; -#if !defined(ANGLE_PLATFORM_WINRT) || WINAPI_FAMILY==WINAPI_FAMILY_PC_APP - mViewportWidth = backbufferWidth; - mViewportHeight = backbufferHeight; -#endif -#if !defined(ANGLE_PLATFORM_WINRT) +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) if (previousOffscreenTexture != NULL) { D3D11_BOX sourceBox = {0}; @@ -310,7 +309,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei if (mSwapChain) { - swapRect(0, 0, mWidth, mHeight, SWAP_NORMAL); + swapRect(0, 0, mWidth, mHeight); } } #endif @@ -327,8 +326,16 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) return EGL_BAD_ACCESS; } + // Windows Phone works around the rotation limitation by using negative values for the swap chain size +#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) + mRotateL = backbufferWidth < 0; // Landscape/InvertedLandscape + mRotateR = backbufferHeight < 0; // InvertedPortrait/InvertedLandscape + backbufferWidth = abs(backbufferWidth); + backbufferHeight = abs(backbufferHeight); +#endif + // EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains - if (backbufferWidth < 1 || backbufferHeight < 1) + if (backbufferWidth == 0 || backbufferHeight == 0) { return EGL_SUCCESS; } @@ -336,19 +343,15 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) // Can only call resize if we have already created our swap buffer and resources ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView); +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) // The swap chain is not directly resized on Windows Phone SafeRelease(mBackBufferTexture); SafeRelease(mBackBufferRTView); // Resize swap chain - HRESULT result; -#if !defined(ANGLE_PLATFORM_WINRT) || WINAPI_FAMILY==WINAPI_FAMILY_PC_APP // Windows phone swap chain is never resized, only the texture is -#if !defined(ANGLE_PLATFORM_WINRT) - const int bufferCount = 1; -#else - const int bufferCount = 2; -#endif + DXGI_SWAP_CHAIN_DESC desc; + mSwapChain->GetDesc(&desc); const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat); - result = mSwapChain->ResizeBuffers(bufferCount, backbufferWidth, backbufferHeight, backbufferFormatInfo.texFormat, 0); + HRESULT result = mSwapChain->ResizeBuffers(desc.BufferCount, backbufferWidth, backbufferHeight, backbufferFormatInfo.texFormat, 0); if (FAILED(result)) { @@ -364,7 +367,6 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) return EGL_BAD_ALLOC; } } -#endif result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture); ASSERT(SUCCEEDED(result)); @@ -379,6 +381,7 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) { d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target"); } +#endif return resetOffscreenTexture(backbufferWidth, backbufferHeight); } @@ -412,62 +415,14 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap return EGL_SUCCESS; } - if (mWindow) + if (mNativeWindow.getNativeWindow()) { 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 = backbufferFormatInfo.texFormat; - swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; - swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; - swapChainDesc.SampleDesc.Count = 1; - swapChainDesc.SampleDesc.Quality = 0; - swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapChainDesc.BufferCount = 1; - swapChainDesc.OutputWindow = mWindow; - swapChainDesc.Windowed = TRUE; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; - swapChainDesc.Flags = 0; - - HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain); -#else - IDXGIFactory2 *factory2; - HRESULT result = factory->QueryInterface(IID_PPV_ARGS(&factory2)); - ASSERT(SUCCEEDED(result)); - - DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0}; - swapChainDesc.Width = 0; - swapChainDesc.Height = 0; - swapChainDesc.Format = backbufferFormatInfo.texFormat; - swapChainDesc.SampleDesc.Count = 1; - swapChainDesc.SampleDesc.Quality = 0; - swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapChainDesc.Stereo = FALSE; - swapChainDesc.Flags = 0; -#if WINAPI_FAMILY==WINAPI_FAMILY_PC_APP - swapChainDesc.Scaling = DXGI_SCALING_NONE; - swapChainDesc.BufferCount = 2; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; -#elif WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP - swapChainDesc.BufferCount = 1; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; -#endif + HRESULT result = mNativeWindow.createSwapChain(device, mRenderer->getDxgiFactory(), + backbufferFormatInfo.texFormat, + backbufferWidth, backbufferHeight, &mSwapChain); - IDXGISwapChain1 *swapChain; - result = factory2->CreateSwapChainForCoreWindow(device, mWindow, &swapChainDesc, NULL, &swapChain); - mSwapChain = swapChain; - HRESULT hr = swapChain->GetDesc1(&swapChainDesc); - ASSERT(SUCCEEDED(hr)); - mViewportWidth = swapChainDesc.Width; - mViewportHeight = swapChainDesc.Height; -#endif if (FAILED(result)) { ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result); @@ -537,7 +492,7 @@ void SwapChain11::initPassThroughResources() samplerDesc.BorderColor[2] = 0.0f; samplerDesc.BorderColor[3] = 0.0f; samplerDesc.MinLOD = 0; - samplerDesc.MaxLOD = FLT_MAX; + samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; result = device->CreateSamplerState(&samplerDesc, &mPassThroughSampler); ASSERT(SUCCEEDED(result)); @@ -563,7 +518,7 @@ void SwapChain11::initPassThroughResources() } // parameters should be validated/clamped by caller -EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint flags) +EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) { if (!mSwapChain) { @@ -573,16 +528,6 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EG ID3D11Device *device = mRenderer->getDevice(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - // Set vertices - D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = deviceContext->Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); - if (FAILED(result)) - { - return EGL_BAD_ACCESS; - } - - d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData); - // Create a quad in homogeneous coordinates float x1 = (x / float(mWidth)) * 2.0f - 1.0f; float y1 = (y / float(mHeight)) * 2.0f - 1.0f; @@ -594,8 +539,18 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EG float u2 = (x + width) / float(mWidth); float v2 = (y + height) / float(mHeight); - const int rotateL = flags & SWAP_ROTATE_90; - const int rotateR = flags & SWAP_ROTATE_270; + const bool rotateL = mRotateL; + const bool rotateR = mRotateR; + + // Set vertices + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = deviceContext->Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + return EGL_BAD_ACCESS; + } + + d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData); d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, rotateL ? u2 : u1, rotateR ? v2 : v1); d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, rotateR ? u2 : u1, rotateL ? v1 : v2); @@ -628,22 +583,23 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EG // Set the viewport D3D11_VIEWPORT viewport; - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; - viewport.Width = mViewportWidth; - viewport.Height = mViewportHeight; + viewport.TopLeftX = 0.0f; + viewport.TopLeftY = 0.0f; + const bool invertViewport = (mRotateL || mRotateR) && !(mRotateL && mRotateR); + viewport.Width = FLOAT(invertViewport ? mHeight : mWidth); + viewport.Height = FLOAT(invertViewport ? mWidth : mHeight); viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; deviceContext->RSSetViewports(1, &viewport); // Apply textures - deviceContext->PSSetShaderResources(0, 1, &mOffscreenSRView); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, mOffscreenSRView); deviceContext->PSSetSamplers(0, 1, &mPassThroughSampler); // Draw deviceContext->Draw(4, 0); -#ifdef ANGLE_FORCE_VSYNC_OFF +#if ANGLE_VSYNC == ANGLE_DISABLED result = mSwapChain->Present(0, 0); #else result = mSwapChain->Present(mSwapInterval, 0); @@ -667,8 +623,7 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EG } // Unbind - static ID3D11ShaderResourceView *const nullSRV = NULL; - deviceContext->PSSetShaderResources(0, 1, &nullSRV); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); mRenderer->unapplyRenderTargets(); mRenderer->markAllStateDirty(); @@ -708,8 +663,8 @@ ID3D11Texture2D *SwapChain11::getDepthStencilTexture() SwapChain11 *SwapChain11::makeSwapChain11(SwapChain *swapChain) { - ASSERT(HAS_DYNAMIC_TYPE(rx::SwapChain11*, swapChain)); - return static_cast<rx::SwapChain11*>(swapChain); + ASSERT(HAS_DYNAMIC_TYPE(SwapChain11*, swapChain)); + return static_cast<SwapChain11*>(swapChain); } void SwapChain11::recreate() diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h index b30b78568a..77509edcd3 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h @@ -19,13 +19,13 @@ class Renderer11; class SwapChain11 : public SwapChain { public: - SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle, + SwapChain11(Renderer11 *renderer, NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat); virtual ~SwapChain11(); EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight); virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval); - virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint flags); + virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height); virtual void recreate(); virtual ID3D11Texture2D *getOffscreenTexture(); @@ -52,13 +52,13 @@ class SwapChain11 : public SwapChain Renderer11 *mRenderer; EGLint mHeight; EGLint mWidth; - EGLint mViewportWidth; - EGLint mViewportHeight; + bool mRotateL; + bool mRotateR; bool mAppCreatedShareHandle; unsigned int mSwapInterval; bool mPassThroughResourcesInit; - IDXGISwapChain *mSwapChain; + DXGISwapChain *mSwapChain; ID3D11Texture2D *mBackBufferTexture; ID3D11RenderTargetView *mBackBufferRTView; 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 91e7147da6..74af27e8b3 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp @@ -8,6 +8,9 @@ // classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture. #include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h" + +#include <tuple> + #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h" #include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h" @@ -15,6 +18,7 @@ #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/MemoryBuffer.h" #include "libGLESv2/renderer/d3d/TextureD3D.h" #include "libGLESv2/main.h" #include "libGLESv2/ImageIndex.h" @@ -52,46 +56,16 @@ TextureStorage11::SRVKey::SRVKey(int baseLevel, int mipLevels, bool swizzle) { } -bool TextureStorage11::SRVKey::operator==(const SRVKey &rhs) const -{ - return baseLevel == rhs.baseLevel && - mipLevels == rhs.mipLevels && - swizzle == rhs.swizzle; -} - -TextureStorage11::SRVCache::~SRVCache() +bool TextureStorage11::SRVKey::operator<(const SRVKey &rhs) const { - for (size_t i = 0; i < cache.size(); i++) - { - SafeRelease(cache[i].srv); - } + return std::tie(baseLevel, mipLevels, swizzle) < std::tie(rhs.baseLevel, rhs.mipLevels, rhs.swizzle); } -ID3D11ShaderResourceView *TextureStorage11::SRVCache::find(const SRVKey &key) const -{ - for (size_t i = 0; i < cache.size(); i++) - { - if (cache[i].key == key) - { - return cache[i].srv; - } - } - - return NULL; -} - -ID3D11ShaderResourceView *TextureStorage11::SRVCache::add(const SRVKey &key, ID3D11ShaderResourceView *srv) -{ - SRVPair pair = {key, srv}; - cache.push_back(pair); - - return srv; -} - -TextureStorage11::TextureStorage11(Renderer *renderer, UINT bindFlags) +TextureStorage11::TextureStorage11(Renderer11 *renderer, UINT bindFlags) : mBindFlags(bindFlags), mTopLevel(0), mMipLevels(0), + mInternalFormat(GL_NONE), mTextureFormat(DXGI_FORMAT_UNKNOWN), mShaderResourceFormat(DXGI_FORMAT_UNKNOWN), mRenderTargetFormat(DXGI_FORMAT_UNKNOWN), @@ -114,6 +88,12 @@ TextureStorage11::~TextureStorage11() { SafeRelease(mLevelSRVs[level]); } + + for (SRVCache::iterator i = mSrvCache.begin(); i != mSrvCache.end(); i++) + { + SafeRelease(i->second); + } + mSrvCache.clear(); } TextureStorage11 *TextureStorage11::makeTextureStorage11(TextureStorage *storage) @@ -183,17 +163,16 @@ int TextureStorage11::getLevelDepth(int mipLevel) const return std::max(static_cast<int>(mTextureDepth) >> mipLevel, 1); } -UINT TextureStorage11::getSubresourceIndex(int mipLevel, int layerTarget) const +UINT TextureStorage11::getSubresourceIndex(const gl::ImageIndex &index) const { - UINT index = 0; - if (getResource()) - { - index = D3D11CalcSubresource(mipLevel, layerTarget, mMipLevels); - } - return index; + UINT mipSlice = static_cast<UINT>(index.mipIndex + mTopLevel); + UINT arraySlice = static_cast<UINT>(index.hasLayer() ? index.layerIndex : 0); + UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels); + ASSERT(subresource != std::numeric_limits<UINT>::max()); + return subresource; } -ID3D11ShaderResourceView *TextureStorage11::getSRV(const gl::SamplerState &samplerState) +gl::Error TextureStorage11::getSRV(const gl::SamplerState &samplerState, ID3D11ShaderResourceView **outSRV) { bool swizzleRequired = samplerState.swizzleRequired(); bool mipmapping = gl::IsMipmapFiltered(samplerState); @@ -206,38 +185,71 @@ ID3D11ShaderResourceView *TextureStorage11::getSRV(const gl::SamplerState &sampl { verifySwizzleExists(samplerState.swizzleRed, samplerState.swizzleGreen, samplerState.swizzleBlue, samplerState.swizzleAlpha); } - - SRVKey key(samplerState.baseLevel, mipLevels, swizzleRequired); - ID3D11ShaderResourceView *srv = srvCache.find(key); - if(srv) + SRVKey key(samplerState.baseLevel, mipLevels, swizzleRequired); + SRVCache::const_iterator iter = mSrvCache.find(key); + if (iter != mSrvCache.end()) { - return srv; + *outSRV = iter->second; } + else + { + ID3D11Resource *texture = NULL; + if (swizzleRequired) + { + gl::Error error = getSwizzleTexture(&texture); + if (error.isError()) + { + return error; + } + } + else + { + gl::Error error = getResource(&texture); + if (error.isError()) + { + return error; + } + } - DXGI_FORMAT format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat); - ID3D11Resource *texture = swizzleRequired ? getSwizzleTexture() : getResource(); + ID3D11ShaderResourceView *srv = NULL; + DXGI_FORMAT format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat); + gl::Error error = createSRV(samplerState.baseLevel, mipLevels, format, texture, &srv); + if (error.isError()) + { + return error; + } + + mSrvCache.insert(std::make_pair(key, srv)); + *outSRV = srv; + } - srv = createSRV(samplerState.baseLevel, mipLevels, format, texture); - - return srvCache.add(key, srv); + return gl::Error(GL_NO_ERROR); } -ID3D11ShaderResourceView *TextureStorage11::getSRVLevel(int mipLevel) +gl::Error TextureStorage11::getSRVLevel(int mipLevel, ID3D11ShaderResourceView **outSRV) { - if (mipLevel >= 0 && mipLevel < getLevelCount()) + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + + if (!mLevelSRVs[mipLevel]) { - if (!mLevelSRVs[mipLevel]) + ID3D11Resource *resource = NULL; + gl::Error error = getResource(&resource); + if (error.isError()) { - mLevelSRVs[mipLevel] = createSRV(mipLevel, 1, mShaderResourceFormat, getResource()); + return error; } - return mLevelSRVs[mipLevel]; - } - else - { - return NULL; + error = createSRV(mipLevel, 1, mShaderResourceFormat, resource, &mLevelSRVs[mipLevel]); + if (error.isError()) + { + return error; + } } + + *outSRV = mLevelSRVs[mipLevel]; + + return gl::Error(GL_NO_ERROR); } gl::Error TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha) @@ -249,14 +261,25 @@ gl::Error TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGr if (mSwizzleCache[level] != swizzleTarget) { // Need to re-render the swizzle for this level - ID3D11ShaderResourceView *sourceSRV = getSRVLevel(level); - ID3D11RenderTargetView *destRTV = getSwizzleRenderTarget(level); + ID3D11ShaderResourceView *sourceSRV = NULL; + gl::Error error = getSRVLevel(level, &sourceSRV); + if (error.isError()) + { + return error; + } + + ID3D11RenderTargetView *destRTV = NULL; + error = getSwizzleRenderTarget(level, &destRTV); + if (error.isError()) + { + return error; + } gl::Extents size(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level)); Blit11 *blitter = mRenderer->getBlitter(); - gl::Error error = blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha); + error = blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha); if (error.isError()) { return error; @@ -287,104 +310,120 @@ void TextureStorage11::invalidateSwizzleCache() } } -bool TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsigned int sourceSubresource, - int level, int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth) +gl::Error TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsigned int sourceSubresource, + const gl::ImageIndex &index, const gl::Box ©Area) { - if (srcTexture) - { - invalidateSwizzleCacheLevel(level); + ASSERT(srcTexture); - gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level)); - gl::Box copyArea(xoffset, yoffset, zoffset, width, height, depth); + GLint level = index.mipIndex; - bool fullCopy = copyArea.x == 0 && - copyArea.y == 0 && - copyArea.z == 0 && - copyArea.width == texSize.width && - copyArea.height == texSize.height && - copyArea.depth == texSize.depth; + invalidateSwizzleCacheLevel(level); - ID3D11Resource *dstTexture = getResource(); - unsigned int dstSubresource = getSubresourceIndex(level + mTopLevel, layerTarget); + gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level)); - ASSERT(dstTexture); + bool fullCopy = copyArea.x == 0 && + copyArea.y == 0 && + copyArea.z == 0 && + copyArea.width == texSize.width && + copyArea.height == texSize.height && + copyArea.depth == texSize.depth; - 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(); + ID3D11Resource *dstTexture = NULL; + gl::Error error = getResource(&dstTexture); + if (error.isError()) + { + return error; + } - return blitter->copyDepthStencil(srcTexture, sourceSubresource, copyArea, texSize, - dstTexture, dstSubresource, copyArea, texSize, - NULL); - } - else - { - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat); + unsigned int dstSubresource = getSubresourceIndex(index); - D3D11_BOX srcBox; - srcBox.left = copyArea.x; - srcBox.top = copyArea.y; - 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; + ASSERT(dstTexture); - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + 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(); - context->CopySubresourceRegion(dstTexture, dstSubresource, copyArea.x, copyArea.y, copyArea.z, - srcTexture, sourceSubresource, fullCopy ? NULL : &srcBox); - return true; - } + return blitter->copyDepthStencil(srcTexture, sourceSubresource, copyArea, texSize, + dstTexture, dstSubresource, copyArea, texSize, + NULL); } + else + { + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat); - return false; + D3D11_BOX srcBox; + srcBox.left = copyArea.x; + srcBox.top = copyArea.y; + srcBox.right = copyArea.x + roundUp(static_cast<UINT>(copyArea.width), dxgiFormatInfo.blockWidth); + srcBox.bottom = copyArea.y + roundUp(static_cast<UINT>(copyArea.height), dxgiFormatInfo.blockHeight); + srcBox.front = copyArea.z; + srcBox.back = copyArea.z + copyArea.depth; + + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + + context->CopySubresourceRegion(dstTexture, dstSubresource, copyArea.x, copyArea.y, copyArea.z, + srcTexture, sourceSubresource, fullCopy ? NULL : &srcBox); + return gl::Error(GL_NO_ERROR); + } } -bool TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource, - int level, int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth) +gl::Error TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource, + const gl::ImageIndex &index, const gl::Box ®ion) { - if (dstTexture) + ASSERT(dstTexture); + + ID3D11Resource *srcTexture = NULL; + gl::Error error = getResource(&srcTexture); + if (error.isError()) { - ID3D11Resource *srcTexture = getResource(); - unsigned int srcSubresource = getSubresourceIndex(level + mTopLevel, layerTarget); + return error; + } - ASSERT(srcTexture); + ASSERT(srcTexture); - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + unsigned int srcSubresource = getSubresourceIndex(index); - context->CopySubresourceRegion(dstTexture, dstSubresource, xoffset, yoffset, zoffset, - srcTexture, srcSubresource, NULL); - return true; - } + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + context->CopySubresourceRegion(dstTexture, dstSubresource, region.x, region.y, region.z, + srcTexture, srcSubresource, NULL); - return false; + return gl::Error(GL_NO_ERROR); } -void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest) +gl::Error TextureStorage11::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) { - if (source && dest) + ASSERT(sourceIndex.layerIndex == destIndex.layerIndex); + + invalidateSwizzleCacheLevel(destIndex.mipIndex); + + RenderTarget *source = NULL; + gl::Error error = getRenderTarget(sourceIndex, &source); + if (error.isError()) { - ID3D11ShaderResourceView *sourceSRV = source->getShaderResourceView(); - ID3D11RenderTargetView *destRTV = dest->getRenderTargetView(); + return error; + } - if (sourceSRV && destRTV) - { - gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth()); - gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth()); + RenderTarget *dest = NULL; + error = getRenderTarget(destIndex, &dest); + if (error.isError()) + { + return error; + } - gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth()); - gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth()); + ID3D11ShaderResourceView *sourceSRV = RenderTarget11::makeRenderTarget11(source)->getShaderResourceView(); + ID3D11RenderTargetView *destRTV = RenderTarget11::makeRenderTarget11(dest)->getRenderTargetView(); - Blit11 *blitter = mRenderer->getBlitter(); + gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth()); + gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth()); - blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL, - gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR); - } - } + gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth()); + gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth()); + + Blit11 *blitter = mRenderer->getBlitter(); + return blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL, + gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR); } void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha) @@ -396,7 +435,112 @@ void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGree } } -TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain) +gl::Error TextureStorage11::copyToStorage(TextureStorage *destStorage) +{ + ASSERT(destStorage); + + ID3D11Resource *sourceResouce = NULL; + gl::Error error = getResource(&sourceResouce); + if (error.isError()) + { + return error; + } + + TextureStorage11 *dest11 = TextureStorage11::makeTextureStorage11(destStorage); + ID3D11Resource *destResource = NULL; + error = dest11->getResource(&destResource); + if (error.isError()) + { + return error; + } + + ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); + immediateContext->CopyResource(destResource, sourceResouce); + + dest11->invalidateSwizzleCache(); + + return gl::Error(GL_NO_ERROR); +} + +gl::Error TextureStorage11::setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type, + const gl::PixelUnpackState &unpack, const uint8_t *pixelData) +{ + ID3D11Resource *resource = NULL; + gl::Error error = getResource(&resource); + if (error.isError()) + { + return error; + } + ASSERT(resource); + + UINT destSubresource = getSubresourceIndex(index); + + const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(image->getInternalFormat()); + + bool fullUpdate = (destBox == NULL || *destBox == gl::Box(0, 0, 0, mTextureWidth, mTextureHeight, mTextureDepth)); + ASSERT(internalFormatInfo.depthBits == 0 || fullUpdate); + + // TODO(jmadill): Handle compressed formats + // Compressed formats have different load syntax, so we'll have to handle them with slightly + // different logic. Will implemnent this in a follow-up patch, and ensure we do not use SetData + // with compressed formats in the calling logic. + ASSERT(!internalFormatInfo.compressed); + + int width = destBox ? destBox->width : static_cast<int>(image->getWidth()); + int height = destBox ? destBox->height : static_cast<int>(image->getHeight()); + int depth = destBox ? destBox->depth : static_cast<int>(image->getDepth()); + UINT srcRowPitch = internalFormatInfo.computeRowPitch(type, width, unpack.alignment); + UINT srcDepthPitch = internalFormatInfo.computeDepthPitch(type, width, height, unpack.alignment); + + const d3d11::TextureFormat &d3d11Format = d3d11::GetTextureFormatInfo(image->getInternalFormat()); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3d11Format.texFormat); + + size_t outputPixelSize = dxgiFormatInfo.pixelBytes; + + UINT bufferRowPitch = outputPixelSize * width; + UINT bufferDepthPitch = bufferRowPitch * height; + + MemoryBuffer conversionBuffer; + if (!conversionBuffer.resize(bufferDepthPitch * depth)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal buffer."); + } + + // TODO: fast path + LoadImageFunction loadFunction = d3d11Format.loadFunctions.at(type); + loadFunction(width, height, depth, + pixelData, srcRowPitch, srcDepthPitch, + conversionBuffer.data(), bufferRowPitch, bufferDepthPitch); + + ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); + + if (!fullUpdate) + { + ASSERT(destBox); + + D3D11_BOX destD3DBox; + destD3DBox.left = destBox->x; + destD3DBox.right = destBox->x + destBox->width; + destD3DBox.top = destBox->y; + destD3DBox.bottom = destBox->y + destBox->height; + destD3DBox.front = 0; + destD3DBox.back = 1; + + immediateContext->UpdateSubresource(resource, destSubresource, + &destD3DBox, conversionBuffer.data(), + bufferRowPitch, bufferDepthPitch); + } + else + { + immediateContext->UpdateSubresource(resource, destSubresource, + NULL, conversionBuffer.data(), + bufferRowPitch, bufferDepthPitch); + } + + return gl::Error(GL_NO_ERROR); +} + +TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain) : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE), mTexture(swapchain->getOffscreenTexture()), mSwizzleTexture(NULL) @@ -418,6 +562,8 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapch mTextureHeight = texDesc.Height; mTextureDepth = 1; + mInternalFormat = swapchain->GetBackBufferInternalFormat(); + ID3D11ShaderResourceView *srv = swapchain->getRenderTargetShaderResource(); D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srv->GetDesc(&srvDesc); @@ -439,7 +585,7 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapch initializeSerials(1, 1); } -TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) +TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget)), mTexture(NULL), mSwizzleTexture(NULL) @@ -451,6 +597,8 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalform mSwizzleRenderTargets[i] = NULL; } + mInternalFormat = internalformat; + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat); mTextureFormat = formatInfo.texFormat; mShaderResourceFormat = formatInfo.srvFormat; @@ -460,51 +608,11 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalform 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 - if (width > 0 && height > 0) - { - // adjust size if needed for compressed textures - d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel); - - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_TEXTURE2D_DESC desc; - desc.Width = width; // Compressed texture size constraints? - desc.Height = height; - desc.MipLevels = desc.MipLevels = mRenderer->isLevel9() ? 1 : ((levels > 0) ? (mTopLevel + levels) : 0); - desc.ArraySize = 1; - desc.Format = mTextureFormat; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = getBindFlags(); - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; - - HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); - - // this can happen from windows TDR - if (d3d11::isDeviceLostError(result)) - { - mRenderer->notifyDeviceLost(); - gl::error(GL_OUT_OF_MEMORY); - } - else if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - ERR("Creating image failed."); - gl::error(GL_OUT_OF_MEMORY); - } - else - { - mTexture->GetDesc(&desc); - mMipLevels = desc.MipLevels; - mTextureWidth = desc.Width; - mTextureHeight = desc.Height; - mTextureDepth = 1; - } - } + d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel); + mMipLevels = mTopLevel + levels; + mTextureWidth = width; + mTextureHeight = height; + mTextureDepth = 1; initializeSerials(getLevelCount(), 1); } @@ -521,7 +629,11 @@ TextureStorage11_2D::~TextureStorage11_2D() if (imageAssociationCorrect) { // We must let the Images recover their data before we delete it from the TextureStorage. - mAssociatedImages[i]->recoverFromAssociatedStorage(); + gl::Error error = mAssociatedImages[i]->recoverFromAssociatedStorage(); + if (error.isError()) + { + // TODO: Find a way to report this back to the context + } } } } @@ -542,8 +654,10 @@ TextureStorage11_2D *TextureStorage11_2D::makeTextureStorage11_2D(TextureStorage return static_cast<TextureStorage11_2D*>(storage); } -void TextureStorage11_2D::associateImage(Image11* image, int level, int layerTarget) +void TextureStorage11_2D::associateImage(Image11* image, const gl::ImageIndex &index) { + GLint level = index.mipIndex; + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) @@ -552,8 +666,10 @@ void TextureStorage11_2D::associateImage(Image11* image, int level, int layerTar } } -bool TextureStorage11_2D::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage) +bool TextureStorage11_2D::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage) { + GLint level = index.mipIndex; + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) { // This validation check should never return false. It means the Image/TextureStorage association is broken. @@ -566,8 +682,10 @@ bool TextureStorage11_2D::isAssociatedImageValid(int level, int layerTarget, Ima } // disassociateImage allows an Image to end its association with a Storage. -void TextureStorage11_2D::disassociateImage(int level, int layerTarget, Image11* expectedImage) +void TextureStorage11_2D::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage) { + GLint level = index.mipIndex; + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) @@ -582,8 +700,10 @@ void TextureStorage11_2D::disassociateImage(int level, int layerTarget, Image11* } // 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) +gl::Error TextureStorage11_2D::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage) { + GLint level = index.mipIndex; + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) @@ -599,137 +719,168 @@ void TextureStorage11_2D::releaseAssociatedImage(int level, int layerTarget, Ima { // Force the image to recover from storage before its data is overwritten. // This will reset mAssociatedImages[level] to NULL too. - mAssociatedImages[level]->recoverFromAssociatedStorage(); + gl::Error error = mAssociatedImages[level]->recoverFromAssociatedStorage(); + if (error.isError()) + { + return error; + } } } } + + return gl::Error(GL_NO_ERROR); } -ID3D11Resource *TextureStorage11_2D::getResource() const +gl::Error TextureStorage11_2D::getResource(ID3D11Resource **outResource) { - return mTexture; + // 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 + if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0) + { + ASSERT(mMipLevels > 0); + + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = mTextureWidth; // Compressed texture size constraints? + desc.Height = mTextureHeight; + desc.MipLevels = mRenderer->isLevel9() ? 1 : mMipLevels; + desc.ArraySize = 1; + desc.Format = mTextureFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); + + // this can happen from windows TDR + if (d3d11::isDeviceLostError(result)) + { + mRenderer->notifyDeviceLost(); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D texture storage, result: 0x%X.", result); + } + else if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D texture storage, result: 0x%X.", result); + } + } + + *outResource = mTexture; + return gl::Error(GL_NO_ERROR); } -RenderTarget *TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index) +gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) { ASSERT(!index.hasLayer()); int level = index.mipIndex; + ASSERT(level >= 0 && level < getLevelCount()); - if (level >= 0 && level < getLevelCount()) + if (!mRenderTarget[level]) { - if (!mRenderTarget[level]) + ID3D11Resource *texture = NULL; + gl::Error error = getResource(&texture); + if (error.isError()) { - ID3D11ShaderResourceView *srv = getSRVLevel(level); - if (!srv) - { - return NULL; - } - - if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) - { - ID3D11Device *device = mRenderer->getDevice(); + return error; + } - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - rtvDesc.Texture2D.MipSlice = mTopLevel + level; + ID3D11ShaderResourceView *srv = NULL; + error = getSRVLevel(level, &srv); + if (error.isError()) + { + return error; + } - ID3D11RenderTargetView *rtv; - HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); + if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) + { + ID3D11Device *device = mRenderer->getDevice(); - if (result == E_OUTOFMEMORY) - { - return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); - } - ASSERT(SUCCEEDED(result)); + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Texture2D.MipSlice = mTopLevel + level; - mRenderTarget[level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1); + ID3D11RenderTargetView *rtv; + HRESULT result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); - // RenderTarget will take ownership of these resources - SafeRelease(rtv); - } - else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN) + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) { - ID3D11Device *device = mRenderer->getDevice(); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); + } - D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = mDepthStencilFormat; - dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; - dsvDesc.Texture2D.MipSlice = mTopLevel + level; - dsvDesc.Flags = 0; + mRenderTarget[level] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0); - ID3D11DepthStencilView *dsv; - HRESULT result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv); + // RenderTarget will take ownership of these resources + SafeRelease(rtv); + } + else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN) + { + ID3D11Device *device = mRenderer->getDevice(); - if (result == E_OUTOFMEMORY) - { - SafeRelease(srv); - return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); - } - ASSERT(SUCCEEDED(result)); + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Format = mDepthStencilFormat; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + dsvDesc.Texture2D.MipSlice = mTopLevel + level; + dsvDesc.Flags = 0; - mRenderTarget[level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1); + ID3D11DepthStencilView *dsv; + HRESULT result = device->CreateDepthStencilView(texture, &dsvDesc, &dsv); - // RenderTarget will take ownership of these resources - SafeRelease(dsv); - } - else + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) { - UNREACHABLE(); + return gl::Error(GL_OUT_OF_MEMORY,"Failed to create internal depth stencil view for texture storage, result: 0x%X.", result); } - } - return mRenderTarget[level]; - } - else - { - return NULL; + mRenderTarget[level] = new TextureRenderTarget11(dsv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0); + + // RenderTarget will take ownership of these resources + SafeRelease(dsv); + } + else + { + UNREACHABLE(); + } } + + ASSERT(outRT); + *outRT = mRenderTarget[level]; + return gl::Error(GL_NO_ERROR); } -ID3D11ShaderResourceView *TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture) +gl::Error TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, + ID3D11ShaderResourceView **outSRV) const { + ASSERT(outSRV); + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = format; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel; - srvDesc.Texture2D.MipLevels = mipLevels; - - ID3D11ShaderResourceView *SRV = NULL; + srvDesc.Texture2D.MipLevels = mRenderer->isLevel9() ? -1 : mipLevels; ID3D11Device *device = mRenderer->getDevice(); - HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV); + HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV); - if (result == E_OUTOFMEMORY) + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) { - gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result); } - ASSERT(SUCCEEDED(result)); - return SRV; + return gl::Error(GL_NO_ERROR); } -void TextureStorage11_2D::generateMipmaps() +gl::Error TextureStorage11_2D::getSwizzleTexture(ID3D11Resource **outTexture) { - // 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(srcIndex)); - RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex)); + ASSERT(outTexture); - generateMipmapLayer(source, dest); - } -} - -ID3D11Resource *TextureStorage11_2D::getSwizzleTexture() -{ if (!mSwizzleTexture) { ID3D11Device *device = mRenderer->getDevice(); @@ -749,52 +900,52 @@ ID3D11Resource *TextureStorage11_2D::getSwizzleTexture() HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture); - if (result == E_OUTOFMEMORY) + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) { - return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL)); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result); } - ASSERT(SUCCEEDED(result)); } - return mSwizzleTexture; + *outTexture = mSwizzleTexture; + return gl::Error(GL_NO_ERROR); } -ID3D11RenderTargetView *TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel) +gl::Error TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) { - if (mipLevel >= 0 && mipLevel < getLevelCount()) + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + ASSERT(outRTV); + + if (!mSwizzleRenderTargets[mipLevel]) { - if (!mSwizzleRenderTargets[mipLevel]) + ID3D11Resource *swizzleTexture = NULL; + gl::Error error = getSwizzleTexture(&swizzleTexture); + if (error.isError()) { - ID3D11Resource *swizzleTexture = getSwizzleTexture(); - if (!swizzleTexture) - { - return NULL; - } + return error; + } - ID3D11Device *device = mRenderer->getDevice(); + ID3D11Device *device = mRenderer->getDevice(); - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mSwizzleRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel; + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mSwizzleRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel; - HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); - if (result == E_OUTOFMEMORY) - { - return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL)); - } - ASSERT(SUCCEEDED(result)); - } + HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); - return mSwizzleRenderTargets[mipLevel]; - } - else - { - return NULL; + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result); + } } + + *outRTV = mSwizzleRenderTargets[mipLevel]; + return gl::Error(GL_NO_ERROR); } -TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels) +TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer, GLenum internalformat, bool renderTarget, int size, int levels) : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget)) { mTexture = NULL; @@ -803,13 +954,15 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internal for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) { mSwizzleRenderTargets[level] = NULL; - for (unsigned int face = 0; face < 6; face++) + for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++) { mAssociatedImages[face][level] = NULL; mRenderTarget[face][level] = NULL; } } + mInternalFormat = internalformat; + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat); mTextureFormat = formatInfo.texFormat; mShaderResourceFormat = formatInfo.srvFormat; @@ -819,56 +972,23 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internal 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 - if (size > 0) - { - // adjust size if needed for compressed textures - int height = size; - d3d11::MakeValidSize(false, mTextureFormat, &size, &height, &mTopLevel); - - ID3D11Device *device = mRenderer->getDevice(); + // adjust size if needed for compressed textures + int height = size; + d3d11::MakeValidSize(false, mTextureFormat, &size, &height, &mTopLevel); - D3D11_TEXTURE2D_DESC desc; - desc.Width = size; - desc.Height = size; - desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0); - desc.ArraySize = 6; - desc.Format = mTextureFormat; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = getBindFlags(); - desc.CPUAccessFlags = 0; - desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; - - HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); - - if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - ERR("Creating image failed."); - gl::error(GL_OUT_OF_MEMORY); - } - else - { - mTexture->GetDesc(&desc); - mMipLevels = desc.MipLevels; - mTextureWidth = desc.Width; - mTextureHeight = desc.Height; - mTextureDepth = 1; - } - } + mMipLevels = mTopLevel + levels; + mTextureWidth = size; + mTextureHeight = size; + mTextureDepth = 1; - initializeSerials(getLevelCount() * 6, 6); + initializeSerials(getLevelCount() * CUBE_FACE_COUNT, CUBE_FACE_COUNT); } - TextureStorage11_Cube::~TextureStorage11_Cube() { for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) { - for (unsigned int face = 0; face < 6; face++) + for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++) { if (mAssociatedImages[face][level] != NULL) { @@ -890,7 +1010,7 @@ TextureStorage11_Cube::~TextureStorage11_Cube() for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) { SafeRelease(mSwizzleRenderTargets[level]); - for (unsigned int face = 0; face < 6; face++) + for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++) { SafeDelete(mRenderTarget[face][level]); } @@ -903,25 +1023,31 @@ TextureStorage11_Cube *TextureStorage11_Cube::makeTextureStorage11_Cube(TextureS return static_cast<TextureStorage11_Cube*>(storage); } -void TextureStorage11_Cube::associateImage(Image11* image, int level, int layerTarget) +void TextureStorage11_Cube::associateImage(Image11* image, const gl::ImageIndex &index) { + GLint level = index.mipIndex; + GLint layerTarget = index.layerIndex; + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); - ASSERT(0 <= layerTarget && layerTarget < 6); + ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT); if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) { - if (0 <= layerTarget && layerTarget < 6) + if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT) { mAssociatedImages[layerTarget][level] = image; } } } -bool TextureStorage11_Cube::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage) +bool TextureStorage11_Cube::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage) { + GLint level = index.mipIndex; + GLint layerTarget = index.layerIndex; + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) { - if (0 <= layerTarget && layerTarget < 6) + if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT) { // This validation check should never return false. It means the Image/TextureStorage association is broken. bool retValue = (mAssociatedImages[layerTarget][level] == expectedImage); @@ -934,14 +1060,17 @@ bool TextureStorage11_Cube::isAssociatedImageValid(int level, int layerTarget, I } // disassociateImage allows an Image to end its association with a Storage. -void TextureStorage11_Cube::disassociateImage(int level, int layerTarget, Image11* expectedImage) +void TextureStorage11_Cube::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage) { + GLint level = index.mipIndex; + GLint layerTarget = index.layerIndex; + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); - ASSERT(0 <= layerTarget && layerTarget < 6); + ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT); if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) { - if (0 <= layerTarget && layerTarget < 6) + if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT) { ASSERT(mAssociatedImages[layerTarget][level] == expectedImage); @@ -954,14 +1083,17 @@ void TextureStorage11_Cube::disassociateImage(int level, int layerTarget, Image1 } // 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) +gl::Error TextureStorage11_Cube::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage) { + GLint level = index.mipIndex; + GLint layerTarget = index.layerIndex; + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); - ASSERT(0 <= layerTarget && layerTarget < 6); + ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT); if ((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)) { - if (0 <= layerTarget && layerTarget < 6) + if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT) { // 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) @@ -974,114 +1106,165 @@ void TextureStorage11_Cube::releaseAssociatedImage(int level, int layerTarget, I { // Force the image to recover from storage before its data is overwritten. // This will reset mAssociatedImages[level] to NULL too. - mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage(); + gl::Error error = mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage(); + if (error.isError()) + { + return error; + } } } } } + + return gl::Error(GL_NO_ERROR); } -ID3D11Resource *TextureStorage11_Cube::getResource() const +gl::Error TextureStorage11_Cube::getResource(ID3D11Resource **outResource) { - return mTexture; + // if the size is not positive this should be treated as an incomplete texture + // we handle that here by skipping the d3d texture creation + if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0) + { + ASSERT(mMipLevels > 0); + + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mMipLevels; + desc.ArraySize = CUBE_FACE_COUNT; + desc.Format = mTextureFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; + + HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); + + // this can happen from windows TDR + if (d3d11::isDeviceLostError(result)) + { + mRenderer->notifyDeviceLost(); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube texture storage, result: 0x%X.", result); + } + else if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube texture storage, result: 0x%X.", result); + } + } + + *outResource = mTexture; + return gl::Error(GL_NO_ERROR); } -RenderTarget *TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index) +gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) { int faceIndex = index.layerIndex; int level = index.mipIndex; - if (level >= 0 && level < getLevelCount()) - { - if (!mRenderTarget[faceIndex][level]) - { - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result; + ASSERT(level >= 0 && level < getLevelCount()); + ASSERT(faceIndex >= 0 && faceIndex < CUBE_FACE_COUNT); - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = mShaderResourceFormat; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube - srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level; - srvDesc.Texture2DArray.MipLevels = 1; - srvDesc.Texture2DArray.FirstArraySlice = faceIndex; - srvDesc.Texture2DArray.ArraySize = 1; + if (!mRenderTarget[faceIndex][level]) + { + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result; - ID3D11ShaderResourceView *srv; - result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv); + ID3D11Resource *texture = NULL; + gl::Error error = getResource(&texture); + if (error.isError()) + { + return error; + } - if (result == E_OUTOFMEMORY) - { - return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); - } - ASSERT(SUCCEEDED(result)); + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = mShaderResourceFormat; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube + srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level; + srvDesc.Texture2DArray.MipLevels = 1; + srvDesc.Texture2DArray.FirstArraySlice = faceIndex; + srvDesc.Texture2DArray.ArraySize = 1; - if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) - { - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Texture2DArray.MipSlice = mTopLevel + level; - rtvDesc.Texture2DArray.FirstArraySlice = faceIndex; - rtvDesc.Texture2DArray.ArraySize = 1; + ID3D11ShaderResourceView *srv; + result = device->CreateShaderResourceView(texture, &srvDesc, &srv); - ID3D11RenderTargetView *rtv; - result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal shader resource view for texture storage, result: 0x%X.", result); + } - if (result == E_OUTOFMEMORY) - { - SafeRelease(srv); - return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); - } - ASSERT(SUCCEEDED(result)); + if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + level; + rtvDesc.Texture2DArray.FirstArraySlice = faceIndex; + rtvDesc.Texture2DArray.ArraySize = 1; - mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1); + ID3D11RenderTargetView *rtv; + result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); - // RenderTarget will take ownership of these resources - SafeRelease(rtv); + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { SafeRelease(srv); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); } - else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN) - { - D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = mDepthStencilFormat; - dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; - dsvDesc.Flags = 0; - dsvDesc.Texture2DArray.MipSlice = mTopLevel + level; - dsvDesc.Texture2DArray.FirstArraySlice = faceIndex; - dsvDesc.Texture2DArray.ArraySize = 1; - - ID3D11DepthStencilView *dsv; - result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv); - - if (result == E_OUTOFMEMORY) - { - SafeRelease(srv); - return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); - } - ASSERT(SUCCEEDED(result)); - mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1); + mRenderTarget[faceIndex][level] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0); - // RenderTarget will take ownership of these resources - SafeRelease(dsv); - SafeRelease(srv); - } - else + // RenderTarget will take ownership of these resources + SafeRelease(rtv); + SafeRelease(srv); + } + else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Format = mDepthStencilFormat; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; + dsvDesc.Flags = 0; + dsvDesc.Texture2DArray.MipSlice = mTopLevel + level; + dsvDesc.Texture2DArray.FirstArraySlice = faceIndex; + dsvDesc.Texture2DArray.ArraySize = 1; + + ID3D11DepthStencilView *dsv; + result = device->CreateDepthStencilView(texture, &dsvDesc, &dsv); + + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) { - UNREACHABLE(); + SafeRelease(srv); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal depth stencil view for texture storage, result: 0x%X.", result); } - } - return mRenderTarget[faceIndex][level]; - } - else - { - return NULL; + mRenderTarget[faceIndex][level] = new TextureRenderTarget11(dsv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0); + + // RenderTarget will take ownership of these resources + SafeRelease(dsv); + SafeRelease(srv); + } + else + { + UNREACHABLE(); + } } + + ASSERT(outRT); + *outRT = mRenderTarget[faceIndex][level]; + return gl::Error(GL_NO_ERROR); } -ID3D11ShaderResourceView *TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture) +gl::Error TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, + ID3D11ShaderResourceView **outSRV) const { + ASSERT(outSRV); + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = format; @@ -1093,7 +1276,7 @@ ID3D11ShaderResourceView *TextureStorage11_Cube::createSRV(int baseLevel, int mi srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel; srvDesc.Texture2DArray.MipLevels = 1; srvDesc.Texture2DArray.FirstArraySlice = 0; - srvDesc.Texture2DArray.ArraySize = 6; + srvDesc.Texture2DArray.ArraySize = CUBE_FACE_COUNT; } else { @@ -1102,43 +1285,22 @@ ID3D11ShaderResourceView *TextureStorage11_Cube::createSRV(int baseLevel, int mi srvDesc.TextureCube.MostDetailedMip = mTopLevel + baseLevel; } - ID3D11ShaderResourceView *SRV = NULL; - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV); + HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV); - if (result == E_OUTOFMEMORY) + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) { - gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result); } - ASSERT(SUCCEEDED(result)); - return SRV; + return gl::Error(GL_NO_ERROR); } -void TextureStorage11_Cube::generateMipmaps() +gl::Error TextureStorage11_Cube::getSwizzleTexture(ID3D11Resource **outTexture) { - // Base level must already be defined - - 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); - - RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex)); - RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex)); + ASSERT(outTexture); - generateMipmapLayer(source, dest); - } - } -} - -ID3D11Resource *TextureStorage11_Cube::getSwizzleTexture() -{ if (!mSwizzleTexture) { ID3D11Device *device = mRenderer->getDevice(); @@ -1147,7 +1309,7 @@ ID3D11Resource *TextureStorage11_Cube::getSwizzleTexture() desc.Width = mTextureWidth; desc.Height = mTextureHeight; desc.MipLevels = mMipLevels; - desc.ArraySize = 6; + desc.ArraySize = CUBE_FACE_COUNT; desc.Format = mSwizzleTextureFormat; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; @@ -1158,55 +1320,54 @@ ID3D11Resource *TextureStorage11_Cube::getSwizzleTexture() HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture); - if (result == E_OUTOFMEMORY) + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) { - return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL)); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result); } - ASSERT(SUCCEEDED(result)); } - return mSwizzleTexture; + *outTexture = mSwizzleTexture; + return gl::Error(GL_NO_ERROR); } -ID3D11RenderTargetView *TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel) +gl::Error TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) { - if (mipLevel >= 0 && mipLevel < getLevelCount()) + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + ASSERT(outRTV); + + if (!mSwizzleRenderTargets[mipLevel]) { - if (!mSwizzleRenderTargets[mipLevel]) + ID3D11Resource *swizzleTexture = NULL; + gl::Error error = getSwizzleTexture(&swizzleTexture); + if (error.isError()) { - ID3D11Resource *swizzleTexture = getSwizzleTexture(); - if (!swizzleTexture) - { - return NULL; - } + return error; + } - ID3D11Device *device = mRenderer->getDevice(); + ID3D11Device *device = mRenderer->getDevice(); - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mSwizzleRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; - rtvDesc.Texture2DArray.FirstArraySlice = 0; - rtvDesc.Texture2DArray.ArraySize = 6; + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mSwizzleRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture2DArray.FirstArraySlice = 0; + rtvDesc.Texture2DArray.ArraySize = CUBE_FACE_COUNT; - HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); + HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); - if (result == E_OUTOFMEMORY) - { - return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL)); - } - ASSERT(SUCCEEDED(result)); + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result); } - - return mSwizzleRenderTargets[mipLevel]; - } - else - { - return NULL; } + + *outRTV = mSwizzleRenderTargets[mipLevel]; + return gl::Error(GL_NO_ERROR); } -TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalformat, bool renderTarget, +TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget)) { @@ -1220,6 +1381,8 @@ TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalform mSwizzleRenderTargets[i] = NULL; } + mInternalFormat = internalformat; + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat); mTextureFormat = formatInfo.texFormat; mShaderResourceFormat = formatInfo.srvFormat; @@ -1229,49 +1392,13 @@ TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalform 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 - if (width > 0 && height > 0 && depth > 0) - { - // adjust size if needed for compressed textures - d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel); - - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_TEXTURE3D_DESC desc; - desc.Width = width; - desc.Height = height; - desc.Depth = depth; - desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0); - desc.Format = mTextureFormat; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = getBindFlags(); - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; - - HRESULT result = device->CreateTexture3D(&desc, NULL, &mTexture); + // adjust size if needed for compressed textures + d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel); - // this can happen from windows TDR - if (d3d11::isDeviceLostError(result)) - { - mRenderer->notifyDeviceLost(); - gl::error(GL_OUT_OF_MEMORY); - } - else if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - ERR("Creating image failed."); - gl::error(GL_OUT_OF_MEMORY); - } - else - { - mTexture->GetDesc(&desc); - mMipLevels = desc.MipLevels; - mTextureWidth = desc.Width; - mTextureHeight = desc.Height; - mTextureDepth = desc.Depth; - } - } + mMipLevels = mTopLevel + levels; + mTextureWidth = width; + mTextureHeight = height; + mTextureDepth = depth; initializeSerials(getLevelCount() * depth, depth); } @@ -1315,8 +1442,10 @@ TextureStorage11_3D *TextureStorage11_3D::makeTextureStorage11_3D(TextureStorage return static_cast<TextureStorage11_3D*>(storage); } -void TextureStorage11_3D::associateImage(Image11* image, int level, int layerTarget) +void TextureStorage11_3D::associateImage(Image11* image, const gl::ImageIndex &index) { + GLint level = index.mipIndex; + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) @@ -1325,8 +1454,10 @@ void TextureStorage11_3D::associateImage(Image11* image, int level, int layerTar } } -bool TextureStorage11_3D::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage) +bool TextureStorage11_3D::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage) { + GLint level = index.mipIndex; + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) { // This validation check should never return false. It means the Image/TextureStorage association is broken. @@ -1339,8 +1470,10 @@ bool TextureStorage11_3D::isAssociatedImageValid(int level, int layerTarget, Ima } // disassociateImage allows an Image to end its association with a Storage. -void TextureStorage11_3D::disassociateImage(int level, int layerTarget, Image11* expectedImage) +void TextureStorage11_3D::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage) { + GLint level = index.mipIndex; + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) @@ -1355,8 +1488,10 @@ void TextureStorage11_3D::disassociateImage(int level, int layerTarget, Image11* } // 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) +gl::Error TextureStorage11_3D::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage) { + GLint level = index.mipIndex; + ASSERT((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)); if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) @@ -1372,148 +1507,188 @@ void TextureStorage11_3D::releaseAssociatedImage(int level, int layerTarget, Ima { // Force the image to recover from storage before its data is overwritten. // This will reset mAssociatedImages[level] to NULL too. - mAssociatedImages[level]->recoverFromAssociatedStorage(); + gl::Error error = mAssociatedImages[level]->recoverFromAssociatedStorage(); + if (error.isError()) + { + return error; + } } } } + + return gl::Error(GL_NO_ERROR); } -ID3D11Resource *TextureStorage11_3D::getResource() const +gl::Error TextureStorage11_3D::getResource(ID3D11Resource **outResource) { - return mTexture; + // 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 + if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0) + { + ASSERT(mMipLevels > 0); + + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_TEXTURE3D_DESC desc; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.Depth = mTextureDepth; + desc.MipLevels = mMipLevels; + desc.Format = mTextureFormat; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + HRESULT result = device->CreateTexture3D(&desc, NULL, &mTexture); + + // this can happen from windows TDR + if (d3d11::isDeviceLostError(result)) + { + mRenderer->notifyDeviceLost(); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 3D texture storage, result: 0x%X.", result); + } + else if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 3D texture storage, result: 0x%X.", result); + } + } + + *outResource = mTexture; + return gl::Error(GL_NO_ERROR); } -ID3D11ShaderResourceView *TextureStorage11_3D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture) +gl::Error TextureStorage11_3D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, + ID3D11ShaderResourceView **outSRV) const { + ASSERT(outSRV); + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = format; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; srvDesc.Texture3D.MostDetailedMip = baseLevel; srvDesc.Texture3D.MipLevels = mipLevels; - ID3D11ShaderResourceView *SRV = NULL; - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV); + HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV); - if (result == E_OUTOFMEMORY) + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) { - gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result); } - ASSERT(SUCCEEDED(result)); - return SRV; + return gl::Error(GL_NO_ERROR); } -RenderTarget *TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index) +gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) { int mipLevel = index.mipIndex; + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); - if (mipLevel >= 0 && mipLevel < getLevelCount()) - { - ASSERT(mRenderTargetFormat != DXGI_FORMAT_UNKNOWN); + ASSERT(mRenderTargetFormat != DXGI_FORMAT_UNKNOWN); - if (!index.hasLayer()) + if (!index.hasLayer()) + { + if (!mLevelRenderTargets[mipLevel]) { - if (!mLevelRenderTargets[mipLevel]) + ID3D11Resource *texture = NULL; + gl::Error error = getResource(&texture); + if (error.isError()) { - ID3D11ShaderResourceView *srv = getSRVLevel(mipLevel); - if (!srv) - { - return NULL; - } - - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; - rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; - rtvDesc.Texture3D.FirstWSlice = 0; - rtvDesc.Texture3D.WSize = -1; - - ID3D11RenderTargetView *rtv; - HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); + return error; + } - if (result == E_OUTOFMEMORY) - { - SafeRelease(srv); - return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); - } - ASSERT(SUCCEEDED(result)); + ID3D11ShaderResourceView *srv = NULL; + error = getSRVLevel(mipLevel, &srv); + if (error.isError()) + { + return error; + } - mLevelRenderTargets[mipLevel] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel)); + ID3D11Device *device = mRenderer->getDevice(); - // RenderTarget will take ownership of these resources - SafeRelease(rtv); - } + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture3D.FirstWSlice = 0; + rtvDesc.Texture3D.WSize = -1; - return mLevelRenderTargets[mipLevel]; - } - else - { - int layer = index.layerIndex; + ID3D11RenderTargetView *rtv; + HRESULT result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); - LevelLayerKey key(mipLevel, layer); - if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end()) + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) { - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result; - - // TODO, what kind of SRV is expected here? - ID3D11ShaderResourceView *srv = NULL; + SafeRelease(srv); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); + } - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; - rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; - rtvDesc.Texture3D.FirstWSlice = layer; - rtvDesc.Texture3D.WSize = 1; + mLevelRenderTargets[mipLevel] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel), 0); - ID3D11RenderTargetView *rtv; - result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); + // RenderTarget will take ownership of these resources + SafeRelease(rtv); + } - if (result == E_OUTOFMEMORY) - { - SafeRelease(srv); - return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); - } - ASSERT(SUCCEEDED(result)); + ASSERT(outRT); + *outRT = mLevelRenderTargets[mipLevel]; + return gl::Error(GL_NO_ERROR); + } + else + { + int layer = index.layerIndex; - mLevelLayerRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1); + LevelLayerKey key(mipLevel, layer); + if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end()) + { + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result; - // RenderTarget will take ownership of these resources - SafeRelease(rtv); - SafeRelease(srv); + ID3D11Resource *texture = NULL; + gl::Error error = getResource(&texture); + if (error.isError()) + { + return error; } - return mLevelLayerRenderTargets[key]; - } - } + // TODO, what kind of SRV is expected here? + ID3D11ShaderResourceView *srv = NULL; - return NULL; -} + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture3D.FirstWSlice = layer; + rtvDesc.Texture3D.WSize = 1; -void TextureStorage11_3D::generateMipmaps() -{ - // Base level must already be defined + ID3D11RenderTargetView *rtv; + result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); - for (int level = 1; level < getLevelCount(); level++) - { - invalidateSwizzleCacheLevel(level); + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + SafeRelease(srv); return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); + } + ASSERT(SUCCEEDED(result)); - gl::ImageIndex srcIndex = gl::ImageIndex::Make3D(level - 1); - gl::ImageIndex destIndex = gl::ImageIndex::Make3D(level); + mLevelLayerRenderTargets[key] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0); - RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex)); - RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex)); + // RenderTarget will take ownership of these resources + SafeRelease(rtv); + } - generateMipmapLayer(source, dest); + ASSERT(outRT); + *outRT = mLevelLayerRenderTargets[key]; + return gl::Error(GL_NO_ERROR); } } -ID3D11Resource *TextureStorage11_3D::getSwizzleTexture() +gl::Error TextureStorage11_3D::getSwizzleTexture(ID3D11Resource **outTexture) { + ASSERT(outTexture); + if (!mSwizzleTexture) { ID3D11Device *device = mRenderer->getDevice(); @@ -1531,55 +1706,54 @@ ID3D11Resource *TextureStorage11_3D::getSwizzleTexture() HRESULT result = device->CreateTexture3D(&desc, NULL, &mSwizzleTexture); - if (result == E_OUTOFMEMORY) + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) { - return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture3D*>(NULL)); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result); } - ASSERT(SUCCEEDED(result)); } - return mSwizzleTexture; + *outTexture = mSwizzleTexture; + return gl::Error(GL_NO_ERROR); } -ID3D11RenderTargetView *TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel) +gl::Error TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) { - if (mipLevel >= 0 && mipLevel < getLevelCount()) + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + ASSERT(outRTV); + + if (!mSwizzleRenderTargets[mipLevel]) { - if (!mSwizzleRenderTargets[mipLevel]) + ID3D11Resource *swizzleTexture = NULL; + gl::Error error = getSwizzleTexture(&swizzleTexture); + if (error.isError()) { - ID3D11Resource *swizzleTexture = getSwizzleTexture(); - if (!swizzleTexture) - { - return NULL; - } + return error; + } - ID3D11Device *device = mRenderer->getDevice(); + ID3D11Device *device = mRenderer->getDevice(); - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mSwizzleRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; - rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; - rtvDesc.Texture3D.FirstWSlice = 0; - rtvDesc.Texture3D.WSize = -1; + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mSwizzleRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture3D.FirstWSlice = 0; + rtvDesc.Texture3D.WSize = -1; - HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); + HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); - if (result == E_OUTOFMEMORY) - { - return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL)); - } - ASSERT(SUCCEEDED(result)); + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result); } - - return mSwizzleRenderTargets[mipLevel]; - } - else - { - return NULL; } + + *outRTV = mSwizzleRenderTargets[mipLevel]; + return gl::Error(GL_NO_ERROR); } -TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum internalformat, bool renderTarget, +TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget)) { @@ -1591,6 +1765,8 @@ TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum in mSwizzleRenderTargets[level] = NULL; } + mInternalFormat = internalformat; + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat); mTextureFormat = formatInfo.texFormat; mShaderResourceFormat = formatInfo.srvFormat; @@ -1600,51 +1776,13 @@ TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum in 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 - if (width > 0 && height > 0 && depth > 0) - { - // adjust size if needed for compressed textures - d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel); + // adjust size if needed for compressed textures + d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel); - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_TEXTURE2D_DESC desc; - desc.Width = width; - desc.Height = height; - desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0); - desc.ArraySize = depth; - desc.Format = mTextureFormat; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = getBindFlags(); - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; - - HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); - - // this can happen from windows TDR - if (d3d11::isDeviceLostError(result)) - { - mRenderer->notifyDeviceLost(); - gl::error(GL_OUT_OF_MEMORY); - } - else if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - ERR("Creating image failed."); - gl::error(GL_OUT_OF_MEMORY); - } - else - { - mTexture->GetDesc(&desc); - mMipLevels = desc.MipLevels; - mTextureWidth = desc.Width; - mTextureHeight = desc.Height; - mTextureDepth = desc.ArraySize; - } - } + mMipLevels = mTopLevel + levels; + mTextureWidth = width; + mTextureHeight = height; + mTextureDepth = depth; initializeSerials(getLevelCount() * depth, depth); } @@ -1685,8 +1823,11 @@ TextureStorage11_2DArray *TextureStorage11_2DArray::makeTextureStorage11_2DArray return static_cast<TextureStorage11_2DArray*>(storage); } -void TextureStorage11_2DArray::associateImage(Image11* image, int level, int layerTarget) +void TextureStorage11_2DArray::associateImage(Image11* image, const gl::ImageIndex &index) { + GLint level = index.mipIndex; + GLint layerTarget = index.layerIndex; + ASSERT(0 <= level && level < getLevelCount()); if (0 <= level && level < getLevelCount()) @@ -1696,8 +1837,11 @@ void TextureStorage11_2DArray::associateImage(Image11* image, int level, int lay } } -bool TextureStorage11_2DArray::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage) +bool TextureStorage11_2DArray::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage) { + GLint level = index.mipIndex; + GLint layerTarget = index.layerIndex; + LevelLayerKey key(level, layerTarget); // This validation check should never return false. It means the Image/TextureStorage association is broken. @@ -1707,8 +1851,11 @@ bool TextureStorage11_2DArray::isAssociatedImageValid(int level, int layerTarget } // disassociateImage allows an Image to end its association with a Storage. -void TextureStorage11_2DArray::disassociateImage(int level, int layerTarget, Image11* expectedImage) +void TextureStorage11_2DArray::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage) { + GLint level = index.mipIndex; + GLint layerTarget = index.layerIndex; + LevelLayerKey key(level, layerTarget); bool imageAssociationCorrect = (mAssociatedImages.find(key) != mAssociatedImages.end() && (mAssociatedImages[key] == expectedImage)); @@ -1721,8 +1868,11 @@ void TextureStorage11_2DArray::disassociateImage(int level, int layerTarget, Ima } // 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) +gl::Error TextureStorage11_2DArray::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage) { + GLint level = index.mipIndex; + GLint layerTarget = index.layerIndex; + LevelLayerKey key(level, layerTarget); ASSERT(mAssociatedImages.find(key) != mAssociatedImages.end()); @@ -1739,18 +1889,62 @@ void TextureStorage11_2DArray::releaseAssociatedImage(int level, int layerTarget { // Force the image to recover from storage before its data is overwritten. // This will reset mAssociatedImages[level] to NULL too. - mAssociatedImages[key]->recoverFromAssociatedStorage(); + gl::Error error = mAssociatedImages[key]->recoverFromAssociatedStorage(); + if (error.isError()) + { + return error; + } } } } + + return gl::Error(GL_NO_ERROR); } -ID3D11Resource *TextureStorage11_2DArray::getResource() const +gl::Error TextureStorage11_2DArray::getResource(ID3D11Resource **outResource) { - return mTexture; + // 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 + if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0) + { + ASSERT(mMipLevels > 0); + + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mMipLevels; + desc.ArraySize = mTextureDepth; + desc.Format = mTextureFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); + + // this can happen from windows TDR + if (d3d11::isDeviceLostError(result)) + { + mRenderer->notifyDeviceLost(); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D array texture storage, result: 0x%X.", result); + } + else if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D array texture storage, result: 0x%X.", result); + } + } + + *outResource = mTexture; + return gl::Error(GL_NO_ERROR); } -ID3D11ShaderResourceView *TextureStorage11_2DArray::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture) +gl::Error TextureStorage11_2DArray::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, + ID3D11ShaderResourceView **outSRV) const { D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = format; @@ -1760,112 +1954,94 @@ ID3D11ShaderResourceView *TextureStorage11_2DArray::createSRV(int baseLevel, int srvDesc.Texture2DArray.FirstArraySlice = 0; srvDesc.Texture2DArray.ArraySize = mTextureDepth; - ID3D11ShaderResourceView *SRV = NULL; - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV); + HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV); - if (result == E_OUTOFMEMORY) + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) { - gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result); } - ASSERT(SUCCEEDED(result)); - return SRV; + return gl::Error(GL_NO_ERROR); } -RenderTarget *TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index) +gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) { ASSERT(index.hasLayer()); int mipLevel = index.mipIndex; int layer = index.layerIndex; - if (mipLevel >= 0 && mipLevel < getLevelCount()) - { - LevelLayerKey key(mipLevel, layer); - if (mRenderTargets.find(key) == mRenderTargets.end()) - { - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result; + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = mShaderResourceFormat; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; - srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + mipLevel; - srvDesc.Texture2DArray.MipLevels = 1; - srvDesc.Texture2DArray.FirstArraySlice = layer; - srvDesc.Texture2DArray.ArraySize = 1; + LevelLayerKey key(mipLevel, layer); + if (mRenderTargets.find(key) == mRenderTargets.end()) + { + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result; - ID3D11ShaderResourceView *srv; - result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv); + ID3D11Resource *texture = NULL; + gl::Error error = getResource(&texture); + if (error.isError()) + { + return error; + } - if (result == E_OUTOFMEMORY) - { - return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); - } - ASSERT(SUCCEEDED(result)); + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = mShaderResourceFormat; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + mipLevel; + srvDesc.Texture2DArray.MipLevels = 1; + srvDesc.Texture2DArray.FirstArraySlice = layer; + srvDesc.Texture2DArray.ArraySize = 1; - if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) - { - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; - rtvDesc.Texture2DArray.FirstArraySlice = layer; - rtvDesc.Texture2DArray.ArraySize = 1; + ID3D11ShaderResourceView *srv; + result = device->CreateShaderResourceView(texture, &srvDesc, &srv); - ID3D11RenderTargetView *rtv; - result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal shader resource view for texture storage, result: 0x%X.", result); + } - if (result == E_OUTOFMEMORY) - { - SafeRelease(srv); - return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); - } - ASSERT(SUCCEEDED(result)); + if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture2DArray.FirstArraySlice = layer; + rtvDesc.Texture2DArray.ArraySize = 1; - mRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1); + ID3D11RenderTargetView *rtv; + result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); - // RenderTarget will take ownership of these resources - SafeRelease(rtv); - SafeRelease(srv); - } - else + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) { - UNREACHABLE(); + SafeRelease(srv); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); } - } - - return mRenderTargets[key]; - } - else - { - return NULL; - } -} -void TextureStorage11_2DArray::generateMipmaps() -{ - // Base level must already be defined + mRenderTargets[key] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0); - for (int level = 0; level < getLevelCount(); level++) - { - invalidateSwizzleCacheLevel(level); - for (unsigned int layer = 0; layer < mTextureDepth; layer++) + // RenderTarget will take ownership of these resources + SafeRelease(rtv); + SafeRelease(srv); + } + else { - gl::ImageIndex sourceIndex = gl::ImageIndex::Make2DArray(level - 1, layer); - gl::ImageIndex destIndex = gl::ImageIndex::Make2DArray(level, layer); - - RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(sourceIndex)); - RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex)); - - generateMipmapLayer(source, dest); + UNREACHABLE(); } } + + ASSERT(outRT); + *outRT = mRenderTargets[key]; + return gl::Error(GL_NO_ERROR); } -ID3D11Resource *TextureStorage11_2DArray::getSwizzleTexture() +gl::Error TextureStorage11_2DArray::getSwizzleTexture(ID3D11Resource **outTexture) { if (!mSwizzleTexture) { @@ -1886,52 +2062,51 @@ ID3D11Resource *TextureStorage11_2DArray::getSwizzleTexture() HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture); - if (result == E_OUTOFMEMORY) + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) { - return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL)); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result); } - ASSERT(SUCCEEDED(result)); } - return mSwizzleTexture; + *outTexture = mSwizzleTexture; + return gl::Error(GL_NO_ERROR); } -ID3D11RenderTargetView *TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel) +gl::Error TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) { - if (mipLevel >= 0 && mipLevel < getLevelCount()) + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + ASSERT(outRTV); + + if (!mSwizzleRenderTargets[mipLevel]) { - if (!mSwizzleRenderTargets[mipLevel]) + ID3D11Resource *swizzleTexture = NULL; + gl::Error error = getSwizzleTexture(&swizzleTexture); + if (error.isError()) { - ID3D11Resource *swizzleTexture = getSwizzleTexture(); - if (!swizzleTexture) - { - return NULL; - } + return error; + } - ID3D11Device *device = mRenderer->getDevice(); + ID3D11Device *device = mRenderer->getDevice(); - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mSwizzleRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; - rtvDesc.Texture2DArray.FirstArraySlice = 0; - rtvDesc.Texture2DArray.ArraySize = mTextureDepth; + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mSwizzleRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture2DArray.FirstArraySlice = 0; + rtvDesc.Texture2DArray.ArraySize = mTextureDepth; - HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); + HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); - if (result == E_OUTOFMEMORY) - { - return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL)); - } - ASSERT(SUCCEEDED(result)); + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result); } - - return mSwizzleRenderTargets[mipLevel]; - } - else - { - return NULL; } + + *outRTV = mSwizzleRenderTargets[mipLevel]; + return gl::Error(GL_NO_ERROR); } } 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 9d63b2699d..930300a63d 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h @@ -25,7 +25,6 @@ namespace rx { class RenderTarget; class RenderTarget11; -class Renderer; class Renderer11; class SwapChain11; class Image11; @@ -41,47 +40,49 @@ class TextureStorage11 : public TextureStorage UINT getBindFlags() const; - virtual ID3D11Resource *getResource() const = 0; - virtual ID3D11ShaderResourceView *getSRV(const gl::SamplerState &samplerState); - virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0; + virtual gl::Error getResource(ID3D11Resource **outResource) = 0; + virtual gl::Error getSRV(const gl::SamplerState &samplerState, ID3D11ShaderResourceView **outSRV); + virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0; - virtual void generateMipmaps() = 0; + virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex); virtual int getTopLevel() const; virtual bool isRenderTarget() const; virtual bool isManaged() const; virtual int getLevelCount() const; - UINT getSubresourceIndex(int mipLevel, int layerTarget) const; + UINT getSubresourceIndex(const gl::ImageIndex &index) const; gl::Error generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha); void invalidateSwizzleCacheLevel(int mipLevel); void invalidateSwizzleCache(); - bool updateSubresourceLevel(ID3D11Resource *texture, unsigned int sourceSubresource, int level, - int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth); + gl::Error updateSubresourceLevel(ID3D11Resource *texture, unsigned int sourceSubresource, + const gl::ImageIndex &index, const gl::Box ©Area); - bool copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource, int level, - int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth); + gl::Error copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource, + const gl::ImageIndex &index, const gl::Box ®ion); - 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; + virtual void associateImage(Image11* image, const gl::ImageIndex &index) = 0; + virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage) = 0; + virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage) = 0; + virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage) = 0; + + virtual gl::Error copyToStorage(TextureStorage *destStorage); + virtual gl::Error setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type, + const gl::PixelUnpackState &unpack, const uint8_t *pixelData); protected: - TextureStorage11(Renderer *renderer, UINT bindFlags); - void generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest); + TextureStorage11(Renderer11 *renderer, UINT bindFlags); int getLevelWidth(int mipLevel) const; int getLevelHeight(int mipLevel) const; int getLevelDepth(int mipLevel) const; - virtual ID3D11Resource *getSwizzleTexture() = 0; - virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel) = 0; - ID3D11ShaderResourceView *getSRVLevel(int mipLevel); + virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture) = 0; + virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) = 0; + gl::Error getSRVLevel(int mipLevel, ID3D11ShaderResourceView **outSRV); - virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture) = 0; + virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, + ID3D11ShaderResourceView **outSRV) const = 0; void verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha); @@ -89,6 +90,7 @@ class TextureStorage11 : public TextureStorage int mTopLevel; unsigned int mMipLevels; + GLenum mInternalFormat; DXGI_FORMAT mTextureFormat; DXGI_FORMAT mShaderResourceFormat; DXGI_FORMAT mRenderTargetFormat; @@ -115,69 +117,53 @@ class TextureStorage11 : public TextureStorage }; SwizzleCacheValue mSwizzleCache[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + private: + DISALLOW_COPY_AND_ASSIGN(TextureStorage11); + + const UINT mBindFlags; + struct SRVKey { SRVKey(int baseLevel = 0, int mipLevels = 0, bool swizzle = false); - bool operator==(const SRVKey &rhs) const; + bool operator<(const SRVKey &rhs) const; int baseLevel; int mipLevels; bool swizzle; }; + typedef std::map<SRVKey, ID3D11ShaderResourceView *> SRVCache; - struct SRVPair - { - SRVKey key; - ID3D11ShaderResourceView *srv; - }; - - struct SRVCache - { - ~SRVCache(); - - ID3D11ShaderResourceView *find(const SRVKey &key) const; - ID3D11ShaderResourceView *add(const SRVKey &key, ID3D11ShaderResourceView *srv); - - std::vector<SRVPair> cache; - }; - - private: - DISALLOW_COPY_AND_ASSIGN(TextureStorage11); - - const UINT mBindFlags; - - SRVCache srvCache; + SRVCache mSrvCache; ID3D11ShaderResourceView *mLevelSRVs[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; }; class TextureStorage11_2D : public TextureStorage11 { public: - TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain); - TextureStorage11_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels); + TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain); + TextureStorage11_2D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels); virtual ~TextureStorage11_2D(); static TextureStorage11_2D *makeTextureStorage11_2D(TextureStorage *storage); - virtual ID3D11Resource *getResource() const; - virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); - - virtual void generateMipmaps(); + virtual gl::Error getResource(ID3D11Resource **outResource); + virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT); - 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); + virtual void associateImage(Image11* image, const gl::ImageIndex &index); + virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage); + virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage); + virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage); protected: - virtual ID3D11Resource *getSwizzleTexture(); - virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel); + virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture); + virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV); private: DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2D); - virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture); + virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, + ID3D11ShaderResourceView **outSRV) const; ID3D11Texture2D *mTexture; RenderTarget11 *mRenderTarget[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; @@ -191,68 +177,68 @@ class TextureStorage11_2D : public TextureStorage11 class TextureStorage11_Cube : public TextureStorage11 { public: - TextureStorage11_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels); + TextureStorage11_Cube(Renderer11 *renderer, GLenum internalformat, bool renderTarget, int size, int levels); virtual ~TextureStorage11_Cube(); static TextureStorage11_Cube *makeTextureStorage11_Cube(TextureStorage *storage); - virtual ID3D11Resource *getResource() const; - virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); - - virtual void generateMipmaps(); + virtual gl::Error getResource(ID3D11Resource **outResource); + virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT); - 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); + virtual void associateImage(Image11* image, const gl::ImageIndex &index); + virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage); + virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage); + virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage); protected: - virtual ID3D11Resource *getSwizzleTexture(); - virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel); + virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture); + virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV); private: DISALLOW_COPY_AND_ASSIGN(TextureStorage11_Cube); - virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture); + virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, + ID3D11ShaderResourceView **outSRV) const; + + static const size_t CUBE_FACE_COUNT = 6; ID3D11Texture2D *mTexture; - RenderTarget11 *mRenderTarget[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + RenderTarget11 *mRenderTarget[CUBE_FACE_COUNT][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; ID3D11Texture2D *mSwizzleTexture; ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; - Image11 *mAssociatedImages[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + Image11 *mAssociatedImages[CUBE_FACE_COUNT][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; }; class TextureStorage11_3D : public TextureStorage11 { public: - TextureStorage11_3D(Renderer *renderer, GLenum internalformat, bool renderTarget, + TextureStorage11_3D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); virtual ~TextureStorage11_3D(); static TextureStorage11_3D *makeTextureStorage11_3D(TextureStorage *storage); - virtual ID3D11Resource *getResource() const; + virtual gl::Error getResource(ID3D11Resource **outResource); // Handles both layer and non-layer RTs - virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); - - virtual void generateMipmaps(); + virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT); - 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); + virtual void associateImage(Image11* image, const gl::ImageIndex &index); + virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage); + virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage); + virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage); protected: - virtual ID3D11Resource *getSwizzleTexture(); - virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel); + virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture); + virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV); private: DISALLOW_COPY_AND_ASSIGN(TextureStorage11_3D); - virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture); + virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, + ID3D11ShaderResourceView **outSRV) const; typedef std::pair<int, int> LevelLayerKey; typedef std::map<LevelLayerKey, RenderTarget11*> RenderTargetMap; @@ -270,30 +256,29 @@ class TextureStorage11_3D : public TextureStorage11 class TextureStorage11_2DArray : public TextureStorage11 { public: - TextureStorage11_2DArray(Renderer *renderer, GLenum internalformat, bool renderTarget, + TextureStorage11_2DArray(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); virtual ~TextureStorage11_2DArray(); static TextureStorage11_2DArray *makeTextureStorage11_2DArray(TextureStorage *storage); - virtual ID3D11Resource *getResource() const; - virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); - - virtual void generateMipmaps(); + virtual gl::Error getResource(ID3D11Resource **outResource); + virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT); - 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); + virtual void associateImage(Image11* image, const gl::ImageIndex &index); + virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage); + virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage); + virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage); protected: - virtual ID3D11Resource *getSwizzleTexture(); - virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel); + virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture); + virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV); private: DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2DArray); - virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture); + virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, + ID3D11ShaderResourceView **outSRV) const; typedef std::pair<int, int> LevelLayerKey; typedef std::map<LevelLayerKey, RenderTarget11*> RenderTargetMap; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h index 590cb9f05a..70bc3bb26f 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h @@ -19,7 +19,7 @@ class Renderer11; class VertexArray11 : public VertexArrayImpl { public: - VertexArray11(rx::Renderer11 *renderer) + VertexArray11(Renderer11 *renderer) : VertexArrayImpl(), mRenderer(renderer) { @@ -34,7 +34,7 @@ class VertexArray11 : public VertexArrayImpl private: DISALLOW_COPY_AND_ASSIGN(VertexArray11); - rx::Renderer11 *mRenderer; + Renderer11 *mRenderer; }; } 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 9bc5b1d2d1..a9d6fa2ca4 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp @@ -16,7 +16,7 @@ namespace rx { -VertexBuffer11::VertexBuffer11(rx::Renderer11 *const renderer) : mRenderer(renderer) +VertexBuffer11::VertexBuffer11(Renderer11 *const renderer) : mRenderer(renderer) { mBuffer = NULL; mBufferSize = 0; @@ -91,8 +91,13 @@ gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attri { if (buffer) { - Buffer11 *storage = Buffer11::makeBuffer11(buffer->getImplementation()); - input = static_cast<const uint8_t*>(storage->getData()) + static_cast<int>(attrib.offset); + BufferD3D *storage = BufferD3D::makeFromBuffer(buffer); + gl::Error error = storage->getData(&input); + if (error.isError()) + { + return error; + } + input += static_cast<int>(attrib.offset); } else { @@ -132,7 +137,7 @@ gl::Error VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GL else { // Round up to divisor, if possible - elementCount = rx::UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor); + elementCount = UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor); } gl::VertexFormat vertexFormat(attrib); 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 0e10da1df8..a9bbac98fa 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h @@ -18,7 +18,7 @@ class Renderer11; class VertexBuffer11 : public VertexBuffer { public: - explicit VertexBuffer11(rx::Renderer11 *const renderer); + explicit VertexBuffer11(Renderer11 *const renderer); virtual ~VertexBuffer11(); virtual gl::Error initialize(unsigned int size, bool dynamicUsage); @@ -40,7 +40,7 @@ class VertexBuffer11 : public VertexBuffer private: DISALLOW_COPY_AND_ASSIGN(VertexBuffer11); - rx::Renderer11 *const mRenderer; + Renderer11 *const mRenderer; ID3D11Buffer *mBuffer; unsigned int mBufferSize; 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 c07828757d..90a879e170 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp @@ -795,7 +795,7 @@ static D3D11ES3FormatMap BuildD3D11FormatMap() // 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_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 ); 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 2af97e73f0..121aa3bbad 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 @@ -10,6 +10,7 @@ #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h" +#include "libGLESv2/renderer/Workarounds.h" #include "libGLESv2/ProgramBinary.h" #include "libGLESv2/Framebuffer.h" @@ -95,9 +96,6 @@ #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 { @@ -357,7 +355,7 @@ static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: @@ -377,7 +375,7 @@ static float GetMaximumAnisotropy(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_MAX_MAXANISOTROPY; @@ -399,7 +397,7 @@ static bool GetOcclusionQuerySupport(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: @@ -421,7 +419,7 @@ static bool GetEventQuerySupport(D3D_FEATURE_LEVEL featureLevel) switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: @@ -441,7 +439,7 @@ static bool GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel) switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: @@ -466,7 +464,7 @@ static bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel) switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: @@ -486,7 +484,7 @@ static size_t GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; @@ -506,7 +504,7 @@ static size_t GetMaximum2DTextureSize(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; @@ -526,7 +524,7 @@ static size_t GetMaximumCubeMapTextureSize(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURECUBE_DIMENSION; @@ -546,7 +544,7 @@ static size_t GetMaximum2DTextureArraySize(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; @@ -566,7 +564,7 @@ static size_t GetMaximum3DTextureSize(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; @@ -586,7 +584,7 @@ static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_VIEWPORT_BOUNDS_MAX; @@ -612,7 +610,7 @@ static size_t GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel) switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: @@ -636,7 +634,7 @@ static size_t GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel) switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: @@ -655,7 +653,7 @@ static size_t GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_STANDARD_VERTEX_ELEMENT_COUNT; @@ -677,7 +675,7 @@ static size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel) // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; @@ -704,7 +702,7 @@ static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers(); @@ -733,7 +731,7 @@ static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel) switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); @@ -754,7 +752,7 @@ static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; @@ -778,7 +776,7 @@ static size_t GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel) // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; @@ -805,7 +803,7 @@ static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers(); @@ -826,7 +824,7 @@ static size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); @@ -847,7 +845,7 @@ static size_t GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; @@ -868,7 +866,7 @@ static int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE; @@ -889,7 +887,7 @@ static int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE; @@ -914,7 +912,7 @@ static size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel) switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent; @@ -935,7 +933,7 @@ static size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_SO_BUFFER_SLOT_COUNT; @@ -951,11 +949,11 @@ static size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel) } } -static size_t GetMaximumStreamOutputInterleavedComponenets(D3D_FEATURE_LEVEL featureLevel) +static size_t GetMaximumStreamOutputInterleavedComponents(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: @@ -971,14 +969,14 @@ static size_t GetMaximumStreamOutputInterleavedComponenets(D3D_FEATURE_LEVEL fea } } -static size_t GetMaximumStreamOutputSeparateCompeonents(D3D_FEATURE_LEVEL featureLevel) +static size_t GetMaximumStreamOutputSeparateComponents(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif - case D3D_FEATURE_LEVEL_11_0: return GetMaximumStreamOutputInterleavedComponenets(featureLevel) / + case D3D_FEATURE_LEVEL_11_0: return GetMaximumStreamOutputInterleavedComponents(featureLevel) / GetMaximumStreamOutputBuffers(featureLevel); @@ -1087,9 +1085,9 @@ void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *text caps->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxTextureImageUnits; // Transform feedback limits - caps->maxTransformFeedbackInterleavedComponents = GetMaximumStreamOutputInterleavedComponenets(featureLevel); + caps->maxTransformFeedbackInterleavedComponents = GetMaximumStreamOutputInterleavedComponents(featureLevel); caps->maxTransformFeedbackSeparateAttributes = GetMaximumStreamOutputBuffers(featureLevel); - caps->maxTransformFeedbackSeparateComponents = GetMaximumStreamOutputSeparateCompeonents(featureLevel); + caps->maxTransformFeedbackSeparateComponents = GetMaximumStreamOutputSeparateComponents(featureLevel); // GL extension support extensions->setTextureExtensionSupport(*textureCapsMap); @@ -1198,17 +1196,31 @@ void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex* vertex, flo HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name) { -#if !defined(__MINGW32__) && defined(_DEBUG) +#if defined(_DEBUG) && !defined(__MINGW32__) return resource->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(name), name); #else return S_OK; #endif } -RenderTarget11 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment) +gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget11 **outRT) +{ + RenderTarget *renderTarget = NULL; + gl::Error error = rx::GetAttachmentRenderTarget(attachment, &renderTarget); + if (error.isError()) + { + return error; + } + *outRT = RenderTarget11::makeRenderTarget11(renderTarget); + return gl::Error(GL_NO_ERROR); +} + +Workarounds GenerateWorkarounds() { - RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment); - return RenderTarget11::makeRenderTarget11(renderTarget); + Workarounds workarounds; + workarounds.mrtPerfWorkaround = true; + workarounds.setDataFasterThanImageUpload = true; + return workarounds; } } 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 4c05eb9256..9df9c95763 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 @@ -12,6 +12,7 @@ #include "libGLESv2/angletypes.h" #include "libGLESv2/Caps.h" +#include "libGLESv2/Error.h" #include <vector> @@ -23,6 +24,7 @@ class FramebufferAttachment; namespace rx { class RenderTarget11; +struct Workarounds; namespace gl_d3d11 { @@ -176,7 +178,9 @@ inline void SetBufferData(ID3D11DeviceContext *context, ID3D11Buffer *constantBu context->Unmap(constantBuffer, 0); } -RenderTarget11 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment); +gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget11 **outRT); + +Workarounds GenerateWorkarounds(); } |