Commit d9e58303 by Jamie Madill

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/226061Tested-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarBrandon Jones <bajones@chromium.org>
parent 4de4fd6e
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
#include <iterator> #include <iterator>
// TODO(jmadill): phase these out // TODO(jmadill): phase these out
#include "libGLESv2/renderer/d3d/IndexDataManager.h"
#include "libGLESv2/renderer/d3d/RendererD3D.h" #include "libGLESv2/renderer/d3d/RendererD3D.h"
namespace gl namespace gl
...@@ -1301,324 +1300,6 @@ bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned ...@@ -1301,324 +1300,6 @@ bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned
return false; 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) Error Context::clear(GLbitfield mask)
{ {
if (mState.isRasterizerDiscardEnabled()) if (mState.isRasterizerDiscardEnabled())
...@@ -1628,7 +1309,11 @@ Error Context::clear(GLbitfield mask) ...@@ -1628,7 +1309,11 @@ Error Context::clear(GLbitfield mask)
ClearParameters clearParams = mState.getClearParameters(mask); 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()) if (error.isError())
{ {
return error; return error;
...@@ -1663,7 +1348,11 @@ Error Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values) ...@@ -1663,7 +1348,11 @@ Error Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values)
clearParams.depthClearValue = values[0]; 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()) if (error.isError())
{ {
return error; return error;
...@@ -1688,7 +1377,11 @@ Error Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int ...@@ -1688,7 +1377,11 @@ Error Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int
clearParams.colorUIClearValue = ColorUI(values[0], values[1], values[2], values[3]); clearParams.colorUIClearValue = ColorUI(values[0], values[1], values[2], values[3]);
clearParams.colorClearType = GL_UNSIGNED_INT; 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()) if (error.isError())
{ {
return error; return error;
...@@ -1723,7 +1416,11 @@ Error Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values) ...@@ -1723,7 +1416,11 @@ Error Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values)
clearParams.stencilClearValue = values[1]; 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()) if (error.isError())
{ {
return error; return error;
...@@ -1746,7 +1443,11 @@ Error Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int ste ...@@ -1746,7 +1443,11 @@ Error Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int ste
clearParams.clearStencil = true; clearParams.clearStencil = true;
clearParams.stencilClearValue = stencil; 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()) if (error.isError())
{ {
return error; return error;
...@@ -1770,164 +1471,14 @@ Error Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, ...@@ -1770,164 +1471,14 @@ Error Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
Error Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances) Error Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
{ {
ASSERT(mState.getCurrentProgramId() != 0); return mRenderer->drawArrays(getData(), mode, first, count, instances);
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);
} }
Error Context::drawElements(GLenum mode, GLsizei count, GLenum type, Error Context::drawElements(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices, GLsizei instances, const GLvoid *indices, GLsizei instances,
const rx::RangeUI &indexRange) const rx::RangeUI &indexRange)
{ {
ASSERT(mState.getCurrentProgramId() != 0); return mRenderer->drawElements(getData(), mode, count, type, indices, instances, indexRange);
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);
} }
// Implements glFlush when block is false, glFinish when block is true // Implements glFlush when block is false, glFinish when block is true
...@@ -2104,95 +1655,6 @@ void Context::detachSampler(GLuint sampler) ...@@ -2104,95 +1655,6 @@ void Context::detachSampler(GLuint sampler)
mState.detachSampler(sampler); 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) void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
{ {
mState.getVertexArray()->setVertexAttribDivisor(index, divisor); mState.getVertexArray()->setVertexAttribDivisor(index, divisor);
...@@ -2325,33 +1787,6 @@ size_t Context::getExtensionStringCount() const ...@@ -2325,33 +1787,6 @@ size_t Context::getExtensionStringCount() const
return mExtensionStrings.size(); 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, Error Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter) GLbitfield mask, GLenum filter)
{ {
......
...@@ -223,19 +223,6 @@ class Context ...@@ -223,19 +223,6 @@ class Context
private: private:
DISALLOW_COPY_AND_ASSIGN(Context); 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 detachBuffer(GLuint buffer);
void detachTexture(GLuint texture); void detachTexture(GLuint texture);
void detachFramebuffer(GLuint framebuffer); void detachFramebuffer(GLuint framebuffer);
...@@ -244,18 +231,9 @@ class Context ...@@ -244,18 +231,9 @@ class Context
void detachTransformFeedback(GLuint transformFeedback); void detachTransformFeedback(GLuint transformFeedback);
void detachSampler(GLuint sampler); 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 initRendererString();
void initExtensionStrings(); void initExtensionStrings();
size_t getBoundFramebufferTextureSerials(FramebufferTextureSerialArray *outSerialArray);
void initCaps(GLuint clientVersion); void initCaps(GLuint clientVersion);
// Caps to use for validation // Caps to use for validation
......
...@@ -295,9 +295,9 @@ Texture *ResourceManager::getTexture(unsigned int handle) ...@@ -295,9 +295,9 @@ Texture *ResourceManager::getTexture(unsigned int handle)
} }
} }
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()) if (program == mProgramMap.end())
{ {
......
...@@ -60,7 +60,7 @@ class ResourceManager ...@@ -60,7 +60,7 @@ class ResourceManager
Buffer *getBuffer(GLuint handle); Buffer *getBuffer(GLuint handle);
Shader *getShader(GLuint handle); Shader *getShader(GLuint handle);
Program *getProgram(GLuint handle); Program *getProgram(GLuint handle) const;
Texture *getTexture(GLuint handle); Texture *getTexture(GLuint handle);
Renderbuffer *getRenderbuffer(GLuint handle); Renderbuffer *getRenderbuffer(GLuint handle);
Sampler *getSampler(GLuint handle); Sampler *getSampler(GLuint handle);
......
...@@ -486,7 +486,7 @@ void State::setSampleCoverageParams(GLclampf value, bool invert) ...@@ -486,7 +486,7 @@ void State::setSampleCoverageParams(GLclampf value, bool invert)
mSampleCoverageInvert = invert; mSampleCoverageInvert = invert;
} }
void State::getSampleCoverageParams(GLclampf *value, bool *invert) void State::getSampleCoverageParams(GLclampf *value, bool *invert) const
{ {
ASSERT(value != NULL && invert != NULL); ASSERT(value != NULL && invert != NULL);
......
...@@ -101,7 +101,7 @@ class State ...@@ -101,7 +101,7 @@ class State
bool isSampleCoverageEnabled() const; bool isSampleCoverageEnabled() const;
void setSampleCoverage(bool enabled); void setSampleCoverage(bool enabled);
void setSampleCoverageParams(GLclampf value, bool invert); void setSampleCoverageParams(GLclampf value, bool invert);
void getSampleCoverageParams(GLclampf *value, bool *invert); void getSampleCoverageParams(GLclampf *value, bool *invert) const;
// Scissor test state toggle & query // Scissor test state toggle & query
bool isScissorTestEnabled() const; bool isScissorTestEnabled() const;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "libGLESv2/angletypes.h" #include "libGLESv2/angletypes.h"
#include "libGLESv2/renderer/Workarounds.h" #include "libGLESv2/renderer/Workarounds.h"
#include "common/NativeWindow.h" #include "common/NativeWindow.h"
#include "common/mathutil.h"
#include <cstdint> #include <cstdint>
...@@ -36,6 +37,7 @@ namespace gl ...@@ -36,6 +37,7 @@ namespace gl
{ {
class Buffer; class Buffer;
class Framebuffer; class Framebuffer;
struct Data;
} }
namespace rx namespace rx
...@@ -77,15 +79,18 @@ class Renderer ...@@ -77,15 +79,18 @@ class Renderer
virtual gl::Error sync(bool block) = 0; 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 // 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 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, 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; 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 getShareHandleSupport() const = 0;
virtual bool getPostSubBufferSupport() const = 0; virtual bool getPostSubBufferSupport() const = 0;
......
...@@ -8,6 +8,14 @@ ...@@ -8,6 +8,14 @@
#include "libGLESv2/renderer/d3d/RendererD3D.h" #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 namespace rx
{ {
...@@ -19,6 +27,11 @@ RendererD3D::RendererD3D(egl::Display *display) ...@@ -19,6 +27,11 @@ RendererD3D::RendererD3D(egl::Display *display)
RendererD3D::~RendererD3D() RendererD3D::~RendererD3D()
{ {
for (auto &incompleteTexture : mIncompleteTextures)
{
incompleteTexture.second.set(NULL);
}
mIncompleteTextures.clear();
} }
// static // static
...@@ -28,4 +41,581 @@ RendererD3D *RendererD3D::makeRendererD3D(Renderer *renderer) ...@@ -28,4 +41,581 @@ RendererD3D *RendererD3D::makeRendererD3D(Renderer *renderer)
return static_cast<RendererD3D*>(renderer); 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();
}
} }
...@@ -10,6 +10,10 @@ ...@@ -10,6 +10,10 @@
#define LIBGLESV2_RENDERER_RENDERERD3D_H_ #define LIBGLESV2_RENDERER_RENDERERD3D_H_
#include "libGLESv2/renderer/Renderer.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 namespace gl
{ {
...@@ -38,6 +42,15 @@ class RendererD3D : public Renderer ...@@ -38,6 +42,15 @@ class RendererD3D : public Renderer
static RendererD3D *makeRendererD3D(Renderer *renderer); 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 // Direct3D Specific methods
virtual SwapChain *createSwapChain(rx::NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0; virtual SwapChain *createSwapChain(rx::NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0;
...@@ -48,7 +61,7 @@ class RendererD3D : public Renderer ...@@ -48,7 +61,7 @@ class RendererD3D : public Renderer
virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]) = 0; 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 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; unsigned int sampleMask) = 0;
virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
int stencilBackRef, bool frontFaceCCW) = 0; int stencilBackRef, bool frontFaceCCW) = 0;
...@@ -57,7 +70,7 @@ class RendererD3D : public Renderer ...@@ -57,7 +70,7 @@ class RendererD3D : public Renderer
virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
bool ignoreViewport) = 0; 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, virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive) = 0; bool rasterizerDiscard, bool transformFeedbackActive) = 0;
virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray) = 0; virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray) = 0;
...@@ -130,13 +143,42 @@ class RendererD3D : public Renderer ...@@ -130,13 +143,42 @@ class RendererD3D : public Renderer
virtual VertexBuffer *createVertexBuffer() = 0; virtual VertexBuffer *createVertexBuffer() = 0;
virtual IndexBuffer *createIndexBuffer() = 0; virtual IndexBuffer *createIndexBuffer() = 0;
//TODO(jmadill): Should be private or protected
gl::Error applyRenderTarget(const gl::Data &data, GLenum drawMode, bool ignoreViewport);
protected: 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; egl::Display *mDisplay;
private: private:
DISALLOW_COPY_AND_ASSIGN(RendererD3D); 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; int mCurrentClientVersion;
gl::TextureMap mIncompleteTextures;
}; };
} }
......
...@@ -643,7 +643,7 @@ gl::Error Renderer11::setRasterizerState(const gl::RasterizerState &rasterState) ...@@ -643,7 +643,7 @@ gl::Error Renderer11::setRasterizerState(const gl::RasterizerState &rasterState)
return gl::Error(GL_NO_ERROR); 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) unsigned int sampleMask)
{ {
if (mForceSetBlendState || if (mForceSetBlendState ||
...@@ -858,7 +858,7 @@ void Renderer11::unsetSRVsWithResource(gl::SamplerType samplerType, const ID3D11 ...@@ -858,7 +858,7 @@ void Renderer11::unsetSRVsWithResource(gl::SamplerType samplerType, const ID3D11
} }
} }
gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer)
{ {
// Get the color render buffer and serial // Get the color render buffer and serial
// Also extract the render target dimensions and view // Also extract the render target dimensions and view
...@@ -3275,7 +3275,7 @@ void Renderer11::invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *atta ...@@ -3275,7 +3275,7 @@ void Renderer11::invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *atta
} }
} }
void Renderer11::invalidateFramebufferSwizzles(gl::Framebuffer *framebuffer) void Renderer11::invalidateFramebufferSwizzles(const gl::Framebuffer *framebuffer)
{ {
for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
{ {
......
...@@ -69,8 +69,8 @@ class Renderer11 : public RendererD3D ...@@ -69,8 +69,8 @@ class Renderer11 : public RendererD3D
virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]); virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]);
virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState); virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState);
virtual gl::Error setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, gl::Error setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
unsigned int sampleMask); unsigned int sampleMask) override;
virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
int stencilBackRef, bool frontFaceCCW); int stencilBackRef, bool frontFaceCCW);
...@@ -79,7 +79,7 @@ class Renderer11 : public RendererD3D ...@@ -79,7 +79,7 @@ class Renderer11 : public RendererD3D
bool ignoreViewport); bool ignoreViewport);
virtual bool applyPrimitiveType(GLenum mode, GLsizei count); 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, virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive); bool rasterizerDiscard, bool transformFeedbackActive);
...@@ -227,7 +227,7 @@ class Renderer11 : public RendererD3D ...@@ -227,7 +227,7 @@ class Renderer11 : public RendererD3D
void unsetSRVsWithResource(gl::SamplerType shaderType, const ID3D11Resource *resource); void unsetSRVsWithResource(gl::SamplerType shaderType, const ID3D11Resource *resource);
static void invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *attachment, int mipLevel); static void invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *attachment, int mipLevel);
static void invalidateFramebufferSwizzles(gl::Framebuffer *framebuffer); static void invalidateFramebufferSwizzles(const gl::Framebuffer *framebuffer);
HMODULE mD3d11Module; HMODULE mD3d11Module;
HMODULE mDxgiModule; HMODULE mDxgiModule;
......
...@@ -797,7 +797,7 @@ gl::Error Renderer9::setRasterizerState(const gl::RasterizerState &rasterState) ...@@ -797,7 +797,7 @@ gl::Error Renderer9::setRasterizerState(const gl::RasterizerState &rasterState)
return gl::Error(GL_NO_ERROR); 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) unsigned int sampleMask)
{ {
bool blendStateChanged = mForceSetBlendState || memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0; bool blendStateChanged = mForceSetBlendState || memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0;
...@@ -1193,7 +1193,7 @@ gl::Error Renderer9::getNullColorbuffer(gl::FramebufferAttachment *depthbuffer, ...@@ -1193,7 +1193,7 @@ gl::Error Renderer9::getNullColorbuffer(gl::FramebufferAttachment *depthbuffer,
return gl::Error(GL_NO_ERROR); 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 // 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. // to keep the D3D runtime happy. This should only be possible if depth texturing.
......
...@@ -72,8 +72,8 @@ class Renderer9 : public RendererD3D ...@@ -72,8 +72,8 @@ class Renderer9 : public RendererD3D
virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]); virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]);
virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState); virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState);
virtual gl::Error setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, gl::Error setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
unsigned int sampleMask); unsigned int sampleMask) override;
virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
int stencilBackRef, bool frontFaceCCW); int stencilBackRef, bool frontFaceCCW);
...@@ -81,7 +81,7 @@ class Renderer9 : public RendererD3D ...@@ -81,7 +81,7 @@ class Renderer9 : public RendererD3D
virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
bool ignoreViewport); 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, virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive); bool rasterizerDiscard, bool transformFeedbackActive);
virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray); virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment