Move Context draw call logic into RendererD3D.
Also move a lot of supporting code.
BUG=angle:789
Change-Id: I098bf7d072ece1f414605783c32ec5354ba63e19
Reviewed-on: https://chromium-review.googlesource.com/226061
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Brandon Jones <bajones@chromium.org>
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 558d3ce..8ada58c 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -35,7 +35,6 @@
#include <iterator>
// TODO(jmadill): phase these out
-#include "libGLESv2/renderer/d3d/IndexDataManager.h"
#include "libGLESv2/renderer/d3d/RendererD3D.h"
namespace gl
@@ -1301,324 +1300,6 @@
return false;
}
-// Applies the render target surface, depth stencil surface, viewport rectangle and
-// scissor rectangle to the renderer
-Error Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport)
-{
- Framebuffer *framebufferObject = mState.getDrawFramebuffer();
- ASSERT(framebufferObject && framebufferObject->completeness(getData()) == GL_FRAMEBUFFER_COMPLETE);
-
- //TODO(jmadill): MANGLE refactor
- rx::RendererD3D *rendererD3D = rx::RendererD3D::makeRendererD3D(mRenderer);
-
- gl::Error error = rendererD3D->applyRenderTarget(framebufferObject);
- if (error.isError())
- {
- return error;
- }
-
- float nearZ, farZ;
- mState.getDepthRange(&nearZ, &farZ);
- rendererD3D->setViewport(mState.getViewport(), nearZ, farZ, drawMode,
- mState.getRasterizerState().frontFace, ignoreViewport);
-
- rendererD3D->setScissorRectangle(mState.getScissor(), mState.isScissorTestEnabled());
-
- return gl::Error(GL_NO_ERROR);
-}
-
-// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
-Error Context::applyState(GLenum drawMode)
-{
- Framebuffer *framebufferObject = mState.getDrawFramebuffer();
- int samples = framebufferObject->getSamples(getData());
-
- RasterizerState rasterizer = mState.getRasterizerState();
- rasterizer.pointDrawMode = (drawMode == GL_POINTS);
- rasterizer.multiSample = (samples != 0);
-
- //TODO(jmadill): MANGLE refactor
- rx::RendererD3D *rendererD3D = rx::RendererD3D::makeRendererD3D(mRenderer);
-
- Error error = rendererD3D->setRasterizerState(rasterizer);
- if (error.isError())
- {
- return error;
- }
-
- unsigned int mask = 0;
- if (mState.isSampleCoverageEnabled())
- {
- GLclampf coverageValue;
- bool coverageInvert = false;
- mState.getSampleCoverageParams(&coverageValue, &coverageInvert);
- if (coverageValue != 0)
- {
- float threshold = 0.5f;
-
- for (int i = 0; i < samples; ++i)
- {
- mask <<= 1;
-
- if ((i + 1) * coverageValue >= threshold)
- {
- threshold += 1.0f;
- mask |= 1;
- }
- }
- }
-
- if (coverageInvert)
- {
- mask = ~mask;
- }
- }
- else
- {
- mask = 0xFFFFFFFF;
- }
- error = rendererD3D->setBlendState(framebufferObject, mState.getBlendState(), mState.getBlendColor(), mask);
- if (error.isError())
- {
- return error;
- }
-
- error = rendererD3D->setDepthStencilState(mState.getDepthStencilState(), mState.getStencilRef(),
- mState.getStencilBackRef(), rasterizer.frontFace == GL_CCW);
- if (error.isError())
- {
- return error;
- }
-
- return Error(GL_NO_ERROR);
-}
-
-// Applies the shaders and shader constants to the Direct3D 9 device
-Error Context::applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive)
-{
- VertexFormat inputLayout[MAX_VERTEX_ATTRIBS];
- VertexFormat::GetInputLayout(inputLayout, programBinary, mState);
-
- const Framebuffer *fbo = mState.getDrawFramebuffer();
-
- //TODO(jmadill): MANGLE refactor
- rx::RendererD3D *rendererD3D = rx::RendererD3D::makeRendererD3D(mRenderer);
-
- Error error = rendererD3D->applyShaders(programBinary, inputLayout, fbo,
- mState.getRasterizerState().rasterizerDiscard,
- transformFeedbackActive);
- if (error.isError())
- {
- return error;
- }
-
- return programBinary->applyUniforms();
-}
-
-Error Context::generateSwizzles(ProgramBinary *programBinary, SamplerType type)
-{
- size_t samplerRange = programBinary->getUsedSamplerRange(type);
-
- for (size_t i = 0; i < samplerRange; i++)
- {
- GLenum textureType = programBinary->getSamplerTextureType(type, i);
- GLint textureUnit = programBinary->getSamplerMapping(type, i, getCaps());
- if (textureUnit != -1)
- {
- Texture *texture = getSamplerTexture(textureUnit, textureType);
- ASSERT(texture);
- if (texture->getSamplerState().swizzleRequired())
- {
- //TODO(jmadill): MANGLE refactor
- rx::RendererD3D *rendererD3D = rx::RendererD3D::makeRendererD3D(mRenderer);
-
- Error error = rendererD3D->generateSwizzle(texture);
- if (error.isError())
- {
- return error;
- }
- }
- }
- }
-
- return Error(GL_NO_ERROR);
-}
-
-Error Context::generateSwizzles(ProgramBinary *programBinary)
-{
- Error error = generateSwizzles(programBinary, SAMPLER_VERTEX);
- if (error.isError())
- {
- return error;
- }
-
- error = generateSwizzles(programBinary, SAMPLER_PIXEL);
- if (error.isError())
- {
- return error;
- }
-
- return Error(GL_NO_ERROR);
-}
-
-// For each Direct3D sampler of either the pixel or vertex stage,
-// looks up the corresponding OpenGL texture image unit and texture type,
-// and sets the texture and its addressing/filtering state (or NULL when inactive).
-Error Context::applyTextures(ProgramBinary *programBinary, SamplerType shaderType,
- const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount)
-{
- //TODO(jmadill): MANGLE refactor
- rx::RendererD3D *rendererD3D = rx::RendererD3D::makeRendererD3D(mRenderer);
-
- size_t samplerRange = programBinary->getUsedSamplerRange(shaderType);
- for (size_t samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
- {
- GLenum textureType = programBinary->getSamplerTextureType(shaderType, samplerIndex);
- GLint textureUnit = programBinary->getSamplerMapping(shaderType, samplerIndex, getCaps());
- if (textureUnit != -1)
- {
- Texture *texture = getSamplerTexture(textureUnit, textureType);
- ASSERT(texture);
- SamplerState sampler = texture->getSamplerState();
-
- Sampler *samplerObject = mState.getSampler(textureUnit);
- if (samplerObject)
- {
- samplerObject->getState(&sampler);
- }
-
- // TODO: std::binary_search may become unavailable using older versions of GCC
- if (texture->isSamplerComplete(sampler, mTextureCaps, mExtensions, mClientVersion) &&
- !std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial()))
- {
- Error error = rendererD3D->setSamplerState(shaderType, samplerIndex, texture, sampler);
- if (error.isError())
- {
- return error;
- }
-
- error = rendererD3D->setTexture(shaderType, samplerIndex, texture);
- if (error.isError())
- {
- return error;
- }
- }
- else
- {
- // Texture is not sampler complete or it is in use by the framebuffer. Bind the incomplete texture.
- Texture *incompleteTexture = getIncompleteTexture(textureType);
- gl::Error error = rendererD3D->setTexture(shaderType, samplerIndex, incompleteTexture);
- if (error.isError())
- {
- return error;
- }
- }
- }
- else
- {
- // No texture bound to this slot even though it is used by the shader, bind a NULL texture
- Error error = rendererD3D->setTexture(shaderType, samplerIndex, NULL);
- if (error.isError())
- {
- return error;
- }
- }
- }
-
- // Set all the remaining textures to NULL
- size_t samplerCount = (shaderType == SAMPLER_PIXEL) ? mCaps.maxTextureImageUnits
- : mCaps.maxVertexTextureImageUnits;
- for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
- {
- //TODO(jmadill): MANGLE refactor
- rx::RendererD3D *rendererD3D = rx::RendererD3D::makeRendererD3D(mRenderer);
-
- Error error = rendererD3D->setTexture(shaderType, samplerIndex, NULL);
- if (error.isError())
- {
- return error;
- }
- }
-
- return Error(GL_NO_ERROR);
-}
-
-Error Context::applyTextures(ProgramBinary *programBinary)
-{
- FramebufferTextureSerialArray framebufferSerials;
- size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&framebufferSerials);
-
- Error error = applyTextures(programBinary, SAMPLER_VERTEX, framebufferSerials, framebufferSerialCount);
- if (error.isError())
- {
- return error;
- }
-
- error = applyTextures(programBinary, SAMPLER_PIXEL, framebufferSerials, framebufferSerialCount);
- if (error.isError())
- {
- return error;
- }
-
- return Error(GL_NO_ERROR);
-}
-
-Error Context::applyUniformBuffers()
-{
- Program *programObject = getProgram(mState.getCurrentProgramId());
- ProgramBinary *programBinary = programObject->getProgramBinary();
-
- std::vector<Buffer*> boundBuffers;
-
- for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++)
- {
- GLuint blockBinding = programObject->getUniformBlockBinding(uniformBlockIndex);
-
- if (mState.getIndexedUniformBuffer(blockBinding)->id() == 0)
- {
- // undefined behaviour
- return gl::Error(GL_INVALID_OPERATION, "It is undefined behaviour to have a used but unbound uniform buffer.");
- }
- else
- {
- Buffer *uniformBuffer = mState.getIndexedUniformBuffer(blockBinding);
- ASSERT(uniformBuffer);
- boundBuffers.push_back(uniformBuffer);
- }
- }
-
- return programBinary->applyUniformBuffers(boundBuffers, getCaps());
-}
-
-bool Context::applyTransformFeedbackBuffers()
-{
- //TODO(jmadill): MANGLE refactor
- rx::RendererD3D *rendererD3D = rx::RendererD3D::makeRendererD3D(mRenderer);
-
- TransformFeedback *curTransformFeedback = mState.getCurrentTransformFeedback();
- if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
- {
- rendererD3D->applyTransformFeedbackBuffers(mState);
- return true;
- }
- else
- {
- return false;
- }
-}
-
-void Context::markTransformFeedbackUsage()
-{
- for (size_t i = 0; i < mCaps.maxTransformFeedbackSeparateAttributes; i++)
- {
- Buffer *buffer = mState.getIndexedTransformFeedbackBuffer(i);
- if (buffer)
- {
- buffer->markTransformFeedbackUsage();
- }
- }
-}
-
Error Context::clear(GLbitfield mask)
{
if (mState.isRasterizerDiscardEnabled())
@@ -1628,7 +1309,11 @@
ClearParameters clearParams = mState.getClearParameters(mask);
- Error error = applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
+ //TODO(jmadill): Renderer refactor
+ rx::RendererD3D *rendererD3D = rx::RendererD3D::makeRendererD3D(mRenderer);
+
+ // Clips the clear to the scissor rectangle but not the viewport
+ Error error = rendererD3D->applyRenderTarget(getData(), GL_TRIANGLES, true);
if (error.isError())
{
return error;
@@ -1663,7 +1348,11 @@
clearParams.depthClearValue = values[0];
}
- Error error = applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
+ //TODO(jmadill): Renderer refactor
+ rx::RendererD3D *rendererD3D = rx::RendererD3D::makeRendererD3D(mRenderer);
+
+ // Clips the clear to the scissor rectangle but not the viewport
+ Error error = rendererD3D->applyRenderTarget(getData(), GL_TRIANGLES, true);
if (error.isError())
{
return error;
@@ -1688,7 +1377,11 @@
clearParams.colorUIClearValue = ColorUI(values[0], values[1], values[2], values[3]);
clearParams.colorClearType = GL_UNSIGNED_INT;
- Error error = applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
+ //TODO(jmadill): Renderer refactor
+ rx::RendererD3D *rendererD3D = rx::RendererD3D::makeRendererD3D(mRenderer);
+
+ // Clips the clear to the scissor rectangle but not the viewport
+ Error error = rendererD3D->applyRenderTarget(getData(), GL_TRIANGLES, true);
if (error.isError())
{
return error;
@@ -1723,7 +1416,11 @@
clearParams.stencilClearValue = values[1];
}
- Error error = applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
+ //TODO(jmadill): Renderer refactor
+ rx::RendererD3D *rendererD3D = rx::RendererD3D::makeRendererD3D(mRenderer);
+
+ // Clips the clear to the scissor rectangle but not the viewport
+ Error error = rendererD3D->applyRenderTarget(getData(), GL_TRIANGLES, true);
if (error.isError())
{
return error;
@@ -1746,7 +1443,11 @@
clearParams.clearStencil = true;
clearParams.stencilClearValue = stencil;
- Error error = applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
+ //TODO(jmadill): Renderer refactor
+ rx::RendererD3D *rendererD3D = rx::RendererD3D::makeRendererD3D(mRenderer);
+
+ // Clips the clear to the scissor rectangle but not the viewport
+ Error error = rendererD3D->applyRenderTarget(getData(), GL_TRIANGLES, true);
if (error.isError())
{
return error;
@@ -1770,164 +1471,14 @@
Error Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
{
- ASSERT(mState.getCurrentProgramId() != 0);
-
- ProgramBinary *programBinary = mState.getCurrentProgramBinary();
- programBinary->updateSamplerMapping();
-
- Error error = generateSwizzles(programBinary);
- if (error.isError())
- {
- return error;
- }
-
- //TODO(jmadill): MANGLE refactor
- rx::RendererD3D *rendererD3D = rx::RendererD3D::makeRendererD3D(mRenderer);
-
- if (!rendererD3D->applyPrimitiveType(mode, count))
- {
- return Error(GL_NO_ERROR);
- }
-
- error = applyRenderTarget(mode, false);
- if (error.isError())
- {
- return error;
- }
-
- error = applyState(mode);
- if (error.isError())
- {
- return error;
- }
-
- error = rendererD3D->applyVertexBuffer(mState, first, count, instances);
- if (error.isError())
- {
- return error;
- }
-
- bool transformFeedbackActive = applyTransformFeedbackBuffers();
-
- error = applyShaders(programBinary, transformFeedbackActive);
- if (error.isError())
- {
- return error;
- }
-
- error = applyTextures(programBinary);
- if (error.isError())
- {
- return error;
- }
-
- error = applyUniformBuffers();
- if (error.isError())
- {
- return error;
- }
-
- if (!skipDraw(mode))
- {
- error = mRenderer->drawArrays(mode, count, instances, transformFeedbackActive);
- if (error.isError())
- {
- return error;
- }
-
- if (transformFeedbackActive)
- {
- markTransformFeedbackUsage();
- }
- }
-
- return gl::Error(GL_NO_ERROR);
+ return mRenderer->drawArrays(getData(), mode, first, count, instances);
}
Error Context::drawElements(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices, GLsizei instances,
const rx::RangeUI &indexRange)
{
- ASSERT(mState.getCurrentProgramId() != 0);
-
- ProgramBinary *programBinary = mState.getCurrentProgramBinary();
- programBinary->updateSamplerMapping();
-
- Error error = generateSwizzles(programBinary);
- if (error.isError())
- {
- return error;
- }
-
- //TODO(jmadill): MANGLE refactor
- rx::RendererD3D *rendererD3D = rx::RendererD3D::makeRendererD3D(mRenderer);
-
- if (!rendererD3D->applyPrimitiveType(mode, count))
- {
- return Error(GL_NO_ERROR);
- }
-
- error = applyRenderTarget(mode, false);
- if (error.isError())
- {
- return error;
- }
-
- error = applyState(mode);
- if (error.isError())
- {
- return error;
- }
-
- VertexArray *vao = mState.getVertexArray();
- rx::TranslatedIndexData indexInfo;
- indexInfo.indexRange = indexRange;
- error = rendererD3D->applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo);
- if (error.isError())
- {
- return error;
- }
-
- GLsizei vertexCount = indexInfo.indexRange.length() + 1;
- error = rendererD3D->applyVertexBuffer(mState, indexInfo.indexRange.start, vertexCount, instances);
- if (error.isError())
- {
- return error;
- }
-
- bool transformFeedbackActive = applyTransformFeedbackBuffers();
- // Transform feedback is not allowed for DrawElements, this error should have been caught at the API validation
- // layer.
- ASSERT(!transformFeedbackActive);
-
- error = applyShaders(programBinary, transformFeedbackActive);
- if (error.isError())
- {
- return error;
- }
-
- error = applyTextures(programBinary);
- if (error.isError())
- {
- return error;
- }
-
- error = applyUniformBuffers();
- if (error.isError())
- {
- return error;
- }
-
- if (!skipDraw(mode))
- {
- error = mRenderer->drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances);
- if (error.isError())
- {
- return error;
- }
- }
-
- return Error(GL_NO_ERROR);
+ return mRenderer->drawElements(getData(), mode, count, type, indices, instances, indexRange);
}
// Implements glFlush when block is false, glFinish when block is true
@@ -2104,95 +1655,6 @@
mState.detachSampler(sampler);
}
-Texture *Context::getIncompleteTexture(GLenum type)
-{
- if (mIncompleteTextures.find(type) == mIncompleteTextures.end())
- {
- const GLubyte color[] = { 0, 0, 0, 255 };
- const PixelUnpackState incompleteUnpackState(1);
-
- Texture* t = NULL;
- switch (type)
- {
- default:
- UNREACHABLE();
- // default falls through to TEXTURE_2D
-
- case GL_TEXTURE_2D:
- {
- Texture2D *incomplete2d = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), Texture::INCOMPLETE_TEXTURE_ID);
- incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
- t = incomplete2d;
- }
- break;
-
- case GL_TEXTURE_CUBE_MAP:
- {
- TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), Texture::INCOMPLETE_TEXTURE_ID);
-
- incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
- incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
- incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
- incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
- incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
- incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
-
- t = incompleteCube;
- }
- break;
-
- case GL_TEXTURE_3D:
- {
- Texture3D *incomplete3d = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), Texture::INCOMPLETE_TEXTURE_ID);
- incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
-
- t = incomplete3d;
- }
- break;
-
- case GL_TEXTURE_2D_ARRAY:
- {
- Texture2DArray *incomplete2darray = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), Texture::INCOMPLETE_TEXTURE_ID);
- incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
-
- t = incomplete2darray;
- }
- break;
- }
-
- mIncompleteTextures[type].set(t);
- }
-
- return mIncompleteTextures[type].get();
-}
-
-bool Context::skipDraw(GLenum drawMode)
-{
- if (drawMode == GL_POINTS)
- {
- // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
- // which affects varying interpolation. Since the value of gl_PointSize is
- // undefined when not written, just skip drawing to avoid unexpected results.
- if (!mState.getCurrentProgramBinary()->usesPointSize())
- {
- // This is stictly speaking not an error, but developers should be
- // notified of risking undefined behavior.
- ERR("Point rendering without writing to gl_PointSize.");
-
- return true;
- }
- }
- else if (IsTriangleMode(drawMode))
- {
- if (mState.getRasterizerState().cullFace && mState.getRasterizerState().cullMode == GL_FRONT_AND_BACK)
- {
- return true;
- }
- }
-
- return false;
-}
-
void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
{
mState.getVertexArray()->setVertexAttribDivisor(index, divisor);
@@ -2325,33 +1787,6 @@
return mExtensionStrings.size();
}
-size_t Context::getBoundFramebufferTextureSerials(FramebufferTextureSerialArray *outSerialArray)
-{
- size_t serialCount = 0;
-
- Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
- for (unsigned int i = 0; i < IMPLEMENTATION_MAX_DRAW_BUFFERS; i++)
- {
- FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i);
- if (attachment && attachment->isTexture())
- {
- Texture *texture = attachment->getTexture();
- (*outSerialArray)[serialCount++] = texture->getTextureSerial();
- }
- }
-
- FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer();
- if (depthStencilAttachment && depthStencilAttachment->isTexture())
- {
- Texture *depthStencilTexture = depthStencilAttachment->getTexture();
- (*outSerialArray)[serialCount++] = depthStencilTexture->getTextureSerial();
- }
-
- std::sort(outSerialArray->begin(), outSerialArray->begin() + serialCount);
-
- return serialCount;
-}
-
Error Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter)
{
diff --git a/src/libGLESv2/Context.h b/src/libGLESv2/Context.h
index 96b0089..fa971b4 100644
--- a/src/libGLESv2/Context.h
+++ b/src/libGLESv2/Context.h
@@ -223,19 +223,6 @@
private:
DISALLOW_COPY_AND_ASSIGN(Context);
- // TODO: std::array may become unavailable using older versions of GCC
- typedef std::array<unsigned int, IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS> FramebufferTextureSerialArray;
-
- Error applyRenderTarget(GLenum drawMode, bool ignoreViewport);
- Error applyState(GLenum drawMode);
- Error applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive);
- Error applyTextures(ProgramBinary *programBinary, SamplerType shaderType, const FramebufferTextureSerialArray &framebufferSerials,
- size_t framebufferSerialCount);
- Error applyTextures(ProgramBinary *programBinary);
- Error applyUniformBuffers();
- bool applyTransformFeedbackBuffers();
- void markTransformFeedbackUsage();
-
void detachBuffer(GLuint buffer);
void detachTexture(GLuint texture);
void detachFramebuffer(GLuint framebuffer);
@@ -244,18 +231,9 @@
void detachTransformFeedback(GLuint transformFeedback);
void detachSampler(GLuint sampler);
- Error generateSwizzles(ProgramBinary *programBinary, SamplerType type);
- Error generateSwizzles(ProgramBinary *programBinary);
-
- Texture *getIncompleteTexture(GLenum type);
-
- bool skipDraw(GLenum drawMode);
-
void initRendererString();
void initExtensionStrings();
- size_t getBoundFramebufferTextureSerials(FramebufferTextureSerialArray *outSerialArray);
-
void initCaps(GLuint clientVersion);
// Caps to use for validation
diff --git a/src/libGLESv2/ResourceManager.cpp b/src/libGLESv2/ResourceManager.cpp
index 0a9c3d3..ac6a0a2 100644
--- a/src/libGLESv2/ResourceManager.cpp
+++ b/src/libGLESv2/ResourceManager.cpp
@@ -295,9 +295,9 @@
}
}
-Program *ResourceManager::getProgram(unsigned int handle)
+Program *ResourceManager::getProgram(unsigned int handle) const
{
- ProgramMap::iterator program = mProgramMap.find(handle);
+ ProgramMap::const_iterator program = mProgramMap.find(handle);
if (program == mProgramMap.end())
{
diff --git a/src/libGLESv2/ResourceManager.h b/src/libGLESv2/ResourceManager.h
index 5421eaf..d75f3d2 100644
--- a/src/libGLESv2/ResourceManager.h
+++ b/src/libGLESv2/ResourceManager.h
@@ -60,7 +60,7 @@
Buffer *getBuffer(GLuint handle);
Shader *getShader(GLuint handle);
- Program *getProgram(GLuint handle);
+ Program *getProgram(GLuint handle) const;
Texture *getTexture(GLuint handle);
Renderbuffer *getRenderbuffer(GLuint handle);
Sampler *getSampler(GLuint handle);
diff --git a/src/libGLESv2/State.cpp b/src/libGLESv2/State.cpp
index fa3bbd6..e7acda2 100644
--- a/src/libGLESv2/State.cpp
+++ b/src/libGLESv2/State.cpp
@@ -486,7 +486,7 @@
mSampleCoverageInvert = invert;
}
-void State::getSampleCoverageParams(GLclampf *value, bool *invert)
+void State::getSampleCoverageParams(GLclampf *value, bool *invert) const
{
ASSERT(value != NULL && invert != NULL);
diff --git a/src/libGLESv2/State.h b/src/libGLESv2/State.h
index 85c96a9..c3e6106 100644
--- a/src/libGLESv2/State.h
+++ b/src/libGLESv2/State.h
@@ -101,7 +101,7 @@
bool isSampleCoverageEnabled() const;
void setSampleCoverage(bool enabled);
void setSampleCoverageParams(GLclampf value, bool invert);
- void getSampleCoverageParams(GLclampf *value, bool *invert);
+ void getSampleCoverageParams(GLclampf *value, bool *invert) const;
// Scissor test state toggle & query
bool isScissorTestEnabled() const;
diff --git a/src/libGLESv2/renderer/Renderer.h b/src/libGLESv2/renderer/Renderer.h
index 902c241..13738f2 100644
--- a/src/libGLESv2/renderer/Renderer.h
+++ b/src/libGLESv2/renderer/Renderer.h
@@ -16,6 +16,7 @@
#include "libGLESv2/angletypes.h"
#include "libGLESv2/renderer/Workarounds.h"
#include "common/NativeWindow.h"
+#include "common/mathutil.h"
#include <cstdint>
@@ -36,6 +37,7 @@
{
class Buffer;
class Framebuffer;
+struct Data;
}
namespace rx
@@ -77,15 +79,18 @@
virtual gl::Error sync(bool block) = 0;
+ virtual gl::Error drawArrays(const gl::Data &data, GLenum mode,
+ GLint first, GLsizei count, GLsizei instances) = 0;
+ virtual gl::Error drawElements(const gl::Data &data, GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices, GLsizei instances,
+ const RangeUI &indexRange) = 0;
+
// TODO(jmadill): pass state and essetial params only
- virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) = 0;
- virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
- gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) = 0;
virtual gl::Error clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) = 0;
virtual gl::Error readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) = 0;
- // TODO(jmadill): caps?
+ // TODO(jmadill): caps? and virtual for egl::Display
virtual bool getShareHandleSupport() const = 0;
virtual bool getPostSubBufferSupport() const = 0;
diff --git a/src/libGLESv2/renderer/d3d/RendererD3D.cpp b/src/libGLESv2/renderer/d3d/RendererD3D.cpp
index 39c9072..6253f21 100644
--- a/src/libGLESv2/renderer/d3d/RendererD3D.cpp
+++ b/src/libGLESv2/renderer/d3d/RendererD3D.cpp
@@ -8,6 +8,14 @@
#include "libGLESv2/renderer/d3d/RendererD3D.h"
+#include "libGLESv2/renderer/d3d/IndexDataManager.h"
+#include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
+#include "libGLESv2/ResourceManager.h"
+#include "libGLESv2/State.h"
+#include "libGLESv2/VertexArray.h"
+#include "common/utilities.h"
+
namespace rx
{
@@ -19,6 +27,11 @@
RendererD3D::~RendererD3D()
{
+ for (auto &incompleteTexture : mIncompleteTextures)
+ {
+ incompleteTexture.second.set(NULL);
+ }
+ mIncompleteTextures.clear();
}
// static
@@ -28,4 +41,581 @@
return static_cast<RendererD3D*>(renderer);
}
+gl::Error RendererD3D::drawElements(const gl::Data &data,
+ GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices, GLsizei instances,
+ const RangeUI &indexRange)
+{
+ ASSERT(data.state->getCurrentProgramId() != 0);
+
+ gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
+ programBinary->updateSamplerMapping();
+
+ gl::Error error = generateSwizzles(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!applyPrimitiveType(mode, count))
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ error = applyRenderTarget(data, mode, false);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyState(data, mode);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ gl::VertexArray *vao = data.state->getVertexArray();
+ rx::TranslatedIndexData indexInfo;
+ indexInfo.indexRange = indexRange;
+ error = applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ GLsizei vertexCount = indexInfo.indexRange.length() + 1;
+ error = applyVertexBuffer(*data.state, indexInfo.indexRange.start, vertexCount, instances);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ bool transformFeedbackActive = applyTransformFeedbackBuffers(data);
+ // Transform feedback is not allowed for DrawElements, this error should have been caught at the API validation
+ // layer.
+ ASSERT(!transformFeedbackActive);
+
+ error = applyShaders(data, transformFeedbackActive);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyTextures(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyUniformBuffers(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!skipDraw(data, mode))
+ {
+ error = drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RendererD3D::drawArrays(const gl::Data &data,
+ GLenum mode, GLint first,
+ GLsizei count, GLsizei instances)
+{
+ ASSERT(data.state->getCurrentProgramId() != 0);
+
+ gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
+ programBinary->updateSamplerMapping();
+
+ gl::Error error = generateSwizzles(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!applyPrimitiveType(mode, count))
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ error = applyRenderTarget(data, mode, false);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyState(data, mode);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyVertexBuffer(*data.state, first, count, instances);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ bool transformFeedbackActive = applyTransformFeedbackBuffers(data);
+
+ error = applyShaders(data, transformFeedbackActive);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyTextures(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyUniformBuffers(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!skipDraw(data, mode))
+ {
+ error = drawArrays(mode, count, instances, transformFeedbackActive);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (transformFeedbackActive)
+ {
+ markTransformFeedbackUsage(data);
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RendererD3D::generateSwizzles(const gl::Data &data, gl::SamplerType type)
+{
+ gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
+
+ size_t samplerRange = programBinary->getUsedSamplerRange(type);
+
+ for (size_t i = 0; i < samplerRange; i++)
+ {
+ GLenum textureType = programBinary->getSamplerTextureType(type, i);
+ GLint textureUnit = programBinary->getSamplerMapping(type, i, *data.caps);
+ if (textureUnit != -1)
+ {
+ gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType);
+ ASSERT(texture);
+ if (texture->getSamplerState().swizzleRequired())
+ {
+ gl::Error error = generateSwizzle(texture);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RendererD3D::generateSwizzles(const gl::Data &data)
+{
+ gl::Error error = generateSwizzles(data, gl::SAMPLER_VERTEX);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = generateSwizzles(data, gl::SAMPLER_PIXEL);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+// Applies the render target surface, depth stencil surface, viewport rectangle and
+// scissor rectangle to the renderer
+gl::Error RendererD3D::applyRenderTarget(const gl::Data &data, GLenum drawMode, bool ignoreViewport)
+{
+ const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer();
+ ASSERT(framebufferObject && framebufferObject->completeness(data) == GL_FRAMEBUFFER_COMPLETE);
+
+ gl::Error error = applyRenderTarget(framebufferObject);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ float nearZ, farZ;
+ data.state->getDepthRange(&nearZ, &farZ);
+ setViewport(data.state->getViewport(), nearZ, farZ, drawMode,
+ data.state->getRasterizerState().frontFace, ignoreViewport);
+
+ setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled());
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D device
+gl::Error RendererD3D::applyState(const gl::Data &data, GLenum drawMode)
+{
+ const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer();
+ int samples = framebufferObject->getSamples(data);
+
+ gl::RasterizerState rasterizer = data.state->getRasterizerState();
+ rasterizer.pointDrawMode = (drawMode == GL_POINTS);
+ rasterizer.multiSample = (samples != 0);
+
+ gl::Error error = setRasterizerState(rasterizer);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ unsigned int mask = 0;
+ if (data.state->isSampleCoverageEnabled())
+ {
+ GLclampf coverageValue;
+ bool coverageInvert = false;
+ data.state->getSampleCoverageParams(&coverageValue, &coverageInvert);
+ if (coverageValue != 0)
+ {
+ float threshold = 0.5f;
+
+ for (int i = 0; i < samples; ++i)
+ {
+ mask <<= 1;
+
+ if ((i + 1) * coverageValue >= threshold)
+ {
+ threshold += 1.0f;
+ mask |= 1;
+ }
+ }
+ }
+
+ if (coverageInvert)
+ {
+ mask = ~mask;
+ }
+ }
+ else
+ {
+ mask = 0xFFFFFFFF;
+ }
+ error = setBlendState(framebufferObject, data.state->getBlendState(), data.state->getBlendColor(), mask);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = setDepthStencilState(data.state->getDepthStencilState(), data.state->getStencilRef(),
+ data.state->getStencilBackRef(), rasterizer.frontFace == GL_CCW);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+bool RendererD3D::applyTransformFeedbackBuffers(const gl::Data &data)
+{
+ gl::TransformFeedback *curTransformFeedback = data.state->getCurrentTransformFeedback();
+ if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
+ {
+ applyTransformFeedbackBuffers(*data.state);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+// Applies the shaders and shader constants to the Direct3D device
+gl::Error RendererD3D::applyShaders(const gl::Data &data, bool transformFeedbackActive)
+{
+ gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
+
+ gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS];
+ gl::VertexFormat::GetInputLayout(inputLayout, programBinary, *data.state);
+
+ const gl::Framebuffer *fbo = data.state->getDrawFramebuffer();
+
+ gl::Error error = applyShaders(programBinary, inputLayout, fbo, data.state->getRasterizerState().rasterizerDiscard, transformFeedbackActive);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return programBinary->applyUniforms();
+}
+
+// For each Direct3D sampler of either the pixel or vertex stage,
+// looks up the corresponding OpenGL texture image unit and texture type,
+// and sets the texture and its addressing/filtering state (or NULL when inactive).
+gl::Error RendererD3D::applyTextures(const gl::Data &data, gl::SamplerType shaderType,
+ const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount)
+{
+ gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
+
+ size_t samplerRange = programBinary->getUsedSamplerRange(shaderType);
+ for (size_t samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
+ {
+ GLenum textureType = programBinary->getSamplerTextureType(shaderType, samplerIndex);
+ GLint textureUnit = programBinary->getSamplerMapping(shaderType, samplerIndex, *data.caps);
+ if (textureUnit != -1)
+ {
+ gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType);
+ ASSERT(texture);
+ gl::SamplerState sampler = texture->getSamplerState();
+
+ gl::Sampler *samplerObject = data.state->getSampler(textureUnit);
+ if (samplerObject)
+ {
+ samplerObject->getState(&sampler);
+ }
+
+ // TODO: std::binary_search may become unavailable using older versions of GCC
+ if (texture->isSamplerComplete(sampler, *data.textureCaps, *data.extensions, data.clientVersion) &&
+ !std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial()))
+ {
+ gl::Error error = setSamplerState(shaderType, samplerIndex, texture, sampler);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = setTexture(shaderType, samplerIndex, texture);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ else
+ {
+ // Texture is not sampler complete or it is in use by the framebuffer. Bind the incomplete texture.
+ gl::Texture *incompleteTexture = getIncompleteTexture(textureType);
+ gl::Error error = setTexture(shaderType, samplerIndex, incompleteTexture);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ }
+ else
+ {
+ // No texture bound to this slot even though it is used by the shader, bind a NULL texture
+ gl::Error error = setTexture(shaderType, samplerIndex, NULL);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ }
+
+ // Set all the remaining textures to NULL
+ size_t samplerCount = (shaderType == gl::SAMPLER_PIXEL) ? data.caps->maxTextureImageUnits
+ : data.caps->maxVertexTextureImageUnits;
+ for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
+ {
+ gl::Error error = setTexture(shaderType, samplerIndex, NULL);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RendererD3D::applyTextures(const gl::Data &data)
+{
+ FramebufferTextureSerialArray framebufferSerials;
+ size_t framebufferSerialCount = getBoundFramebufferTextureSerials(data, &framebufferSerials);
+
+ gl::Error error = applyTextures(data, gl::SAMPLER_VERTEX, framebufferSerials, framebufferSerialCount);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyTextures(data, gl::SAMPLER_PIXEL, framebufferSerials, framebufferSerialCount);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RendererD3D::applyUniformBuffers(const gl::Data &data)
+{
+ gl::Program *programObject = data.resourceManager->getProgram(data.state->getCurrentProgramId());
+ gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+
+ std::vector<gl::Buffer*> boundBuffers;
+
+ for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++)
+ {
+ GLuint blockBinding = programObject->getUniformBlockBinding(uniformBlockIndex);
+
+ if (data.state->getIndexedUniformBuffer(blockBinding)->id() == 0)
+ {
+ // undefined behaviour
+ return gl::Error(GL_INVALID_OPERATION, "It is undefined behaviour to have a used but unbound uniform buffer.");
+ }
+ else
+ {
+ gl::Buffer *uniformBuffer = data.state->getIndexedUniformBuffer(blockBinding);
+ ASSERT(uniformBuffer);
+ boundBuffers.push_back(uniformBuffer);
+ }
+ }
+
+ return programBinary->applyUniformBuffers(boundBuffers, *data.caps);
+}
+
+bool RendererD3D::skipDraw(const gl::Data &data, GLenum drawMode)
+{
+ if (drawMode == GL_POINTS)
+ {
+ // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
+ // which affects varying interpolation. Since the value of gl_PointSize is
+ // undefined when not written, just skip drawing to avoid unexpected results.
+ if (!data.state->getCurrentProgramBinary()->usesPointSize())
+ {
+ // This is stictly speaking not an error, but developers should be
+ // notified of risking undefined behavior.
+ ERR("Point rendering without writing to gl_PointSize.");
+
+ return true;
+ }
+ }
+ else if (gl::IsTriangleMode(drawMode))
+ {
+ if (data.state->getRasterizerState().cullFace && data.state->getRasterizerState().cullMode == GL_FRONT_AND_BACK)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void RendererD3D::markTransformFeedbackUsage(const gl::Data &data)
+{
+ for (size_t i = 0; i < data.caps->maxTransformFeedbackSeparateAttributes; i++)
+ {
+ gl::Buffer *buffer = data.state->getIndexedTransformFeedbackBuffer(i);
+ if (buffer)
+ {
+ buffer->markTransformFeedbackUsage();
+ }
+ }
+}
+
+size_t RendererD3D::getBoundFramebufferTextureSerials(const gl::Data &data,
+ FramebufferTextureSerialArray *outSerialArray)
+{
+ size_t serialCount = 0;
+
+ const gl::Framebuffer *drawFramebuffer = data.state->getDrawFramebuffer();
+ for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; i++)
+ {
+ gl::FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i);
+ if (attachment && attachment->isTexture())
+ {
+ gl::Texture *texture = attachment->getTexture();
+ (*outSerialArray)[serialCount++] = texture->getTextureSerial();
+ }
+ }
+
+ gl::FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer();
+ if (depthStencilAttachment && depthStencilAttachment->isTexture())
+ {
+ gl::Texture *depthStencilTexture = depthStencilAttachment->getTexture();
+ (*outSerialArray)[serialCount++] = depthStencilTexture->getTextureSerial();
+ }
+
+ std::sort(outSerialArray->begin(), outSerialArray->begin() + serialCount);
+
+ return serialCount;
+}
+
+gl::Texture *RendererD3D::getIncompleteTexture(GLenum type)
+{
+ if (mIncompleteTextures.find(type) == mIncompleteTextures.end())
+ {
+ const GLubyte color[] = { 0, 0, 0, 255 };
+ const gl::PixelUnpackState incompleteUnpackState(1);
+
+ gl::Texture* t = NULL;
+ switch (type)
+ {
+ default:
+ UNREACHABLE();
+ // default falls through to TEXTURE_2D
+
+ case GL_TEXTURE_2D:
+ {
+ gl::Texture2D *incomplete2d = new gl::Texture2D(createTexture(GL_TEXTURE_2D), gl::Texture::INCOMPLETE_TEXTURE_ID);
+ incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+ t = incomplete2d;
+ }
+ break;
+
+ case GL_TEXTURE_CUBE_MAP:
+ {
+ gl::TextureCubeMap *incompleteCube = new gl::TextureCubeMap(createTexture(GL_TEXTURE_CUBE_MAP), gl::Texture::INCOMPLETE_TEXTURE_ID);
+
+ incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+ incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+ incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+ incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+ incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+ incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+
+ t = incompleteCube;
+ }
+ break;
+
+ case GL_TEXTURE_3D:
+ {
+ gl::Texture3D *incomplete3d = new gl::Texture3D(createTexture(GL_TEXTURE_3D), gl::Texture::INCOMPLETE_TEXTURE_ID);
+ incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+
+ t = incomplete3d;
+ }
+ break;
+
+ case GL_TEXTURE_2D_ARRAY:
+ {
+ gl::Texture2DArray *incomplete2darray = new gl::Texture2DArray(createTexture(GL_TEXTURE_2D_ARRAY), gl::Texture::INCOMPLETE_TEXTURE_ID);
+ incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+
+ t = incomplete2darray;
+ }
+ break;
+ }
+
+ mIncompleteTextures[type].set(t);
+ }
+
+ return mIncompleteTextures[type].get();
+}
+
}
diff --git a/src/libGLESv2/renderer/d3d/RendererD3D.h b/src/libGLESv2/renderer/d3d/RendererD3D.h
index 2fb237d..91773f4 100644
--- a/src/libGLESv2/renderer/d3d/RendererD3D.h
+++ b/src/libGLESv2/renderer/d3d/RendererD3D.h
@@ -10,6 +10,10 @@
#define LIBGLESV2_RENDERER_RENDERERD3D_H_
#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/Data.h"
+
+//FIXME(jmadill): std::array is currently prohibited by Chromium style guide
+#include <array>
namespace gl
{
@@ -38,6 +42,15 @@
static RendererD3D *makeRendererD3D(Renderer *renderer);
+ gl::Error drawArrays(const gl::Data &data,
+ GLenum mode, GLint first,
+ GLsizei count, GLsizei instances) override;
+
+ gl::Error drawElements(const gl::Data &data,
+ GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices, GLsizei instances,
+ const RangeUI &indexRange) override;
+
// Direct3D Specific methods
virtual SwapChain *createSwapChain(rx::NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0;
@@ -48,7 +61,7 @@
virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]) = 0;
virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState) = 0;
- virtual gl::Error setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
+ virtual gl::Error setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
unsigned int sampleMask) = 0;
virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
int stencilBackRef, bool frontFaceCCW) = 0;
@@ -57,7 +70,7 @@
virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
bool ignoreViewport) = 0;
- virtual gl::Error applyRenderTarget(gl::Framebuffer *frameBuffer) = 0;
+ virtual gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) = 0;
virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive) = 0;
virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray) = 0;
@@ -130,13 +143,42 @@
virtual VertexBuffer *createVertexBuffer() = 0;
virtual IndexBuffer *createIndexBuffer() = 0;
+ //TODO(jmadill): Should be private or protected
+ gl::Error applyRenderTarget(const gl::Data &data, GLenum drawMode, bool ignoreViewport);
+
protected:
+ virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) = 0;
+ virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
+ gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) = 0;
+
egl::Display *mDisplay;
private:
DISALLOW_COPY_AND_ASSIGN(RendererD3D);
+ //FIXME(jmadill): std::array is currently prohibited by Chromium style guide
+ typedef std::array<unsigned int, gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS> FramebufferTextureSerialArray;
+
+ gl::Error generateSwizzles(const gl::Data &data, gl::SamplerType type);
+ gl::Error generateSwizzles(const gl::Data &data);
+
+ gl::Error applyState(const gl::Data &data, GLenum drawMode);
+ bool applyTransformFeedbackBuffers(const gl::Data &data);
+ gl::Error applyShaders(const gl::Data &data, bool transformFeedbackActive);
+ gl::Error applyTextures(const gl::Data &data, gl::SamplerType shaderType,
+ const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount);
+ gl::Error applyTextures(const gl::Data &data);
+ gl::Error applyUniformBuffers(const gl::Data &data);
+
+ bool skipDraw(const gl::Data &data, GLenum drawMode);
+ void markTransformFeedbackUsage(const gl::Data &data);
+
+ size_t getBoundFramebufferTextureSerials(const gl::Data &data,
+ FramebufferTextureSerialArray *outSerialArray);
+ gl::Texture *getIncompleteTexture(GLenum type);
+
int mCurrentClientVersion;
+ gl::TextureMap mIncompleteTextures;
};
}
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
index 75b5f5e..772bc18 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
@@ -643,7 +643,7 @@
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
+gl::Error Renderer11::setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
unsigned int sampleMask)
{
if (mForceSetBlendState ||
@@ -858,7 +858,7 @@
}
}
-gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
+gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer)
{
// Get the color render buffer and serial
// Also extract the render target dimensions and view
@@ -3275,7 +3275,7 @@
}
}
-void Renderer11::invalidateFramebufferSwizzles(gl::Framebuffer *framebuffer)
+void Renderer11::invalidateFramebufferSwizzles(const gl::Framebuffer *framebuffer)
{
for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
{
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
index 0dfd4e3..dbfc90d 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
@@ -69,8 +69,8 @@
virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]);
virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState);
- virtual gl::Error setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
- unsigned int sampleMask);
+ gl::Error setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
+ unsigned int sampleMask) override;
virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
int stencilBackRef, bool frontFaceCCW);
@@ -79,7 +79,7 @@
bool ignoreViewport);
virtual bool applyPrimitiveType(GLenum mode, GLsizei count);
- virtual gl::Error applyRenderTarget(gl::Framebuffer *frameBuffer);
+ gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override;
virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive);
@@ -227,7 +227,7 @@
void unsetSRVsWithResource(gl::SamplerType shaderType, const ID3D11Resource *resource);
static void invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *attachment, int mipLevel);
- static void invalidateFramebufferSwizzles(gl::Framebuffer *framebuffer);
+ static void invalidateFramebufferSwizzles(const gl::Framebuffer *framebuffer);
HMODULE mD3d11Module;
HMODULE mDxgiModule;
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
index ecfaacb..61ca443 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
@@ -797,7 +797,7 @@
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer9::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
+gl::Error Renderer9::setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
unsigned int sampleMask)
{
bool blendStateChanged = mForceSetBlendState || memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0;
@@ -1193,7 +1193,7 @@
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer)
+gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer)
{
// 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.
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
index 333b57f..c22c9d5 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
@@ -72,8 +72,8 @@
virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]);
virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState);
- virtual gl::Error setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
- unsigned int sampleMask);
+ gl::Error setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
+ unsigned int sampleMask) override;
virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
int stencilBackRef, bool frontFaceCCW);
@@ -81,7 +81,7 @@
virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
bool ignoreViewport);
- virtual gl::Error applyRenderTarget(gl::Framebuffer *frameBuffer);
+ gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override;
virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive);
virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray);