diff options
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9')
37 files changed, 2454 insertions, 1089 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp index a0bc2960b7..2ac8ee3a29 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp @@ -135,7 +135,7 @@ gl::Error Blit9::setShader(ShaderId source, const char *profile, { IDirect3DDevice9 *device = mRenderer->getDevice(); - D3DShaderType *shader; + D3DShaderType *shader = nullptr; if (mCompiledShaders[source] != NULL) { @@ -236,11 +236,11 @@ gl::Error Blit9::copy2D(const gl::Framebuffer *framebuffer, const RECT &sourceRe return error; } - gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0); + const gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0); ASSERT(colorbuffer); - RenderTarget9 *renderTarget9 = NULL; - error = d3d9::GetAttachmentRenderTarget(colorbuffer, &renderTarget9); + RenderTarget9 *renderTarget9 = nullptr; + error = colorbuffer->getRenderTarget(&renderTarget9); if (error.isError()) { return error; @@ -251,10 +251,11 @@ gl::Error Blit9::copy2D(const gl::Framebuffer *framebuffer, const RECT &sourceRe ASSERT(source); IDirect3DSurface9 *destSurface = NULL; - TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage); - error = storage9->getSurfaceLevel(level, true, &destSurface); + TextureStorage9 *storage9 = GetAs<TextureStorage9>(storage); + error = storage9->getSurfaceLevel(GL_TEXTURE_2D, level, true, &destSurface); if (error.isError()) { + SafeRelease(source); return error; } ASSERT(destSurface); @@ -275,11 +276,11 @@ gl::Error Blit9::copyCube(const gl::Framebuffer *framebuffer, const RECT &source return error; } - gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0); + const gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0); ASSERT(colorbuffer); - RenderTarget9 *renderTarget9 = NULL; - error = d3d9::GetAttachmentRenderTarget(colorbuffer, &renderTarget9); + RenderTarget9 *renderTarget9 = nullptr; + error = colorbuffer->getRenderTarget(&renderTarget9); if (error.isError()) { return error; @@ -290,10 +291,11 @@ gl::Error Blit9::copyCube(const gl::Framebuffer *framebuffer, const RECT &source ASSERT(source); IDirect3DSurface9 *destSurface = NULL; - TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage); - error = storage9->getCubeMapSurface(target, level, true, &destSurface); + TextureStorage9 *storage9 = GetAs<TextureStorage9>(storage); + error = storage9->getSurfaceLevel(target, level, true, &destSurface); if (error.isError()) { + SafeRelease(source); return error; } ASSERT(destSurface); diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp index b051c81aa8..804b6971ce 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp @@ -14,7 +14,6 @@ namespace rx Buffer9::Buffer9(Renderer9 *renderer) : BufferD3D(renderer), - mRenderer(renderer), mSize(0) {} @@ -23,12 +22,6 @@ Buffer9::~Buffer9() mSize = 0; } -Buffer9 *Buffer9::makeBuffer9(BufferImpl *buffer) -{ - ASSERT(HAS_DYNAMIC_TYPE(Buffer9*, buffer)); - return static_cast<Buffer9*>(buffer); -} - gl::Error Buffer9::setData(const void* data, size_t size, GLenum usage) { if (size > mMemory.size()) @@ -45,13 +38,9 @@ gl::Error Buffer9::setData(const void* data, size_t size, GLenum usage) memcpy(mMemory.data(), data, size); } - invalidateStaticData(); - - if (usage == GL_STATIC_DRAW) - { - initializeStaticData(); - } + invalidateStaticData(D3D_BUFFER_INVALIDATE_WHOLE_CACHE); + updateD3DBufferUsage(usage); return gl::Error(GL_NO_ERROR); } @@ -77,7 +66,7 @@ gl::Error Buffer9::setSubData(const void* data, size_t size, size_t offset) memcpy(mMemory.data() + offset, data, size); } - invalidateStaticData(); + invalidateStaticData(D3D_BUFFER_INVALIDATE_WHOLE_CACHE); return gl::Error(GL_NO_ERROR); } @@ -85,24 +74,30 @@ gl::Error Buffer9::setSubData(const void* data, size_t size, size_t offset) gl::Error Buffer9::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) { // Note: this method is currently unreachable - Buffer9* sourceBuffer = makeBuffer9(source); + Buffer9* sourceBuffer = GetAs<Buffer9>(source); ASSERT(sourceBuffer); memcpy(mMemory.data() + destOffset, sourceBuffer->mMemory.data() + sourceOffset, size); - invalidateStaticData(); + invalidateStaticData(D3D_BUFFER_INVALIDATE_WHOLE_CACHE); return gl::Error(GL_NO_ERROR); } // We do not support buffer mapping in D3D9 -gl::Error Buffer9::map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) +gl::Error Buffer9::map(GLenum access, GLvoid **mapPtr) +{ + UNREACHABLE(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error Buffer9::mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) { UNREACHABLE(); return gl::Error(GL_INVALID_OPERATION); } -gl::Error Buffer9::unmap() +gl::Error Buffer9::unmap(GLboolean *result) { UNREACHABLE(); return gl::Error(GL_INVALID_OPERATION); diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h index c1984146fc..44a524ba28 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h @@ -23,23 +23,21 @@ class Buffer9 : public BufferD3D Buffer9(Renderer9 *renderer); virtual ~Buffer9(); - static Buffer9 *makeBuffer9(BufferImpl *buffer); - // BufferD3D implementation virtual size_t getSize() const { return mSize; } virtual bool supportsDirectBinding() const { return false; } + gl::Error getData(const uint8_t **outData) override; // BufferImpl implementation virtual gl::Error setData(const void* data, size_t size, GLenum usage); - gl::Error getData(const uint8_t **outData) override; virtual gl::Error setSubData(const void* data, size_t size, size_t offset); virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); - virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr); - virtual gl::Error unmap(); + virtual gl::Error map(GLenum access, GLvoid **mapPtr); + virtual gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr); + virtual gl::Error unmap(GLboolean *result); virtual void markTransformFeedbackUsage(); private: - Renderer9 *mRenderer; MemoryBuffer mMemory; size_t mSize; }; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp index 09b229bcb1..6ec35e16a7 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp @@ -13,9 +13,9 @@ namespace rx { -void DebugAnnotator9::beginEvent(const std::wstring &eventName) +void DebugAnnotator9::beginEvent(const wchar_t *eventName) { - D3DPERF_BeginEvent(0, eventName.c_str()); + D3DPERF_BeginEvent(0, eventName); } void DebugAnnotator9::endEvent() @@ -23,9 +23,9 @@ void DebugAnnotator9::endEvent() D3DPERF_EndEvent(); } -void DebugAnnotator9::setMarker(const std::wstring &markerName) +void DebugAnnotator9::setMarker(const wchar_t *markerName) { - D3DPERF_SetMarker(0, markerName.c_str()); + D3DPERF_SetMarker(0, markerName); } bool DebugAnnotator9::getStatus() diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h index 02956f7183..54e3bb9490 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h @@ -18,9 +18,9 @@ class DebugAnnotator9 : public gl::DebugAnnotator { public: DebugAnnotator9() {} - void beginEvent(const std::wstring &eventName) override; + void beginEvent(const wchar_t *eventName) override; void endEvent() override; - void setMarker(const std::wstring &markerName) override; + void setMarker(const wchar_t *markerName) override; bool getStatus() override; }; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp index 27c265e28d..3300681277 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp @@ -25,7 +25,7 @@ FenceNV9::~FenceNV9() SafeRelease(mQuery); } -gl::Error FenceNV9::set() +gl::Error FenceNV9::set(GLenum condition) { if (!mQuery) { @@ -47,7 +47,29 @@ gl::Error FenceNV9::set() return gl::Error(GL_NO_ERROR); } -gl::Error FenceNV9::test(bool flushCommandBuffer, GLboolean *outFinished) +gl::Error FenceNV9::test(GLboolean *outFinished) +{ + return testHelper(true, outFinished); +} + +gl::Error FenceNV9::finish() +{ + GLboolean finished = GL_FALSE; + while (finished != GL_TRUE) + { + gl::Error error = testHelper(true, &finished); + if (error.isError()) + { + return error; + } + + Sleep(0); + } + + return gl::Error(GL_NO_ERROR); +} + +gl::Error FenceNV9::testHelper(bool flushCommandBuffer, GLboolean *outFinished) { ASSERT(mQuery); @@ -69,22 +91,4 @@ gl::Error FenceNV9::test(bool flushCommandBuffer, GLboolean *outFinished) return gl::Error(GL_NO_ERROR); } -gl::Error FenceNV9::finishFence(GLboolean *outFinished) -{ - ASSERT(outFinished); - - while (*outFinished != GL_TRUE) - { - gl::Error error = test(true, outFinished); - if (error.isError()) - { - return error; - } - - Sleep(0); - } - - return gl::Error(GL_NO_ERROR); -} - } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.h index 4b86747396..200ac68d27 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.h @@ -20,13 +20,15 @@ class FenceNV9 : public FenceNVImpl { public: explicit FenceNV9(Renderer9 *renderer); - virtual ~FenceNV9(); + ~FenceNV9() override; - gl::Error set(); - gl::Error test(bool flushCommandBuffer, GLboolean *outFinished); - gl::Error finishFence(GLboolean *outFinished); + gl::Error set(GLenum condition) override; + gl::Error test(GLboolean *outFinished) override; + gl::Error finish() override; private: + gl::Error testHelper(bool flushCommandBuffer, GLboolean *outFinished); + Renderer9 *mRenderer; IDirect3DQuery9 *mQuery; }; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp index dbdfc6d6de..9c269a8565 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp @@ -22,8 +22,7 @@ namespace rx { Framebuffer9::Framebuffer9(const gl::Framebuffer::Data &data, Renderer9 *renderer) - : FramebufferD3D(data, renderer), - mRenderer(renderer) + : FramebufferD3D(data, renderer), mRenderer(renderer) { ASSERT(mRenderer != nullptr); } @@ -32,9 +31,30 @@ Framebuffer9::~Framebuffer9() { } -gl::Error Framebuffer9::clear(const gl::State &state, const ClearParameters &clearParams) +gl::Error Framebuffer9::discard(size_t, const GLenum *) { - const gl::FramebufferAttachment *colorAttachment = mData.mColorAttachments[0]; + // Extension not implemented in D3D9 renderer + UNREACHABLE(); + return gl::Error(GL_NO_ERROR); +} + +gl::Error Framebuffer9::invalidate(size_t, const GLenum *) +{ + // Shouldn't ever reach here in D3D9 + UNREACHABLE(); + return gl::Error(GL_NO_ERROR); +} + +gl::Error Framebuffer9::invalidateSub(size_t, const GLenum *, const gl::Rectangle &) +{ + // Shouldn't ever reach here in D3D9 + UNREACHABLE(); + return gl::Error(GL_NO_ERROR); +} + +gl::Error Framebuffer9::clear(const gl::Data &data, const ClearParameters &clearParams) +{ + const gl::FramebufferAttachment *colorAttachment = mData.getColorAttachment(0); const gl::FramebufferAttachment *depthStencilAttachment = mData.getDepthOrStencilAttachment(); gl::Error error = mRenderer->applyRenderTarget(colorAttachment, depthStencilAttachment); @@ -43,24 +63,30 @@ gl::Error Framebuffer9::clear(const gl::State &state, const ClearParameters &cle return error; } - float nearZ, farZ; - state.getDepthRange(&nearZ, &farZ); - mRenderer->setViewport(state.getViewport(), nearZ, farZ, GL_TRIANGLES, state.getRasterizerState().frontFace, true); + float nearZ = data.state->getNearPlane(); + float farZ = data.state->getFarPlane(); + mRenderer->setViewport(data.caps, data.state->getViewport(), nearZ, farZ, GL_TRIANGLES, + data.state->getRasterizerState().frontFace, true); - mRenderer->setScissorRectangle(state.getScissor(), state.isScissorTestEnabled()); + mRenderer->setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled()); return mRenderer->clear(clearParams, colorAttachment, depthStencilAttachment); } -gl::Error Framebuffer9::readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) const +gl::Error Framebuffer9::readPixelsImpl(const gl::Rectangle &area, + GLenum format, + GLenum type, + size_t outputPitch, + const gl::PixelPackState &pack, + uint8_t *pixels) const { - ASSERT(pack.pixelBuffer.get() == NULL); + ASSERT(pack.pixelBuffer.get() == nullptr); - const gl::FramebufferAttachment *colorbuffer = mData.mColorAttachments[0]; + const gl::FramebufferAttachment *colorbuffer = mData.getColorAttachment(0); ASSERT(colorbuffer); - RenderTarget9 *renderTarget = NULL; - gl::Error error = d3d9::GetAttachmentRenderTarget(colorbuffer, &renderTarget); + RenderTarget9 *renderTarget = nullptr; + gl::Error error = colorbuffer->getRenderTarget(&renderTarget); if (error.isError()) { return error; @@ -84,7 +110,7 @@ gl::Error Framebuffer9::readPixels(const gl::Rectangle &area, GLenum format, GLe ASSERT(device); HRESULT result; - IDirect3DSurface9 *systemSurface = NULL; + IDirect3DSurface9 *systemSurface = nullptr; bool directToPixels = !pack.reverseRowOrder && pack.alignment <= 4 && mRenderer->getShareHandleSupport() && area.x == 0 && area.y == 0 && static_cast<UINT>(area.width) == desc.Width && static_cast<UINT>(area.height) == desc.Height && @@ -104,7 +130,7 @@ gl::Error Framebuffer9::readPixels(const gl::Rectangle &area, GLenum format, GLe if (!directToPixels) { result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, - D3DPOOL_SYSTEMMEM, &systemSurface, NULL); + D3DPOOL_SYSTEMMEM, &systemSurface, nullptr); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); @@ -246,19 +272,19 @@ gl::Error Framebuffer9::blit(const gl::Rectangle &sourceArea, const gl::Rectangl const gl::FramebufferAttachment *readBuffer = sourceFramebuffer->getColorbuffer(0); ASSERT(readBuffer); - RenderTarget9 *readRenderTarget = NULL; - gl::Error error = d3d9::GetAttachmentRenderTarget(readBuffer, &readRenderTarget); + RenderTarget9 *readRenderTarget = nullptr; + gl::Error error = readBuffer->getRenderTarget(&readRenderTarget); if (error.isError()) { return error; } ASSERT(readRenderTarget); - const gl::FramebufferAttachment *drawBuffer = mData.mColorAttachments[0]; + const gl::FramebufferAttachment *drawBuffer = mData.getColorAttachment(0); ASSERT(drawBuffer); - RenderTarget9 *drawRenderTarget = NULL; - error = d3d9::GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget); + RenderTarget9 *drawRenderTarget = nullptr; + error = drawBuffer->getRenderTarget(&drawRenderTarget); if (error.isError()) { return error; @@ -372,8 +398,8 @@ gl::Error Framebuffer9::blit(const gl::Rectangle &sourceArea, const gl::Rectangl const gl::FramebufferAttachment *readBuffer = sourceFramebuffer->getDepthOrStencilbuffer(); ASSERT(readBuffer); - RenderTarget9 *readDepthStencil = NULL; - gl::Error error = d3d9::GetAttachmentRenderTarget(readBuffer, &readDepthStencil); + RenderTarget9 *readDepthStencil = nullptr; + gl::Error error = readBuffer->getRenderTarget(&readDepthStencil); if (error.isError()) { return error; @@ -383,8 +409,8 @@ gl::Error Framebuffer9::blit(const gl::Rectangle &sourceArea, const gl::Rectangl const gl::FramebufferAttachment *drawBuffer = mData.getDepthOrStencilAttachment(); ASSERT(drawBuffer); - RenderTarget9 *drawDepthStencil = NULL; - error = d3d9::GetAttachmentRenderTarget(drawBuffer, &drawDepthStencil); + RenderTarget9 *drawDepthStencil = nullptr; + error = drawBuffer->getRenderTarget(&drawDepthStencil); if (error.isError()) { return error; @@ -398,7 +424,7 @@ gl::Error Framebuffer9::blit(const gl::Rectangle &sourceArea, const gl::Rectangl IDirect3DSurface9* drawSurface = drawDepthStencil->getSurface(); ASSERT(drawDepthStencil); - HRESULT result = device->StretchRect(readSurface, NULL, drawSurface, NULL, D3DTEXF_NONE); + HRESULT result = device->StretchRect(readSurface, nullptr, drawSurface, nullptr, D3DTEXF_NONE); SafeRelease(readSurface); SafeRelease(drawSurface); @@ -414,7 +440,7 @@ gl::Error Framebuffer9::blit(const gl::Rectangle &sourceArea, const gl::Rectangl GLenum Framebuffer9::getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const { - RenderTarget9 *renderTarget9 = RenderTarget9::makeRenderTarget9(renderTarget); + RenderTarget9 *renderTarget9 = GetAs<RenderTarget9>(renderTarget); const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(renderTarget9->getD3DFormat()); return d3dFormatInfo.internalFormat; } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h index 292118e6db..fe12079ae0 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h @@ -21,11 +21,19 @@ class Framebuffer9 : public FramebufferD3D Framebuffer9(const gl::Framebuffer::Data &data, Renderer9 *renderer); virtual ~Framebuffer9(); - private: - gl::Error clear(const gl::State &state, const ClearParameters &clearParams) override; + gl::Error discard(size_t count, const GLenum *attachments) override; + gl::Error invalidate(size_t count, const GLenum *attachments) override; + gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) override; - gl::Error readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, - const gl::PixelPackState &pack, uint8_t *pixels) const override; + private: + gl::Error clear(const gl::Data &data, const ClearParameters &clearParams) override; + + gl::Error readPixelsImpl(const gl::Rectangle &area, + GLenum format, + GLenum type, + size_t outputPitch, + const gl::PixelPackState &pack, + uint8_t *pixels) const override; gl::Error blit(const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter, diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp index d149f7a806..fec7e3e19d 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp @@ -94,12 +94,6 @@ gl::Error Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 return gl::Error(GL_NO_ERROR); } -Image9 *Image9::makeImage9(ImageD3D *img) -{ - ASSERT(HAS_DYNAMIC_TYPE(Image9*, img)); - return static_cast<Image9*>(img); -} - gl::Error Image9::generateMipmap(Image9 *dest, Image9 *source) { IDirect3DSurface9 *sourceSurface = NULL; @@ -336,8 +330,8 @@ gl::Error Image9::getSurface(IDirect3DSurface9 **outSurface) gl::Error Image9::setManagedSurface2D(TextureStorage *storage, int level) { IDirect3DSurface9 *surface = NULL; - TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage); - gl::Error error = storage9->getSurfaceLevel(level, false, &surface); + TextureStorage9 *storage9 = GetAs<TextureStorage9>(storage); + gl::Error error = storage9->getSurfaceLevel(GL_TEXTURE_2D, level, false, &surface); if (error.isError()) { return error; @@ -348,8 +342,9 @@ gl::Error Image9::setManagedSurface2D(TextureStorage *storage, int level) gl::Error Image9::setManagedSurfaceCube(TextureStorage *storage, int face, int level) { IDirect3DSurface9 *surface = NULL; - TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage); - gl::Error error = storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false, &surface); + TextureStorage9 *storage9 = GetAs<TextureStorage9>(storage); + gl::Error error = + storage9->getSurfaceLevel(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false, &surface); if (error.isError()) { return error; @@ -390,12 +385,13 @@ gl::Error Image9::copyToStorage(TextureStorage *storage, const gl::ImageIndex &i return error; } + TextureStorage9 *storage9 = GetAs<TextureStorage9>(storage); + IDirect3DSurface9 *destSurface = NULL; if (index.type == GL_TEXTURE_2D) { - TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage); - error = storage9->getSurfaceLevel(index.mipIndex, true, &destSurface); + error = storage9->getSurfaceLevel(GL_TEXTURE_2D, index.mipIndex, true, &destSurface); if (error.isError()) { return error; @@ -404,8 +400,7 @@ gl::Error Image9::copyToStorage(TextureStorage *storage, const gl::ImageIndex &i else { ASSERT(gl::IsCubeMapTextureTarget(index.type)); - TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage); - error = storage9->getCubeMapSurface(index.type, index.mipIndex, true, &destSurface); + error = storage9->getSurfaceLevel(index.type, index.mipIndex, true, &destSurface); if (error.isError()) { return error; @@ -485,6 +480,8 @@ gl::Error Image9::loadData(const gl::Box &area, const gl::PixelUnpackState &unpa const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); GLsizei inputRowPitch = formatInfo.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength); + GLsizei inputSkipBytes = formatInfo.computeSkipPixels(inputRowPitch, 0, unpack.skipImages, + unpack.skipRows, unpack.skipPixels); const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat); ASSERT(d3dFormatInfo.loadFunction != NULL); @@ -503,8 +500,9 @@ gl::Error Image9::loadData(const gl::Box &area, const gl::PixelUnpackState &unpa } d3dFormatInfo.loadFunction(area.width, area.height, area.depth, - reinterpret_cast<const uint8_t*>(input), inputRowPitch, 0, - reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0); + reinterpret_cast<const uint8_t *>(input) + inputSkipBytes, + inputRowPitch, 0, reinterpret_cast<uint8_t *>(locked.pBits), + locked.Pitch, 0); unlock(); @@ -518,7 +516,8 @@ gl::Error Image9::loadCompressedData(const gl::Box &area, const void *input) const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, area.width, 1, 0); - GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0); + GLsizei inputDepthPitch = + formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0, 0); const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat); @@ -550,14 +549,16 @@ gl::Error Image9::loadCompressedData(const gl::Box &area, const void *input) } // This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures -gl::Error Image9::copy(const gl::Offset &destOffset, const gl::Rectangle &sourceArea, RenderTargetD3D *source) +gl::Error Image9::copyFromRTInternal(const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + RenderTargetD3D *source) { ASSERT(source); // ES3.0 only behaviour to copy into a 3d texture ASSERT(destOffset.z == 0); - RenderTarget9 *renderTarget = RenderTarget9::makeRenderTarget9(source); + RenderTarget9 *renderTarget = GetAs<RenderTarget9>(source); IDirect3DSurface9 *surface = renderTarget->getSurface(); ASSERT(surface); @@ -667,9 +668,9 @@ gl::Error Image9::copy(const gl::Offset &destOffset, const gl::Rectangle &source for (int x = 0; x < width; x++) { unsigned short rgb = ((unsigned short*)sourcePixels)[x]; - unsigned char red = (rgb & 0xF800) >> 8; - unsigned char green = (rgb & 0x07E0) >> 3; - unsigned char blue = (rgb & 0x001F) << 3; + unsigned char red = static_cast<unsigned char>((rgb & 0xF800) >> 8); + unsigned char green = static_cast<unsigned char>((rgb & 0x07E0) >> 3); + unsigned char blue = static_cast<unsigned char>((rgb & 0x001F) << 3); destPixels[x + 0] = blue | (blue >> 5); destPixels[x + 1] = green | (green >> 6); destPixels[x + 2] = red | (red >> 5); @@ -704,9 +705,9 @@ gl::Error Image9::copy(const gl::Offset &destOffset, const gl::Rectangle &source for (int x = 0; x < width; x++) { unsigned short argb = ((unsigned short*)sourcePixels)[x]; - unsigned char red = (argb & 0x7C00) >> 7; - unsigned char green = (argb & 0x03E0) >> 2; - unsigned char blue = (argb & 0x001F) << 3; + unsigned char red = static_cast<unsigned char>((argb & 0x7C00) >> 7); + unsigned char green = static_cast<unsigned char>((argb & 0x03E0) >> 2); + unsigned char blue = static_cast<unsigned char>((argb & 0x001F) << 3); destPixels[x + 0] = blue | (blue >> 5); destPixels[x + 1] = green | (green >> 5); destPixels[x + 2] = red | (red >> 5); @@ -722,9 +723,9 @@ gl::Error Image9::copy(const gl::Offset &destOffset, const gl::Rectangle &source for (int x = 0; x < width; x++) { unsigned short argb = ((unsigned short*)sourcePixels)[x]; - unsigned char red = (argb & 0x7C00) >> 7; - unsigned char green = (argb & 0x03E0) >> 2; - unsigned char blue = (argb & 0x001F) << 3; + unsigned char red = static_cast<unsigned char>((argb & 0x7C00) >> 7); + unsigned char green = static_cast<unsigned char>((argb & 0x03E0) >> 2); + unsigned char blue = static_cast<unsigned char>((argb & 0x001F) << 3); unsigned char alpha = (signed short)argb >> 15; destPixels[x + 0] = blue | (blue >> 5); destPixels[x + 1] = green | (green >> 5); @@ -778,11 +779,35 @@ gl::Error Image9::copy(const gl::Offset &destOffset, const gl::Rectangle &source return gl::Error(GL_NO_ERROR); } -gl::Error Image9::copy(const gl::Offset &destOffset, const gl::Box &area, const gl::ImageIndex &srcIndex, TextureStorage *srcStorage) +gl::Error Image9::copyFromTexStorage(const gl::ImageIndex &imageIndex, TextureStorage *source) { - // Currently unreachable, due to only being used in a D3D11-only workaround - UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION); + RenderTargetD3D *renderTarget = nullptr; + gl::Error error = source->getRenderTarget(imageIndex, &renderTarget); + if (error.isError()) + { + return error; + } + + gl::Rectangle sourceArea(0, 0, mWidth, mHeight); + return copyFromRTInternal(gl::Offset(), sourceArea, renderTarget); } +gl::Error Image9::copyFromFramebuffer(const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + const gl::Framebuffer *source) +{ + const gl::FramebufferAttachment *srcAttachment = source->getReadColorbuffer(); + ASSERT(srcAttachment); + + RenderTargetD3D *renderTarget = NULL; + gl::Error error = srcAttachment->getRenderTarget(&renderTarget); + if (error.isError()) + { + return error; + } + + ASSERT(renderTarget); + return copyFromRTInternal(destOffset, sourceArea, renderTarget); } + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.h index 8cbfbbebf6..91448cc849 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.h @@ -28,8 +28,6 @@ class Image9 : public ImageD3D Image9(Renderer9 *renderer); ~Image9(); - static Image9 *makeImage9(ImageD3D *img); - static gl::Error generateMipmap(Image9 *dest, Image9 *source); static gl::Error generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface); static gl::Error copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source); @@ -47,9 +45,10 @@ class Image9 : public ImageD3D virtual gl::Error loadData(const gl::Box &area, const gl::PixelUnpackState &unpack, GLenum type, const void *input); virtual gl::Error loadCompressedData(const gl::Box &area, const void *input); - virtual gl::Error copy(const gl::Offset &destOffset, const gl::Rectangle &sourceArea, RenderTargetD3D *source); - virtual gl::Error copy(const gl::Offset &destOffset, const gl::Box &sourceArea, - const gl::ImageIndex &sourceIndex, TextureStorage *source); + gl::Error copyFromTexStorage(const gl::ImageIndex &imageIndex, TextureStorage *source) override; + gl::Error copyFromFramebuffer(const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + const gl::Framebuffer *source) override; private: gl::Error getSurface(IDirect3DSurface9 **outSurface); @@ -61,6 +60,10 @@ class Image9 : public ImageD3D gl::Error lock(D3DLOCKED_RECT *lockedRect, const RECT &rect); void unlock(); + gl::Error copyFromRTInternal(const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + RenderTargetD3D *source); + Renderer9 *mRenderer; D3DPOOL mD3DPool; // can only be D3DPOOL_SYSTEMMEM or D3DPOOL_MANAGED since it needs to be lockable. diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp index c5d72e6a50..97c7f72136 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp @@ -65,12 +65,6 @@ gl::Error IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bo return gl::Error(GL_NO_ERROR); } -IndexBuffer9 *IndexBuffer9::makeIndexBuffer9(IndexBuffer *indexBuffer) -{ - ASSERT(HAS_DYNAMIC_TYPE(IndexBuffer9*, indexBuffer)); - return static_cast<IndexBuffer9*>(indexBuffer); -} - gl::Error IndexBuffer9::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) { if (!mIndexBuffer) diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h index 61f8b11566..ba03ba703f 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h @@ -23,8 +23,6 @@ class IndexBuffer9 : public IndexBuffer virtual gl::Error initialize(unsigned int bufferSize, GLenum indexType, bool dynamic); - static IndexBuffer9 *makeIndexBuffer9(IndexBuffer *indexBuffer); - virtual gl::Error mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory); virtual gl::Error unmapBuffer(); diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.cpp index 96f12d7868..c826abf81c 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.cpp @@ -66,7 +66,14 @@ gl::Error Query9::end() return gl::Error(GL_NO_ERROR); } -gl::Error Query9::getResult(GLuint *params) +gl::Error Query9::queryCounter() +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION, "Unimplemented"); +} + +template <typename T> +gl::Error Query9::getResultBase(T *params) { while (!mQueryFinished) { @@ -83,12 +90,31 @@ gl::Error Query9::getResult(GLuint *params) } ASSERT(mQueryFinished); - *params = mResult; - + *params = static_cast<T>(mResult); return gl::Error(GL_NO_ERROR); } -gl::Error Query9::isResultAvailable(GLuint *available) +gl::Error Query9::getResult(GLint *params) +{ + return getResultBase(params); +} + +gl::Error Query9::getResult(GLuint *params) +{ + return getResultBase(params); +} + +gl::Error Query9::getResult(GLint64 *params) +{ + return getResultBase(params); +} + +gl::Error Query9::getResult(GLuint64 *params) +{ + return getResultBase(params); +} + +gl::Error Query9::isResultAvailable(bool *available) { gl::Error error = testQuery(); if (error.isError()) @@ -96,7 +122,7 @@ gl::Error Query9::isResultAvailable(GLuint *available) return error; } - *available = (mQueryFinished ? GL_TRUE : GL_FALSE); + *available = mQueryFinished; return gl::Error(GL_NO_ERROR); } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.h index 399da2ed83..9d17711a00 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.h @@ -23,13 +23,20 @@ class Query9 : public QueryImpl virtual gl::Error begin(); virtual gl::Error end(); + virtual gl::Error queryCounter(); + virtual gl::Error getResult(GLint *params); virtual gl::Error getResult(GLuint *params); - virtual gl::Error isResultAvailable(GLuint *available); + virtual gl::Error getResult(GLint64 *params); + virtual gl::Error getResult(GLuint64 *params); + virtual gl::Error isResultAvailable(bool *available); private: gl::Error testQuery(); - GLuint mResult; + template <typename T> + gl::Error getResultBase(T *params); + + GLuint64 mResult; bool mQueryFinished; Renderer9 *mRenderer; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp index 412c0109f5..419bff1f63 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp @@ -16,14 +16,14 @@ namespace rx { -RenderTarget9 *RenderTarget9::makeRenderTarget9(RenderTargetD3D *target) -{ - ASSERT(HAS_DYNAMIC_TYPE(RenderTarget9*, target)); - return static_cast<RenderTarget9*>(target); -} - // TODO: AddRef the incoming surface to take ownership instead of expecting that its ref is being given. -TextureRenderTarget9::TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, +TextureRenderTarget9::TextureRenderTarget9(IDirect3DBaseTexture9 *texture, + size_t textureLevel, + IDirect3DSurface9 *surface, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, GLsizei samples) : mWidth(width), mHeight(height), @@ -31,6 +31,8 @@ TextureRenderTarget9::TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum in mInternalFormat(internalFormat), mD3DFormat(D3DFMT_UNKNOWN), mSamples(samples), + mTexture(texture), + mTextureLevel(textureLevel), mRenderTarget(surface) { ASSERT(mDepth == 1); @@ -45,6 +47,7 @@ TextureRenderTarget9::TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum in TextureRenderTarget9::~TextureRenderTarget9() { + SafeRelease(mTexture); SafeRelease(mRenderTarget); } @@ -73,7 +76,17 @@ GLsizei TextureRenderTarget9::getSamples() const return mSamples; } -IDirect3DSurface9 *TextureRenderTarget9::getSurface() +IDirect3DBaseTexture9 *TextureRenderTarget9::getTexture() const +{ + return mTexture; +} + +size_t TextureRenderTarget9::getTextureLevel() const +{ + return mTextureLevel; +} + +IDirect3DSurface9 *TextureRenderTarget9::getSurface() const { // Caller is responsible for releasing the returned surface reference. // TODO: remove the AddRef to match RenderTarget11 @@ -117,7 +130,7 @@ GLsizei SurfaceRenderTarget9::getDepth() const GLenum SurfaceRenderTarget9::getInternalFormat() const { - return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetBackBufferInternalFormat()); + return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetRenderTargetInternalFormat()); } GLsizei SurfaceRenderTarget9::getSamples() const @@ -126,11 +139,21 @@ GLsizei SurfaceRenderTarget9::getSamples() const return 0; } -IDirect3DSurface9 *SurfaceRenderTarget9::getSurface() +IDirect3DSurface9 *SurfaceRenderTarget9::getSurface() const { return (mDepth ? mSwapChain->getDepthStencil() : mSwapChain->getRenderTarget()); } +IDirect3DBaseTexture9 *SurfaceRenderTarget9::getTexture() const +{ + return (mDepth ? nullptr : mSwapChain->getOffscreenTexture()); +} + +size_t SurfaceRenderTarget9::getTextureLevel() const +{ + return 0; +} + D3DFORMAT SurfaceRenderTarget9::getD3DFormat() const { return d3d9::GetTextureFormatInfo(getInternalFormat()).texFormat; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h index 32c7dfa09c..f19c54de7b 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h @@ -22,10 +22,12 @@ class RenderTarget9 : public RenderTargetD3D public: RenderTarget9() { } virtual ~RenderTarget9() { } + // Retrieve the texture that backs this render target, may be null for swap chain render + // targets. + virtual IDirect3DBaseTexture9 *getTexture() const = 0; + virtual size_t getTextureLevel() const = 0; - static RenderTarget9 *makeRenderTarget9(RenderTargetD3D *renderTarget); - - virtual IDirect3DSurface9 *getSurface() = 0; + virtual IDirect3DSurface9 *getSurface() const = 0; virtual D3DFORMAT getD3DFormat() const = 0; }; @@ -33,7 +35,13 @@ class RenderTarget9 : public RenderTargetD3D class TextureRenderTarget9 : public RenderTarget9 { public: - TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, + TextureRenderTarget9(IDirect3DBaseTexture9 *texture, + size_t textureLevel, + IDirect3DSurface9 *surface, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, GLsizei samples); virtual ~TextureRenderTarget9(); @@ -43,7 +51,9 @@ class TextureRenderTarget9 : public RenderTarget9 GLenum getInternalFormat() const override; GLsizei getSamples() const override; - IDirect3DSurface9 *getSurface() override; + IDirect3DBaseTexture9 *getTexture() const override; + size_t getTextureLevel() const override; + IDirect3DSurface9 *getSurface() const override; D3DFORMAT getD3DFormat() const override; @@ -55,6 +65,8 @@ class TextureRenderTarget9 : public RenderTarget9 D3DFORMAT mD3DFormat; GLsizei mSamples; + IDirect3DBaseTexture9 *mTexture; + size_t mTextureLevel; IDirect3DSurface9 *mRenderTarget; }; @@ -70,7 +82,9 @@ class SurfaceRenderTarget9 : public RenderTarget9 GLenum getInternalFormat() const override; GLsizei getSamples() const override; - IDirect3DSurface9 *getSurface() override; + IDirect3DBaseTexture9 *getTexture() const override; + size_t getTextureLevel() const override; + IDirect3DSurface9 *getSurface() const override; D3DFORMAT getD3DFormat() const override; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp index bf1c367693..6bb975b0e4 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp @@ -8,49 +8,50 @@ #include "libANGLE/renderer/d3d/d3d9/Renderer9.h" +#include <sstream> +#include <EGL/eglext.h> + #include "common/utilities.h" +#include "libANGLE/angletypes.h" #include "libANGLE/Buffer.h" #include "libANGLE/Display.h" +#include "libANGLE/features.h" +#include "libANGLE/formatutils.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/FramebufferAttachment.h" #include "libANGLE/Program.h" #include "libANGLE/Renderbuffer.h" -#include "libANGLE/State.h" -#include "libANGLE/Surface.h" -#include "libANGLE/Texture.h" -#include "libANGLE/angletypes.h" -#include "libANGLE/features.h" -#include "libANGLE/formatutils.h" -#include "libANGLE/renderer/d3d/CompilerD3D.h" -#include "libANGLE/renderer/d3d/FramebufferD3D.h" -#include "libANGLE/renderer/d3d/IndexDataManager.h" -#include "libANGLE/renderer/d3d/ProgramD3D.h" -#include "libANGLE/renderer/d3d/RenderbufferD3D.h" -#include "libANGLE/renderer/d3d/ShaderD3D.h" -#include "libANGLE/renderer/d3d/SurfaceD3D.h" -#include "libANGLE/renderer/d3d/TextureD3D.h" -#include "libANGLE/renderer/d3d/TransformFeedbackD3D.h" #include "libANGLE/renderer/d3d/d3d9/Blit9.h" #include "libANGLE/renderer/d3d/d3d9/Buffer9.h" #include "libANGLE/renderer/d3d/d3d9/Fence9.h" +#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" #include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h" #include "libANGLE/renderer/d3d/d3d9/Image9.h" #include "libANGLE/renderer/d3d/d3d9/IndexBuffer9.h" #include "libANGLE/renderer/d3d/d3d9/Query9.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" #include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" #include "libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h" #include "libANGLE/renderer/d3d/d3d9/SwapChain9.h" #include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h" #include "libANGLE/renderer/d3d/d3d9/VertexArray9.h" #include "libANGLE/renderer/d3d/d3d9/VertexBuffer9.h" -#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" -#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" - +#include "libANGLE/renderer/d3d/CompilerD3D.h" +#include "libANGLE/renderer/d3d/DeviceD3D.h" +#include "libANGLE/renderer/d3d/FramebufferD3D.h" +#include "libANGLE/renderer/d3d/IndexDataManager.h" +#include "libANGLE/renderer/d3d/ProgramD3D.h" +#include "libANGLE/renderer/d3d/RenderbufferD3D.h" +#include "libANGLE/renderer/d3d/ShaderD3D.h" +#include "libANGLE/renderer/d3d/SurfaceD3D.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/renderer/d3d/TransformFeedbackD3D.h" +#include "libANGLE/State.h" +#include "libANGLE/Surface.h" +#include "libANGLE/Texture.h" #include "third_party/trace_event/trace_event.h" -#include <sstream> -#include <EGL/eglext.h> #if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL) #define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3 @@ -76,12 +77,8 @@ enum MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4 }; -Renderer9::Renderer9(egl::Display *display) - : RendererD3D(display) +Renderer9::Renderer9(egl::Display *display) : RendererD3D(display), mStateManager(this) { - // Initialize global annotator - gl::InitializeDebugAnnotations(&mAnnotator); - mD3d9Module = NULL; mD3d9 = NULL; @@ -133,6 +130,10 @@ Renderer9::Renderer9(egl::Display *display) mAppliedVertexShader = NULL; mAppliedPixelShader = NULL; mAppliedProgramSerial = 0; + + initializeDebugAnnotator(); + + mEGLDevice = nullptr; } Renderer9::~Renderer9() @@ -147,8 +148,6 @@ Renderer9::~Renderer9() } release(); - - gl::UninitializeDebugAnnotations(); } void Renderer9::release() @@ -157,6 +156,7 @@ void Renderer9::release() releaseDeviceResources(); + SafeDelete(mEGLDevice); SafeRelease(mDevice); SafeRelease(mDeviceEx); SafeRelease(mD3d9); @@ -173,22 +173,9 @@ void Renderer9::release() mD3d9Module = NULL; } -Renderer9 *Renderer9::makeRenderer9(Renderer *renderer) -{ - ASSERT(HAS_DYNAMIC_TYPE(Renderer9*, renderer)); - return static_cast<Renderer9*>(renderer); -} - egl::Error Renderer9::initialize() { - if (!mCompiler.initialize()) - { - return egl::Error(EGL_NOT_INITIALIZED, - D3D9_INIT_COMPILER_ERROR, - "Compiler failed to initialize."); - } - - TRACE_EVENT0("gpu", "GetModuleHandle_d3d9"); + TRACE_EVENT0("gpu.angle", "GetModuleHandle_d3d9"); mD3d9Module = GetModuleHandle(TEXT("d3d9.dll")); if (mD3d9Module == NULL) @@ -204,14 +191,14 @@ egl::Error Renderer9::initialize() // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available. if (ANGLE_D3D9EX == ANGLE_ENABLED && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex))) { - TRACE_EVENT0("gpu", "D3d9Ex_QueryInterface"); + TRACE_EVENT0("gpu.angle", "D3d9Ex_QueryInterface"); ASSERT(mD3d9Ex); mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9)); ASSERT(mD3d9); } else { - TRACE_EVENT0("gpu", "Direct3DCreate9"); + TRACE_EVENT0("gpu.angle", "Direct3DCreate9"); mD3d9 = Direct3DCreate9(D3D_SDK_VERSION); } @@ -229,7 +216,7 @@ egl::Error Renderer9::initialize() // Give up on getting device caps after about one second. { - TRACE_EVENT0("gpu", "GetDeviceCaps"); + TRACE_EVENT0("gpu.angle", "GetDeviceCaps"); for (int i = 0; i < 10; ++i) { result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps); @@ -273,7 +260,7 @@ egl::Error Renderer9::initialize() } { - TRACE_EVENT0("gpu", "GetAdapterIdentifier"); + TRACE_EVENT0("gpu.angle", "GetAdapterIdentifier"); mD3d9->GetAdapterIdentifier(mAdapter, 0, &mAdapterIdentifier); } @@ -281,7 +268,7 @@ egl::Error Renderer9::initialize() static const TCHAR className[] = TEXT("STATIC"); { - TRACE_EVENT0("gpu", "CreateWindowEx"); + TRACE_EVENT0("gpu.angle", "CreateWindowEx"); mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL); } @@ -289,7 +276,7 @@ egl::Error Renderer9::initialize() DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES | D3DCREATE_MULTITHREADED; { - TRACE_EVENT0("gpu", "D3d9_CreateDevice"); + TRACE_EVENT0("gpu.angle", "D3d9_CreateDevice"); result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice); } if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DEVICELOST) @@ -300,7 +287,7 @@ egl::Error Renderer9::initialize() if (FAILED(result)) { - TRACE_EVENT0("gpu", "D3d9_CreateDevice2"); + TRACE_EVENT0("gpu.angle", "D3d9_CreateDevice2"); result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice); if (FAILED(result)) @@ -313,13 +300,13 @@ egl::Error Renderer9::initialize() if (mD3d9Ex) { - TRACE_EVENT0("gpu", "mDevice_QueryInterface"); + TRACE_EVENT0("gpu.angle", "mDevice_QueryInterface"); result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**)&mDeviceEx); ASSERT(SUCCEEDED(result)); } { - TRACE_EVENT0("gpu", "ShaderCache initialize"); + TRACE_EVENT0("gpu.angle", "ShaderCache initialize"); mVertexShaderCache.initialize(mDevice); mPixelShaderCache.initialize(mDevice); } @@ -359,14 +346,11 @@ void Renderer9::initializeDevice() const gl::Caps &rendererCaps = getRendererCaps(); - mForceSetVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); - - mForceSetPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); - mCurVertexTextureSerials.resize(rendererCaps.maxVertexTextureImageUnits); - mCurPixelTextureSerials.resize(rendererCaps.maxTextureImageUnits); + mCurVertexTextures.resize(rendererCaps.maxVertexTextureImageUnits); + mCurPixelTextures.resize(rendererCaps.maxTextureImageUnits); markAllStateDirty(); @@ -379,6 +363,9 @@ void Renderer9::initializeDevice() ASSERT(!mVertexDataManager && !mIndexDataManager); mVertexDataManager = new VertexDataManager(this); mIndexDataManager = new IndexDataManager(this, getRendererClass()); + + // TODO(jmadill): use context caps, and place in common D3D location + mTranslatedAttribCache.resize(getRendererCaps().maxVertexAttributes); } D3DPRESENT_PARAMETERS Renderer9::getDefaultPresentParameters() @@ -523,6 +510,31 @@ egl::ConfigSet Renderer9::generateConfigs() const return configs; } +void Renderer9::generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const +{ + outExtensions->createContextRobustness = true; + + if (getShareHandleSupport()) + { + outExtensions->d3dShareHandleClientBuffer = true; + outExtensions->surfaceD3DTexture2DShareHandle = true; + } + + outExtensions->querySurfacePointer = true; + outExtensions->windowFixedSize = true; + outExtensions->postSubBuffer = true; + outExtensions->createContext = true; + outExtensions->deviceQuery = true; + outExtensions->createContextNoError = true; + + outExtensions->image = true; + outExtensions->imageBase = true; + outExtensions->glTexture2DImage = true; + outExtensions->glRenderbufferImage = true; + + outExtensions->flexibleSurfaceCompatibility = true; +} + void Renderer9::startScene() { if (!mSceneStarted) @@ -612,7 +624,7 @@ gl::Error Renderer9::finish() while (result == S_FALSE) { // Keep polling, but allow other threads to do something useful first - Sleep(0); + ScheduleYield(); result = query->GetData(NULL, 0, D3DGETDATA_FLUSH); @@ -642,9 +654,24 @@ gl::Error Renderer9::finish() return gl::Error(GL_NO_ERROR); } -SwapChainD3D *Renderer9::createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) +SwapChainD3D *Renderer9::createSwapChain(NativeWindow nativeWindow, + HANDLE shareHandle, + GLenum backBufferFormat, + GLenum depthBufferFormat, + EGLint orientation) +{ + return new SwapChain9(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat, + orientation); +} + +CompilerImpl *Renderer9::createCompiler() +{ + return new CompilerD3D(SH_HLSL_3_0_OUTPUT); +} + +void *Renderer9::getD3DDevice() { - return new SwapChain9(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat); + return reinterpret_cast<void*>(mDevice); } gl::Error Renderer9::allocateEventQuery(IDirect3DQuery9 **outQuery) @@ -716,9 +743,9 @@ BufferImpl *Renderer9::createBuffer() return new Buffer9(this); } -VertexArrayImpl *Renderer9::createVertexArray() +VertexArrayImpl *Renderer9::createVertexArray(const gl::VertexArray::Data &data) { - return new VertexArray9(this); + return new VertexArray9(data); } QueryImpl *Renderer9::createQuery(GLenum type) @@ -766,46 +793,52 @@ gl::Error Renderer9::generateSwizzle(gl::Texture *texture) gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &samplerState) { - std::vector<bool> &forceSetSamplers = (type == gl::SAMPLER_PIXEL) ? mForceSetPixelSamplerStates : mForceSetVertexSamplerStates; - std::vector<gl::SamplerState> &appliedSamplers = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates: mCurVertexSamplerStates; + CurSamplerState &appliedSampler = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates[index] + : mCurVertexSamplerStates[index]; - if (forceSetSamplers[index] || memcmp(&samplerState, &appliedSamplers[index], sizeof(gl::SamplerState)) != 0) - { - int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; - int d3dSampler = index + d3dSamplerOffset; + // Make sure to add the level offset for our tiny compressed texture workaround + TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture); - // Make sure to add the level offset for our tiny compressed texture workaround - TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture); + TextureStorage *storage = nullptr; + gl::Error error = textureD3D->getNativeTexture(&storage); + if (error.isError()) + { + return error; + } - TextureStorage *storage = nullptr; - gl::Error error = textureD3D->getNativeTexture(&storage); - if (error.isError()) - { - return error; - } + // Storage should exist, texture should be complete + ASSERT(storage); - // Storage should exist, texture should be complete - ASSERT(storage); + DWORD baseLevel = texture->getBaseLevel() + storage->getTopLevel(); - DWORD baseLevel = samplerState.baseLevel + storage->getTopLevel(); + if (appliedSampler.forceSet || appliedSampler.baseLevel != baseLevel || + memcmp(&samplerState, &appliedSampler, sizeof(gl::SamplerState)) != 0) + { + int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; + int d3dSampler = index + d3dSamplerOffset; mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, gl_d3d9::ConvertTextureWrap(samplerState.wrapS)); mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, gl_d3d9::ConvertTextureWrap(samplerState.wrapT)); mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAGFILTER, gl_d3d9::ConvertMagFilter(samplerState.magFilter, samplerState.maxAnisotropy)); + D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter; - gl_d3d9::ConvertMinFilter(samplerState.minFilter, &d3dMinFilter, &d3dMipFilter, samplerState.maxAnisotropy); + float lodBias; + gl_d3d9::ConvertMinFilter(samplerState.minFilter, &d3dMinFilter, &d3dMipFilter, &lodBias, + samplerState.maxAnisotropy, baseLevel); mDevice->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter); mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter); mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, baseLevel); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPMAPLODBIAS, static_cast<DWORD>(lodBias)); if (getRendererExtensions().textureFilterAnisotropic) { mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, (DWORD)samplerState.maxAnisotropy); } } - forceSetSamplers[index] = false; - appliedSamplers[index] = samplerState; + appliedSampler.forceSet = false; + appliedSampler.samplerState = samplerState; + appliedSampler.baseLevel = baseLevel; return gl::Error(GL_NO_ERROR); } @@ -815,10 +848,9 @@ gl::Error Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *te int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; int d3dSampler = index + d3dSamplerOffset; IDirect3DBaseTexture9 *d3dTexture = NULL; - unsigned int serial = 0; bool forceSetTexture = false; - std::vector<unsigned int> &appliedSerials = (type == gl::SAMPLER_PIXEL) ? mCurPixelTextureSerials : mCurVertexTextureSerials; + std::vector<uintptr_t> &appliedTextures = (type == gl::SAMPLER_PIXEL) ? mCurPixelTextures : mCurVertexTextures; if (texture) { @@ -834,7 +866,7 @@ gl::Error Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *te // Texture should be complete and have a storage ASSERT(texStorage); - TextureStorage9 *storage9 = TextureStorage9::makeTextureStorage9(texStorage); + TextureStorage9 *storage9 = GetAs<TextureStorage9>(texStorage); error = storage9->getBaseTexture(&d3dTexture); if (error.isError()) { @@ -845,372 +877,99 @@ gl::Error Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *te // in the texture class and we're unexpectedly missing the d3d texture ASSERT(d3dTexture != NULL); - serial = texture->getTextureSerial(); forceSetTexture = textureImpl->hasDirtyImages(); textureImpl->resetDirty(); } - if (forceSetTexture || appliedSerials[index] != serial) + if (forceSetTexture || appliedTextures[index] != reinterpret_cast<uintptr_t>(d3dTexture)) { mDevice->SetTexture(d3dSampler, d3dTexture); } - appliedSerials[index] = serial; + appliedTextures[index] = reinterpret_cast<uintptr_t>(d3dTexture); return gl::Error(GL_NO_ERROR); } gl::Error Renderer9::setUniformBuffers(const gl::Data &/*data*/, - const GLint /*vertexUniformBuffers*/[], - const GLint /*fragmentUniformBuffers*/[]) + const std::vector<GLint> &/*vertexUniformBuffers*/, + const std::vector<GLint> &/*fragmentUniformBuffers*/) { // No effect in ES2/D3D9 return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::setRasterizerState(const gl::RasterizerState &rasterState) +void Renderer9::syncState(const gl::State &state, const gl::State::DirtyBits &bitmask) { - bool rasterStateChanged = mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0; - - if (rasterStateChanged) - { - // Set the cull mode - if (rasterState.cullFace) - { - mDevice->SetRenderState(D3DRS_CULLMODE, gl_d3d9::ConvertCullMode(rasterState.cullMode, rasterState.frontFace)); - } - else - { - mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - } - - if (rasterState.polygonOffsetFill) - { - if (mCurDepthSize > 0) - { - mDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *(DWORD*)&rasterState.polygonOffsetFactor); - - float depthBias = ldexp(rasterState.polygonOffsetUnits, -static_cast<int>(mCurDepthSize)); - mDevice->SetRenderState(D3DRS_DEPTHBIAS, *(DWORD*)&depthBias); - } - } - else - { - mDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0); - mDevice->SetRenderState(D3DRS_DEPTHBIAS, 0); - } - - mCurRasterState = rasterState; - } - - mForceSetRasterState = false; - - return gl::Error(GL_NO_ERROR); + mStateManager.syncState(state, bitmask); } -gl::Error Renderer9::setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, - unsigned int sampleMask) +gl::Error Renderer9::updateState(const gl::Data &data, GLenum drawMode) { - bool blendStateChanged = mForceSetBlendState || memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0; - bool blendColorChanged = mForceSetBlendState || memcmp(&blendColor, &mCurBlendColor, sizeof(gl::ColorF)) != 0; - bool sampleMaskChanged = mForceSetBlendState || sampleMask != mCurSampleMask; - - if (blendStateChanged || blendColorChanged) - { - if (blendState.blend) - { - mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - - if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA && blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA && - blendState.destBlendRGB != GL_CONSTANT_ALPHA && blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA) - { - mDevice->SetRenderState(D3DRS_BLENDFACTOR, gl_d3d9::ConvertColor(blendColor)); - } - else - { - mDevice->SetRenderState(D3DRS_BLENDFACTOR, D3DCOLOR_RGBA(gl::unorm<8>(blendColor.alpha), - gl::unorm<8>(blendColor.alpha), - gl::unorm<8>(blendColor.alpha), - gl::unorm<8>(blendColor.alpha))); - } - - mDevice->SetRenderState(D3DRS_SRCBLEND, gl_d3d9::ConvertBlendFunc(blendState.sourceBlendRGB)); - mDevice->SetRenderState(D3DRS_DESTBLEND, gl_d3d9::ConvertBlendFunc(blendState.destBlendRGB)); - mDevice->SetRenderState(D3DRS_BLENDOP, gl_d3d9::ConvertBlendOp(blendState.blendEquationRGB)); - - if (blendState.sourceBlendRGB != blendState.sourceBlendAlpha || - blendState.destBlendRGB != blendState.destBlendAlpha || - blendState.blendEquationRGB != blendState.blendEquationAlpha) - { - mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); - - mDevice->SetRenderState(D3DRS_SRCBLENDALPHA, gl_d3d9::ConvertBlendFunc(blendState.sourceBlendAlpha)); - mDevice->SetRenderState(D3DRS_DESTBLENDALPHA, gl_d3d9::ConvertBlendFunc(blendState.destBlendAlpha)); - mDevice->SetRenderState(D3DRS_BLENDOPALPHA, gl_d3d9::ConvertBlendOp(blendState.blendEquationAlpha)); - } - else - { - mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE); - } - } - else - { - mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - } - - if (blendState.sampleAlphaToCoverage) - { - FIXME("Sample alpha to coverage is unimplemented."); - } - - gl::FramebufferAttachment *attachment = framebuffer->getFirstColorbuffer(); - GLenum internalFormat = attachment ? attachment->getInternalFormat() : GL_NONE; + // Applies the render target surface, depth stencil surface, viewport rectangle and + // scissor rectangle to the renderer + const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer(); + ASSERT(framebufferObject && framebufferObject->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE); - // Set the color mask - bool zeroColorMaskAllowed = getVendorId() != VENDOR_ID_AMD; - // Apparently some ATI cards have a bug where a draw with a zero color - // write mask can cause later draws to have incorrect results. Instead, - // set a nonzero color write mask but modify the blend state so that no - // drawing is done. - // http://code.google.com/p/angleproject/issues/detail?id=169 - - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); - DWORD colorMask = gl_d3d9::ConvertColorMask(formatInfo.redBits > 0 && blendState.colorMaskRed, - formatInfo.greenBits > 0 && blendState.colorMaskGreen, - formatInfo.blueBits > 0 && blendState.colorMaskBlue, - formatInfo.alphaBits > 0 && blendState.colorMaskAlpha); - if (colorMask == 0 && !zeroColorMaskAllowed) - { - // Enable green channel, but set blending so nothing will be drawn. - mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_GREEN); - mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - - mDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); - mDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); - mDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); - } - else - { - mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, colorMask); - } - - mDevice->SetRenderState(D3DRS_DITHERENABLE, blendState.dither ? TRUE : FALSE); - - mCurBlendState = blendState; - mCurBlendColor = blendColor; - } - - if (sampleMaskChanged) + gl::Error error = applyRenderTarget(framebufferObject); + if (error.isError()) { - // Set the multisample mask - mDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE); - mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, static_cast<DWORD>(sampleMask)); - - mCurSampleMask = sampleMask; + return error; } - mForceSetBlendState = false; + // Setting viewport state + setViewport(data.caps, data.state->getViewport(), data.state->getNearPlane(), + data.state->getFarPlane(), drawMode, data.state->getRasterizerState().frontFace, + false); - return gl::Error(GL_NO_ERROR); -} + // Setting scissors state + setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled()); -gl::Error Renderer9::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, - int stencilBackRef, bool frontFaceCCW) -{ - bool depthStencilStateChanged = mForceSetDepthStencilState || - memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0; - bool stencilRefChanged = mForceSetDepthStencilState || stencilRef != mCurStencilRef || - stencilBackRef != mCurStencilBackRef; - bool frontFaceCCWChanged = mForceSetDepthStencilState || frontFaceCCW != mCurFrontFaceCCW; + // Setting blend, depth stencil, and rasterizer states + int samples = framebufferObject->getSamples(data); + gl::RasterizerState rasterizer = data.state->getRasterizerState(); + rasterizer.pointDrawMode = (drawMode == GL_POINTS); + rasterizer.multiSample = (samples != 0); - if (depthStencilStateChanged) - { - if (depthStencilState.depthTest) - { - mDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); - mDevice->SetRenderState(D3DRS_ZFUNC, gl_d3d9::ConvertComparison(depthStencilState.depthFunc)); - } - else - { - mDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); - } + unsigned int mask = GetBlendSampleMask(data, samples); + error = setBlendDepthRasterStates(data, mask); - mCurDepthStencilState = depthStencilState; - } - - if (depthStencilStateChanged || stencilRefChanged || frontFaceCCWChanged) + if (error.isError()) { - if (depthStencilState.stencilTest && mCurStencilSize > 0) - { - mDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); - mDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE); - - // FIXME: Unsupported by D3D9 - const D3DRENDERSTATETYPE D3DRS_CCW_STENCILREF = D3DRS_STENCILREF; - const D3DRENDERSTATETYPE D3DRS_CCW_STENCILMASK = D3DRS_STENCILMASK; - const D3DRENDERSTATETYPE D3DRS_CCW_STENCILWRITEMASK = D3DRS_STENCILWRITEMASK; - - ASSERT(depthStencilState.stencilWritemask == depthStencilState.stencilBackWritemask); - ASSERT(stencilRef == stencilBackRef); - ASSERT(depthStencilState.stencilMask == depthStencilState.stencilBackMask); - - // get the maximum size of the stencil ref - unsigned int maxStencil = (1 << mCurStencilSize) - 1; - - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, - depthStencilState.stencilWritemask); - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, - gl_d3d9::ConvertComparison(depthStencilState.stencilFunc)); - - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, - (stencilRef < (int)maxStencil) ? stencilRef : maxStencil); - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, - depthStencilState.stencilMask); - - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilFail)); - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilPassDepthFail)); - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilPassDepthPass)); - - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, - depthStencilState.stencilBackWritemask); - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, - gl_d3d9::ConvertComparison(depthStencilState.stencilBackFunc)); - - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, - (stencilBackRef < (int)maxStencil) ? stencilBackRef : maxStencil); - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, - depthStencilState.stencilBackMask); - - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackFail)); - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackPassDepthFail)); - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackPassDepthPass)); - } - else - { - mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); - } - - mDevice->SetRenderState(D3DRS_ZWRITEENABLE, depthStencilState.depthMask ? TRUE : FALSE); - - mCurStencilRef = stencilRef; - mCurStencilBackRef = stencilBackRef; - mCurFrontFaceCCW = frontFaceCCW; + return error; } - mForceSetDepthStencilState = false; + mStateManager.resetDirtyBits(); - return gl::Error(GL_NO_ERROR); + return error; } void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) { - bool scissorChanged = mForceSetScissor || - memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 || - enabled != mScissorEnabled; - - if (scissorChanged) - { - if (enabled) - { - RECT rect; - rect.left = gl::clamp(scissor.x, 0, static_cast<int>(mRenderTargetDesc.width)); - rect.top = gl::clamp(scissor.y, 0, static_cast<int>(mRenderTargetDesc.height)); - rect.right = gl::clamp(scissor.x + scissor.width, 0, static_cast<int>(mRenderTargetDesc.width)); - rect.bottom = gl::clamp(scissor.y + scissor.height, 0, static_cast<int>(mRenderTargetDesc.height)); - mDevice->SetScissorRect(&rect); - } - - mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, enabled ? TRUE : FALSE); + mStateManager.setScissorState(scissor, enabled); +} - mScissorEnabled = enabled; - mCurScissor = scissor; - } +gl::Error Renderer9::setBlendDepthRasterStates(const gl::Data &glData, GLenum drawMode) +{ + int samples = glData.state->getDrawFramebuffer()->getSamples(glData); + gl::RasterizerState rasterizer = glData.state->getRasterizerState(); + rasterizer.pointDrawMode = (drawMode == GL_POINTS); + rasterizer.multiSample = (samples != 0); - mForceSetScissor = false; + unsigned int mask = GetBlendSampleMask(glData, samples); + return mStateManager.setBlendDepthRasterStates(*glData.state, mask); } -void Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, +void Renderer9::setViewport(const gl::Caps *caps, + const gl::Rectangle &viewport, + float zNear, + float zFar, + GLenum drawMode, + GLenum frontFace, bool ignoreViewport) { - gl::Rectangle actualViewport = viewport; - float actualZNear = gl::clamp01(zNear); - float actualZFar = gl::clamp01(zFar); - if (ignoreViewport) - { - actualViewport.x = 0; - actualViewport.y = 0; - actualViewport.width = mRenderTargetDesc.width; - actualViewport.height = mRenderTargetDesc.height; - actualZNear = 0.0f; - actualZFar = 1.0f; - } - - D3DVIEWPORT9 dxViewport; - dxViewport.X = gl::clamp(actualViewport.x, 0, static_cast<int>(mRenderTargetDesc.width)); - dxViewport.Y = gl::clamp(actualViewport.y, 0, static_cast<int>(mRenderTargetDesc.height)); - dxViewport.Width = gl::clamp(actualViewport.width, 0, static_cast<int>(mRenderTargetDesc.width) - static_cast<int>(dxViewport.X)); - dxViewport.Height = gl::clamp(actualViewport.height, 0, static_cast<int>(mRenderTargetDesc.height) - static_cast<int>(dxViewport.Y)); - dxViewport.MinZ = actualZNear; - dxViewport.MaxZ = actualZFar; - - float depthFront = !gl::IsTriangleMode(drawMode) ? 0.0f : (frontFace == GL_CCW ? 1.0f : -1.0f); - - bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 || - actualZNear != mCurNear || actualZFar != mCurFar || mCurDepthFront != depthFront; - if (viewportChanged) - { - mDevice->SetViewport(&dxViewport); - - mCurViewport = actualViewport; - mCurNear = actualZNear; - mCurFar = actualZFar; - mCurDepthFront = depthFront; - - dx_VertexConstants vc = {0}; - dx_PixelConstants pc = {0}; - - vc.viewAdjust[0] = (float)((actualViewport.width - (int)dxViewport.Width) + 2 * (actualViewport.x - (int)dxViewport.X) - 1) / dxViewport.Width; - vc.viewAdjust[1] = (float)((actualViewport.height - (int)dxViewport.Height) + 2 * (actualViewport.y - (int)dxViewport.Y) - 1) / dxViewport.Height; - vc.viewAdjust[2] = (float)actualViewport.width / dxViewport.Width; - vc.viewAdjust[3] = (float)actualViewport.height / dxViewport.Height; - - pc.viewCoords[0] = actualViewport.width * 0.5f; - pc.viewCoords[1] = actualViewport.height * 0.5f; - pc.viewCoords[2] = actualViewport.x + (actualViewport.width * 0.5f); - pc.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f); - - pc.depthFront[0] = (actualZFar - actualZNear) * 0.5f; - pc.depthFront[1] = (actualZNear + actualZFar) * 0.5f; - pc.depthFront[2] = depthFront; - - vc.depthRange[0] = actualZNear; - vc.depthRange[1] = actualZFar; - vc.depthRange[2] = actualZFar - actualZNear; - - pc.depthRange[0] = actualZNear; - pc.depthRange[1] = actualZFar; - pc.depthRange[2] = actualZFar - actualZNear; - - if (memcmp(&vc, &mVertexConstants, sizeof(dx_VertexConstants)) != 0) - { - mVertexConstants = vc; - mDxUniformsDirty = true; - } - - if (memcmp(&pc, &mPixelConstants, sizeof(dx_PixelConstants)) != 0) - { - mPixelConstants = pc; - mDxUniformsDirty = true; - } - } - - mForceSetViewport = false; + mStateManager.setViewportState(caps, viewport, zNear, zFar, drawMode, frontFace, + ignoreViewport); } bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize) @@ -1258,15 +1017,14 @@ gl::Error Renderer9::getNullColorbuffer(const gl::FramebufferAttachment *depthbu { ASSERT(depthbuffer); - GLsizei width = depthbuffer->getWidth(); - GLsizei height = depthbuffer->getHeight(); + const gl::Extents &size = depthbuffer->getSize(); // search cached nullcolorbuffers for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) { if (mNullColorbufferCache[i].buffer != NULL && - mNullColorbufferCache[i].width == width && - mNullColorbufferCache[i].height == height) + mNullColorbufferCache[i].width == size.width && + mNullColorbufferCache[i].height == size.height) { mNullColorbufferCache[i].lruCount = ++mMaxNullColorbufferLRU; *outColorBuffer = mNullColorbufferCache[i].buffer; @@ -1275,14 +1033,14 @@ gl::Error Renderer9::getNullColorbuffer(const gl::FramebufferAttachment *depthbu } gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(createRenderbuffer(), 0); - gl::Error error = nullRenderbuffer->setStorage(GL_NONE, width, height); + gl::Error error = nullRenderbuffer->setStorage(GL_NONE, size.width, size.height); if (error.isError()) { SafeDelete(nullRenderbuffer); return error; } - gl::RenderbufferAttachment *nullbuffer = new gl::RenderbufferAttachment(GL_NONE, nullRenderbuffer); + gl::FramebufferAttachment *nullbuffer = new gl::FramebufferAttachment(GL_RENDERBUFFER, GL_NONE, gl::ImageIndex::MakeInvalid(), nullRenderbuffer); // add nullbuffer to the cache NullColorbufferCacheEntry *oldest = &mNullColorbufferCache[0]; @@ -1297,44 +1055,48 @@ gl::Error Renderer9::getNullColorbuffer(const gl::FramebufferAttachment *depthbu delete oldest->buffer; oldest->buffer = nullbuffer; oldest->lruCount = ++mMaxNullColorbufferLRU; - oldest->width = width; - oldest->height = height; + oldest->width = size.width; + oldest->height = size.height; *outColorBuffer = nullbuffer; return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorBuffer, const gl::FramebufferAttachment *depthStencilBuffer) +gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAttachment, + const gl::FramebufferAttachment *depthStencilAttachment) { + const gl::FramebufferAttachment *renderAttachment = colorAttachment; + gl::Error error(GL_NO_ERROR); + // if there is no color attachment we must synthesize a NULL colorattachment // to keep the D3D runtime happy. This should only be possible if depth texturing. - if (!colorBuffer) + if (renderAttachment == nullptr) { - gl::Error error = getNullColorbuffer(depthStencilBuffer, &colorBuffer); + error = getNullColorbuffer(depthStencilAttachment, &renderAttachment); if (error.isError()) { return error; } } - ASSERT(colorBuffer); + ASSERT(renderAttachment != nullptr); size_t renderTargetWidth = 0; size_t renderTargetHeight = 0; D3DFORMAT renderTargetFormat = D3DFMT_UNKNOWN; + RenderTarget9 *renderTarget = nullptr; + error = renderAttachment->getRenderTarget(&renderTarget); + if (error.isError()) + { + return error; + } + ASSERT(renderTarget); + bool renderTargetChanged = false; - unsigned int renderTargetSerial = GetAttachmentSerial(colorBuffer); + unsigned int renderTargetSerial = renderTarget->getSerial(); if (renderTargetSerial != mAppliedRenderTargetSerial) { // Apply the render target on the device - RenderTarget9 *renderTarget = NULL; - gl::Error error = d3d9::GetAttachmentRenderTarget(colorBuffer, &renderTarget); - if (error.isError()) - { - return error; - } - ASSERT(renderTarget); - IDirect3DSurface9 *renderTargetSurface = renderTarget->getSurface(); ASSERT(renderTargetSurface); @@ -1349,48 +1111,45 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorBuf renderTargetChanged = true; } - unsigned int depthStencilSerial = (depthStencilBuffer != nullptr) ? GetAttachmentSerial(depthStencilBuffer) : 0; + RenderTarget9 *depthStencilRenderTarget = nullptr; + unsigned int depthStencilSerial = 0; + + if (depthStencilAttachment != nullptr) + { + error = depthStencilAttachment->getRenderTarget(&depthStencilRenderTarget); + if (error.isError()) + { + return error; + } + ASSERT(depthStencilRenderTarget); + + depthStencilSerial = depthStencilRenderTarget->getSerial(); + } + if (depthStencilSerial != mAppliedDepthStencilSerial || !mDepthStencilInitialized) { unsigned int depthSize = 0; unsigned int stencilSize = 0; // Apply the depth stencil on the device - if (depthStencilBuffer) + if (depthStencilRenderTarget) { - RenderTarget9 *depthStencilRenderTarget = NULL; - gl::Error error = d3d9::GetAttachmentRenderTarget(depthStencilBuffer, &depthStencilRenderTarget); - if (error.isError()) - { - return error; - } - ASSERT(depthStencilRenderTarget); - IDirect3DSurface9 *depthStencilSurface = depthStencilRenderTarget->getSurface(); ASSERT(depthStencilSurface); mDevice->SetDepthStencilSurface(depthStencilSurface); SafeRelease(depthStencilSurface); - depthSize = depthStencilBuffer->getDepthSize(); - stencilSize = depthStencilBuffer->getStencilSize(); + depthSize = depthStencilAttachment->getDepthSize(); + stencilSize = depthStencilAttachment->getStencilSize(); } else { mDevice->SetDepthStencilSurface(NULL); } - if (!mDepthStencilInitialized || depthSize != mCurDepthSize) - { - mCurDepthSize = depthSize; - mForceSetRasterState = true; - } - - if (!mDepthStencilInitialized || stencilSize != mCurStencilSize) - { - mCurStencilSize = stencilSize; - mForceSetDepthStencilState = true; - } + mStateManager.updateDepthSizeIfChanged(mDepthStencilInitialized, depthSize); + mStateManager.updateStencilSizeIfChanged(mDepthStencilInitialized, stencilSize); mAppliedDepthStencilSerial = depthStencilSerial; mDepthStencilInitialized = true; @@ -1398,13 +1157,9 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorBuf if (renderTargetChanged || !mRenderTargetDescInitialized) { - mForceSetScissor = true; - mForceSetViewport = true; - mForceSetBlendState = true; - - mRenderTargetDesc.width = renderTargetWidth; - mRenderTargetDesc.height = renderTargetHeight; - mRenderTargetDesc.format = renderTargetFormat; + mStateManager.forceSetBlendState(); + mStateManager.forceSetScissorState(); + mStateManager.setRenderTargetBounds(renderTargetWidth, renderTargetHeight); mRenderTargetDescInitialized = true; } @@ -1416,22 +1171,34 @@ gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer) return applyRenderTarget(framebuffer->getColorbuffer(0), framebuffer->getDepthOrStencilbuffer()); } -gl::Error Renderer9::applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances) +gl::Error Renderer9::applyVertexBuffer(const gl::State &state, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instances, + TranslatedIndexData * /*indexInfo*/) { - TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS]; - gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, attributes, instances); + gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, &mTranslatedAttribCache, instances); if (error.isError()) { return error; } - return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, state.getProgram(), instances, &mRepeatDraw); + return mVertexDeclarationCache.applyDeclaration(mDevice, mTranslatedAttribCache, state.getProgram(), instances, &mRepeatDraw); } // Applies the indices and element array bindings to the Direct3D 9 device -gl::Error Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) -{ - gl::Error error = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo); +gl::Error Renderer9::applyIndexBuffer(const gl::Data &data, + const GLvoid *indices, + GLsizei count, + GLenum mode, + GLenum type, + TranslatedIndexData *indexInfo) +{ + gl::VertexArray *vao = data.state->getVertexArray(); + gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); + gl::Error error = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, + indexInfo, false); if (error.isError()) { return error; @@ -1442,7 +1209,7 @@ gl::Error Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *element if (indexInfo->serial != mAppliedIBSerial) { - IndexBuffer9* indexBuffer = IndexBuffer9::makeIndexBuffer9(indexInfo->indexBuffer); + IndexBuffer9* indexBuffer = GetAs<IndexBuffer9>(indexInfo->indexBuffer); mDevice->SetIndices(indexBuffer->getBuffer()); mAppliedIBSerial = indexInfo->serial; @@ -1456,7 +1223,10 @@ void Renderer9::applyTransformFeedbackBuffers(const gl::State& state) ASSERT(!state.isTransformFeedbackActiveUnpaused()); } -gl::Error Renderer9::drawArrays(const gl::Data &data, GLenum mode, GLsizei count, GLsizei instances, bool usesPointSize) +gl::Error Renderer9::drawArraysImpl(const gl::Data &data, + GLenum mode, + GLsizei count, + GLsizei instances) { ASSERT(!data.state->isTransformFeedbackActiveUnpaused()); @@ -1477,7 +1247,7 @@ gl::Error Renderer9::drawArrays(const gl::Data &data, GLenum mode, GLsizei count if (mAppliedIBSerial != countingIB->getSerial()) { - IndexBuffer9 *indexBuffer = IndexBuffer9::makeIndexBuffer9(countingIB->getIndexBuffer()); + IndexBuffer9 *indexBuffer = GetAs<IndexBuffer9>(countingIB->getIndexBuffer()); mDevice->SetIndices(indexBuffer->getBuffer()); mAppliedIBSerial = countingIB->getSerial(); @@ -1497,13 +1267,21 @@ gl::Error Renderer9::drawArrays(const gl::Data &data, GLenum mode, GLsizei count } } -gl::Error Renderer9::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, - gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei /*instances*/) +gl::Error Renderer9::drawElementsImpl(const gl::Data &data, + const TranslatedIndexData &indexInfo, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei /*instances*/) { startScene(); int minIndex = static_cast<int>(indexInfo.indexRange.start); + gl::VertexArray *vao = data.state->getVertexArray(); + gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); + if (mode == GL_POINTS) { return drawIndexedPoints(count, type, indices, minIndex, elementArrayBuffer); @@ -1514,10 +1292,12 @@ gl::Error Renderer9::drawElements(GLenum mode, GLsizei count, GLenum type, const } else { + size_t vertexCount = indexInfo.indexRange.vertexCount(); for (int i = 0; i < mRepeatDraw; i++) { - GLsizei vertexCount = static_cast<int>(indexInfo.indexRange.length()) + 1; - mDevice->DrawIndexedPrimitive(mPrimitiveType, -minIndex, minIndex, vertexCount, indexInfo.startIndex, mPrimitiveCount); + mDevice->DrawIndexedPrimitive(mPrimitiveType, -minIndex, minIndex, + static_cast<UINT>(vertexCount), indexInfo.startIndex, + mPrimitiveCount); } return gl::Error(GL_NO_ERROR); } @@ -1663,7 +1443,7 @@ gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indi case GL_NONE: // Non-indexed draw for (int i = 0; i < count; i++) { - data[i] = i; + data[i] = static_cast<unsigned short>(i); } data[count] = 0; break; @@ -1684,9 +1464,9 @@ gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indi case GL_UNSIGNED_INT: for (int i = 0; i < count; i++) { - data[i] = static_cast<const GLuint*>(indices)[i]; + data[i] = static_cast<unsigned short>(static_cast<const GLuint*>(indices)[i]); } - data[count] = static_cast<const GLuint*>(indices)[0]; + data[count] = static_cast<unsigned short>(static_cast<const GLuint*>(indices)[0]); break; default: UNREACHABLE(); } @@ -1700,7 +1480,7 @@ gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indi if (mAppliedIBSerial != mLineLoopIB->getSerial()) { - IndexBuffer9 *indexBuffer = IndexBuffer9::makeIndexBuffer9(mLineLoopIB->getIndexBuffer()); + IndexBuffer9 *indexBuffer = GetAs<IndexBuffer9>(mLineLoopIB->getIndexBuffer()); mDevice->SetIndices(indexBuffer->getBuffer()); mAppliedIBSerial = mLineLoopIB->getSerial(); @@ -1757,7 +1537,7 @@ gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **ou // Update the counting index buffer if it is not large enough or has not been created yet. if (count <= 65536) // 16-bit indices { - const unsigned int spaceNeeded = count * sizeof(unsigned short); + const unsigned int spaceNeeded = static_cast<unsigned int>(count) * sizeof(unsigned short); if (!mCountingIB || mCountingIB->getBufferSize() < spaceNeeded) { @@ -1775,7 +1555,7 @@ gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **ou unsigned short *data = reinterpret_cast<unsigned short*>(mappedMemory); for (size_t i = 0; i < count; i++) { - data[i] = i; + data[i] = static_cast<unsigned short>(i); } error = mCountingIB->unmapBuffer(); @@ -1787,7 +1567,7 @@ gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **ou } else if (getRendererExtensions().elementIndexUint) { - const unsigned int spaceNeeded = count * sizeof(unsigned int); + const unsigned int spaceNeeded = static_cast<unsigned int>(count) * sizeof(unsigned int); if (!mCountingIB || mCountingIB->getBufferSize() < spaceNeeded) { @@ -1803,7 +1583,7 @@ gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **ou } unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory); - for (size_t i = 0; i < count; i++) + for (unsigned int i = 0; i < count; i++) { data[i] = i; } @@ -1824,13 +1604,10 @@ gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **ou return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::applyShaders(gl::Program *program, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, - bool rasterizerDiscard, bool transformFeedbackActive) +gl::Error Renderer9::applyShadersImpl(const gl::Data &data, GLenum /*drawMode*/) { - ASSERT(!transformFeedbackActive); - ASSERT(!rasterizerDiscard); - - ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program); + ProgramD3D *programD3D = GetImplAs<ProgramD3D>(data.state->getProgram()); + const auto &inputLayout = programD3D->getCachedInputLayout(); ShaderExecutableD3D *vertexExe = NULL; gl::Error error = programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe, nullptr); @@ -1839,15 +1616,16 @@ gl::Error Renderer9::applyShaders(gl::Program *program, const gl::VertexFormat i return error; } + const gl::Framebuffer *drawFramebuffer = data.state->getDrawFramebuffer(); ShaderExecutableD3D *pixelExe = NULL; - error = programD3D->getPixelExecutableForFramebuffer(framebuffer, &pixelExe); + error = programD3D->getPixelExecutableForFramebuffer(drawFramebuffer, &pixelExe); if (error.isError()) { return error; } - IDirect3DVertexShader9 *vertexShader = (vertexExe ? ShaderExecutable9::makeShaderExecutable9(vertexExe)->getVertexShader() : NULL); - IDirect3DPixelShader9 *pixelShader = (pixelExe ? ShaderExecutable9::makeShaderExecutable9(pixelExe)->getPixelShader() : NULL); + IDirect3DVertexShader9 *vertexShader = (vertexExe ? GetAs<ShaderExecutable9>(vertexExe)->getVertexShader() : nullptr); + IDirect3DPixelShader9 *pixelShader = (pixelExe ? GetAs<ShaderExecutable9>(pixelExe)->getPixelShader() : nullptr); if (vertexShader != mAppliedVertexShader) { @@ -1870,68 +1648,63 @@ gl::Error Renderer9::applyShaders(gl::Program *program, const gl::VertexFormat i if (programSerial != mAppliedProgramSerial) { programD3D->dirtyAllUniforms(); - mDxUniformsDirty = true; + mStateManager.forceSetDXUniformsState(); mAppliedProgramSerial = programSerial; } return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray) +gl::Error Renderer9::applyUniforms(const ProgramD3D &programD3D, + GLenum /*drawMode*/, + const std::vector<D3DUniform *> &uniformArray) { - for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++) + for (const D3DUniform *targetUniform : uniformArray) { - gl::LinkedUniform *targetUniform = uniformArray[uniformIndex]; + if (!targetUniform->dirty) + continue; - if (targetUniform->dirty) - { - GLfloat *f = (GLfloat*)targetUniform->data; - GLint *i = (GLint*)targetUniform->data; + GLfloat *f = (GLfloat *)targetUniform->data; + GLint *i = (GLint *)targetUniform->data; - switch (targetUniform->type) - { - case GL_SAMPLER_2D: - case GL_SAMPLER_CUBE: + switch (targetUniform->type) + { + case GL_SAMPLER_2D: + case GL_SAMPLER_CUBE: break; - case GL_BOOL: - case GL_BOOL_VEC2: - case GL_BOOL_VEC3: - case GL_BOOL_VEC4: + case GL_BOOL: + case GL_BOOL_VEC2: + case GL_BOOL_VEC3: + case GL_BOOL_VEC4: applyUniformnbv(targetUniform, i); break; - case GL_FLOAT: - case GL_FLOAT_VEC2: - case GL_FLOAT_VEC3: - case GL_FLOAT_VEC4: - case GL_FLOAT_MAT2: - case GL_FLOAT_MAT3: - case GL_FLOAT_MAT4: + case GL_FLOAT: + case GL_FLOAT_VEC2: + case GL_FLOAT_VEC3: + case GL_FLOAT_VEC4: + case GL_FLOAT_MAT2: + case GL_FLOAT_MAT3: + case GL_FLOAT_MAT4: applyUniformnfv(targetUniform, f); break; - case GL_INT: - case GL_INT_VEC2: - case GL_INT_VEC3: - case GL_INT_VEC4: + case GL_INT: + case GL_INT_VEC2: + case GL_INT_VEC3: + case GL_INT_VEC4: applyUniformniv(targetUniform, i); break; - default: + default: UNREACHABLE(); - } } } // Driver uniforms - if (mDxUniformsDirty) - { - mDevice->SetVertexShaderConstantF(0, (float*)&mVertexConstants, sizeof(dx_VertexConstants) / sizeof(float[4])); - mDevice->SetPixelShaderConstantF(0, (float*)&mPixelConstants, sizeof(dx_PixelConstants) / sizeof(float[4])); - mDxUniformsDirty = false; - } + mStateManager.setShaderConstants(); return gl::Error(GL_NO_ERROR); } -void Renderer9::applyUniformnfv(gl::LinkedUniform *targetUniform, const GLfloat *v) +void Renderer9::applyUniformnfv(const D3DUniform *targetUniform, const GLfloat *v) { if (targetUniform->isReferencedByFragmentShader()) { @@ -1944,7 +1717,7 @@ void Renderer9::applyUniformnfv(gl::LinkedUniform *targetUniform, const GLfloat } } -void Renderer9::applyUniformniv(gl::LinkedUniform *targetUniform, const GLint *v) +void Renderer9::applyUniformniv(const D3DUniform *targetUniform, const GLint *v) { ASSERT(targetUniform->registerCount <= MAX_VERTEX_CONSTANT_VECTORS_D3D9); GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4]; @@ -1960,7 +1733,7 @@ void Renderer9::applyUniformniv(gl::LinkedUniform *targetUniform, const GLint *v applyUniformnfv(targetUniform, (GLfloat*)vector); } -void Renderer9::applyUniformnbv(gl::LinkedUniform *targetUniform, const GLint *v) +void Renderer9::applyUniformnbv(const D3DUniform *targetUniform, const GLint *v) { ASSERT(targetUniform->registerCount <= MAX_VERTEX_CONSTANT_VECTORS_D3D9); GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4]; @@ -2004,14 +1777,16 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, unsigned int stencilUnmasked = 0x0; if (clearParams.clearStencil && depthStencilBuffer->getStencilSize() > 0) { - RenderTargetD3D *stencilRenderTarget = NULL; - gl::Error error = GetAttachmentRenderTarget(depthStencilBuffer, &stencilRenderTarget); + ASSERT(depthStencilBuffer != nullptr); + + RenderTargetD3D *stencilRenderTarget = nullptr; + gl::Error error = depthStencilBuffer->getRenderTarget(&stencilRenderTarget); if (error.isError()) { return error; } - RenderTarget9 *stencilRenderTarget9 = RenderTarget9::makeRenderTarget9(stencilRenderTarget); + RenderTarget9 *stencilRenderTarget9 = GetAs<RenderTarget9>(stencilRenderTarget); ASSERT(stencilRenderTarget9); const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(stencilRenderTarget9->getD3DFormat()); @@ -2025,14 +1800,16 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, D3DCOLOR color = D3DCOLOR_ARGB(255, 0, 0, 0); if (clearColor) { + ASSERT(colorBuffer != nullptr); + RenderTargetD3D *colorRenderTarget = NULL; - gl::Error error = GetAttachmentRenderTarget(colorBuffer, &colorRenderTarget); + gl::Error error = colorBuffer->getRenderTarget(&colorRenderTarget); if (error.isError()) { return error; } - RenderTarget9 *colorRenderTarget9 = RenderTarget9::makeRenderTarget9(colorRenderTarget); + RenderTarget9 *colorRenderTarget9 = GetAs<RenderTarget9>(colorRenderTarget); ASSERT(colorRenderTarget9); const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(colorBuffer->getInternalFormat()); @@ -2156,14 +1933,17 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, mDevice->SetStreamSourceFreq(i, 1); } + int renderTargetWidth = mStateManager.getRenderTargetWidth(); + int renderTargetHeight = mStateManager.getRenderTargetHeight(); + float quad[4][4]; // A quadrilateral covering the target, aligned to match the edges quad[0][0] = -0.5f; - quad[0][1] = mRenderTargetDesc.height - 0.5f; + quad[0][1] = renderTargetHeight - 0.5f; quad[0][2] = 0.0f; quad[0][3] = 1.0f; - quad[1][0] = mRenderTargetDesc.width - 0.5f; - quad[1][1] = mRenderTargetDesc.height - 0.5f; + quad[1][0] = renderTargetWidth - 0.5f; + quad[1][1] = renderTargetHeight - 0.5f; quad[1][2] = 0.0f; quad[1][3] = 1.0f; @@ -2172,7 +1952,7 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, quad[2][2] = 0.0f; quad[2][3] = 1.0f; - quad[3][0] = mRenderTargetDesc.width - 0.5f; + quad[3][0] = renderTargetWidth - 0.5f; quad[3][1] = -0.5f; quad[3][2] = 0.0f; quad[3][3] = 1.0f; @@ -2221,31 +2001,31 @@ void Renderer9::markAllStateDirty() mDepthStencilInitialized = false; mRenderTargetDescInitialized = false; - mForceSetDepthStencilState = true; - mForceSetRasterState = true; - mForceSetScissor = true; - mForceSetViewport = true; - mForceSetBlendState = true; + mStateManager.forceSetRasterState(); + mStateManager.forceSetDepthStencilState(); + mStateManager.forceSetBlendState(); + mStateManager.forceSetScissorState(); + mStateManager.forceSetViewportState(); - ASSERT(mForceSetVertexSamplerStates.size() == mCurVertexTextureSerials.size()); - for (unsigned int i = 0; i < mForceSetVertexSamplerStates.size(); i++) + ASSERT(mCurVertexSamplerStates.size() == mCurVertexTextures.size()); + for (unsigned int i = 0; i < mCurVertexTextures.size(); i++) { - mForceSetVertexSamplerStates[i] = true; - mCurVertexTextureSerials[i] = 0; + mCurVertexSamplerStates[i].forceSet = true; + mCurVertexTextures[i] = angle::DirtyPointer; } - ASSERT(mForceSetPixelSamplerStates.size() == mCurPixelTextureSerials.size()); - for (unsigned int i = 0; i < mForceSetPixelSamplerStates.size(); i++) + ASSERT(mCurPixelSamplerStates.size() == mCurPixelTextures.size()); + for (unsigned int i = 0; i < mCurPixelSamplerStates.size(); i++) { - mForceSetPixelSamplerStates[i] = true; - mCurPixelTextureSerials[i] = 0; + mCurPixelSamplerStates[i].forceSet = true; + mCurPixelTextures[i] = angle::DirtyPointer; } mAppliedIBSerial = 0; mAppliedVertexShader = NULL; mAppliedPixelShader = NULL; mAppliedProgramSerial = 0; - mDxUniformsDirty = true; + mStateManager.forceSetDXUniformsState(); mVertexDeclarationCache.markStateDirty(); } @@ -2458,19 +2238,26 @@ std::string Renderer9::getRendererDescription() const return rendererString.str(); } -GUID Renderer9::getAdapterIdentifier() const +DeviceIdentifier Renderer9::getAdapterIdentifier() const { - return mAdapterIdentifier.DeviceIdentifier; + DeviceIdentifier deviceIdentifier = { 0 }; + deviceIdentifier.VendorId = static_cast<UINT>(mAdapterIdentifier.VendorId); + deviceIdentifier.DeviceId = static_cast<UINT>(mAdapterIdentifier.DeviceId); + deviceIdentifier.SubSysId = static_cast<UINT>(mAdapterIdentifier.SubSysId); + deviceIdentifier.Revision = static_cast<UINT>(mAdapterIdentifier.Revision); + deviceIdentifier.FeatureLevel = 0; + + return deviceIdentifier; } unsigned int Renderer9::getReservedVertexUniformVectors() const { - return 2; // dx_ViewAdjust and dx_DepthRange. + return d3d9_gl::GetReservedVertexUniformVectors(); } unsigned int Renderer9::getReservedFragmentUniformVectors() const { - return 3; // dx_ViewCoords, dx_DepthFront and dx_DepthRange. + return d3d9_gl::GetReservedFragmentUniformVectors(); } unsigned int Renderer9::getReservedVertexUniformBuffers() const @@ -2489,11 +2276,6 @@ bool Renderer9::getShareHandleSupport() const return (mD3d9Ex != NULL) && !gl::DebugAnnotationsActive(); } -bool Renderer9::getPostSubBufferSupport() const -{ - return true; -} - int Renderer9::getMajorShaderModel() const { return D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion); @@ -2578,6 +2360,7 @@ gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GL const gl::TextureCaps &textureCaps = getRendererTextureCaps().get(format); GLuint supportedSamples = textureCaps.getNearestSamples(samples); + IDirect3DTexture9 *texture = nullptr; IDirect3DSurface9 *renderTarget = NULL; if (width > 0 && height > 0) { @@ -2593,10 +2376,23 @@ gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GL } else { - requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != NULL); - result = mDevice->CreateRenderTarget(width, height, d3d9FormatInfo.renderFormat, - gl_d3d9::GetMultisampleType(supportedSamples), - 0, FALSE, &renderTarget, NULL); + requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != nullptr); + if (supportedSamples > 0) + { + result = mDevice->CreateRenderTarget(width, height, d3d9FormatInfo.renderFormat, + gl_d3d9::GetMultisampleType(supportedSamples), + 0, FALSE, &renderTarget, nullptr); + } + else + { + result = mDevice->CreateTexture( + width, height, 1, D3DUSAGE_RENDERTARGET, d3d9FormatInfo.texFormat, + getTexturePool(D3DUSAGE_RENDERTARGET), &texture, nullptr); + if (!FAILED(result)) + { + result = texture->GetSurfaceLevel(0, &renderTarget); + } + } } if (FAILED(result)) @@ -2618,13 +2414,36 @@ gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GL } } - *outRT = new TextureRenderTarget9(renderTarget, format, width, height, 1, supportedSamples); + *outRT = new TextureRenderTarget9(texture, 0, renderTarget, format, width, height, 1, + supportedSamples); return gl::Error(GL_NO_ERROR); } -FramebufferImpl *Renderer9::createDefaultFramebuffer(const gl::Framebuffer::Data &data) +gl::Error Renderer9::createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) { - return createFramebuffer(data); + ASSERT(source != nullptr); + + RenderTargetD3D *newRT = nullptr; + gl::Error error = createRenderTarget(source->getWidth(), source->getHeight(), + source->getInternalFormat(), source->getSamples(), &newRT); + if (error.isError()) + { + return error; + } + + RenderTarget9 *source9 = GetAs<RenderTarget9>(source); + RenderTarget9 *dest9 = GetAs<RenderTarget9>(newRT); + + HRESULT result = mDevice->StretchRect(source9->getSurface(), nullptr, dest9->getSurface(), + nullptr, D3DTEXF_NONE); + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to copy render target, result: 0x%X.", result); + } + + *outRT = newRT; + return gl::Error(GL_NO_ERROR); } FramebufferImpl *Renderer9::createFramebuffer(const gl::Framebuffer::Data &data) @@ -2632,27 +2451,25 @@ FramebufferImpl *Renderer9::createFramebuffer(const gl::Framebuffer::Data &data) return new Framebuffer9(data, this); } -CompilerImpl *Renderer9::createCompiler(const gl::Data &data) +ShaderImpl *Renderer9::createShader(const gl::Shader::Data &data) { - return new CompilerD3D(data, SH_HLSL9_OUTPUT); + return new ShaderD3D(data); } -ShaderImpl *Renderer9::createShader(GLenum type) +ProgramImpl *Renderer9::createProgram(const gl::Program::Data &data) { - return new ShaderD3D(type); + return new ProgramD3D(data, this); } -ProgramImpl *Renderer9::createProgram() -{ - return new ProgramD3D(this); -} - -gl::Error Renderer9::loadExecutable(const void *function, size_t length, ShaderType type, - const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, - bool separatedOutputBuffers, ShaderExecutableD3D **outExecutable) +gl::Error Renderer9::loadExecutable(const void *function, + size_t length, + ShaderType type, + const std::vector<D3DVarying> &streamOutVaryings, + bool separatedOutputBuffers, + ShaderExecutableD3D **outExecutable) { // Transform feedback is not supported in ES2 or D3D9 - ASSERT(transformFeedbackVaryings.size() == 0); + ASSERT(streamOutVaryings.empty()); switch (type) { @@ -2686,13 +2503,16 @@ gl::Error Renderer9::loadExecutable(const void *function, size_t length, ShaderT return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type, - const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, - bool separatedOutputBuffers, const D3DCompilerWorkarounds &workarounds, +gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, + const std::string &shaderHLSL, + ShaderType type, + const std::vector<D3DVarying> &streamOutVaryings, + bool separatedOutputBuffers, + const D3DCompilerWorkarounds &workarounds, ShaderExecutableD3D **outExectuable) { // Transform feedback is not supported in ES2 or D3D9 - ASSERT(transformFeedbackVaryings.size() == 0); + ASSERT(streamOutVaryings.empty()); const char *profileType = NULL; switch (type) @@ -2755,7 +2575,7 @@ gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, const std::string } error = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type, - transformFeedbackVaryings, separatedOutputBuffers, outExectuable); + streamOutVaryings, separatedOutputBuffers, outExectuable); SafeRelease(binary); if (error.isError()) @@ -2841,17 +2661,29 @@ ImageD3D *Renderer9::createImage() gl::Error Renderer9::generateMipmap(ImageD3D *dest, ImageD3D *src) { - Image9 *src9 = Image9::makeImage9(src); - Image9 *dst9 = Image9::makeImage9(dest); + Image9 *src9 = GetAs<Image9>(src); + Image9 *dst9 = GetAs<Image9>(dest); return Image9::generateMipmap(dst9, src9); } +gl::Error Renderer9::generateMipmapsUsingD3D(TextureStorage *storage, + const gl::TextureState &textureState) +{ + UNREACHABLE(); + return gl::Error(GL_NO_ERROR); +} + TextureStorage *Renderer9::createTextureStorage2D(SwapChainD3D *swapChain) { - SwapChain9 *swapChain9 = SwapChain9::makeSwapChain9(swapChain); + SwapChain9 *swapChain9 = GetAs<SwapChain9>(swapChain); return new TextureStorage9_2D(this, swapChain9); } +TextureStorage *Renderer9::createTextureStorageEGLImage(EGLImageD3D *eglImage) +{ + return new TextureStorage9_EGLImage(this, eglImage); +} + TextureStorage *Renderer9::createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly) { return new TextureStorage9_2D(this, internalformat, renderTarget, width, height, levels); @@ -2910,24 +2742,75 @@ bool Renderer9::getLUID(LUID *adapterLuid) const return false; } -VertexConversionType Renderer9::getVertexConversionType(const gl::VertexFormat &vertexFormat) const +VertexConversionType Renderer9::getVertexConversionType(gl::VertexFormatType vertexFormatType) const { - return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormat).conversionType; + return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormatType).conversionType; } -GLenum Renderer9::getVertexComponentType(const gl::VertexFormat &vertexFormat) const +GLenum Renderer9::getVertexComponentType(gl::VertexFormatType vertexFormatType) const { - return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormat).componentType; + return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormatType).componentType; } -void Renderer9::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const +void Renderer9::generateCaps(gl::Caps *outCaps, + gl::TextureCapsMap *outTextureCaps, + gl::Extensions *outExtensions, + gl::Limitations *outLimitations) const { - d3d9_gl::GenerateCaps(mD3d9, mDevice, mDeviceType, mAdapter, outCaps, outTextureCaps, outExtensions); + d3d9_gl::GenerateCaps(mD3d9, mDevice, mDeviceType, mAdapter, outCaps, outTextureCaps, + outExtensions, outLimitations); } -Workarounds Renderer9::generateWorkarounds() const +WorkaroundsD3D Renderer9::generateWorkarounds() const { return d3d9::GenerateWorkarounds(); } +void Renderer9::createAnnotator() +{ + mAnnotator = new DebugAnnotator9(); +} + +gl::Error Renderer9::clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) +{ + // TODO(jmadill): faster way? + for (size_t samplerIndex = rangeStart; samplerIndex < rangeEnd; samplerIndex++) + { + gl::Error error = setTexture(samplerType, static_cast<int>(samplerIndex), nullptr); + if (error.isError()) + { + return error; + } + } + + return gl::Error(GL_NO_ERROR); +} + +egl::Error Renderer9::getEGLDevice(DeviceImpl **device) +{ + if (mEGLDevice == nullptr) + { + ASSERT(mDevice != nullptr); + mEGLDevice = new DeviceD3D(); + egl::Error error = mEGLDevice->initialize(reinterpret_cast<void *>(mDevice), + EGL_D3D9_DEVICE_ANGLE, EGL_FALSE); + + if (error.isError()) + { + SafeDelete(mEGLDevice); + return error; + } + } + + *device = static_cast<DeviceImpl *>(mEGLDevice); + return egl::Error(EGL_SUCCESS); +} + +Renderer9::CurSamplerState::CurSamplerState() + : forceSet(true), + baseLevel(std::numeric_limits<size_t>::max()), + samplerState() +{ +} + } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h index 19bea3eb35..a0dfecb02e 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h @@ -17,6 +17,7 @@ #include "libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h" #include "libANGLE/renderer/d3d/d3d9/ShaderCache.h" #include "libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h" +#include "libANGLE/renderer/d3d/d3d9/StateManager9.h" namespace gl { @@ -32,10 +33,12 @@ namespace rx { class Blit9; class IndexDataManager; +class ProgramD3D; class StreamingIndexBufferInterface; class StaticIndexBufferInterface; class VertexDataManager; struct ClearParameters; +struct D3DUniform; struct TranslatedAttribute; enum D3D9InitError @@ -64,12 +67,11 @@ class Renderer9 : public RendererD3D explicit Renderer9(egl::Display *display); virtual ~Renderer9(); - static Renderer9 *makeRenderer9(Renderer *renderer); - egl::Error initialize() override; virtual bool resetDevice(); egl::ConfigSet generateConfigs() const override; + void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const override; void startScene(); void endScene(); @@ -77,7 +79,13 @@ class Renderer9 : public RendererD3D gl::Error flush() override; gl::Error finish() override; - virtual SwapChainD3D *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat); + SwapChainD3D *createSwapChain(NativeWindow nativeWindow, + HANDLE shareHandle, + GLenum backBufferFormat, + GLenum depthBufferFormat, + EGLint orientation) override; + + CompilerImpl *createCompiler() override; gl::Error allocateEventQuery(IDirect3DQuery9 **outQuery); void freeEventQuery(IDirect3DQuery9* query); @@ -92,34 +100,42 @@ class Renderer9 : public RendererD3D virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture); gl::Error setUniformBuffers(const gl::Data &data, - const GLint vertexUniformBuffers[], - const GLint fragmentUniformBuffers[]) override; + const std::vector<GLint> &vertexUniformBuffers, + const std::vector<GLint> &fragmentUniformBuffers) override; - virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState); - gl::Error setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, - unsigned int sampleMask) override; - virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, - int stencilBackRef, bool frontFaceCCW); + gl::Error updateState(const gl::Data &data, GLenum drawMode) override; - virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled); - virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, - bool ignoreViewport); + void setScissorRectangle(const gl::Rectangle &scissor, bool enabled); + void setViewport(const gl::Caps *caps, + const gl::Rectangle &viewport, + float zNear, + float zFar, + GLenum drawMode, + GLenum frontFace, + bool ignoreViewport); gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override; - gl::Error applyRenderTarget(const gl::FramebufferAttachment *colorBuffer, const gl::FramebufferAttachment *depthStencilBuffer); - virtual gl::Error applyShaders(gl::Program *program, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, - bool rasterizerDiscard, bool transformFeedbackActive); - virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray); + gl::Error applyRenderTarget(const gl::FramebufferAttachment *colorAttachment, + const gl::FramebufferAttachment *depthStencilAttachment); + gl::Error applyUniforms(const ProgramD3D &programD3D, + GLenum drawMode, + const std::vector<D3DUniform *> &uniformArray) override; virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize); - virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances); - virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo); + virtual gl::Error applyVertexBuffer(const gl::State &state, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instances, + TranslatedIndexData *indexInfo); + gl::Error applyIndexBuffer(const gl::Data &data, + const GLvoid *indices, + GLsizei count, + GLenum mode, + GLenum type, + TranslatedIndexData *indexInfo) override; void applyTransformFeedbackBuffers(const gl::State &state) override; - gl::Error drawArrays(const gl::Data &data, GLenum mode, GLsizei count, GLsizei instances, bool usesPointSize) override; - virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, - gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances); - gl::Error clear(const ClearParameters &clearParams, const gl::FramebufferAttachment *colorBuffer, const gl::FramebufferAttachment *depthStencilBuffer); @@ -130,18 +146,19 @@ class Renderer9 : public RendererD3D bool testDeviceLost() override; bool testDeviceResettable() override; - VendorID getVendorId() const override; + VendorID getVendorId() const; std::string getRendererDescription() const override; - GUID getAdapterIdentifier() const override; + DeviceIdentifier getAdapterIdentifier() const override; IDirect3DDevice9 *getDevice() { return mDevice; } + void *getD3DDevice() override; virtual unsigned int getReservedVertexUniformVectors() const; virtual unsigned int getReservedFragmentUniformVectors() const; virtual unsigned int getReservedVertexUniformBuffers() const; virtual unsigned int getReservedFragmentUniformBuffers() const; - virtual bool getShareHandleSupport() const; - virtual bool getPostSubBufferSupport() const; + + bool getShareHandleSupport() const; virtual int getMajorShaderModel() const; int getMinorShaderModel() const override; @@ -161,30 +178,38 @@ class Renderer9 : public RendererD3D // RenderTarget creation virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT); + gl::Error createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) override; // Framebuffer creation - FramebufferImpl *createDefaultFramebuffer(const gl::Framebuffer::Data &data) override; FramebufferImpl *createFramebuffer(const gl::Framebuffer::Data &data) override; // Shader creation - virtual CompilerImpl *createCompiler(const gl::Data &data); - virtual ShaderImpl *createShader(GLenum type); - virtual ProgramImpl *createProgram(); + ShaderImpl *createShader(const gl::Shader::Data &data) override; + ProgramImpl *createProgram(const gl::Program::Data &data) override; // Shader operations - virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type, - const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, - bool separatedOutputBuffers, ShaderExecutableD3D **outExecutable); - virtual gl::Error compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type, - const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, - bool separatedOutputBuffers, const D3DCompilerWorkarounds &workarounds, - ShaderExecutableD3D **outExectuable); - virtual UniformStorageD3D *createUniformStorage(size_t storageSize); + gl::Error loadExecutable(const void *function, + size_t length, + ShaderType type, + const std::vector<D3DVarying> &streamOutVaryings, + bool separatedOutputBuffers, + ShaderExecutableD3D **outExecutable) override; + gl::Error compileToExecutable(gl::InfoLog &infoLog, + const std::string &shaderHLSL, + ShaderType type, + const std::vector<D3DVarying> &streamOutVaryings, + bool separatedOutputBuffers, + const D3DCompilerWorkarounds &workarounds, + ShaderExecutableD3D **outExectuable) override; + UniformStorageD3D *createUniformStorage(size_t storageSize) override; // Image operations virtual ImageD3D *createImage(); gl::Error generateMipmap(ImageD3D *dest, ImageD3D *source) override; + gl::Error generateMipmapsUsingD3D(TextureStorage *storage, + const gl::TextureState &textureState) override; virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain); + TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage) override; virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly); virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly); virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); @@ -202,7 +227,7 @@ class Renderer9 : public RendererD3D virtual IndexBuffer *createIndexBuffer(); // Vertex Array creation - virtual VertexArrayImpl *createVertexArray(); + VertexArrayImpl *createVertexArray(const gl::VertexArray::Data &data) override; // Query and Fence creation virtual QueryImpl *createQuery(GLenum type); @@ -217,14 +242,16 @@ class Renderer9 : public RendererD3D virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget, GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); + void syncState(const gl::State &state, const gl::State::DirtyBits &bitmask) override; + // D3D9-renderer specific methods gl::Error boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest); D3DPOOL getTexturePool(DWORD usage) const; bool getLUID(LUID *adapterLuid) const override; - virtual VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const; - virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const; + VertexConversionType getVertexConversionType(gl::VertexFormatType vertexFormatType) const override; + GLenum getVertexComponentType(gl::VertexFormatType vertexFormatType) const override; gl::Error copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged); @@ -232,15 +259,39 @@ class Renderer9 : public RendererD3D D3DDEVTYPE getD3D9DeviceType() const { return mDeviceType; } + egl::Error getEGLDevice(DeviceImpl **device) override; + + protected: + void createAnnotator() override; + gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) override; + gl::Error applyShadersImpl(const gl::Data &data, GLenum drawMode) override; + private: - void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const override; - Workarounds generateWorkarounds() const override; + gl::Error drawArraysImpl(const gl::Data &data, + GLenum mode, + GLsizei count, + GLsizei instances) override; + gl::Error drawElementsImpl(const gl::Data &data, + const TranslatedIndexData &indexInfo, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei instances) override; + + void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, + gl::Extensions *outExtensions, + gl::Limitations *outLimitations) const override; + + WorkaroundsD3D generateWorkarounds() const override; + + gl::Error setBlendDepthRasterStates(const gl::Data &glData, GLenum drawMode); void release(); - void applyUniformnfv(gl::LinkedUniform *targetUniform, const GLfloat *v); - void applyUniformniv(gl::LinkedUniform *targetUniform, const GLint *v); - void applyUniformnbv(gl::LinkedUniform *targetUniform, const GLint *v); + void applyUniformnfv(const D3DUniform *targetUniform, const GLfloat *v); + void applyUniformniv(const D3DUniform *targetUniform, const GLint *v); + void applyUniformnbv(const D3DUniform *targetUniform, const GLint *v); gl::Error drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); gl::Error drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); @@ -290,64 +341,32 @@ class Renderer9 : public RendererD3D unsigned int mAppliedDepthStencilSerial; bool mDepthStencilInitialized; bool mRenderTargetDescInitialized; - unsigned int mCurStencilSize; - unsigned int mCurDepthSize; - - struct RenderTargetDesc - { - size_t width; - size_t height; - D3DFORMAT format; - }; - RenderTargetDesc mRenderTargetDesc; IDirect3DStateBlock9 *mMaskedClearSavedState; - // previously set render states - bool mForceSetDepthStencilState; - gl::DepthStencilState mCurDepthStencilState; - int mCurStencilRef; - int mCurStencilBackRef; - bool mCurFrontFaceCCW; - - bool mForceSetRasterState; - gl::RasterizerState mCurRasterState; - - bool mForceSetScissor; - gl::Rectangle mCurScissor; - bool mScissorEnabled; - - bool mForceSetViewport; - gl::Rectangle mCurViewport; - float mCurNear; - float mCurFar; - float mCurDepthFront; - - bool mForceSetBlendState; - gl::BlendState mCurBlendState; - gl::ColorF mCurBlendColor; - GLuint mCurSampleMask; + StateManager9 mStateManager; // Currently applied sampler states - std::vector<bool> mForceSetVertexSamplerStates; - std::vector<gl::SamplerState> mCurVertexSamplerStates; + struct CurSamplerState + { + CurSamplerState(); - std::vector<bool> mForceSetPixelSamplerStates; - std::vector<gl::SamplerState> mCurPixelSamplerStates; + bool forceSet; + size_t baseLevel; + gl::SamplerState samplerState; + }; + std::vector<CurSamplerState> mCurVertexSamplerStates; + std::vector<CurSamplerState> mCurPixelSamplerStates; // Currently applied textures - std::vector<unsigned int> mCurVertexTextureSerials; - std::vector<unsigned int> mCurPixelTextureSerials; + std::vector<uintptr_t> mCurVertexTextures; + std::vector<uintptr_t> mCurPixelTextures; unsigned int mAppliedIBSerial; IDirect3DVertexShader9 *mAppliedVertexShader; IDirect3DPixelShader9 *mAppliedPixelShader; unsigned int mAppliedProgramSerial; - dx_VertexConstants mVertexConstants; - dx_PixelConstants mPixelConstants; - bool mDxUniformsDirty; - // A pool of event queries that are currently unused. std::vector<IDirect3DQuery9*> mEventQueryPool; VertexShaderCache mVertexShaderCache; @@ -370,7 +389,7 @@ class Renderer9 : public RendererD3D } mNullColorbufferCache[NUM_NULL_COLORBUFFER_CACHE_ENTRIES]; UINT mMaxNullColorbufferLRU; - DebugAnnotator9 mAnnotator; + DeviceD3D *mEGLDevice; }; } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp index 280e80930b..28a486056b 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp @@ -34,12 +34,6 @@ ShaderExecutable9::~ShaderExecutable9() SafeRelease(mPixelExecutable); } -ShaderExecutable9 *ShaderExecutable9::makeShaderExecutable9(ShaderExecutableD3D *executable) -{ - ASSERT(HAS_DYNAMIC_TYPE(ShaderExecutable9*, executable)); - return static_cast<ShaderExecutable9*>(executable); -} - IDirect3DVertexShader9 *ShaderExecutable9::getVertexShader() const { return mVertexExecutable; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h index 561f7defc8..382a68c820 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h @@ -22,8 +22,6 @@ class ShaderExecutable9 : public ShaderExecutableD3D ShaderExecutable9(const void *function, size_t length, IDirect3DVertexShader9 *executable); virtual ~ShaderExecutable9(); - static ShaderExecutable9 *makeShaderExecutable9(ShaderExecutableD3D *executable); - IDirect3DPixelShader9 *getPixelShader() const; IDirect3DVertexShader9 *getVertexShader() const; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp new file mode 100644 index 0000000000..c4c600aedb --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp @@ -0,0 +1,903 @@ +// +// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// StateManager9.cpp: Defines a class for caching D3D9 state +#include "libANGLE/renderer/d3d/d3d9/StateManager9.h" + +#include "common/BitSetIterator.h" +#include "common/utilities.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" +#include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" + +namespace rx +{ + +StateManager9::StateManager9(Renderer9 *renderer9) + : mCurBlendState(), + mCurBlendColor(0, 0, 0, 0), + mCurSampleMask(0), + mCurRasterState(), + mCurDepthSize(0), + mCurDepthStencilState(), + mCurStencilRef(0), + mCurStencilBackRef(0), + mCurFrontFaceCCW(0), + mCurStencilSize(0), + mCurScissorRect(), + mCurScissorEnabled(false), + mCurViewport(), + mCurNear(0.0f), + mCurFar(0.0f), + mCurDepthFront(0.0f), + mCurIgnoreViewport(false), + mRenderer9(renderer9), + mDirtyBits() +{ + mBlendStateDirtyBits.set(DIRTY_BIT_BLEND_ENABLED); + mBlendStateDirtyBits.set(DIRTY_BIT_BLEND_COLOR); + mBlendStateDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); + mBlendStateDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE); + mBlendStateDirtyBits.set(DIRTY_BIT_COLOR_MASK); + mBlendStateDirtyBits.set(DIRTY_BIT_DITHER); + mBlendStateDirtyBits.set(DIRTY_BIT_SAMPLE_MASK); + + mRasterizerStateDirtyBits.set(DIRTY_BIT_CULL_MODE); + mRasterizerStateDirtyBits.set(DIRTY_BIT_DEPTH_BIAS); + + mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_MASK); + mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_FUNC); + mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED); + mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT); + mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK); + mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT); + mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK); + mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT); + mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK); + + mScissorStateDirtyBits.set(DIRTY_BIT_SCISSOR_ENABLED); + mScissorStateDirtyBits.set(DIRTY_BIT_SCISSOR_RECT); +} + +StateManager9::~StateManager9() +{ +} + +void StateManager9::forceSetBlendState() +{ + mDirtyBits |= mBlendStateDirtyBits; +} + +void StateManager9::forceSetRasterState() +{ + mDirtyBits |= mRasterizerStateDirtyBits; +} + +void StateManager9::forceSetDepthStencilState() +{ + mDirtyBits |= mDepthStencilStateDirtyBits; +} + +void StateManager9::forceSetScissorState() +{ + mDirtyBits |= mScissorStateDirtyBits; +} + +void StateManager9::forceSetViewportState() +{ + mForceSetViewport = true; +} + +void StateManager9::forceSetDXUniformsState() +{ + mDxUniformsDirty = true; +} + +void StateManager9::updateStencilSizeIfChanged(bool depthStencilInitialized, + unsigned int stencilSize) +{ + if (!depthStencilInitialized || stencilSize != mCurStencilSize) + { + mCurStencilSize = stencilSize; + forceSetDepthStencilState(); + } +} + +void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) +{ + if (!dirtyBits.any()) + { + return; + } + + for (auto dirtyBit : angle::IterateBitSet(dirtyBits)) + { + switch (dirtyBit) + { + case gl::State::DIRTY_BIT_BLEND_ENABLED: + if (state.getBlendState().blend != mCurBlendState.blend) + { + mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED); + // BlendColor and funcs and equations has to be set if blend is enabled + mDirtyBits.set(DIRTY_BIT_BLEND_COLOR); + mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); + } + break; + case gl::State::DIRTY_BIT_BLEND_FUNCS: + { + const gl::BlendState &blendState = state.getBlendState(); + if (blendState.sourceBlendRGB != mCurBlendState.sourceBlendRGB || + blendState.destBlendRGB != mCurBlendState.destBlendRGB || + blendState.sourceBlendAlpha != mCurBlendState.sourceBlendAlpha || + blendState.destBlendAlpha != mCurBlendState.destBlendAlpha) + { + mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); + // BlendColor depends on the values of blend funcs + mDirtyBits.set(DIRTY_BIT_BLEND_COLOR); + } + break; + } + case gl::State::DIRTY_BIT_BLEND_EQUATIONS: + { + const gl::BlendState &blendState = state.getBlendState(); + if (blendState.blendEquationRGB != mCurBlendState.blendEquationRGB || + blendState.blendEquationAlpha != mCurBlendState.blendEquationAlpha) + { + mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); + } + break; + } + case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED: + if (state.getBlendState().sampleAlphaToCoverage != + mCurBlendState.sampleAlphaToCoverage) + { + mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE); + } + break; + case gl::State::DIRTY_BIT_COLOR_MASK: + { + const gl::BlendState &blendState = state.getBlendState(); + if (blendState.colorMaskRed != mCurBlendState.colorMaskRed || + blendState.colorMaskGreen != mCurBlendState.colorMaskGreen || + blendState.colorMaskBlue != mCurBlendState.colorMaskBlue || + blendState.colorMaskAlpha != mCurBlendState.colorMaskAlpha) + { + mDirtyBits.set(DIRTY_BIT_COLOR_MASK); + } + break; + } + case gl::State::DIRTY_BIT_DITHER_ENABLED: + if (state.getBlendState().dither != mCurBlendState.dither) + { + mDirtyBits.set(DIRTY_BIT_DITHER); + } + break; + case gl::State::DIRTY_BIT_BLEND_COLOR: + if (state.getBlendColor() != mCurBlendColor) + { + mDirtyBits.set(DIRTY_BIT_BLEND_COLOR); + } + break; + case gl::State::DIRTY_BIT_CULL_FACE_ENABLED: + if (state.getRasterizerState().cullFace != mCurRasterState.cullFace) + { + mDirtyBits.set(DIRTY_BIT_CULL_MODE); + } + break; + case gl::State::DIRTY_BIT_CULL_FACE: + if (state.getRasterizerState().cullMode != mCurRasterState.cullMode) + { + mDirtyBits.set(DIRTY_BIT_CULL_MODE); + } + break; + case gl::State::DIRTY_BIT_FRONT_FACE: + if (state.getRasterizerState().frontFace != mCurRasterState.frontFace) + { + mDirtyBits.set(DIRTY_BIT_CULL_MODE); + + // Viewport state depends on rasterizer.frontface + mDirtyBits.set(DIRTY_BIT_VIEWPORT); + } + break; + case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED: + if (state.getRasterizerState().polygonOffsetFill != + mCurRasterState.polygonOffsetFill) + { + mDirtyBits.set(DIRTY_BIT_DEPTH_BIAS); + } + break; + case gl::State::DIRTY_BIT_POLYGON_OFFSET: + { + const gl::RasterizerState &rasterizerState = state.getRasterizerState(); + if (rasterizerState.polygonOffsetFactor != mCurRasterState.polygonOffsetFactor || + rasterizerState.polygonOffsetUnits != mCurRasterState.polygonOffsetUnits) + { + mDirtyBits.set(DIRTY_BIT_DEPTH_BIAS); + } + } + case gl::State::DIRTY_BIT_DEPTH_MASK: + if (state.getDepthStencilState().depthMask != mCurDepthStencilState.depthMask) + { + mDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_MASK); + } + break; + case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED: + if (state.getDepthStencilState().depthTest != mCurDepthStencilState.depthTest) + { + mDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_FUNC); + } + break; + case gl::State::DIRTY_BIT_DEPTH_FUNC: + if (state.getDepthStencilState().depthFunc != mCurDepthStencilState.depthFunc) + { + mDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_FUNC); + } + break; + case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED: + if (state.getDepthStencilState().stencilTest != mCurDepthStencilState.stencilTest) + { + mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED); + // If we enable the stencil test, all of these must be set + mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK); + mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT); + mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT); + mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK); + mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT); + mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK); + } + break; + case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT: + { + const gl::DepthStencilState &depthStencilState = state.getDepthStencilState(); + if (depthStencilState.stencilFunc != mCurDepthStencilState.stencilFunc || + depthStencilState.stencilMask != mCurDepthStencilState.stencilMask || + state.getStencilRef() != mCurStencilRef) + { + mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT); + } + break; + } + case gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK: + { + const gl::DepthStencilState &depthStencilState = state.getDepthStencilState(); + if (depthStencilState.stencilBackFunc != mCurDepthStencilState.stencilBackFunc || + depthStencilState.stencilBackMask != mCurDepthStencilState.stencilBackMask || + state.getStencilBackRef() != mCurStencilBackRef) + { + mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK); + } + break; + } + case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT: + if (state.getDepthStencilState().stencilWritemask != + mCurDepthStencilState.stencilWritemask) + { + mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT); + } + break; + case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK: + if (state.getDepthStencilState().stencilBackWritemask != + mCurDepthStencilState.stencilBackWritemask) + { + mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK); + } + break; + case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT: + { + const gl::DepthStencilState &depthStencilState = state.getDepthStencilState(); + if (depthStencilState.stencilFail != mCurDepthStencilState.stencilFail || + depthStencilState.stencilPassDepthFail != + mCurDepthStencilState.stencilPassDepthFail || + depthStencilState.stencilPassDepthPass != + mCurDepthStencilState.stencilPassDepthPass) + { + mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT); + } + break; + } + case gl::State::DIRTY_BIT_STENCIL_OPS_BACK: + { + const gl::DepthStencilState &depthStencilState = state.getDepthStencilState(); + if (depthStencilState.stencilBackFail != mCurDepthStencilState.stencilBackFail || + depthStencilState.stencilBackPassDepthFail != + mCurDepthStencilState.stencilBackPassDepthFail || + depthStencilState.stencilBackPassDepthPass != + mCurDepthStencilState.stencilBackPassDepthPass) + { + mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK); + } + break; + } + case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED: + if (state.isScissorTestEnabled() != mCurScissorEnabled) + { + mDirtyBits.set(DIRTY_BIT_SCISSOR_ENABLED); + // If scissor is enabled, we have to set the scissor rect + mDirtyBits.set(DIRTY_BIT_SCISSOR_RECT); + } + break; + case gl::State::DIRTY_BIT_SCISSOR: + if (state.getScissor() != mCurScissorRect) + { + mDirtyBits.set(DIRTY_BIT_SCISSOR_RECT); + } + break; + case gl::State::DIRTY_BIT_DEPTH_RANGE: + if (state.getNearPlane() != mCurNear || state.getFarPlane() != mCurFar) + { + mDirtyBits.set(DIRTY_BIT_VIEWPORT); + } + break; + case gl::State::DIRTY_BIT_VIEWPORT: + if (state.getViewport() != mCurViewport) + { + mDirtyBits.set(DIRTY_BIT_VIEWPORT); + } + break; + default: + break; + } + } +} + +gl::Error StateManager9::setBlendDepthRasterStates(const gl::State &glState, + unsigned int sampleMask) +{ + const gl::Framebuffer *framebuffer = glState.getDrawFramebuffer(); + + const gl::BlendState &blendState = glState.getBlendState(); + const gl::ColorF &blendColor = glState.getBlendColor(); + const gl::RasterizerState &rasterState = glState.getRasterizerState(); + + const auto &depthStencilState = glState.getDepthStencilState(); + bool frontFaceCCW = (glState.getRasterizerState().frontFace == GL_CCW); + unsigned int maxStencil = (1 << mCurStencilSize) - 1; + + // All the depth stencil states depends on the front face ccw variable + if (frontFaceCCW != mCurFrontFaceCCW) + { + forceSetDepthStencilState(); + mCurFrontFaceCCW = frontFaceCCW; + } + + for (auto dirtyBit : angle::IterateBitSet(mDirtyBits)) + { + switch (dirtyBit) + { + case DIRTY_BIT_BLEND_ENABLED: + setBlendEnabled(blendState.blend); + break; + case DIRTY_BIT_BLEND_COLOR: + setBlendColor(blendState, blendColor); + break; + case DIRTY_BIT_BLEND_FUNCS_EQUATIONS: + setBlendFuncsEquations(blendState); + break; + case DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE: + setSampleAlphaToCoverage(blendState.sampleAlphaToCoverage); + break; + case DIRTY_BIT_COLOR_MASK: + setColorMask(framebuffer, blendState.colorMaskRed, blendState.colorMaskBlue, + blendState.colorMaskGreen, blendState.colorMaskAlpha); + break; + case DIRTY_BIT_DITHER: + setDither(blendState.dither); + break; + case DIRTY_BIT_CULL_MODE: + setCullMode(rasterState.cullFace, rasterState.cullMode, rasterState.frontFace); + break; + case DIRTY_BIT_DEPTH_BIAS: + setDepthBias(rasterState.polygonOffsetFill, rasterState.polygonOffsetFactor, + rasterState.polygonOffsetUnits); + break; + case DIRTY_BIT_STENCIL_DEPTH_MASK: + setDepthMask(depthStencilState.depthMask); + break; + case DIRTY_BIT_STENCIL_DEPTH_FUNC: + setDepthFunc(depthStencilState.depthTest, depthStencilState.depthFunc); + break; + case DIRTY_BIT_STENCIL_TEST_ENABLED: + setStencilTestEnabled(depthStencilState.stencilTest); + break; + case DIRTY_BIT_STENCIL_FUNCS_FRONT: + setStencilFuncsFront(depthStencilState.stencilFunc, depthStencilState.stencilMask, + glState.getStencilRef(), frontFaceCCW, maxStencil); + break; + case DIRTY_BIT_STENCIL_FUNCS_BACK: + setStencilFuncsBack(depthStencilState.stencilBackFunc, + depthStencilState.stencilBackMask, glState.getStencilBackRef(), + frontFaceCCW, maxStencil); + break; + case DIRTY_BIT_STENCIL_WRITEMASK_FRONT: + setStencilWriteMask(depthStencilState.stencilWritemask, frontFaceCCW); + break; + case DIRTY_BIT_STENCIL_WRITEMASK_BACK: + setStencilBackWriteMask(depthStencilState.stencilBackWritemask, frontFaceCCW); + break; + case DIRTY_BIT_STENCIL_OPS_FRONT: + setStencilOpsFront(depthStencilState.stencilFail, + depthStencilState.stencilPassDepthFail, + depthStencilState.stencilPassDepthPass, frontFaceCCW); + break; + case DIRTY_BIT_STENCIL_OPS_BACK: + setStencilOpsBack(depthStencilState.stencilBackFail, + depthStencilState.stencilBackPassDepthFail, + depthStencilState.stencilBackPassDepthPass, frontFaceCCW); + break; + default: + break; + } + } + + if (sampleMask != mCurSampleMask) + { + setSampleMask(sampleMask); + } + + return gl::Error(GL_NO_ERROR); +} + +void StateManager9::setViewportState(const gl::Caps *caps, + const gl::Rectangle &viewport, + float zNear, + float zFar, + GLenum drawMode, + GLenum frontFace, + bool ignoreViewport) +{ + if (!mDirtyBits.test(DIRTY_BIT_VIEWPORT) && mCurIgnoreViewport == ignoreViewport) + return; + + gl::Rectangle actualViewport = viewport; + float actualZNear = gl::clamp01(zNear); + float actualZFar = gl::clamp01(zFar); + + if (ignoreViewport) + { + actualViewport.x = 0; + actualViewport.y = 0; + actualViewport.width = static_cast<int>(mRenderTargetBounds.width); + actualViewport.height = static_cast<int>(mRenderTargetBounds.height); + actualZNear = 0.0f; + actualZFar = 1.0f; + } + + D3DVIEWPORT9 dxViewport; + dxViewport.X = gl::clamp(actualViewport.x, 0, static_cast<int>(mRenderTargetBounds.width)); + dxViewport.Y = gl::clamp(actualViewport.y, 0, static_cast<int>(mRenderTargetBounds.height)); + dxViewport.Width = + gl::clamp(actualViewport.width, 0, + static_cast<int>(mRenderTargetBounds.width) - static_cast<int>(dxViewport.X)); + dxViewport.Height = + gl::clamp(actualViewport.height, 0, + static_cast<int>(mRenderTargetBounds.height) - static_cast<int>(dxViewport.Y)); + dxViewport.MinZ = actualZNear; + dxViewport.MaxZ = actualZFar; + + float depthFront = !gl::IsTriangleMode(drawMode) ? 0.0f : (frontFace == GL_CCW ? 1.0f : -1.0f); + + mRenderer9->getDevice()->SetViewport(&dxViewport); + + mCurViewport = actualViewport; + mCurNear = actualZNear; + mCurFar = actualZFar; + mCurDepthFront = depthFront; + mCurIgnoreViewport = ignoreViewport; + + // Setting shader constants + dx_VertexConstants9 vc = {}; + dx_PixelConstants9 pc = {}; + + vc.viewAdjust[0] = + static_cast<float>((actualViewport.width - static_cast<int>(dxViewport.Width)) + + 2 * (actualViewport.x - static_cast<int>(dxViewport.X)) - 1) / + dxViewport.Width; + vc.viewAdjust[1] = + static_cast<float>((actualViewport.height - static_cast<int>(dxViewport.Height)) + + 2 * (actualViewport.y - static_cast<int>(dxViewport.Y)) - 1) / + dxViewport.Height; + vc.viewAdjust[2] = static_cast<float>(actualViewport.width) / dxViewport.Width; + vc.viewAdjust[3] = static_cast<float>(actualViewport.height) / dxViewport.Height; + + pc.viewCoords[0] = actualViewport.width * 0.5f; + pc.viewCoords[1] = actualViewport.height * 0.5f; + pc.viewCoords[2] = actualViewport.x + (actualViewport.width * 0.5f); + pc.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f); + + pc.depthFront[0] = (actualZFar - actualZNear) * 0.5f; + pc.depthFront[1] = (actualZNear + actualZFar) * 0.5f; + pc.depthFront[2] = depthFront; + + vc.depthRange[0] = actualZNear; + vc.depthRange[1] = actualZFar; + vc.depthRange[2] = actualZFar - actualZNear; + + pc.depthRange[0] = actualZNear; + pc.depthRange[1] = actualZFar; + pc.depthRange[2] = actualZFar - actualZNear; + + if (memcmp(&vc, &mVertexConstants, sizeof(dx_VertexConstants9)) != 0) + { + mVertexConstants = vc; + mDxUniformsDirty = true; + } + + if (memcmp(&pc, &mPixelConstants, sizeof(dx_PixelConstants9)) != 0) + { + mPixelConstants = pc; + mDxUniformsDirty = true; + } + + mForceSetViewport = false; +} + +void StateManager9::setShaderConstants() +{ + if (!mDxUniformsDirty) + return; + + IDirect3DDevice9 *device = mRenderer9->getDevice(); + device->SetVertexShaderConstantF(0, reinterpret_cast<float *>(&mVertexConstants), + sizeof(dx_VertexConstants9) / sizeof(float[4])); + device->SetPixelShaderConstantF(0, reinterpret_cast<float *>(&mPixelConstants), + sizeof(dx_PixelConstants9) / sizeof(float[4])); + mDxUniformsDirty = false; +} + +// This is separate from the main state loop because other functions +// outside call only setScissorState to update scissor state +void StateManager9::setScissorState(const gl::Rectangle &scissor, bool enabled) +{ + if (mDirtyBits.test(DIRTY_BIT_SCISSOR_ENABLED)) + setScissorEnabled(enabled); + + if (mDirtyBits.test(DIRTY_BIT_SCISSOR_RECT)) + setScissorRect(scissor, enabled); +} + +void StateManager9::setRenderTargetBounds(size_t width, size_t height) +{ + mRenderTargetBounds.width = (int)width; + mRenderTargetBounds.height = (int)height; + forceSetViewportState(); +} + +void StateManager9::setScissorEnabled(bool scissorEnabled) +{ + mRenderer9->getDevice()->SetRenderState(D3DRS_SCISSORTESTENABLE, scissorEnabled ? TRUE : FALSE); + mCurScissorEnabled = scissorEnabled; +} + +void StateManager9::setScissorRect(const gl::Rectangle &scissor, bool enabled) +{ + if (!enabled) + return; + + RECT rect; + rect.left = gl::clamp(scissor.x, 0, static_cast<int>(mRenderTargetBounds.width)); + rect.top = gl::clamp(scissor.y, 0, static_cast<int>(mRenderTargetBounds.height)); + rect.right = + gl::clamp(scissor.x + scissor.width, 0, static_cast<int>(mRenderTargetBounds.width)); + rect.bottom = + gl::clamp(scissor.y + scissor.height, 0, static_cast<int>(mRenderTargetBounds.height)); + mRenderer9->getDevice()->SetScissorRect(&rect); +} + +void StateManager9::setDepthFunc(bool depthTest, GLenum depthFunc) +{ + if (depthTest) + { + IDirect3DDevice9 *device = mRenderer9->getDevice(); + device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); + device->SetRenderState(D3DRS_ZFUNC, gl_d3d9::ConvertComparison(depthFunc)); + } + else + { + mRenderer9->getDevice()->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); + } + + mCurDepthStencilState.depthTest = depthTest; + mCurDepthStencilState.depthFunc = depthFunc; +} + +void StateManager9::setStencilOpsFront(GLenum stencilFail, + GLenum stencilPassDepthFail, + GLenum stencilPassDepthPass, + bool frontFaceCCW) +{ + // TODO(dianx) It may be slightly more efficient todo these and other similar areas + // with separate dirty bits. + IDirect3DDevice9 *device = mRenderer9->getDevice(); + device->SetRenderState(frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, + gl_d3d9::ConvertStencilOp(stencilFail)); + device->SetRenderState(frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, + gl_d3d9::ConvertStencilOp(stencilPassDepthFail)); + device->SetRenderState(frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, + gl_d3d9::ConvertStencilOp(stencilPassDepthPass)); + + mCurDepthStencilState.stencilFail = stencilFail; + mCurDepthStencilState.stencilPassDepthFail = stencilPassDepthFail; + mCurDepthStencilState.stencilPassDepthPass = stencilPassDepthPass; +} + +void StateManager9::setStencilOpsBack(GLenum stencilBackFail, + GLenum stencilBackPassDepthFail, + GLenum stencilBackPassDepthPass, + bool frontFaceCCW) +{ + IDirect3DDevice9 *device = mRenderer9->getDevice(); + device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, + gl_d3d9::ConvertStencilOp(stencilBackFail)); + device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, + gl_d3d9::ConvertStencilOp(stencilBackPassDepthFail)); + device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, + gl_d3d9::ConvertStencilOp(stencilBackPassDepthPass)); + + mCurDepthStencilState.stencilBackFail = stencilBackFail; + mCurDepthStencilState.stencilBackPassDepthFail = stencilBackPassDepthFail; + mCurDepthStencilState.stencilBackPassDepthPass = stencilBackPassDepthPass; +} + +void StateManager9::setStencilBackWriteMask(GLuint stencilBackWriteMask, bool frontFaceCCW) +{ + mRenderer9->getDevice()->SetRenderState( + !frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, stencilBackWriteMask); + + mCurDepthStencilState.stencilBackWritemask = stencilBackWriteMask; +} + +void StateManager9::setStencilFuncsBack(GLenum stencilBackFunc, + GLuint stencilBackMask, + GLint stencilBackRef, + bool frontFaceCCW, + unsigned int maxStencil) +{ + IDirect3DDevice9 *device = mRenderer9->getDevice(); + device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, + gl_d3d9::ConvertComparison(stencilBackFunc)); + device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, + (stencilBackRef < (int)maxStencil) ? stencilBackRef : maxStencil); + device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, + stencilBackMask); + + mCurDepthStencilState.stencilBackFunc = stencilBackFunc; + mCurStencilBackRef = stencilBackRef; + mCurDepthStencilState.stencilBackMask = stencilBackMask; +} + +void StateManager9::setStencilWriteMask(GLuint stencilWriteMask, bool frontFaceCCW) +{ + mRenderer9->getDevice()->SetRenderState( + frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, stencilWriteMask); + mCurDepthStencilState.stencilWritemask = stencilWriteMask; +} + +void StateManager9::setStencilFuncsFront(GLenum stencilFunc, + GLuint stencilMask, + GLint stencilRef, + bool frontFaceCCW, + unsigned int maxStencil) +{ + IDirect3DDevice9 *device = mRenderer9->getDevice(); + device->SetRenderState(frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, + gl_d3d9::ConvertComparison(stencilFunc)); + device->SetRenderState(frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, + (stencilRef < static_cast<int>(maxStencil)) ? stencilRef : maxStencil); + device->SetRenderState(frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, stencilMask); + + mCurDepthStencilState.stencilFunc = stencilFunc; + mCurStencilRef = stencilRef; + mCurDepthStencilState.stencilMask = stencilMask; +} +void StateManager9::setStencilTestEnabled(bool stencilTestEnabled) +{ + if (stencilTestEnabled && mCurStencilSize > 0) + { + mRenderer9->getDevice()->SetRenderState(D3DRS_STENCILENABLE, TRUE); + } + else + { + mRenderer9->getDevice()->SetRenderState(D3DRS_STENCILENABLE, FALSE); + } + + mCurDepthStencilState.stencilTest = stencilTestEnabled; +} + +void StateManager9::setDepthMask(bool depthMask) +{ + mRenderer9->getDevice()->SetRenderState(D3DRS_ZWRITEENABLE, depthMask ? TRUE : FALSE); + mCurDepthStencilState.depthMask = depthMask; +} + +// TODO(dianx) one bit for sampleAlphaToCoverage +void StateManager9::setSampleAlphaToCoverage(bool enabled) +{ + if (enabled) + { + FIXME("Sample alpha to coverage is unimplemented."); + } +} + +void StateManager9::setBlendColor(const gl::BlendState &blendState, const gl::ColorF &blendColor) +{ + if (!blendState.blend) + return; + + if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA && + blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA && + blendState.destBlendRGB != GL_CONSTANT_ALPHA && + blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA) + { + mRenderer9->getDevice()->SetRenderState(D3DRS_BLENDFACTOR, + gl_d3d9::ConvertColor(blendColor)); + } + else + { + mRenderer9->getDevice()->SetRenderState( + D3DRS_BLENDFACTOR, + D3DCOLOR_RGBA(gl::unorm<8>(blendColor.alpha), gl::unorm<8>(blendColor.alpha), + gl::unorm<8>(blendColor.alpha), gl::unorm<8>(blendColor.alpha))); + } + mCurBlendColor = blendColor; +} + +void StateManager9::setBlendFuncsEquations(const gl::BlendState &blendState) +{ + if (!blendState.blend) + return; + + IDirect3DDevice9 *device = mRenderer9->getDevice(); + + device->SetRenderState(D3DRS_SRCBLEND, gl_d3d9::ConvertBlendFunc(blendState.sourceBlendRGB)); + device->SetRenderState(D3DRS_DESTBLEND, gl_d3d9::ConvertBlendFunc(blendState.destBlendRGB)); + device->SetRenderState(D3DRS_BLENDOP, gl_d3d9::ConvertBlendOp(blendState.blendEquationRGB)); + + if (blendState.sourceBlendRGB != blendState.sourceBlendAlpha || + blendState.destBlendRGB != blendState.destBlendAlpha || + blendState.blendEquationRGB != blendState.blendEquationAlpha) + { + device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); + + device->SetRenderState(D3DRS_SRCBLENDALPHA, + gl_d3d9::ConvertBlendFunc(blendState.sourceBlendAlpha)); + device->SetRenderState(D3DRS_DESTBLENDALPHA, + gl_d3d9::ConvertBlendFunc(blendState.destBlendAlpha)); + device->SetRenderState(D3DRS_BLENDOPALPHA, + gl_d3d9::ConvertBlendOp(blendState.blendEquationAlpha)); + } + else + { + device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE); + } + + mCurBlendState.sourceBlendRGB = blendState.sourceBlendRGB; + mCurBlendState.destBlendRGB = blendState.destBlendRGB; + mCurBlendState.blendEquationRGB = blendState.blendEquationRGB; + mCurBlendState.blendEquationAlpha = blendState.blendEquationAlpha; +} + +void StateManager9::setBlendEnabled(bool enabled) +{ + mRenderer9->getDevice()->SetRenderState(D3DRS_ALPHABLENDENABLE, enabled ? TRUE : FALSE); + mCurBlendState.blend = enabled; +} + +void StateManager9::setDither(bool dither) +{ + mRenderer9->getDevice()->SetRenderState(D3DRS_DITHERENABLE, dither ? TRUE : FALSE); + mCurBlendState.dither = dither; +} + +// TODO(dianx) one bit for color mask +void StateManager9::setColorMask(const gl::Framebuffer *framebuffer, + bool red, + bool blue, + bool green, + bool alpha) +{ + // Set the color mask + bool zeroColorMaskAllowed = mRenderer9->getVendorId() != VENDOR_ID_AMD; + // Apparently some ATI cards have a bug where a draw with a zero color + // write mask can cause later draws to have incorrect results. Instead, + // set a nonzero color write mask but modify the blend state so that no + // drawing is done. + // http://code.google.com/p/angleproject/issues/detail?id=169 + + const gl::FramebufferAttachment *attachment = framebuffer->getFirstColorbuffer(); + GLenum internalFormat = attachment ? attachment->getInternalFormat() : GL_NONE; + + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); + + DWORD colorMask = gl_d3d9::ConvertColorMask( + formatInfo.redBits > 0 && red, formatInfo.greenBits > 0 && green, + formatInfo.blueBits > 0 && blue, formatInfo.alphaBits > 0 && alpha); + + if (colorMask == 0 && !zeroColorMaskAllowed) + { + IDirect3DDevice9 *device = mRenderer9->getDevice(); + // Enable green channel, but set blending so nothing will be drawn. + device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_GREEN); + device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + + device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); + device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); + device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); + } + else + { + mRenderer9->getDevice()->SetRenderState(D3DRS_COLORWRITEENABLE, colorMask); + } + + mCurBlendState.colorMaskRed = red; + mCurBlendState.colorMaskGreen = green; + mCurBlendState.colorMaskBlue = blue; + mCurBlendState.colorMaskAlpha = alpha; +} + +void StateManager9::setSampleMask(unsigned int sampleMask) +{ + IDirect3DDevice9 *device = mRenderer9->getDevice(); + // Set the multisample mask + device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE); + device->SetRenderState(D3DRS_MULTISAMPLEMASK, static_cast<DWORD>(sampleMask)); + + mCurSampleMask = sampleMask; +} + +void StateManager9::setCullMode(bool cullFace, GLenum cullMode, GLenum frontFace) +{ + if (cullFace) + { + mRenderer9->getDevice()->SetRenderState(D3DRS_CULLMODE, + gl_d3d9::ConvertCullMode(cullMode, frontFace)); + } + else + { + mRenderer9->getDevice()->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + } + + mCurRasterState.cullFace = cullFace; + mCurRasterState.cullMode = cullMode; + mCurRasterState.frontFace = frontFace; +} + +void StateManager9::setDepthBias(bool polygonOffsetFill, + GLfloat polygonOffsetFactor, + GLfloat polygonOffsetUnits) +{ + if (polygonOffsetFill) + { + if (mCurDepthSize > 0) + { + IDirect3DDevice9 *device = mRenderer9->getDevice(); + device->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *(DWORD *)&polygonOffsetFactor); + + float depthBias = ldexp(polygonOffsetUnits, -static_cast<int>(mCurDepthSize)); + device->SetRenderState(D3DRS_DEPTHBIAS, *(DWORD *)&depthBias); + } + } + else + { + IDirect3DDevice9 *device = mRenderer9->getDevice(); + device->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0); + device->SetRenderState(D3DRS_DEPTHBIAS, 0); + } + + mCurRasterState.polygonOffsetFill = polygonOffsetFill; + mCurRasterState.polygonOffsetFactor = polygonOffsetFactor; + mCurRasterState.polygonOffsetUnits = polygonOffsetUnits; +} + +void StateManager9::updateDepthSizeIfChanged(bool depthStencilInitialized, unsigned int depthSize) +{ + if (!depthStencilInitialized || depthSize != mCurDepthSize) + { + mCurDepthSize = depthSize; + forceSetRasterState(); + } +} +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.h new file mode 100644 index 0000000000..d8c1eb9812 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.h @@ -0,0 +1,206 @@ +// +// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// StateManager9.h: Defines a class for caching D3D9 state + +#ifndef LIBANGLE_RENDERER_D3D9_STATEMANAGER9_H_ +#define LIBANGLE_RENDERER_D3D9_STATEMANAGER9_H_ + +#include "libANGLE/angletypes.h" +#include "libANGLE/Data.h" +#include "libANGLE/State.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" + +namespace rx +{ + +class Renderer9; + +struct dx_VertexConstants9 +{ + float depthRange[4]; + float viewAdjust[4]; + float viewCoords[4]; +}; + +struct dx_PixelConstants9 +{ + float depthRange[4]; + float viewCoords[4]; + float depthFront[4]; +}; + +class StateManager9 final : angle::NonCopyable +{ + public: + StateManager9(Renderer9 *renderer9); + ~StateManager9(); + + void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits); + + gl::Error setBlendDepthRasterStates(const gl::State &glState, unsigned int sampleMask); + void setScissorState(const gl::Rectangle &scissor, bool enabled); + void setViewportState(const gl::Caps *caps, + const gl::Rectangle &viewport, + float zNear, + float zFar, + GLenum drawMode, + GLenum frontFace, + bool ignoreViewport); + + void setShaderConstants(); + + void forceSetBlendState(); + void forceSetRasterState(); + void forceSetDepthStencilState(); + void forceSetScissorState(); + void forceSetViewportState(); + void forceSetDXUniformsState(); + + void updateDepthSizeIfChanged(bool depthStencilInitialized, unsigned int depthSize); + void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize); + + void setRenderTargetBounds(size_t width, size_t height); + + int getRenderTargetWidth() const { return mRenderTargetBounds.width; } + int getRenderTargetHeight() const { return mRenderTargetBounds.height; } + + void resetDirtyBits() { mDirtyBits.reset(); } + + private: + // Blend state functions + void setBlendEnabled(bool enabled); + void setBlendColor(const gl::BlendState &blendState, const gl::ColorF &blendColor); + void setBlendFuncsEquations(const gl::BlendState &blendState); + void setColorMask(const gl::Framebuffer *framebuffer, + bool red, + bool blue, + bool green, + bool alpha); + void setSampleAlphaToCoverage(bool enabled); + void setDither(bool dither); + void setSampleMask(unsigned int sampleMask); + + // Current raster state functions + void setCullMode(bool cullFace, GLenum cullMode, GLenum frontFace); + void setDepthBias(bool polygonOffsetFill, + GLfloat polygonOffsetFactor, + GLfloat polygonOffsetUnits); + + // Depth stencil state functions + void setStencilOpsFront(GLenum stencilFail, + GLenum stencilPassDepthFail, + GLenum stencilPassDepthPass, + bool frontFaceCCW); + void setStencilOpsBack(GLenum stencilBackFail, + GLenum stencilBackPassDepthFail, + GLenum stencilBackPassDepthPass, + bool frontFaceCCW); + void setStencilBackWriteMask(GLuint stencilBackWriteMask, bool frontFaceCCW); + void setDepthFunc(bool depthTest, GLenum depthFunc); + void setStencilTestEnabled(bool enabled); + void setDepthMask(bool depthMask); + void setStencilFuncsFront(GLenum stencilFunc, + GLuint stencilMask, + GLint stencilRef, + bool frontFaceCCW, + unsigned int maxStencil); + void setStencilFuncsBack(GLenum stencilBackFunc, + GLuint stencilBackMask, + GLint stencilBackRef, + bool frontFaceCCW, + unsigned int maxStencil); + void setStencilWriteMask(GLuint stencilWriteMask, bool frontFaceCCW); + + void setScissorEnabled(bool scissorEnabled); + void setScissorRect(const gl::Rectangle &scissor, bool enabled); + + enum DirtyBitType + { + // Blend dirty bits + DIRTY_BIT_BLEND_ENABLED, + DIRTY_BIT_BLEND_COLOR, + DIRTY_BIT_BLEND_FUNCS_EQUATIONS, + DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE, + DIRTY_BIT_COLOR_MASK, + DIRTY_BIT_DITHER, + DIRTY_BIT_SAMPLE_MASK, + + // Rasterizer dirty bits + DIRTY_BIT_CULL_MODE, + DIRTY_BIT_DEPTH_BIAS, + + // Depth stencil dirty bits + DIRTY_BIT_STENCIL_DEPTH_MASK, + DIRTY_BIT_STENCIL_DEPTH_FUNC, + DIRTY_BIT_STENCIL_TEST_ENABLED, + DIRTY_BIT_STENCIL_FUNCS_FRONT, + DIRTY_BIT_STENCIL_FUNCS_BACK, + DIRTY_BIT_STENCIL_WRITEMASK_FRONT, + DIRTY_BIT_STENCIL_WRITEMASK_BACK, + DIRTY_BIT_STENCIL_OPS_FRONT, + DIRTY_BIT_STENCIL_OPS_BACK, + + // Scissor dirty bits + DIRTY_BIT_SCISSOR_ENABLED, + DIRTY_BIT_SCISSOR_RECT, + + // Viewport dirty bits + DIRTY_BIT_VIEWPORT, + + DIRTY_BIT_MAX + }; + + typedef std::bitset<DIRTY_BIT_MAX> DirtyBits; + + // Currently applied blend state + gl::BlendState mCurBlendState; + gl::ColorF mCurBlendColor; + unsigned int mCurSampleMask; + DirtyBits mBlendStateDirtyBits; + + // Currently applied raster state + gl::RasterizerState mCurRasterState; + unsigned int mCurDepthSize; + DirtyBits mRasterizerStateDirtyBits; + + // Currently applied depth stencil state + gl::DepthStencilState mCurDepthStencilState; + int mCurStencilRef; + int mCurStencilBackRef; + bool mCurFrontFaceCCW; + unsigned int mCurStencilSize; + DirtyBits mDepthStencilStateDirtyBits; + + // Currently applied scissor states + gl::Rectangle mCurScissorRect; + bool mCurScissorEnabled; + gl::Extents mRenderTargetBounds; + DirtyBits mScissorStateDirtyBits; + + // Currently applied viewport states + bool mForceSetViewport; + gl::Rectangle mCurViewport; + float mCurNear; + float mCurFar; + float mCurDepthFront; + bool mCurIgnoreViewport; + + dx_VertexConstants9 mVertexConstants; + dx_PixelConstants9 mPixelConstants; + bool mDxUniformsDirty; + + // FIXME: Unsupported by D3D9 + static const D3DRENDERSTATETYPE D3DRS_CCW_STENCILREF = D3DRS_STENCILREF; + static const D3DRENDERSTATETYPE D3DRS_CCW_STENCILMASK = D3DRS_STENCILMASK; + static const D3DRENDERSTATETYPE D3DRS_CCW_STENCILWRITEMASK = D3DRS_STENCILWRITEMASK; + + Renderer9 *mRenderer9; + DirtyBits mDirtyBits; +}; + +} // namespace rx +#endif // LIBANGLE_RENDERER_D3D9_STATEMANAGER9_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp index 1620668166..be6a9c424c 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp @@ -15,21 +15,26 @@ namespace rx { -SwapChain9::SwapChain9(Renderer9 *renderer, NativeWindow nativeWindow, HANDLE shareHandle, - GLenum backBufferFormat, GLenum depthBufferFormat) - : mRenderer(renderer), - SwapChainD3D(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat), +SwapChain9::SwapChain9(Renderer9 *renderer, + NativeWindow nativeWindow, + HANDLE shareHandle, + GLenum backBufferFormat, + GLenum depthBufferFormat, + EGLint orientation) + : SwapChainD3D(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat), + mRenderer(renderer), + mWidth(-1), + mHeight(-1), + mSwapInterval(-1), + mSwapChain(nullptr), + mBackBuffer(nullptr), + mRenderTarget(nullptr), + mDepthStencil(nullptr), + mOffscreenTexture(nullptr), mColorRenderTarget(this, false), mDepthStencilRenderTarget(this, true) { - mSwapChain = NULL; - mBackBuffer = NULL; - mDepthStencil = NULL; - mRenderTarget = NULL; - mOffscreenTexture = NULL; - mWidth = -1; - mHeight = -1; - mSwapInterval = -1; + ASSERT(orientation == 0); } SwapChain9::~SwapChain9() @@ -104,7 +109,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI pShareHandle = &mShareHandle; } - const d3d9::TextureFormat &backBufferd3dFormatInfo = d3d9::GetTextureFormatInfo(mBackBufferFormat); + const d3d9::TextureFormat &backBufferd3dFormatInfo = d3d9::GetTextureFormatInfo(mOffscreenRenderTargetFormat); result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET, backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle); @@ -286,7 +291,7 @@ EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) device->SetStreamSourceFreq(streamIndex, 1); } - D3DVIEWPORT9 viewport = {0, 0, mWidth, mHeight, 0.0f, 1.0f}; + D3DVIEWPORT9 viewport = {0, 0, static_cast<DWORD>(mWidth), static_cast<DWORD>(mHeight), 0.0f, 1.0f}; device->SetViewport(&viewport); float x1 = x - 0.5f; @@ -312,8 +317,8 @@ EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) RECT rect = { - x, mHeight - y - height, - x + width, mHeight - y + static_cast<LONG>(x), static_cast<LONG>(mHeight - y - height), + static_cast<LONG>(x + width), static_cast<LONG>(mHeight - y) }; HRESULT result = mSwapChain->Present(&rect, &rect, NULL, NULL, 0); @@ -384,10 +389,10 @@ IDirect3DTexture9 *SwapChain9::getOffscreenTexture() return mOffscreenTexture; } -SwapChain9 *SwapChain9::makeSwapChain9(SwapChainD3D *swapChain) +void *SwapChain9::getKeyedMutex() { - ASSERT(HAS_DYNAMIC_TYPE(SwapChain9*, swapChain)); - return static_cast<SwapChain9*>(swapChain); + UNREACHABLE(); + return nullptr; } void SwapChain9::recreate() diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h index 81ac08ca7b..55a700c2d6 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h @@ -20,8 +20,12 @@ class Renderer9; class SwapChain9 : public SwapChainD3D { public: - SwapChain9(Renderer9 *renderer, NativeWindow nativeWindow, HANDLE shareHandle, - GLenum backBufferFormat, GLenum depthBufferFormat); + SwapChain9(Renderer9 *renderer, + NativeWindow nativeWindow, + HANDLE shareHandle, + GLenum backBufferFormat, + GLenum depthBufferFormat, + EGLint orientation); virtual ~SwapChain9(); EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight); @@ -39,14 +43,14 @@ class SwapChain9 : public SwapChainD3D EGLint getWidth() const { return mWidth; } EGLint getHeight() const { return mHeight; } - static SwapChain9 *makeSwapChain9(SwapChainD3D *swapChain); + void *getKeyedMutex() override; private: void release(); Renderer9 *mRenderer; - EGLint mHeight; EGLint mWidth; + EGLint mHeight; EGLint mSwapInterval; IDirect3DSwapChain9 *mSwapChain; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp index 139cb3eb08..b28d5076b5 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp @@ -9,14 +9,16 @@ // D3D9 texture. #include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h" -#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" -#include "libANGLE/renderer/d3d/d3d9/SwapChain9.h" -#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" -#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" -#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" -#include "libANGLE/renderer/d3d/TextureD3D.h" + #include "libANGLE/formatutils.h" #include "libANGLE/Texture.h" +#include "libANGLE/renderer/d3d/EGLImageD3D.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" +#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" +#include "libANGLE/renderer/d3d/d3d9/SwapChain9.h" namespace rx { @@ -27,7 +29,7 @@ TextureStorage9::TextureStorage9(Renderer9 *renderer, DWORD usage) mTextureHeight(0), mInternalFormat(GL_NONE), mTextureFormat(D3DFMT_UNKNOWN), - mRenderer(Renderer9::makeRenderer9(renderer)), + mRenderer(renderer), mD3DUsage(usage), mD3DPool(mRenderer->getTexturePool(usage)) { @@ -37,12 +39,6 @@ TextureStorage9::~TextureStorage9() { } -TextureStorage9 *TextureStorage9::makeTextureStorage9(TextureStorage *storage) -{ - ASSERT(HAS_DYNAMIC_TYPE(TextureStorage9*, storage)); - return static_cast<TextureStorage9*>(storage); -} - DWORD TextureStorage9::GetTextureUsage(GLenum internalformat, bool renderTarget) { DWORD d3dusage = 0; @@ -72,6 +68,11 @@ bool TextureStorage9::isManaged() const return (mD3DPool == D3DPOOL_MANAGED); } +bool TextureStorage9::supportsNativeMipmapFunction() const +{ + return false; +} + D3DPOOL TextureStorage9::getPool() const { return mD3DPool; @@ -89,7 +90,7 @@ int TextureStorage9::getTopLevel() const int TextureStorage9::getLevelCount() const { - return mMipLevels - mTopLevel; + return static_cast<int>(mMipLevels) - mTopLevel; } gl::Error TextureStorage9::setData(const gl::ImageIndex &index, ImageD3D *image, const gl::Box *destBox, GLenum type, @@ -106,7 +107,7 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchai mTexture = surfaceTexture; mMipLevels = surfaceTexture->GetLevelCount(); - mInternalFormat = swapchain->GetBackBufferInternalFormat(); + mInternalFormat = swapchain->GetRenderTargetInternalFormat(); D3DSURFACE_DESC surfaceDesc; surfaceTexture->GetLevelDesc(0, &surfaceDesc); @@ -114,16 +115,13 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchai mTextureHeight = surfaceDesc.Height; mTextureFormat = surfaceDesc.Format; - mRenderTarget = NULL; - - initializeSerials(1, 1); + mRenderTargets.resize(mMipLevels, nullptr); } TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) : TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget)) { mTexture = NULL; - mRenderTarget = NULL; mInternalFormat = internalformat; @@ -135,25 +133,28 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, GLenum internalforma mTextureHeight = height; mMipLevels = mTopLevel + levels; - initializeSerials(getLevelCount(), 1); + mRenderTargets.resize(levels, nullptr); } TextureStorage9_2D::~TextureStorage9_2D() { SafeRelease(mTexture); - SafeDelete(mRenderTarget); -} - -TextureStorage9_2D *TextureStorage9_2D::makeTextureStorage9_2D(TextureStorage *storage) -{ - ASSERT(HAS_DYNAMIC_TYPE(TextureStorage9_2D*, storage)); - return static_cast<TextureStorage9_2D*>(storage); + for (auto &renderTarget : mRenderTargets) + { + SafeDelete(renderTarget); + } } // Increments refcount on surface. // caller must Release() the returned surface -gl::Error TextureStorage9_2D::getSurfaceLevel(int level, bool dirty, IDirect3DSurface9 **outSurface) +gl::Error TextureStorage9_2D::getSurfaceLevel(GLenum target, + int level, + bool dirty, + IDirect3DSurface9 **outSurface) { + ASSERT(target == GL_TEXTURE_2D); + UNUSED_ASSERTION_VARIABLE(target); + IDirect3DBaseTexture9 *baseTexture = NULL; gl::Error error = getBaseTexture(&baseTexture); if (error.isError()) @@ -180,36 +181,52 @@ gl::Error TextureStorage9_2D::getSurfaceLevel(int level, bool dirty, IDirect3DSu return gl::Error(GL_NO_ERROR); } -gl::Error TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &/*index*/, RenderTargetD3D **outRT) +gl::Error TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) { - if (!mRenderTarget && isRenderTarget()) + ASSERT(index.mipIndex < getLevelCount()); + + if (!mRenderTargets[index.mipIndex] && isRenderTarget()) { + IDirect3DBaseTexture9 *baseTexture = NULL; + gl::Error error = getBaseTexture(&baseTexture); + if (error.isError()) + { + return error; + } + IDirect3DSurface9 *surface = NULL; - gl::Error error = getSurfaceLevel(0, false, &surface); + error = getSurfaceLevel(GL_TEXTURE_2D, index.mipIndex, false, &surface); if (error.isError()) { return error; } - mRenderTarget = new TextureRenderTarget9(surface, mInternalFormat, mTextureWidth, mTextureHeight, 1, 0); + size_t textureMipLevel = mTopLevel + index.mipIndex; + size_t mipWidth = std::max<size_t>(mTextureWidth >> textureMipLevel, 1u); + size_t mipHeight = std::max<size_t>(mTextureHeight >> textureMipLevel, 1u); + + baseTexture->AddRef(); + mRenderTargets[index.mipIndex] = new TextureRenderTarget9( + baseTexture, textureMipLevel, surface, mInternalFormat, static_cast<GLsizei>(mipWidth), + static_cast<GLsizei>(mipHeight), 1, 0); } ASSERT(outRT); - *outRT = mRenderTarget; + *outRT = mRenderTargets[index.mipIndex]; return gl::Error(GL_NO_ERROR); } gl::Error TextureStorage9_2D::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) { IDirect3DSurface9 *upper = NULL; - gl::Error error = getSurfaceLevel(sourceIndex.mipIndex, false, &upper); + gl::Error error = getSurfaceLevel(GL_TEXTURE_2D, sourceIndex.mipIndex, false, &upper); if (error.isError()) { return error; } IDirect3DSurface9 *lower = NULL; - error = getSurfaceLevel(destIndex.mipIndex, true, &lower); + error = getSurfaceLevel(GL_TEXTURE_2D, destIndex.mipIndex, true, &lower); if (error.isError()) { SafeRelease(upper); @@ -234,8 +251,10 @@ gl::Error TextureStorage9_2D::getBaseTexture(IDirect3DBaseTexture9 **outTexture) ASSERT(mMipLevels > 0); IDirect3DDevice9 *device = mRenderer->getDevice(); - HRESULT result = device->CreateTexture(mTextureWidth, mTextureHeight, mMipLevels, getUsage(), mTextureFormat, - getPool(), &mTexture, NULL); + HRESULT result = device->CreateTexture(static_cast<unsigned int>(mTextureWidth), + static_cast<unsigned int>(mTextureHeight), + static_cast<unsigned int>(mMipLevels), getUsage(), + mTextureFormat, getPool(), &mTexture, NULL); if (FAILED(result)) { @@ -252,20 +271,20 @@ gl::Error TextureStorage9_2D::copyToStorage(TextureStorage *destStorage) { ASSERT(destStorage); - TextureStorage9_2D *dest9 = TextureStorage9_2D::makeTextureStorage9_2D(destStorage); + TextureStorage9_2D *dest9 = GetAs<TextureStorage9_2D>(destStorage); int levels = getLevelCount(); for (int i = 0; i < levels; ++i) { IDirect3DSurface9 *srcSurf = NULL; - gl::Error error = getSurfaceLevel(i, false, &srcSurf); + gl::Error error = getSurfaceLevel(GL_TEXTURE_2D, i, false, &srcSurf); if (error.isError()) { return error; } IDirect3DSurface9 *dstSurf = NULL; - error = dest9->getSurfaceLevel(i, true, &dstSurf); + error = dest9->getSurfaceLevel(GL_TEXTURE_2D, i, true, &dstSurf); if (error.isError()) { SafeRelease(srcSurf); @@ -286,6 +305,131 @@ gl::Error TextureStorage9_2D::copyToStorage(TextureStorage *destStorage) return gl::Error(GL_NO_ERROR); } +TextureStorage9_EGLImage::TextureStorage9_EGLImage(Renderer9 *renderer, EGLImageD3D *image) + : TextureStorage9(renderer, D3DUSAGE_RENDERTARGET), mImage(image) +{ + RenderTargetD3D *renderTargetD3D = nullptr; + mImage->getRenderTarget(&renderTargetD3D); + + RenderTarget9 *renderTarget9 = GetAs<RenderTarget9>(renderTargetD3D); + + mInternalFormat = renderTarget9->getInternalFormat(); + mTextureFormat = renderTarget9->getD3DFormat(); + mTextureWidth = renderTarget9->getWidth(); + mTextureHeight = renderTarget9->getHeight(); + mTopLevel = static_cast<int>(renderTarget9->getTextureLevel()); + mMipLevels = mTopLevel + 1; +} + +TextureStorage9_EGLImage::~TextureStorage9_EGLImage() +{ +} + +gl::Error TextureStorage9_EGLImage::getSurfaceLevel(GLenum target, + int level, + bool, + IDirect3DSurface9 **outSurface) +{ + ASSERT(target == GL_TEXTURE_2D); + ASSERT(level == 0); + UNUSED_ASSERTION_VARIABLE(target); + UNUSED_ASSERTION_VARIABLE(level); + + RenderTargetD3D *renderTargetD3D = nullptr; + gl::Error error = mImage->getRenderTarget(&renderTargetD3D); + if (error.isError()) + { + return error; + } + + RenderTarget9 *renderTarget9 = GetAs<RenderTarget9>(renderTargetD3D); + + *outSurface = renderTarget9->getSurface(); + return gl::Error(GL_NO_ERROR); +} + +gl::Error TextureStorage9_EGLImage::getRenderTarget(const gl::ImageIndex &index, + RenderTargetD3D **outRT) +{ + ASSERT(!index.hasLayer()); + ASSERT(index.mipIndex == 0); + UNUSED_ASSERTION_VARIABLE(index); + + return mImage->getRenderTarget(outRT); +} + +gl::Error TextureStorage9_EGLImage::getBaseTexture(IDirect3DBaseTexture9 **outTexture) +{ + RenderTargetD3D *renderTargetD3D = nullptr; + gl::Error error = mImage->getRenderTarget(&renderTargetD3D); + if (error.isError()) + { + return error; + } + + RenderTarget9 *renderTarget9 = GetAs<RenderTarget9>(renderTargetD3D); + *outTexture = renderTarget9->getTexture(); + ASSERT(*outTexture != nullptr); + + return gl::Error(GL_NO_ERROR); +} + +gl::Error TextureStorage9_EGLImage::generateMipmap(const gl::ImageIndex &, const gl::ImageIndex &) +{ + UNREACHABLE(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error TextureStorage9_EGLImage::copyToStorage(TextureStorage *destStorage) +{ + ASSERT(destStorage); + ASSERT(getLevelCount() == 1); + + TextureStorage9 *dest9 = GetAs<TextureStorage9>(destStorage); + + IDirect3DBaseTexture9 *destBaseTexture9 = nullptr; + gl::Error error = dest9->getBaseTexture(&destBaseTexture9); + if (error.isError()) + { + return error; + } + + IDirect3DTexture9 *destTexture9 = static_cast<IDirect3DTexture9 *>(destBaseTexture9); + + IDirect3DSurface9 *destSurface = nullptr; + HRESULT result = destTexture9->GetSurfaceLevel(destStorage->getTopLevel(), &destSurface); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to get the surface from a texture, result: 0x%X.", result); + } + + RenderTargetD3D *sourceRenderTarget = nullptr; + error = mImage->getRenderTarget(&sourceRenderTarget); + if (error.isError()) + { + SafeRelease(destSurface); + return error; + } + + RenderTarget9 *sourceRenderTarget9 = GetAs<RenderTarget9>(sourceRenderTarget); + error = + mRenderer->copyToRenderTarget(destSurface, sourceRenderTarget9->getSurface(), isManaged()); + if (error.isError()) + { + SafeRelease(destSurface); + return error; + } + + if (destStorage->getTopLevel() != 0) + { + destTexture9->AddDirtyRect(nullptr); + } + + SafeRelease(destSurface); + return gl::Error(GL_NO_ERROR); +} + TextureStorage9_Cube::TextureStorage9_Cube(Renderer9 *renderer, GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly) : TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget)) { @@ -305,8 +449,6 @@ TextureStorage9_Cube::TextureStorage9_Cube(Renderer9 *renderer, GLenum internalf mTextureWidth = size; mTextureHeight = size; mMipLevels = mTopLevel + levels; - - initializeSerials(getLevelCount() * CUBE_FACE_COUNT, CUBE_FACE_COUNT); } TextureStorage9_Cube::~TextureStorage9_Cube() @@ -319,15 +461,12 @@ TextureStorage9_Cube::~TextureStorage9_Cube() } } -TextureStorage9_Cube *TextureStorage9_Cube::makeTextureStorage9_Cube(TextureStorage *storage) -{ - ASSERT(HAS_DYNAMIC_TYPE(TextureStorage9_Cube*, storage)); - return static_cast<TextureStorage9_Cube*>(storage); -} - // Increments refcount on surface. // caller must Release() the returned surface -gl::Error TextureStorage9_Cube::getCubeMapSurface(GLenum faceTarget, int level, bool dirty, IDirect3DSurface9 **outSurface) +gl::Error TextureStorage9_Cube::getSurfaceLevel(GLenum target, + int level, + bool dirty, + IDirect3DSurface9 **outSurface) { IDirect3DBaseTexture9 *baseTexture = NULL; gl::Error error = getBaseTexture(&baseTexture); @@ -338,8 +477,8 @@ gl::Error TextureStorage9_Cube::getCubeMapSurface(GLenum faceTarget, int level, IDirect3DCubeTexture9 *texture = static_cast<IDirect3DCubeTexture9*>(baseTexture); - D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(faceTarget); - HRESULT result = texture->GetCubeMapSurface(face, level + mTopLevel, outSurface); + D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(target); + HRESULT result = texture->GetCubeMapSurface(face, level, outSurface); ASSERT(SUCCEEDED(result)); if (FAILED(result)) @@ -364,14 +503,25 @@ gl::Error TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index, Ren if (mRenderTarget[index.layerIndex] == NULL && isRenderTarget()) { + IDirect3DBaseTexture9 *baseTexture = NULL; + gl::Error error = getBaseTexture(&baseTexture); + if (error.isError()) + { + return error; + } + IDirect3DSurface9 *surface = NULL; - gl::Error error = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + index.layerIndex, 0, false, &surface); + error = getSurfaceLevel(GL_TEXTURE_CUBE_MAP_POSITIVE_X + index.layerIndex, + mTopLevel + index.mipIndex, false, &surface); if (error.isError()) { return error; } - mRenderTarget[index.layerIndex] = new TextureRenderTarget9(surface, mInternalFormat, mTextureWidth, mTextureHeight, 1, 0); + baseTexture->AddRef(); + mRenderTarget[index.layerIndex] = new TextureRenderTarget9( + baseTexture, mTopLevel + index.mipIndex, surface, mInternalFormat, + static_cast<GLsizei>(mTextureWidth), static_cast<GLsizei>(mTextureHeight), 1, 0); } *outRT = mRenderTarget[index.layerIndex]; @@ -381,14 +531,14 @@ gl::Error TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index, Ren gl::Error TextureStorage9_Cube::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) { IDirect3DSurface9 *upper = NULL; - gl::Error error = getCubeMapSurface(sourceIndex.type, sourceIndex.mipIndex, false, &upper); + gl::Error error = getSurfaceLevel(sourceIndex.type, sourceIndex.mipIndex, false, &upper); if (error.isError()) { return error; } IDirect3DSurface9 *lower = NULL; - error = getCubeMapSurface(destIndex.type, destIndex.mipIndex, true, &lower); + error = getSurfaceLevel(destIndex.type, destIndex.mipIndex, true, &lower); if (error.isError()) { SafeRelease(upper); @@ -414,8 +564,9 @@ gl::Error TextureStorage9_Cube::getBaseTexture(IDirect3DBaseTexture9 **outTextur ASSERT(mTextureWidth == mTextureHeight); IDirect3DDevice9 *device = mRenderer->getDevice(); - HRESULT result = device->CreateCubeTexture(mTextureWidth, mMipLevels, getUsage(), mTextureFormat, getPool(), - &mTexture, NULL); + HRESULT result = device->CreateCubeTexture( + static_cast<unsigned int>(mTextureWidth), static_cast<unsigned int>(mMipLevels), + getUsage(), mTextureFormat, getPool(), &mTexture, NULL); if (FAILED(result)) { @@ -432,7 +583,7 @@ gl::Error TextureStorage9_Cube::copyToStorage(TextureStorage *destStorage) { ASSERT(destStorage); - TextureStorage9_Cube *dest9 = TextureStorage9_Cube::makeTextureStorage9_Cube(destStorage); + TextureStorage9_Cube *dest9 = GetAs<TextureStorage9_Cube>(destStorage); int levels = getLevelCount(); for (int f = 0; f < CUBE_FACE_COUNT; f++) @@ -440,14 +591,15 @@ gl::Error TextureStorage9_Cube::copyToStorage(TextureStorage *destStorage) for (int i = 0; i < levels; i++) { IDirect3DSurface9 *srcSurf = NULL; - gl::Error error = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false, &srcSurf); + gl::Error error = + getSurfaceLevel(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false, &srcSurf); if (error.isError()) { return error; } IDirect3DSurface9 *dstSurf = NULL; - error = dest9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true, &dstSurf); + error = dest9->getSurfaceLevel(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true, &dstSurf); if (error.isError()) { SafeRelease(srcSurf); diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h index 5cc06f07b1..50e63a6f14 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h @@ -16,6 +16,7 @@ namespace rx { +class EGLImageD3D; class Renderer9; class SwapChain9; class RenderTargetD3D; @@ -26,19 +27,22 @@ class TextureStorage9 : public TextureStorage public: virtual ~TextureStorage9(); - static TextureStorage9 *makeTextureStorage9(TextureStorage *storage); - static DWORD GetTextureUsage(GLenum internalformat, bool renderTarget); D3DPOOL getPool() const; DWORD getUsage() const; + virtual gl::Error getSurfaceLevel(GLenum target, + int level, + bool dirty, + IDirect3DSurface9 **outSurface) = 0; virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture) = 0; virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) = 0; virtual int getTopLevel() const; virtual bool isRenderTarget() const; virtual bool isManaged() const; + bool supportsNativeMipmapFunction() const override; virtual int getLevelCount() const; virtual gl::Error setData(const gl::ImageIndex &index, ImageD3D *image, const gl::Box *destBox, GLenum type, @@ -68,9 +72,10 @@ class TextureStorage9_2D : public TextureStorage9 TextureStorage9_2D(Renderer9 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels); virtual ~TextureStorage9_2D(); - static TextureStorage9_2D *makeTextureStorage9_2D(TextureStorage *storage); - - gl::Error getSurfaceLevel(int level, bool dirty, IDirect3DSurface9 **outSurface); + gl::Error getSurfaceLevel(GLenum target, + int level, + bool dirty, + IDirect3DSurface9 **outSurface) override; virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT); virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture); virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex); @@ -78,7 +83,27 @@ class TextureStorage9_2D : public TextureStorage9 private: IDirect3DTexture9 *mTexture; - RenderTarget9 *mRenderTarget; + std::vector<RenderTarget9 *> mRenderTargets; +}; + +class TextureStorage9_EGLImage final : public TextureStorage9 +{ + public: + TextureStorage9_EGLImage(Renderer9 *renderer, EGLImageD3D *image); + ~TextureStorage9_EGLImage() override; + + gl::Error getSurfaceLevel(GLenum target, + int level, + bool dirty, + IDirect3DSurface9 **outSurface) override; + gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) override; + gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture) override; + gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, + const gl::ImageIndex &destIndex) override; + gl::Error copyToStorage(TextureStorage *destStorage) override; + + private: + EGLImageD3D *mImage; }; class TextureStorage9_Cube : public TextureStorage9 @@ -87,9 +112,10 @@ class TextureStorage9_Cube : public TextureStorage9 TextureStorage9_Cube(Renderer9 *renderer, GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly); virtual ~TextureStorage9_Cube(); - static TextureStorage9_Cube *makeTextureStorage9_Cube(TextureStorage *storage); - - gl::Error getCubeMapSurface(GLenum faceTarget, int level, bool dirty, IDirect3DSurface9 **outSurface); + gl::Error getSurfaceLevel(GLenum target, + int level, + bool dirty, + IDirect3DSurface9 **outSurface) override; virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT); virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture); virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex); diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h index fb626bc0cf..992201737f 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h @@ -19,21 +19,12 @@ class Renderer9; class VertexArray9 : public VertexArrayImpl { public: - VertexArray9(Renderer9 *renderer) - : VertexArrayImpl(), - mRenderer(renderer) + VertexArray9(const gl::VertexArray::Data &data) + : VertexArrayImpl(data) { } virtual ~VertexArray9() { } - - virtual void setElementArrayBuffer(const gl::Buffer *buffer) { } - virtual void setAttribute(size_t idx, const gl::VertexAttribute &attr) { } - virtual void setAttributeDivisor(size_t idx, GLuint divisor) { } - virtual void enableAttribute(size_t idx, bool enabledState) { } - - private: - Renderer9 *mRenderer; }; } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp index cb5003997f..bfdf137126 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp @@ -56,24 +56,21 @@ gl::Error VertexBuffer9::initialize(unsigned int size, bool dynamicUsage) return gl::Error(GL_NO_ERROR); } -VertexBuffer9 *VertexBuffer9::makeVertexBuffer9(VertexBuffer *vertexBuffer) -{ - ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer9*, vertexBuffer)); - return static_cast<VertexBuffer9*>(vertexBuffer); -} - -gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, - GLint start, GLsizei count, GLsizei instances, unsigned int offset) +gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, + GLenum currentValueType, + GLint start, + GLsizei count, + GLsizei instances, + unsigned int offset, + const uint8_t *sourceData) { if (!mVertexBuffer) { return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized."); } - gl::Buffer *buffer = attrib.buffer.get(); - - int inputStride = gl::ComputeVertexAttributeStride(attrib); - int elementSize = gl::ComputeVertexAttributeTypeSize(attrib); + int inputStride = static_cast<int>(gl::ComputeVertexAttributeStride(attrib)); + int elementSize = static_cast<int>(gl::ComputeVertexAttributeTypeSize(attrib)); DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0; @@ -92,37 +89,15 @@ gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal vertex buffer, HRESULT: 0x%08x.", result); } - const uint8_t *input = NULL; - if (attrib.enabled) - { - if (buffer) - { - BufferD3D *storage = GetImplAs<BufferD3D>(buffer); - ASSERT(storage); - error = storage->getData(&input); - if (error.isError()) - { - return error; - } - input += static_cast<int>(attrib.offset); - } - else - { - input = static_cast<const uint8_t*>(attrib.pointer); - } - } - else - { - input = reinterpret_cast<const uint8_t*>(currentValue.FloatValues); - } + const uint8_t *input = sourceData; if (instances == 0 || attrib.divisor == 0) { input += inputStride * start; } - gl::VertexFormat vertexFormat(attrib, currentValue.Type); - const d3d9::VertexFormat &d3dVertexInfo = d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormat); + gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib, currentValueType); + const d3d9::VertexFormat &d3dVertexInfo = d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormatType); bool needsConversion = (d3dVertexInfo.conversionType & VERTEX_CONVERT_CPU) > 0; if (!needsConversion && inputStride == elementSize) @@ -196,15 +171,15 @@ IDirect3DVertexBuffer9 * VertexBuffer9::getBuffer() const gl::Error VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, unsigned int *outSpaceRequired) const { - gl::VertexFormat vertexFormat(attrib, GL_FLOAT); - const d3d9::VertexFormat &d3d9VertexInfo = d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormat); + gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib, GL_FLOAT); + const d3d9::VertexFormat &d3d9VertexInfo = d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormatType); if (attrib.enabled) { unsigned int elementCount = 0; if (instances == 0 || attrib.divisor == 0) { - elementCount = count; + elementCount = static_cast<unsigned int>(count); } else { @@ -216,7 +191,8 @@ gl::Error VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::s { if (outSpaceRequired) { - *outSpaceRequired = d3d9VertexInfo.outputElementSize * elementCount; + *outSpaceRequired = + static_cast<unsigned int>(d3d9VertexInfo.outputElementSize) * elementCount; } return gl::Error(GL_NO_ERROR); } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h index f5b110b22b..64271cbe2a 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h @@ -23,10 +23,13 @@ class VertexBuffer9 : public VertexBuffer virtual gl::Error initialize(unsigned int size, bool dynamicUsage); - static VertexBuffer9 *makeVertexBuffer9(VertexBuffer *vertexBuffer); - - virtual gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, - GLint start, GLsizei count, GLsizei instances, unsigned int offset); + gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, + GLenum currentValueType, + GLint start, + GLsizei count, + GLsizei instances, + unsigned int offset, + const uint8_t *sourceData) override; virtual gl::Error getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, unsigned int *outSpaceRequired) const; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp index f9eded9b50..a23ab4a290 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp @@ -7,10 +7,12 @@ // VertexDeclarationCache.cpp: Implements a helper class to construct and cache vertex declarations. #include "libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h" + +#include "libANGLE/VertexAttribute.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/ProgramD3D.h" #include "libANGLE/renderer/d3d/d3d9/VertexBuffer9.h" #include "libANGLE/renderer/d3d/d3d9/formatutils9.h" -#include "libANGLE/Program.h" -#include "libANGLE/VertexAttribute.h" namespace rx { @@ -40,16 +42,23 @@ VertexDeclarationCache::~VertexDeclarationCache() } } -gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::Program *program, GLsizei instances, GLsizei *repeatDraw) +gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, + const std::vector<TranslatedAttribute> &attributes, + gl::Program *program, + GLsizei instances, + GLsizei *repeatDraw) { + ASSERT(gl::MAX_VERTEX_ATTRIBS >= attributes.size()); + *repeatDraw = 1; - int indexedAttribute = gl::MAX_VERTEX_ATTRIBS; - int instancedAttribute = gl::MAX_VERTEX_ATTRIBS; + const size_t invalidAttribIndex = attributes.size(); + size_t indexedAttribute = invalidAttribIndex; + size_t instancedAttribute = invalidAttribIndex; if (instances == 0) { - for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; ++i) + for (size_t i = 0; i < attributes.size(); ++i) { if (attributes[i].divisor != 0) { @@ -64,26 +73,26 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Tra if (instances > 0) { // Find an indexed attribute to be mapped to D3D stream 0 - for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + for (size_t i = 0; i < attributes.size(); i++) { if (attributes[i].active) { - if (indexedAttribute == gl::MAX_VERTEX_ATTRIBS && attributes[i].divisor == 0) + if (indexedAttribute == invalidAttribIndex && attributes[i].divisor == 0) { indexedAttribute = i; } - else if (instancedAttribute == gl::MAX_VERTEX_ATTRIBS && attributes[i].divisor != 0) + else if (instancedAttribute == invalidAttribIndex && attributes[i].divisor != 0) { instancedAttribute = i; } - if (indexedAttribute != gl::MAX_VERTEX_ATTRIBS && instancedAttribute != gl::MAX_VERTEX_ATTRIBS) + if (indexedAttribute != invalidAttribIndex && instancedAttribute != invalidAttribIndex) break; // Found both an indexed and instanced attribute } } // The validation layer checks that there is at least one active attribute with a zero divisor as per // the GL_ANGLE_instanced_arrays spec. - ASSERT(indexedAttribute != gl::MAX_VERTEX_ATTRIBS); + ASSERT(indexedAttribute != invalidAttribIndex); } D3DCAPS9 caps; @@ -92,19 +101,22 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Tra D3DVERTEXELEMENT9 elements[gl::MAX_VERTEX_ATTRIBS + 1]; D3DVERTEXELEMENT9 *element = &elements[0]; - for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program); + const auto &semanticIndexes = programD3D->getSemanticIndexes(); + + for (size_t i = 0; i < attributes.size(); i++) { if (attributes[i].active) { // Directly binding the storage buffer is not supported for d3d9 ASSERT(attributes[i].storage == NULL); - int stream = i; + int stream = static_cast<int>(i); if (instances > 0) { // Due to a bug on ATI cards we can't enable instancing when none of the attributes are instanced. - if (instancedAttribute == gl::MAX_VERTEX_ATTRIBS) + if (instancedAttribute == invalidAttribIndex) { *repeatDraw = instances; } @@ -116,7 +128,7 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Tra } else if (i == 0) { - stream = indexedAttribute; + stream = static_cast<int>(indexedAttribute); } UINT frequency = 1; @@ -135,7 +147,7 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Tra } } - VertexBuffer9 *vertexBuffer = VertexBuffer9::makeVertexBuffer9(attributes[i].vertexBuffer); + VertexBuffer9 *vertexBuffer = GetAs<VertexBuffer9>(attributes[i].vertexBuffer); if (mAppliedVBs[stream].serial != attributes[i].serial || mAppliedVBs[stream].stride != attributes[i].stride || @@ -147,20 +159,20 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Tra mAppliedVBs[stream].offset = attributes[i].offset; } - gl::VertexFormat vertexFormat(*attributes[i].attribute, GL_FLOAT); - const d3d9::VertexFormat &d3d9VertexInfo = d3d9::GetVertexFormatInfo(caps.DeclTypes, vertexFormat); + gl::VertexFormatType vertexformatType = gl::GetVertexFormatType(*attributes[i].attribute, GL_FLOAT); + const d3d9::VertexFormat &d3d9VertexInfo = d3d9::GetVertexFormatInfo(caps.DeclTypes, vertexformatType); - element->Stream = stream; + element->Stream = static_cast<WORD>(stream); element->Offset = 0; - element->Type = d3d9VertexInfo.nativeFormat; + element->Type = static_cast<BYTE>(d3d9VertexInfo.nativeFormat); element->Method = D3DDECLMETHOD_DEFAULT; element->Usage = D3DDECLUSAGE_TEXCOORD; - element->UsageIndex = program->getSemanticIndex(i); + element->UsageIndex = static_cast<BYTE>(semanticIndexes[i]); element++; } } - if (instances == 0 || instancedAttribute == gl::MAX_VERTEX_ATTRIBS) + if (instances == 0 || instancedAttribute == invalidAttribIndex) { if (mInstancingEnabled) { diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h index fbd673097f..bad4de4d6b 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h @@ -27,7 +27,11 @@ class VertexDeclarationCache VertexDeclarationCache(); ~VertexDeclarationCache(); - gl::Error applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::Program *program, GLsizei instances, GLsizei *repeatDraw); + gl::Error applyDeclaration(IDirect3DDevice9 *device, + const std::vector<TranslatedAttribute> &attributes, + gl::Program *program, + GLsizei instances, + GLsizei *repeatDraw); void markStateDirty(); diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp index 9bad5503d9..b672a60e3c 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp @@ -119,8 +119,8 @@ static D3D9FormatInfoMap BuildD3D9FormatInfoMap() InsertD3DFormatInfo(&map, D3DFMT_L8, 8, 1, 1, 0, 0, 0, 0, 8, 0, 0, GL_LUMINANCE8_EXT, GenerateMip<L8>, ReadColor<L8, GLfloat> ); InsertD3DFormatInfo(&map, D3DFMT_A8, 8, 1, 1, 0, 0, 0, 8, 0, 0, 0, GL_ALPHA8_EXT, GenerateMip<A8>, ReadColor<A8, GLfloat> ); InsertD3DFormatInfo(&map, D3DFMT_A8L8, 16, 1, 1, 0, 0, 0, 8, 8, 0, 0, GL_LUMINANCE8_ALPHA8_EXT, GenerateMip<A8L8>, ReadColor<A8L8, GLfloat> ); - InsertD3DFormatInfo(&map, D3DFMT_A4R4G4B4, 16, 1, 1, 4, 4, 4, 4, 0, 0, 0, GL_BGRA4_ANGLEX, GenerateMip<B4G4R4A4>, ReadColor<B4G4R4A4, GLfloat> ); - InsertD3DFormatInfo(&map, D3DFMT_A1R5G5B5, 16, 1, 1, 5, 5, 5, 1, 0, 0, 0, GL_BGR5_A1_ANGLEX, GenerateMip<B5G5R5A1>, ReadColor<B5G5R5A1, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_A4R4G4B4, 16, 1, 1, 4, 4, 4, 4, 0, 0, 0, GL_BGRA4_ANGLEX, GenerateMip<A4R4G4B4>, ReadColor<A4R4G4B4, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_A1R5G5B5, 16, 1, 1, 5, 5, 5, 1, 0, 0, 0, GL_BGR5_A1_ANGLEX, GenerateMip<A1R5G5B5>, ReadColor<A1R5G5B5, GLfloat> ); InsertD3DFormatInfo(&map, D3DFMT_R5G6B5, 16, 1, 1, 5, 6, 5, 0, 0, 0, 0, GL_RGB565, GenerateMip<R5G6B5>, ReadColor<R5G6B5, GLfloat> ); InsertD3DFormatInfo(&map, D3DFMT_X8R8G8B8, 32, 1, 1, 8, 8, 8, 0, 0, 0, 0, GL_BGRA8_EXT, GenerateMip<B8G8R8X8>, ReadColor<B8G8R8X8, GLfloat> ); InsertD3DFormatInfo(&map, D3DFMT_A8R8G8B8, 32, 1, 1, 8, 8, 8, 8, 0, 0, 0, GL_BGRA8_EXT, GenerateMip<B8G8R8A8>, ReadColor<B8G8R8A8, GLfloat> ); @@ -475,16 +475,25 @@ template <class T> struct UseFallback { enum { type = T::fallback }; }; // and the D3DDECLTYPE member needed for the vertex declaration in declflag. template <GLenum fromType, bool normalized, int size, template <class T> class PreferenceRule> struct Converter - : VertexDataConverter<typename GLToCType<fromType>::type, - WidenRule<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type, size>, - ConversionRule<fromType, - normalized, - PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>, - DefaultVertexValues<typename D3DToCType<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>::type, normalized > > + : VertexDataConverter< + typename GLToCType<fromType>::type, + WidenRule<PreferenceRule<VertexTypeMapping<fromType, normalized>>::type, size>, + ConversionRule<fromType, + normalized, + PreferenceRule<VertexTypeMapping<fromType, normalized>>::type>, + DefaultVertexValues<typename D3DToCType<PreferenceRule< + VertexTypeMapping<fromType, normalized>>::type>::type, + normalized>> { private: - enum { d3dtype = PreferenceRule< VertexTypeMapping<fromType, normalized> >::type }; - enum { d3dsize = WidenRule<d3dtype, size>::finalWidth }; + enum + { + d3dtype = PreferenceRule<VertexTypeMapping<fromType, normalized>>::type + }; + enum + { + d3dsize = WidenRule<d3dtype, size>::finalWidth + }; public: enum { capflag = VertexTypeFlags<d3dtype, d3dsize>::capflag }; @@ -555,12 +564,12 @@ static inline unsigned int ComputeTypeIndex(GLenum type) } } -const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, const gl::VertexFormat &vertexFormat) +const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, gl::VertexFormatType vertexFormatType) { static bool initialized = false; - static DWORD intializedDeclTypes = 0; + static DWORD initializedDeclTypes = 0; static VertexFormat formatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; - if (intializedDeclTypes != supportedDeclTypes) + if (initializedDeclTypes != supportedDeclTypes) { const TranslationDescription translations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1] { @@ -589,12 +598,14 @@ const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, const gl::Vert } } initialized = true; - intializedDeclTypes = supportedDeclTypes; + initializedDeclTypes = supportedDeclTypes; } + const gl::VertexFormat &vertexFormat = gl::GetVertexFormatFromType(vertexFormatType); + // Pure integer attributes only supported in ES3.0 - ASSERT(!vertexFormat.mPureInteger); - return formatConverters[ComputeTypeIndex(vertexFormat.mType)][vertexFormat.mNormalized][vertexFormat.mComponents - 1]; + ASSERT(!vertexFormat.pureInteger); + return formatConverters[ComputeTypeIndex(vertexFormat.type)][vertexFormat.normalized][vertexFormat.components - 1]; } } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h index 15e26599c8..c55010760d 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h @@ -10,12 +10,12 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D9_FORMATUTILS9_H_ #define LIBANGLE_RENDERER_D3D_D3D9_FORMATUTILS9_H_ -#include "libANGLE/renderer/d3d/formatutilsD3D.h" -#include "libANGLE/angletypes.h" +#include <map> #include "common/platform.h" - -#include <map> +#include "libANGLE/angletypes.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/formatutilsD3D.h" namespace rx { @@ -64,7 +64,7 @@ struct VertexFormat D3DDECLTYPE nativeFormat; GLenum componentType; }; -const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, const gl::VertexFormat &vertexFormat); +const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, gl::VertexFormatType vertexFormatType); struct TextureFormat { diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp index c9711ac052..8622dc4d13 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp @@ -8,16 +8,17 @@ // specific to the D3D9 renderer. #include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" -#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" -#include "libANGLE/renderer/d3d/FramebufferD3D.h" -#include "libANGLE/renderer/Workarounds.h" -#include "libANGLE/formatutils.h" -#include "libANGLE/Framebuffer.h" -#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" #include "common/mathutil.h" #include "common/debug.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" +#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" +#include "libANGLE/renderer/d3d/FramebufferD3D.h" +#include "libANGLE/renderer/d3d/WorkaroundsD3D.h" + #include "third_party/systeminfo/SystemInfo.h" namespace rx @@ -208,7 +209,8 @@ D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy) return d3dMagFilter; } -void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy) +void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, + float *d3dLodBias, float maxAnisotropy, size_t baseLevel) { switch (minFilter) { @@ -242,6 +244,20 @@ void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DT UNREACHABLE(); } + // Disabling mipmapping will always sample from level 0 of the texture. It is possible to work + // around this by modifying D3DSAMP_MAXMIPLEVEL to force a specific mip level to become the + // lowest sampled mip level and using a large negative value for D3DSAMP_MIPMAPLODBIAS to + // ensure that only the base mip level is sampled. + if (baseLevel > 0 && *d3dMipFilter == D3DTEXF_NONE) + { + *d3dMipFilter = D3DTEXF_POINT; + *d3dLodBias = -static_cast<float>(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + } + else + { + *d3dLodBias = 0.0f; + } + if (maxAnisotropy > 1.0f) { *d3dMinFilter = D3DTEXF_ANISOTROPIC; @@ -258,6 +274,16 @@ D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples) namespace d3d9_gl { +unsigned int GetReservedVertexUniformVectors() +{ + return 3; // dx_ViewCoords, dx_ViewAdjust and dx_DepthRange. +} + +unsigned int GetReservedFragmentUniformVectors() +{ + return 3; // dx_ViewCoords, dx_DepthFront and dx_DepthRange. +} + GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type) { return (type != D3DMULTISAMPLE_NONMASKABLE) ? type : 0; @@ -303,7 +329,7 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, IDirect3 } textureCaps.sampleCounts.insert(1); - for (size_t i = D3DMULTISAMPLE_2_SAMPLES; i <= D3DMULTISAMPLE_16_SAMPLES; i++) + for (unsigned int i = D3DMULTISAMPLE_2_SAMPLES; i <= D3DMULTISAMPLE_16_SAMPLES; i++) { D3DMULTISAMPLE_TYPE multisampleType = D3DMULTISAMPLE_TYPE(i); @@ -318,8 +344,14 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, IDirect3 return textureCaps; } -void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceType, UINT adapter, gl::Caps *caps, - gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions) +void GenerateCaps(IDirect3D9 *d3d9, + IDirect3DDevice9 *device, + D3DDEVTYPE deviceType, + UINT adapter, + gl::Caps *caps, + gl::TextureCapsMap *textureCapsMap, + gl::Extensions *extensions, + gl::Limitations *limitations) { D3DCAPS9 deviceCaps; if (FAILED(d3d9->GetDeviceCaps(adapter, deviceType, &deviceCaps))) @@ -413,9 +445,9 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT // Vertex shader limits caps->maxVertexAttributes = 16; - const size_t reservedVertexUniformVectors = 2; // dx_ViewAdjust and dx_DepthRange. const size_t MAX_VERTEX_CONSTANT_VECTORS_D3D9 = 256; - caps->maxVertexUniformVectors = MAX_VERTEX_CONSTANT_VECTORS_D3D9 - reservedVertexUniformVectors; + caps->maxVertexUniformVectors = + MAX_VERTEX_CONSTANT_VECTORS_D3D9 - GetReservedVertexUniformVectors(); caps->maxVertexUniformComponents = caps->maxVertexUniformVectors * 4; caps->maxVertexUniformBlocks = 0; @@ -441,12 +473,12 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT } // Fragment shader limits - const size_t reservedPixelUniformVectors = 3; // dx_ViewCoords, dx_DepthFront and dx_DepthRange. - const size_t MAX_PIXEL_CONSTANT_VECTORS_SM3 = 224; const size_t MAX_PIXEL_CONSTANT_VECTORS_SM2 = 32; - caps->maxFragmentUniformVectors = ((deviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) ? MAX_PIXEL_CONSTANT_VECTORS_SM3 - : MAX_PIXEL_CONSTANT_VECTORS_SM2) - reservedPixelUniformVectors; + caps->maxFragmentUniformVectors = + ((deviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) ? MAX_PIXEL_CONSTANT_VECTORS_SM3 + : MAX_PIXEL_CONSTANT_VECTORS_SM2) - + GetReservedFragmentUniformVectors(); caps->maxFragmentUniformComponents = caps->maxFragmentUniformVectors * 4; caps->maxFragmentUniformBlocks = 0; caps->maxFragmentInputComponents = caps->maxVertexOutputComponents; @@ -472,10 +504,12 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT caps->maxTransformFeedbackSeparateAttributes = 0; caps->maxTransformFeedbackSeparateComponents = 0; + // Multisample limits + caps->maxSamples = maxSamples; + // GL extension support extensions->setTextureExtensionSupport(*textureCapsMap); extensions->elementIndexUint = deviceCaps.MaxVertexIndex >= (1 << 16); - extensions->packedDepthStencil = true; extensions->getProgramBinary = true; extensions->rgb8rgba8 = true; extensions->readFormatBGRA = true; @@ -486,7 +520,7 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT // textureRG is emulated and not performant. extensions->textureRG = false; - D3DADAPTER_IDENTIFIER9 adapterId = { 0 }; + D3DADAPTER_IDENTIFIER9 adapterId = {}; if (SUCCEEDED(d3d9->GetAdapterIdentifier(adapter, 0, &adapterId))) { // ATI cards on XP have problems with non-power-of-two textures. @@ -524,11 +558,11 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT SafeRelease(eventQuery); extensions->timerQuery = false; // Unimplemented + extensions->disjointTimerQuery = false; extensions->robustness = true; extensions->blendMinMax = true; extensions->framebufferBlit = true; extensions->framebufferMultisample = true; - extensions->maxSamples = maxSamples; extensions->instancedArrays = deviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0); extensions->packReverseRowOrder = true; extensions->standardDerivatives = (deviceCaps.PS20Caps.Caps & D3DPS20CAPS_GRADIENTINSTRUCTIONS) != 0; @@ -536,7 +570,27 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT extensions->fragDepth = true; extensions->textureUsage = true; extensions->translatedShaderSource = true; + extensions->fboRenderMipmap = false; + extensions->discardFramebuffer = false; // It would be valid to set this to true, since glDiscardFramebufferEXT is just a hint extensions->colorBufferFloat = false; + extensions->debugMarker = true; + extensions->eglImage = true; + extensions->unpackSubimage = true; + extensions->packSubimage = true; + extensions->vertexArrayObject = true; + extensions->noError = true; + + // D3D9 has no concept of separate masks and refs for front and back faces in the depth stencil + // state. + limitations->noSeparateStencilRefsAndMasks = true; + + // D3D9 shader models have limited support for looping, so the Appendix A + // index/loop limitations are necessary. Workarounds that are needed to + // support dynamic indexing of vectors on HLSL also don't work on D3D9. + limitations->shadersRequireIndexedLoopValidation = true; + + // D3D9 cannot support constant color and alpha blend funcs together + limitations->noSimultaneousConstantColorAndAlphaBlendFunc = true; } } @@ -571,21 +625,9 @@ void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsize *levelOffset = upsampleCount; } -gl::Error GetAttachmentRenderTarget(const gl::FramebufferAttachment *attachment, RenderTarget9 **outRT) -{ - RenderTargetD3D *renderTarget = NULL; - gl::Error error = rx::GetAttachmentRenderTarget(attachment, &renderTarget); - if (error.isError()) - { - return error; - } - *outRT = RenderTarget9::makeRenderTarget9(renderTarget); - return gl::Error(GL_NO_ERROR); -} - -Workarounds GenerateWorkarounds() +WorkaroundsD3D GenerateWorkarounds() { - Workarounds workarounds; + WorkaroundsD3D workarounds; workarounds.mrtPerfWorkaround = true; workarounds.setDataFasterThanImageUpload = false; workarounds.useInstancedPointSpriteEmulation = false; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h index 3c6a57aee3..aa494adb62 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h @@ -22,7 +22,7 @@ class FramebufferAttachment; namespace rx { class RenderTarget9; -struct Workarounds; +struct WorkaroundsD3D; namespace gl_d3d9 { @@ -37,7 +37,8 @@ D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace); D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace); DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha); D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy); -void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy); +void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, + float *d3dLodBias, float maxAnisotropy, size_t baseLevel); D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples); @@ -46,13 +47,22 @@ D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples); namespace d3d9_gl { +unsigned int GetReservedVertexUniformVectors(); + +unsigned int GetReservedFragmentUniformVectors(); + GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type); bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format); -void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceType, UINT adapter, gl::Caps *caps, - gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions); - +void GenerateCaps(IDirect3D9 *d3d9, + IDirect3DDevice9 *device, + D3DDEVTYPE deviceType, + UINT adapter, + gl::Caps *caps, + gl::TextureCapsMap *textureCapsMap, + gl::Extensions *extensions, + gl::Limitations *limitations); } namespace d3d9 @@ -76,9 +86,7 @@ inline bool isDeviceLostError(HRESULT errorCode) } } -gl::Error GetAttachmentRenderTarget(const gl::FramebufferAttachment *attachment, RenderTarget9 **outRT); -Workarounds GenerateWorkarounds(); - +WorkaroundsD3D GenerateWorkarounds(); } } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/vertexconversion.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/vertexconversion.h index 32eb376a78..aa05934bc8 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/vertexconversion.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/vertexconversion.h @@ -149,7 +149,10 @@ struct NormalizedDefaultValues // static const std::size_t finalSize: number of bytes per output vertex // static void convertArray(const void *in, std::size_t stride, std::size_t n, void *out): convert an array of vertices. Input may be strided, but output will be unstrided. -template <class InT, class WidenRule, class Converter, class DefaultValueRule = SimpleDefaultValues<InT> > +template <class InT, + class WidenRule, + class Converter, + class DefaultValueRule = SimpleDefaultValues<InT>> struct VertexDataConverter { typedef typename Converter::OutputType OutputType; |