summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9')
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp24
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp31
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h10
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp8
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h4
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp44
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.h10
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp78
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h16
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp89
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.h13
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp6
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h2
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.cpp36
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.h11
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp43
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h26
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp1067
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h203
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp6
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h2
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp903
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.h206
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp43
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h12
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp272
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h44
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h13
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp58
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h11
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp56
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h6
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp43
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h10
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp108
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h24
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/vertexconversion.h5
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 &currentValue,
- 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 &currentValue,
- GLint start, GLsizei count, GLsizei instances, unsigned int offset);
+ gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib,
+ GLenum currentValueType,
+ GLint start,
+ GLsizei count,
+ GLsizei instances,
+ unsigned int offset,
+ const uint8_t *sourceData) override;
virtual gl::Error getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, unsigned int *outSpaceRequired) const;
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/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;