summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
diff options
context:
space:
mode:
authorAndrew Knight <andrew.knight@digia.com>2014-09-25 13:22:55 +0300
committerAndrew Knight <andrew.knight@digia.com>2014-09-29 16:09:29 +0200
commit311157c3c6849e8efccd88f7594bb34c570a6780 (patch)
treea50c252b638488326529c0e69aa05e42abce7462 /src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
parent04d3a89e20d49a3b5015b071bfdedc81973b090c (diff)
ANGLE: Upgrade to 2.1~abce76206141
Upgrade to address issues discovered since the last upgrade. Patch notes: 0000-General-fixes-for-ANGLE-2.1.patch added removal of the unused third-party tracing functions 0003-Fix-compilation-with-MinGW-gcc-64-bit.patch removed as it is no longer needed 0011-ANGLE-Fix-compilation-error-on-MinGW-caused-by-trace.patch removed as it is no longer needed 0016-ANGLE-Fix-compilation-with-MinGW-D3D11.patch now supports MinGW 64-bit [ChangeLog][Third-party libraries] ANGLE updated to 2.1~f8602ad91e4f Task-number: QTBUG-40649 Task-number: QTBUG-40658 Task-number: QTBUG-41031 Task-number: QTBUG-41081 Task-number: QTBUG-41308 Task-number: QTBUG-41563 Change-Id: I9f776c8d5cb94ddb12d608a8d5630bfc54437bea Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com> Reviewed-by: Oliver Wolff <oliver.wolff@digia.com> Reviewed-by: Kai Koehne <kai.koehne@digia.com>
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp')
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp822
1 files changed, 379 insertions, 443 deletions
diff --git a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
index 9fad5fbfc5..3f6d9e0ef9 100644
--- a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
//
// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -11,33 +10,34 @@
#include "libGLESv2/BinaryStream.h"
#include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
#include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/renderer/ShaderExecutable.h"
#include "common/debug.h"
#include "common/version.h"
#include "common/utilities.h"
+#include "common/platform.h"
#include "libGLESv2/main.h"
#include "libGLESv2/Shader.h"
#include "libGLESv2/Program.h"
+#include "libGLESv2/renderer/ProgramImpl.h"
#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/d3d/DynamicHLSL.h"
+#include "libGLESv2/renderer/d3d/ShaderD3D.h"
#include "libGLESv2/renderer/d3d/VertexDataManager.h"
#include "libGLESv2/Context.h"
#include "libGLESv2/Buffer.h"
-#include "libGLESv2/DynamicHLSL.h"
#include "common/blocklayout.h"
-#undef near
-#undef far
-
namespace gl
{
namespace
{
-TextureType GetTextureType(GLenum samplerType)
+GLenum GetTextureType(GLenum samplerType)
{
switch (samplerType)
{
@@ -45,26 +45,26 @@ TextureType GetTextureType(GLenum samplerType)
case GL_INT_SAMPLER_2D:
case GL_UNSIGNED_INT_SAMPLER_2D:
case GL_SAMPLER_2D_SHADOW:
- return TEXTURE_2D;
+ return GL_TEXTURE_2D;
case GL_SAMPLER_3D:
case GL_INT_SAMPLER_3D:
case GL_UNSIGNED_INT_SAMPLER_3D:
- return TEXTURE_3D;
+ return GL_TEXTURE_3D;
case GL_SAMPLER_CUBE:
case GL_SAMPLER_CUBE_SHADOW:
- return TEXTURE_CUBE;
+ return GL_TEXTURE_CUBE_MAP;
case GL_INT_SAMPLER_CUBE:
case GL_UNSIGNED_INT_SAMPLER_CUBE:
- return TEXTURE_CUBE;
+ return GL_TEXTURE_CUBE_MAP;
case GL_SAMPLER_2D_ARRAY:
case GL_INT_SAMPLER_2D_ARRAY:
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
case GL_SAMPLER_2D_ARRAY_SHADOW:
- return TEXTURE_2D_ARRAY;
+ return GL_TEXTURE_2D_ARRAY;
default: UNREACHABLE();
}
- return TEXTURE_2D;
+ return GL_TEXTURE_2D;
}
unsigned int ParseAndStripArrayIndex(std::string* name)
@@ -83,7 +83,7 @@ unsigned int ParseAndStripArrayIndex(std::string* name)
return subscript;
}
-void GetInputLayoutFromShader(const std::vector<sh::Attribute> &shaderAttributes, VertexFormat inputLayout[MAX_VERTEX_ATTRIBS])
+void GetDefaultInputLayoutFromShader(const std::vector<sh::Attribute> &shaderAttributes, VertexFormat inputLayout[MAX_VERTEX_ATTRIBS])
{
size_t layoutIndex = 0;
for (size_t attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
@@ -109,6 +109,26 @@ void GetInputLayoutFromShader(const std::vector<sh::Attribute> &shaderAttributes
}
}
+std::vector<GLenum> GetDefaultOutputLayoutFromShader(const std::vector<rx::PixelShaderOutputVariable> &shaderOutputVars)
+{
+ std::vector<GLenum> defaultPixelOutput(1);
+
+ ASSERT(!shaderOutputVars.empty());
+ defaultPixelOutput[0] = GL_COLOR_ATTACHMENT0 + shaderOutputVars[0].outputIndex;
+
+ return defaultPixelOutput;
+}
+
+bool IsRowMajorLayout(const sh::InterfaceBlockField &var)
+{
+ return var.isRowMajorLayout;
+}
+
+bool IsRowMajorLayout(const sh::ShaderVariable &var)
+{
+ return false;
+}
+
}
VariableLocation::VariableLocation(const std::string &name, unsigned int element, unsigned int index)
@@ -169,45 +189,30 @@ LinkedVarying::LinkedVarying(const std::string &name, GLenum type, GLsizei size,
unsigned int ProgramBinary::mCurrentSerial = 1;
-ProgramBinary::ProgramBinary(rx::Renderer *renderer)
+ProgramBinary::ProgramBinary(rx::ProgramImpl *impl)
: RefCountObject(0),
- mRenderer(renderer),
- mDynamicHLSL(NULL),
- mVertexWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE),
- mPixelWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE),
+ mProgram(impl),
mGeometryExecutable(NULL),
mUsedVertexSamplerRange(0),
mUsedPixelSamplerRange(0),
mUsesPointSize(false),
mShaderVersion(100),
mDirtySamplerMapping(true),
- mVertexUniformStorage(NULL),
- mFragmentUniformStorage(NULL),
mValidated(false),
mSerial(issueSerial())
{
+ ASSERT(impl);
+
for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
{
mSemanticIndex[index] = -1;
}
-
- for (int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++)
- {
- mSamplersPS[index].active = false;
- }
-
- for (int index = 0; index < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; index++)
- {
- mSamplersVS[index].active = false;
- }
-
- mDynamicHLSL = new DynamicHLSL(renderer);
}
ProgramBinary::~ProgramBinary()
{
reset();
- SafeDelete(mDynamicHLSL);
+ SafeDelete(mProgram);
}
unsigned int ProgramBinary::getSerial() const
@@ -227,17 +232,21 @@ unsigned int ProgramBinary::issueSerial()
rx::ShaderExecutable *ProgramBinary::getPixelExecutableForFramebuffer(const Framebuffer *fbo)
{
- std::vector<GLenum> outputs(IMPLEMENTATION_MAX_DRAW_BUFFERS);
- for (size_t outputIndex = 0; outputIndex < IMPLEMENTATION_MAX_DRAW_BUFFERS; outputIndex++)
+ std::vector<GLenum> outputs;
+
+ const gl::ColorbufferInfo &colorbuffers = fbo->getColorbuffersForRender();
+
+ for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
{
- if (fbo->getColorbuffer(outputIndex) != NULL)
+ const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment];
+
+ if (colorbuffer)
{
- // Always output floats for now
- outputs[outputIndex] = GL_FLOAT;
+ outputs.push_back(colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0 : colorbuffer->getBinding());
}
else
{
- outputs[outputIndex] = GL_NONE;
+ outputs.push_back(GL_NONE);
}
}
@@ -254,15 +263,9 @@ rx::ShaderExecutable *ProgramBinary::getPixelExecutableForOutputLayout(const std
}
}
- std::string finalPixelHLSL = mDynamicHLSL->generatePixelShaderForOutputSignature(mPixelHLSL, mPixelShaderKey, mUsesFragDepth,
- outputSignature);
-
- // Generate new pixel executable
InfoLog tempInfoLog;
- rx::ShaderExecutable *pixelExecutable = mRenderer->compileToExecutable(tempInfoLog, finalPixelHLSL.c_str(), rx::SHADER_PIXEL,
- mTransformFeedbackLinkedVaryings,
- (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
- mPixelWorkarounds);
+ rx::ShaderExecutable *pixelExecutable = mProgram->getPixelExecutableForOutputLayout(tempInfoLog, outputSignature,
+ mTransformFeedbackLinkedVaryings, (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
if (!pixelExecutable)
{
@@ -281,7 +284,7 @@ rx::ShaderExecutable *ProgramBinary::getPixelExecutableForOutputLayout(const std
rx::ShaderExecutable *ProgramBinary::getVertexExecutableForInputLayout(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS])
{
GLenum signature[MAX_VERTEX_ATTRIBS];
- mDynamicHLSL->getInputLayoutSignature(inputLayout, signature);
+ mProgram->getDynamicHLSL()->getInputLayoutSignature(inputLayout, signature);
for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++)
{
@@ -291,16 +294,9 @@ rx::ShaderExecutable *ProgramBinary::getVertexExecutableForInputLayout(const Ver
}
}
- // Generate new dynamic layout with attribute conversions
- std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(mVertexHLSL, inputLayout, mShaderAttributes);
-
- // Generate new vertex executable
InfoLog tempInfoLog;
- rx::ShaderExecutable *vertexExecutable = mRenderer->compileToExecutable(tempInfoLog, finalVertexHLSL.c_str(),
- rx::SHADER_VERTEX,
- mTransformFeedbackLinkedVaryings,
- (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
- mVertexWorkarounds);
+ rx::ShaderExecutable *vertexExecutable = mProgram->getVertexExecutableForInputLayout(tempInfoLog, inputLayout, mShaderAttributes,
+ mTransformFeedbackLinkedVaryings, (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
if (!vertexExecutable)
{
@@ -366,7 +362,7 @@ bool ProgramBinary::usesPointSize() const
bool ProgramBinary::usesPointSpriteEmulation() const
{
- return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4;
+ return mUsesPointSize && mProgram->getRenderer()->getMajorShaderModel() >= 4;
}
bool ProgramBinary::usesGeometryShader() const
@@ -374,26 +370,22 @@ bool ProgramBinary::usesGeometryShader() const
return usesPointSpriteEmulation();
}
-// Returns the index of the texture image unit (0-19) corresponding to a Direct3D 9 sampler
-// index (0-15 for the pixel shader and 0-3 for the vertex shader).
-GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex)
+GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps)
{
GLint logicalTextureUnit = -1;
switch (type)
{
case SAMPLER_PIXEL:
- ASSERT(samplerIndex < ArraySize(mSamplersPS));
-
- if (mSamplersPS[samplerIndex].active)
+ ASSERT(samplerIndex < caps.maxTextureImageUnits);
+ if (samplerIndex < mSamplersPS.size() && mSamplersPS[samplerIndex].active)
{
logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit;
}
break;
case SAMPLER_VERTEX:
- ASSERT(samplerIndex < ArraySize(mSamplersVS));
-
- if (mSamplersVS[samplerIndex].active)
+ ASSERT(samplerIndex < caps.maxVertexTextureImageUnits);
+ if (samplerIndex < mSamplersVS.size() && mSamplersVS[samplerIndex].active)
{
logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit;
}
@@ -401,7 +393,7 @@ GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerInd
default: UNREACHABLE();
}
- if (logicalTextureUnit >= 0 && logicalTextureUnit < (GLint)mRenderer->getMaxCombinedTextureImageUnits())
+ if (logicalTextureUnit >= 0 && logicalTextureUnit < static_cast<GLint>(caps.maxCombinedTextureImageUnits))
{
return logicalTextureUnit;
}
@@ -411,22 +403,22 @@ GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerInd
// Returns the texture type for a given Direct3D 9 sampler type and
// index (0-15 for the pixel shader and 0-3 for the vertex shader).
-TextureType ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
+GLenum ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
{
switch (type)
{
case SAMPLER_PIXEL:
- ASSERT(samplerIndex < ArraySize(mSamplersPS));
+ ASSERT(samplerIndex < mSamplersPS.size());
ASSERT(mSamplersPS[samplerIndex].active);
return mSamplersPS[samplerIndex].textureType;
case SAMPLER_VERTEX:
- ASSERT(samplerIndex < ArraySize(mSamplersVS));
+ ASSERT(samplerIndex < mSamplersVS.size());
ASSERT(mSamplersVS[samplerIndex].active);
return mSamplersVS[samplerIndex].textureType;
default: UNREACHABLE();
}
- return TEXTURE_2D;
+ return GL_TEXTURE_2D;
}
GLint ProgramBinary::getUniformLocation(std::string name)
@@ -562,38 +554,64 @@ void ProgramBinary::setUniform(GLint location, GLsizei count, const T* v, GLenum
if (targetUniform->type == targetUniformType)
{
- T *target = (T*)targetUniform->data + mUniformIndex[location].element * 4;
+ T *target = reinterpret_cast<T*>(targetUniform->data) + mUniformIndex[location].element * 4;
for (int i = 0; i < count; i++)
{
+ T *dest = target + (i * 4);
+ const T *source = v + (i * components);
+
for (int c = 0; c < components; c++)
{
- SetIfDirty(target + c, v[c], &targetUniform->dirty);
+ SetIfDirty(dest + c, source[c], &targetUniform->dirty);
}
for (int c = components; c < 4; c++)
{
- SetIfDirty(target + c, T(0), &targetUniform->dirty);
+ SetIfDirty(dest + c, T(0), &targetUniform->dirty);
}
- target += 4;
- v += components;
}
}
else if (targetUniform->type == targetBoolType)
{
- GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
+ GLint *boolParams = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4;
for (int i = 0; i < count; i++)
{
+ GLint *dest = boolParams + (i * 4);
+ const T *source = v + (i * components);
+
for (int c = 0; c < components; c++)
{
- SetIfDirty(boolParams + c, (v[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE, &targetUniform->dirty);
+ SetIfDirty(dest + c, (source[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE, &targetUniform->dirty);
}
for (int c = components; c < 4; c++)
{
- SetIfDirty(boolParams + c, GL_FALSE, &targetUniform->dirty);
+ SetIfDirty(dest + c, GL_FALSE, &targetUniform->dirty);
}
- boolParams += 4;
- v += components;
+ }
+ }
+ else if (IsSampler(targetUniform->type))
+ {
+ ASSERT(targetUniformType == GL_INT);
+
+ GLint *target = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4;
+
+ bool wasDirty = targetUniform->dirty;
+
+ for (int i = 0; i < count; i++)
+ {
+ GLint *dest = target + (i * 4);
+ const GLint *source = reinterpret_cast<const GLint*>(v) + (i * components);
+
+ SetIfDirty(dest + 0, source[0], &targetUniform->dirty);
+ SetIfDirty(dest + 1, 0, &targetUniform->dirty);
+ SetIfDirty(dest + 2, 0, &targetUniform->dirty);
+ SetIfDirty(dest + 3, 0, &targetUniform->dirty);
+ }
+
+ if (!wasDirty && targetUniform->dirty)
+ {
+ mDirtySamplerMapping = true;
}
}
else UNREACHABLE();
@@ -761,48 +779,7 @@ void ProgramBinary::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboole
void ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v)
{
- LinkedUniform *targetUniform = mUniforms[mUniformIndex[location].index];
-
- int elementCount = targetUniform->elementCount();
-
- count = std::min(elementCount - (int)mUniformIndex[location].element, count);
-
- if (targetUniform->type == GL_INT || IsSampler(targetUniform->type))
- {
- GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
-
- for (int i = 0; i < count; i++)
- {
- SetIfDirty(target + 0, v[0], &targetUniform->dirty);
- SetIfDirty(target + 1, 0, &targetUniform->dirty);
- SetIfDirty(target + 2, 0, &targetUniform->dirty);
- SetIfDirty(target + 3, 0, &targetUniform->dirty);
- target += 4;
- v += 1;
- }
- }
- else if (targetUniform->type == GL_BOOL)
- {
- GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
-
- for (int i = 0; i < count; i++)
- {
- SetIfDirty(boolParams + 0, (v[0] == 0) ? GL_FALSE : GL_TRUE, &targetUniform->dirty);
- SetIfDirty(boolParams + 1, GL_FALSE, &targetUniform->dirty);
- SetIfDirty(boolParams + 2, GL_FALSE, &targetUniform->dirty);
- SetIfDirty(boolParams + 3, GL_FALSE, &targetUniform->dirty);
- boolParams += 4;
- v += 1;
- }
- }
- else UNREACHABLE();
-
- // Set a special flag if we change a sampler uniform
- if (IsSampler(targetUniform->type) &&
- (memcmp(targetUniform->data, v, sizeof(GLint)) != 0))
- {
- mDirtySamplerMapping = true;
- }
+ setUniform(location, count, v, GL_INT);
}
void ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v)
@@ -841,20 +818,10 @@ void ProgramBinary::setUniform4uiv(GLint location, GLsizei count, const GLuint *
}
template <typename T>
-bool ProgramBinary::getUniformv(GLint location, GLsizei *bufSize, T *params, GLenum uniformType)
+void ProgramBinary::getUniformv(GLint location, T *params, GLenum uniformType)
{
LinkedUniform *targetUniform = mUniforms[mUniformIndex[location].index];
- // sized queries -- ensure the provided buffer is large enough
- if (bufSize)
- {
- int requiredBytes = VariableExternalSize(targetUniform->type);
- if (*bufSize < requiredBytes)
- {
- return false;
- }
- }
-
if (IsMatrixType(targetUniform->type))
{
const int rows = VariableRowCount(targetUniform->type);
@@ -919,23 +886,21 @@ bool ProgramBinary::getUniformv(GLint location, GLsizei *bufSize, T *params, GLe
default: UNREACHABLE();
}
}
-
- return true;
}
-bool ProgramBinary::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params)
+void ProgramBinary::getUniformfv(GLint location, GLfloat *params)
{
- return getUniformv(location, bufSize, params, GL_FLOAT);
+ getUniformv(location, params, GL_FLOAT);
}
-bool ProgramBinary::getUniformiv(GLint location, GLsizei *bufSize, GLint *params)
+void ProgramBinary::getUniformiv(GLint location, GLint *params)
{
- return getUniformv(location, bufSize, params, GL_INT);
+ getUniformv(location, params, GL_INT);
}
-bool ProgramBinary::getUniformuiv(GLint location, GLsizei *bufSize, GLuint *params)
+void ProgramBinary::getUniformuiv(GLint location, GLuint *params)
{
- return getUniformv(location, bufSize, params, GL_UNSIGNED_INT);
+ getUniformv(location, params, GL_UNSIGNED_INT);
}
void ProgramBinary::dirtyAllUniforms()
@@ -976,7 +941,7 @@ void ProgramBinary::updateSamplerMapping()
{
unsigned int samplerIndex = firstIndex + i;
- if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
+ if (samplerIndex < mSamplersPS.size())
{
ASSERT(mSamplersPS[samplerIndex].active);
mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0];
@@ -992,7 +957,7 @@ void ProgramBinary::updateSamplerMapping()
{
unsigned int samplerIndex = firstIndex + i;
- if (samplerIndex < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS)
+ if (samplerIndex < mSamplersVS.size())
{
ASSERT(mSamplersVS[samplerIndex].active);
mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0];
@@ -1005,25 +970,31 @@ void ProgramBinary::updateSamplerMapping()
}
// Applies all the uniforms set for this program object to the renderer
-void ProgramBinary::applyUniforms()
+Error ProgramBinary::applyUniforms()
{
updateSamplerMapping();
- mRenderer->applyUniforms(*this);
+ Error error = mProgram->getRenderer()->applyUniforms(*this);
+ if (error.isError())
+ {
+ return error;
+ }
for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
{
mUniforms[uniformIndex]->dirty = false;
}
+
+ return gl::Error(GL_NO_ERROR);
}
-bool ProgramBinary::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers)
+Error ProgramBinary::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const Caps &caps)
{
const gl::Buffer *vertexUniformBuffers[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS] = {NULL};
const gl::Buffer *fragmentUniformBuffers[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS] = {NULL};
- const unsigned int reservedBuffersInVS = mRenderer->getReservedVertexUniformBuffers();
- const unsigned int reservedBuffersInFS = mRenderer->getReservedFragmentUniformBuffers();
+ const unsigned int reservedBuffersInVS = mProgram->getRenderer()->getReservedVertexUniformBuffers();
+ const unsigned int reservedBuffersInFS = mProgram->getRenderer()->getReservedFragmentUniformBuffers();
ASSERT(boundBuffers.size() == mUniformBlocks.size());
@@ -1037,16 +1008,20 @@ bool ProgramBinary::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuff
if (uniformBuffer->getSize() < uniformBlock->dataSize)
{
// undefined behaviour
- return false;
+ return gl::Error(GL_INVALID_OPERATION, "It is undefined behaviour to use a uniform buffer that is too small.");
}
- ASSERT(uniformBlock->isReferencedByVertexShader() || uniformBlock->isReferencedByFragmentShader());
+ // Unnecessary to apply an unreferenced standard or shared UBO
+ if (!uniformBlock->isReferencedByVertexShader() && !uniformBlock->isReferencedByFragmentShader())
+ {
+ continue;
+ }
if (uniformBlock->isReferencedByVertexShader())
{
unsigned int registerIndex = uniformBlock->vsRegisterIndex - reservedBuffersInVS;
ASSERT(vertexUniformBuffers[registerIndex] == NULL);
- ASSERT(registerIndex < mRenderer->getMaxVertexShaderUniformBuffers());
+ ASSERT(registerIndex < caps.maxVertexUniformBlocks);
vertexUniformBuffers[registerIndex] = uniformBuffer;
}
@@ -1054,15 +1029,15 @@ bool ProgramBinary::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuff
{
unsigned int registerIndex = uniformBlock->psRegisterIndex - reservedBuffersInFS;
ASSERT(fragmentUniformBuffers[registerIndex] == NULL);
- ASSERT(registerIndex < mRenderer->getMaxFragmentShaderUniformBuffers());
+ ASSERT(registerIndex < caps.maxFragmentUniformBlocks);
fragmentUniformBuffers[registerIndex] = uniformBuffer;
}
}
- return mRenderer->setUniformBuffers(vertexUniformBuffers, fragmentUniformBuffers);
+ return mProgram->getRenderer()->setUniformBuffers(vertexUniformBuffers, fragmentUniformBuffers);
}
-bool ProgramBinary::linkVaryings(InfoLog &infoLog, FragmentShader *fragmentShader, VertexShader *vertexShader)
+bool ProgramBinary::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader)
{
std::vector<PackedVarying> &fragmentVaryings = fragmentShader->getVaryings();
std::vector<PackedVarying> &vertexVaryings = vertexShader->getVaryings();
@@ -1072,24 +1047,32 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, FragmentShader *fragmentShade
PackedVarying *input = &fragmentVaryings[fragVaryingIndex];
bool matched = false;
+ // Built-in varyings obey special rules
+ if (input->isBuiltIn())
+ {
+ continue;
+ }
+
for (size_t vertVaryingIndex = 0; vertVaryingIndex < vertexVaryings.size(); vertVaryingIndex++)
{
PackedVarying *output = &vertexVaryings[vertVaryingIndex];
if (output->name == input->name)
{
- if (!linkValidateVariables(infoLog, output->name, *input, *output))
+ if (!linkValidateVaryings(infoLog, output->name, *input, *output))
{
return false;
}
output->registerIndex = input->registerIndex;
+ output->columnIndex = input->columnIndex;
matched = true;
break;
}
}
- if (!matched)
+ // We permit unmatched, unreferenced varyings
+ if (!matched && input->staticUse)
{
infoLog.append("Fragment varying %s does not match any vertex varying", input->name.c_str());
return false;
@@ -1099,17 +1082,19 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, FragmentShader *fragmentShade
return true;
}
-bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
+bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length)
{
#ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD
return false;
#else
+ ASSERT(binaryFormat == mProgram->getBinaryFormat());
+
reset();
BinaryInputStream stream(binary, length);
- int format = stream.readInt<int>();
- if (format != GL_PROGRAM_BINARY_ANGLE)
+ GLenum format = stream.readInt<GLenum>();
+ if (format != mProgram->getBinaryFormat())
{
infoLog.append("Invalid program binary format.");
return false;
@@ -1149,18 +1134,23 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
initAttributesByLayout();
- for (unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i)
+ const unsigned int psSamplerCount = stream.readInt<unsigned int>();
+ for (unsigned int i = 0; i < psSamplerCount; ++i)
{
- stream.readBool(&mSamplersPS[i].active);
- stream.readInt(&mSamplersPS[i].logicalTextureUnit);
- stream.readInt(&mSamplersPS[i].textureType);
+ Sampler sampler;
+ stream.readBool(&sampler.active);
+ stream.readInt(&sampler.logicalTextureUnit);
+ stream.readInt(&sampler.textureType);
+ mSamplersPS.push_back(sampler);
}
-
- for (unsigned int i = 0; i < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++i)
+ const unsigned int vsSamplerCount = stream.readInt<unsigned int>();
+ for (unsigned int i = 0; i < vsSamplerCount; ++i)
{
- stream.readBool(&mSamplersVS[i].active);
- stream.readInt(&mSamplersVS[i].logicalTextureUnit);
- stream.readInt(&mSamplersVS[i].textureType);
+ Sampler sampler;
+ stream.readBool(&sampler.active);
+ stream.readInt(&sampler.logicalTextureUnit);
+ stream.readInt(&sampler.textureType);
+ mSamplersVS.push_back(sampler);
}
stream.readInt(&mUsedVertexSamplerRange);
@@ -1260,10 +1250,6 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
stream.readInt(&varying.semanticIndexCount);
}
- stream.readString(&mVertexHLSL);
-
- stream.readInt(&mVertexWorkarounds);
-
const unsigned int vertexShaderCount = stream.readInt<unsigned int>();
for (unsigned int vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++)
{
@@ -1280,7 +1266,7 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
unsigned int vertexShaderSize = stream.readInt<unsigned int>();
const unsigned char *vertexShaderFunction = reinterpret_cast<const unsigned char*>(binary) + stream.offset();
- rx::ShaderExecutable *shaderExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(vertexShaderFunction),
+ rx::ShaderExecutable *shaderExecutable = mProgram->getRenderer()->loadExecutable(reinterpret_cast<const DWORD*>(vertexShaderFunction),
vertexShaderSize, rx::SHADER_VERTEX,
mTransformFeedbackLinkedVaryings,
(mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
@@ -1292,7 +1278,7 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
// generated converted input layout
GLenum signature[MAX_VERTEX_ATTRIBS];
- mDynamicHLSL->getInputLayoutSignature(inputLayout, signature);
+ mProgram->getDynamicHLSL()->getInputLayoutSignature(inputLayout, signature);
// add new binary
mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, shaderExecutable));
@@ -1300,20 +1286,6 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
stream.skip(vertexShaderSize);
}
- stream.readString(&mPixelHLSL);
- stream.readInt(&mPixelWorkarounds);
- stream.readBool(&mUsesFragDepth);
-
- const size_t pixelShaderKeySize = stream.readInt<unsigned int>();
- mPixelShaderKey.resize(pixelShaderKeySize);
- for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKeySize; pixelShaderKeyIndex++)
- {
- stream.readInt(&mPixelShaderKey[pixelShaderKeyIndex].type);
- stream.readString(&mPixelShaderKey[pixelShaderKeyIndex].name);
- stream.readString(&mPixelShaderKey[pixelShaderKeyIndex].source);
- stream.readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputIndex);
- }
-
const size_t pixelShaderCount = stream.readInt<unsigned int>();
for (size_t pixelShaderIndex = 0; pixelShaderIndex < pixelShaderCount; pixelShaderIndex++)
{
@@ -1326,10 +1298,11 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
const size_t pixelShaderSize = stream.readInt<unsigned int>();
const unsigned char *pixelShaderFunction = reinterpret_cast<const unsigned char*>(binary) + stream.offset();
- rx::ShaderExecutable *shaderExecutable = mRenderer->loadExecutable(pixelShaderFunction, pixelShaderSize,
- rx::SHADER_PIXEL,
- mTransformFeedbackLinkedVaryings,
- (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
+ rx::Renderer *renderer = mProgram->getRenderer();
+ rx::ShaderExecutable *shaderExecutable = renderer->loadExecutable(pixelShaderFunction, pixelShaderSize,
+ rx::SHADER_PIXEL, mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
+
if (!shaderExecutable)
{
infoLog.append("Could not create pixel shader.");
@@ -1347,9 +1320,11 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
if (geometryShaderSize > 0)
{
const char *geometryShaderFunction = (const char*) binary + stream.offset();
- mGeometryExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(geometryShaderFunction),
- geometryShaderSize, rx::SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
- (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
+ rx::Renderer *renderer = mProgram->getRenderer();
+ mGeometryExecutable = renderer->loadExecutable(reinterpret_cast<const DWORD*>(geometryShaderFunction),
+ geometryShaderSize, rx::SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
+
if (!mGeometryExecutable)
{
infoLog.append("Could not create geometry shader.");
@@ -1358,29 +1333,39 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
stream.skip(geometryShaderSize);
}
+ if (!mProgram->load(infoLog, &stream))
+ {
+ return false;
+ }
+
const char *ptr = (const char*) binary + stream.offset();
const GUID *binaryIdentifier = (const GUID *) ptr;
ptr += sizeof(GUID);
- GUID identifier = mRenderer->getAdapterIdentifier();
+ GUID identifier = mProgram->getRenderer()->getAdapterIdentifier();
if (memcmp(&identifier, binaryIdentifier, sizeof(GUID)) != 0)
{
infoLog.append("Invalid program binary.");
return false;
}
- initializeUniformStorage();
+ mProgram->initializeUniformStorage(mUniforms);
return true;
#endif // #ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD
}
-bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length)
+bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length)
{
+ if (binaryFormat)
+ {
+ *binaryFormat = mProgram->getBinaryFormat();
+ }
+
BinaryOutputStream stream;
- stream.writeInt(GL_PROGRAM_BINARY_ANGLE);
+ stream.writeInt(mProgram->getBinaryFormat());
stream.writeInt(ANGLE_MAJOR_VERSION);
stream.writeInt(ANGLE_MINOR_VERSION);
stream.writeBytes(reinterpret_cast<const unsigned char*>(ANGLE_COMMIT_HASH), ANGLE_COMMIT_HASH_SIZE);
@@ -1395,14 +1380,16 @@ bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length)
stream.writeInt(mSemanticIndex[i]);
}
- for (unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i)
+ stream.writeInt(mSamplersPS.size());
+ for (unsigned int i = 0; i < mSamplersPS.size(); ++i)
{
stream.writeInt(mSamplersPS[i].active);
stream.writeInt(mSamplersPS[i].logicalTextureUnit);
stream.writeInt(mSamplersPS[i].textureType);
}
- for (unsigned int i = 0; i < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++i)
+ stream.writeInt(mSamplersVS.size());
+ for (unsigned int i = 0; i < mSamplersVS.size(); ++i)
{
stream.writeInt(mSamplersVS[i].active);
stream.writeInt(mSamplersVS[i].logicalTextureUnit);
@@ -1477,9 +1464,6 @@ bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length)
stream.writeInt(varying.semanticIndexCount);
}
- stream.writeString(mVertexHLSL);
- stream.writeInt(mVertexWorkarounds);
-
stream.writeInt(mVertexExecutables.size());
for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size(); vertexExecutableIndex++)
{
@@ -1501,20 +1485,6 @@ bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length)
stream.writeBytes(vertexBlob, vertexShaderSize);
}
- stream.writeString(mPixelHLSL);
- stream.writeInt(mPixelWorkarounds);
- stream.writeInt(mUsesFragDepth);
-
- stream.writeInt(mPixelShaderKey.size());
- for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < mPixelShaderKey.size(); pixelShaderKeyIndex++)
- {
- const PixelShaderOuputVariable &variable = mPixelShaderKey[pixelShaderKeyIndex];
- stream.writeInt(variable.type);
- stream.writeString(variable.name);
- stream.writeString(variable.source);
- stream.writeInt(variable.outputIndex);
- }
-
stream.writeInt(mPixelExecutables.size());
for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size(); pixelExecutableIndex++)
{
@@ -1543,7 +1513,17 @@ bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length)
stream.writeBytes(geometryBlob, geometryShaderSize);
}
- GUID identifier = mRenderer->getAdapterIdentifier();
+ if (!mProgram->save(&stream))
+ {
+ if (length)
+ {
+ *length = 0;
+ }
+
+ return false;
+ }
+
+ GUID identifier = mProgram->getRenderer()->getAdapterIdentifier();
GLsizei streamLength = stream.length();
const void *streamData = stream.data();
@@ -1583,7 +1563,7 @@ bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length)
GLint ProgramBinary::getLength()
{
GLint length;
- if (save(NULL, INT_MAX, &length))
+ if (save(NULL, NULL, INT_MAX, &length))
{
return length;
}
@@ -1593,68 +1573,56 @@ GLint ProgramBinary::getLength()
}
}
-bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader,
- const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode)
+bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader,
+ const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode, const Caps &caps)
{
if (!fragmentShader || !fragmentShader->isCompiled())
{
return false;
}
+ ASSERT(fragmentShader->getType() == GL_FRAGMENT_SHADER);
if (!vertexShader || !vertexShader->isCompiled())
{
return false;
}
+ ASSERT(vertexShader->getType() == GL_VERTEX_SHADER);
reset();
- mTransformFeedbackBufferMode = transformFeedbackBufferMode;
-
- mShaderVersion = vertexShader->getShaderVersion();
+ mSamplersPS.resize(caps.maxTextureImageUnits);
+ mSamplersVS.resize(caps.maxVertexTextureImageUnits);
- mPixelHLSL = fragmentShader->getHLSL();
- mPixelWorkarounds = fragmentShader->getD3DWorkarounds();
-
- mVertexHLSL = vertexShader->getHLSL();
- mVertexWorkarounds = vertexShader->getD3DWorkarounds();
+ mTransformFeedbackBufferMode = transformFeedbackBufferMode;
- // Map the varyings to the register file
- VaryingPacking packing = { NULL };
- int registers = mDynamicHLSL->packVaryings(infoLog, packing, fragmentShader, vertexShader, transformFeedbackVaryings);
+ rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
+ rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
- if (registers < 0)
- {
- return false;
- }
+ mShaderVersion = vertexShaderD3D->getShaderVersion();
- if (!linkVaryings(infoLog, fragmentShader, vertexShader))
- {
- return false;
- }
-
- mUsesPointSize = vertexShader->usesPointSize();
+ int registers;
std::vector<LinkedVarying> linkedVaryings;
- if (!mDynamicHLSL->generateShaderLinkHLSL(infoLog, registers, packing, mPixelHLSL, mVertexHLSL,
- fragmentShader, vertexShader, transformFeedbackVaryings,
- &linkedVaryings, &mOutputVariables, &mPixelShaderKey, &mUsesFragDepth))
+ if (!mProgram->link(infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, &registers, &linkedVaryings, &mOutputVariables))
{
return false;
}
+ mUsesPointSize = vertexShaderD3D->usesPointSize();
+
bool success = true;
- if (!linkAttributes(infoLog, attributeBindings, fragmentShader, vertexShader))
+ if (!linkAttributes(infoLog, attributeBindings, vertexShader))
{
success = false;
}
- if (!linkUniforms(infoLog, *vertexShader, *fragmentShader))
+ if (!linkUniforms(infoLog, *vertexShader, *fragmentShader, caps))
{
success = false;
}
// special case for gl_DepthRange, the only built-in uniform (also a struct)
- if (vertexShader->usesDepthRange() || fragmentShader->usesDepthRange())
+ if (vertexShaderD3D->usesDepthRange() || fragmentShaderD3D->usesDepthRange())
{
const sh::BlockMemberInfo &defaultInfo = sh::BlockMemberInfo::getDefaultBlockInfo();
@@ -1663,13 +1631,13 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin
mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0, -1, defaultInfo));
}
- if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader))
+ if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader, caps))
{
success = false;
}
if (!gatherTransformFeedbackLinkedVaryings(infoLog, linkedVaryings, transformFeedbackVaryings,
- transformFeedbackBufferMode, &mTransformFeedbackLinkedVaryings))
+ transformFeedbackBufferMode, &mTransformFeedbackLinkedVaryings, caps))
{
success = false;
}
@@ -1677,23 +1645,19 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin
if (success)
{
VertexFormat defaultInputLayout[MAX_VERTEX_ATTRIBS];
- GetInputLayoutFromShader(vertexShader->activeAttributes(), defaultInputLayout);
+ GetDefaultInputLayoutFromShader(vertexShader->getActiveAttributes(), defaultInputLayout);
rx::ShaderExecutable *defaultVertexExecutable = getVertexExecutableForInputLayout(defaultInputLayout);
- std::vector<GLenum> defaultPixelOutput(IMPLEMENTATION_MAX_DRAW_BUFFERS);
- for (size_t i = 0; i < defaultPixelOutput.size(); i++)
- {
- defaultPixelOutput[i] = (i == 0) ? GL_FLOAT : GL_NONE;
- }
+ std::vector<GLenum> defaultPixelOutput = GetDefaultOutputLayoutFromShader(mProgram->getPixelShaderKey());
rx::ShaderExecutable *defaultPixelExecutable = getPixelExecutableForOutputLayout(defaultPixelOutput);
if (usesGeometryShader())
{
- std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(registers, fragmentShader, vertexShader);
- mGeometryExecutable = mRenderer->compileToExecutable(infoLog, geometryHLSL.c_str(), rx::SHADER_GEOMETRY,
- mTransformFeedbackLinkedVaryings,
- (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
- rx::ANGLE_D3D_WORKAROUND_NONE);
+ std::string geometryHLSL = mProgram->getDynamicHLSL()->generateGeometryShaderHLSL(registers, fragmentShaderD3D, vertexShaderD3D);
+ mGeometryExecutable = mProgram->getRenderer()->compileToExecutable(infoLog, geometryHLSL.c_str(),
+ rx::SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
+ rx::ANGLE_D3D_WORKAROUND_NONE);
}
if (!defaultVertexExecutable || !defaultPixelExecutable || (usesGeometryShader() && !mGeometryExecutable))
@@ -1708,15 +1672,20 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin
}
// Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices
-bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader)
+bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader)
{
+ const rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
+
unsigned int usedLocations = 0;
- const std::vector<sh::Attribute> &activeAttributes = vertexShader->activeAttributes();
+ const std::vector<sh::Attribute> &shaderAttributes = vertexShader->getActiveAttributes();
// Link attributes that have a binding location
- for (unsigned int attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
+ for (unsigned int attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
{
- const sh::Attribute &attribute = activeAttributes[attributeIndex];
+ const sh::Attribute &attribute = shaderAttributes[attributeIndex];
+
+ ASSERT(attribute.staticUse);
+
const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location;
mShaderAttributes[attributeIndex] = attribute;
@@ -1755,9 +1724,12 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at
}
// Link attributes that don't have a binding location
- for (unsigned int attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
+ for (unsigned int attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
{
- const sh::Attribute &attribute = activeAttributes[attributeIndex];
+ const sh::Attribute &attribute = shaderAttributes[attributeIndex];
+
+ ASSERT(attribute.staticUse);
+
const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location;
if (location == -1) // Not set by glBindAttribLocation or by location layout qualifier
@@ -1778,7 +1750,7 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )
{
- int index = vertexShader->getSemanticIndex(mLinkedAttribute[attributeIndex].name);
+ int index = vertexShaderD3D->getSemanticIndex(mLinkedAttribute[attributeIndex].name);
int rows = VariableRegisterCount(mLinkedAttribute[attributeIndex].type);
for (int r = 0; r < rows; r++)
@@ -1811,32 +1783,29 @@ bool ProgramBinary::linkValidateVariablesBase(InfoLog &infoLog, const std::strin
return false;
}
- return true;
-}
-
-template <class ShaderVarType>
-bool ProgramBinary::linkValidateFields(InfoLog &infoLog, const std::string &varName, const ShaderVarType &vertexVar, const ShaderVarType &fragmentVar)
-{
- if (vertexVar.fields.size() != fragmentVar.fields.size())
+ if (vertexVariable.fields.size() != fragmentVariable.fields.size())
{
- infoLog.append("Structure lengths for %s differ between vertex and fragment shaders", varName.c_str());
+ infoLog.append("Structure lengths for %s differ between vertex and fragment shaders", variableName.c_str());
return false;
}
- const unsigned int numMembers = vertexVar.fields.size();
+ const unsigned int numMembers = vertexVariable.fields.size();
for (unsigned int memberIndex = 0; memberIndex < numMembers; memberIndex++)
{
- const ShaderVarType &vertexMember = vertexVar.fields[memberIndex];
- const ShaderVarType &fragmentMember = fragmentVar.fields[memberIndex];
+ const sh::ShaderVariable &vertexMember = vertexVariable.fields[memberIndex];
+ const sh::ShaderVariable &fragmentMember = fragmentVariable.fields[memberIndex];
if (vertexMember.name != fragmentMember.name)
{
infoLog.append("Name mismatch for field '%d' of %s: (in vertex: '%s', in fragment: '%s')",
- memberIndex, varName.c_str(), vertexMember.name.c_str(), fragmentMember.name.c_str());
+ memberIndex, variableName.c_str(),
+ vertexMember.name.c_str(), fragmentMember.name.c_str());
return false;
}
- const std::string memberName = varName.substr(0, varName.length()-1) + "." + vertexVar.name + "'";
- if (!linkValidateVariables(infoLog, memberName, vertexMember, fragmentMember))
+ const std::string memberName = variableName.substr(0, variableName.length() - 1) + "." +
+ vertexMember.name + "'";
+
+ if (!linkValidateVariablesBase(infoLog, vertexMember.name, vertexMember, fragmentMember, validatePrecision))
{
return false;
}
@@ -1845,22 +1814,17 @@ bool ProgramBinary::linkValidateFields(InfoLog &infoLog, const std::string &varN
return true;
}
-bool ProgramBinary::linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform)
+bool ProgramBinary::linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform)
{
if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, true))
{
return false;
}
- if (!linkValidateFields<sh::Uniform>(infoLog, uniformName, vertexUniform, fragmentUniform))
- {
- return false;
- }
-
return true;
}
-bool ProgramBinary::linkValidateVariables(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying)
+bool ProgramBinary::linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying)
{
if (!linkValidateVariablesBase(infoLog, varyingName, vertexVarying, fragmentVarying, false))
{
@@ -1873,37 +1837,30 @@ bool ProgramBinary::linkValidateVariables(InfoLog &infoLog, const std::string &v
return false;
}
- if (!linkValidateFields<sh::Varying>(infoLog, varyingName, vertexVarying, fragmentVarying))
- {
- return false;
- }
-
return true;
}
-bool ProgramBinary::linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform)
+bool ProgramBinary::linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform)
{
if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, true))
{
return false;
}
- if (vertexUniform.isRowMajorMatrix != fragmentUniform.isRowMajorMatrix)
+ if (vertexUniform.isRowMajorLayout != fragmentUniform.isRowMajorLayout)
{
infoLog.append("Matrix packings for %s differ between vertex and fragment shaders", uniformName.c_str());
return false;
}
- if (!linkValidateFields<sh::InterfaceBlockField>(infoLog, uniformName, vertexUniform, fragmentUniform))
- {
- return false;
- }
-
return true;
}
-bool ProgramBinary::linkUniforms(InfoLog &infoLog, const VertexShader &vertexShader, const FragmentShader &fragmentShader)
+bool ProgramBinary::linkUniforms(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps)
{
+ const rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader.getImplementation());
+ const rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader.getImplementation());
+
const std::vector<sh::Uniform> &vertexUniforms = vertexShader.getUniforms();
const std::vector<sh::Uniform> &fragmentUniforms = fragmentShader.getUniforms();
@@ -1925,7 +1882,7 @@ bool ProgramBinary::linkUniforms(InfoLog &infoLog, const VertexShader &vertexSha
{
const sh::Uniform &vertexUniform = *entry->second;
const std::string &uniformName = "uniform '" + vertexUniform.name + "'";
- if (!linkValidateVariables(infoLog, uniformName, vertexUniform, fragmentUniform))
+ if (!linkValidateUniforms(infoLog, uniformName, vertexUniform, fragmentUniform))
{
return false;
}
@@ -1935,35 +1892,43 @@ bool ProgramBinary::linkUniforms(InfoLog &infoLog, const VertexShader &vertexSha
for (unsigned int uniformIndex = 0; uniformIndex < vertexUniforms.size(); uniformIndex++)
{
const sh::Uniform &uniform = vertexUniforms[uniformIndex];
- defineUniformBase(GL_VERTEX_SHADER, uniform, vertexShader.getUniformRegister(uniform.name));
+
+ if (uniform.staticUse)
+ {
+ defineUniformBase(GL_VERTEX_SHADER, uniform, vertexShaderD3D->getUniformRegister(uniform.name));
+ }
}
for (unsigned int uniformIndex = 0; uniformIndex < fragmentUniforms.size(); uniformIndex++)
{
const sh::Uniform &uniform = fragmentUniforms[uniformIndex];
- defineUniformBase(GL_FRAGMENT_SHADER, uniform, fragmentShader.getUniformRegister(uniform.name));
+
+ if (uniform.staticUse)
+ {
+ defineUniformBase(GL_FRAGMENT_SHADER, uniform, fragmentShaderD3D->getUniformRegister(uniform.name));
+ }
}
- if (!indexUniforms(infoLog))
+ if (!indexUniforms(infoLog, caps))
{
return false;
}
- initializeUniformStorage();
+ mProgram->initializeUniformStorage(mUniforms);
return true;
}
void ProgramBinary::defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister)
{
- ShShaderOutput outputType = Shader::getCompilerOutputType(shader);
+ ShShaderOutput outputType = rx::ShaderD3D::getCompilerOutputType(shader);
sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType));
encoder.skipRegisters(uniformRegister);
defineUniform(shader, uniform, uniform.name, &encoder);
}
-void ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &uniform,
+void ProgramBinary::defineUniform(GLenum shader, const sh::ShaderVariable &uniform,
const std::string &fullName, sh::HLSLBlockEncoder *encoder)
{
if (uniform.isStruct())
@@ -1976,7 +1941,7 @@ void ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &uniform,
for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++)
{
- const sh::Uniform &field = uniform.fields[fieldIndex];
+ const sh::ShaderVariable &field = uniform.fields[fieldIndex];
const std::string &fieldFullName = (fullName + elementString + "." + field.name);
defineUniform(shader, field, fieldFullName, encoder);
@@ -2027,7 +1992,7 @@ void ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &uniform,
}
}
-bool ProgramBinary::indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog)
+bool ProgramBinary::indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog, const Caps &caps)
{
ASSERT(IsSampler(uniform.type));
ASSERT(uniform.vsRegisterIndex != GL_INVALID_INDEX || uniform.psRegisterIndex != GL_INVALID_INDEX);
@@ -2035,19 +2000,18 @@ bool ProgramBinary::indexSamplerUniform(const LinkedUniform &uniform, InfoLog &i
if (uniform.vsRegisterIndex != GL_INVALID_INDEX)
{
if (!assignSamplers(uniform.vsRegisterIndex, uniform.type, uniform.arraySize, mSamplersVS,
- &mUsedVertexSamplerRange, mRenderer->getMaxVertexTextureImageUnits()))
+ &mUsedVertexSamplerRange))
{
infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).",
- mRenderer->getMaxVertexTextureImageUnits());
+ mSamplersVS.size());
return false;
}
- unsigned int maxVertexVectors = mRenderer->getReservedVertexUniformVectors() +
- mRenderer->getMaxVertexUniformVectors();
+ unsigned int maxVertexVectors = mProgram->getRenderer()->getReservedVertexUniformVectors() + caps.maxVertexUniformVectors;
if (uniform.vsRegisterIndex + uniform.registerCount > maxVertexVectors)
{
infoLog.append("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%u)",
- mRenderer->getMaxVertexUniformVectors());
+ caps.maxVertexUniformVectors);
return false;
}
}
@@ -2055,19 +2019,18 @@ bool ProgramBinary::indexSamplerUniform(const LinkedUniform &uniform, InfoLog &i
if (uniform.psRegisterIndex != GL_INVALID_INDEX)
{
if (!assignSamplers(uniform.psRegisterIndex, uniform.type, uniform.arraySize, mSamplersPS,
- &mUsedPixelSamplerRange, MAX_TEXTURE_IMAGE_UNITS))
+ &mUsedPixelSamplerRange))
{
infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).",
- MAX_TEXTURE_IMAGE_UNITS);
+ mSamplersPS.size());
return false;
}
- unsigned int maxFragmentVectors = mRenderer->getReservedFragmentUniformVectors() +
- mRenderer->getMaxFragmentUniformVectors();
+ unsigned int maxFragmentVectors = mProgram->getRenderer()->getReservedFragmentUniformVectors() + caps.maxFragmentUniformVectors;
if (uniform.psRegisterIndex + uniform.registerCount > maxFragmentVectors)
{
infoLog.append("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%u)",
- mRenderer->getMaxFragmentUniformVectors());
+ caps.maxFragmentUniformVectors);
return false;
}
}
@@ -2075,7 +2038,7 @@ bool ProgramBinary::indexSamplerUniform(const LinkedUniform &uniform, InfoLog &i
return true;
}
-bool ProgramBinary::indexUniforms(InfoLog &infoLog)
+bool ProgramBinary::indexUniforms(InfoLog &infoLog, const Caps &caps)
{
for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
{
@@ -2083,7 +2046,7 @@ bool ProgramBinary::indexUniforms(InfoLog &infoLog)
if (IsSampler(uniform.type))
{
- if (!indexSamplerUniform(uniform, infoLog))
+ if (!indexSamplerUniform(uniform, infoLog, caps))
{
return false;
}
@@ -2101,20 +2064,20 @@ bool ProgramBinary::indexUniforms(InfoLog &infoLog)
bool ProgramBinary::assignSamplers(unsigned int startSamplerIndex,
GLenum samplerType,
unsigned int samplerCount,
- Sampler *outArray,
- GLuint *usedRange,
- unsigned int limit)
+ std::vector<Sampler> &outSamplers,
+ GLuint *outUsedRange)
{
unsigned int samplerIndex = startSamplerIndex;
do
{
- if (samplerIndex < limit)
+ if (samplerIndex < outSamplers.size())
{
- outArray[samplerIndex].active = true;
- outArray[samplerIndex].textureType = GetTextureType(samplerType);
- outArray[samplerIndex].logicalTextureUnit = 0;
- *usedRange = std::max(samplerIndex + 1, *usedRange);
+ Sampler& sampler = outSamplers[samplerIndex];
+ sampler.active = true;
+ sampler.textureType = GetTextureType(samplerType);
+ sampler.logicalTextureUnit = 0;
+ *outUsedRange = std::max(samplerIndex + 1, *outUsedRange);
}
else
{
@@ -2163,8 +2126,8 @@ bool ProgramBinary::areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::Inter
return false;
}
- std::string uniformName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'";
- if (!linkValidateVariables(infoLog, uniformName, vertexMember, fragmentMember))
+ std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'";
+ if (!linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember))
{
return false;
}
@@ -2173,8 +2136,7 @@ bool ProgramBinary::areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::Inter
return true;
}
-bool ProgramBinary::linkUniformBlocks(InfoLog &infoLog, const VertexShader &vertexShader,
- const FragmentShader &fragmentShader)
+bool ProgramBinary::linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps)
{
const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks();
const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks();
@@ -2205,17 +2167,29 @@ bool ProgramBinary::linkUniformBlocks(InfoLog &infoLog, const VertexShader &vert
for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
{
- if (!defineUniformBlock(infoLog, vertexShader, vertexInterfaceBlocks[blockIndex]))
+ const sh::InterfaceBlock &interfaceBlock = vertexInterfaceBlocks[blockIndex];
+
+ // Note: shared and std140 layouts are always considered active
+ if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
{
- return false;
+ if (!defineUniformBlock(infoLog, vertexShader, interfaceBlock, caps))
+ {
+ return false;
+ }
}
}
for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
{
- if (!defineUniformBlock(infoLog, fragmentShader, fragmentInterfaceBlocks[blockIndex]))
+ const sh::InterfaceBlock &interfaceBlock = fragmentInterfaceBlocks[blockIndex];
+
+ // Note: shared and std140 layouts are always considered active
+ if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
{
- return false;
+ if (!defineUniformBlock(infoLog, fragmentShader, interfaceBlock, caps))
+ {
+ return false;
+ }
}
}
@@ -2225,11 +2199,10 @@ bool ProgramBinary::linkUniformBlocks(InfoLog &infoLog, const VertexShader &vert
bool ProgramBinary::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings,
const std::vector<std::string> &transformFeedbackVaryingNames,
GLenum transformFeedbackBufferMode,
- std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings) const
+ std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings,
+ const Caps &caps) const
{
size_t totalComponents = 0;
- const size_t maxSeparateComponents = mRenderer->getMaxTransformFeedbackSeparateComponents();
- const size_t maxInterleavedComponents = mRenderer->getMaxTransformFeedbackInterleavedComponents();
// Gather the linked varyings that are used for transform feedback, they should all exist.
outTransformFeedbackLinkedVaryings->clear();
@@ -2251,10 +2224,10 @@ bool ProgramBinary::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, cons
size_t componentCount = linkedVaryings[j].semanticIndexCount * 4;
if (transformFeedbackBufferMode == GL_SEPARATE_ATTRIBS &&
- componentCount > maxSeparateComponents)
+ componentCount > caps.maxTransformFeedbackSeparateComponents)
{
infoLog.append("Transform feedback varying's %s components (%u) exceed the maximum separate components (%u).",
- linkedVaryings[j].name.c_str(), componentCount, maxSeparateComponents);
+ linkedVaryings[j].name.c_str(), componentCount, caps.maxTransformFeedbackSeparateComponents);
return false;
}
@@ -2270,39 +2243,45 @@ bool ProgramBinary::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, cons
ASSERT(found);
}
- if (transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS && totalComponents > maxInterleavedComponents)
+ if (transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS && totalComponents > caps.maxTransformFeedbackInterleavedComponents)
{
infoLog.append("Transform feedback varying total components (%u) exceed the maximum interleaved components (%u).",
- totalComponents, maxInterleavedComponents);
+ totalComponents, caps.maxTransformFeedbackInterleavedComponents);
return false;
}
return true;
}
-void ProgramBinary::defineUniformBlockMembers(const std::vector<sh::InterfaceBlockField> &fields, const std::string &prefix, int blockIndex,
- sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes)
+template <typename VarT>
+void ProgramBinary::defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex,
+ sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
+ bool inRowMajorLayout)
{
for (unsigned int uniformIndex = 0; uniformIndex < fields.size(); uniformIndex++)
{
- const sh::InterfaceBlockField &field = fields[uniformIndex];
+ const VarT &field = fields[uniformIndex];
const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name);
if (field.isStruct())
{
+ bool rowMajorLayout = (inRowMajorLayout || IsRowMajorLayout(field));
+
for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++)
{
encoder->enterAggregateType();
const std::string uniformElementName = fieldName + (field.isArray() ? ArrayString(arrayElement) : "");
- defineUniformBlockMembers(field.fields, uniformElementName, blockIndex, encoder, blockUniformIndexes);
+ defineUniformBlockMembers(field.fields, uniformElementName, blockIndex, encoder, blockUniformIndexes, rowMajorLayout);
encoder->exitAggregateType();
}
}
else
{
- sh::BlockMemberInfo memberInfo = encoder->encodeInterfaceBlockField(field);
+ bool isRowMajorMatrix = (IsMatrixType(field.type) && inRowMajorLayout);
+
+ sh::BlockMemberInfo memberInfo = encoder->encodeType(field.type, field.arraySize, isRowMajorMatrix);
LinkedUniform *newUniform = new LinkedUniform(field.type, field.precision, fieldName, field.arraySize,
blockIndex, memberInfo);
@@ -2314,8 +2293,10 @@ void ProgramBinary::defineUniformBlockMembers(const std::vector<sh::InterfaceBlo
}
}
-bool ProgramBinary::defineUniformBlock(InfoLog &infoLog, const Shader &shader, const sh::InterfaceBlock &interfaceBlock)
+bool ProgramBinary::defineUniformBlock(InfoLog &infoLog, const Shader &shader, const sh::InterfaceBlock &interfaceBlock, const Caps &caps)
{
+ const rx::ShaderD3D* shaderD3D = rx::ShaderD3D::makeShaderD3D(shader.getImplementation());
+
// create uniform block entries if they do not exist
if (getUniformBlockIndex(interfaceBlock.name) == GL_INVALID_INDEX)
{
@@ -2335,7 +2316,7 @@ bool ProgramBinary::defineUniformBlock(InfoLog &infoLog, const Shader &shader, c
}
ASSERT(encoder);
- defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex, encoder, &blockUniformIndexes);
+ defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex, encoder, &blockUniformIndexes, interfaceBlock.isRowMajorLayout);
size_t dataSize = encoder->getBlockSize();
@@ -2357,50 +2338,49 @@ bool ProgramBinary::defineUniformBlock(InfoLog &infoLog, const Shader &shader, c
}
}
- // Assign registers to the uniform blocks
- const GLuint blockIndex = getUniformBlockIndex(interfaceBlock.name);
- const unsigned int elementCount = std::max(1u, interfaceBlock.arraySize);
- ASSERT(blockIndex != GL_INVALID_INDEX);
- ASSERT(blockIndex + elementCount <= mUniformBlocks.size());
-
- unsigned int interfaceBlockRegister = shader.getInterfaceBlockRegister(interfaceBlock.name);
-
- for (unsigned int uniformBlockElement = 0; uniformBlockElement < elementCount; uniformBlockElement++)
+ if (interfaceBlock.staticUse)
{
- UniformBlock *uniformBlock = mUniformBlocks[blockIndex + uniformBlockElement];
- ASSERT(uniformBlock->name == interfaceBlock.name);
+ // Assign registers to the uniform blocks
+ const GLuint blockIndex = getUniformBlockIndex(interfaceBlock.name);
+ const unsigned int elementCount = std::max(1u, interfaceBlock.arraySize);
+ ASSERT(blockIndex != GL_INVALID_INDEX);
+ ASSERT(blockIndex + elementCount <= mUniformBlocks.size());
+
+ unsigned int interfaceBlockRegister = shaderD3D->getInterfaceBlockRegister(interfaceBlock.name);
- if (!assignUniformBlockRegister(infoLog, uniformBlock, shader.getType(),
- interfaceBlockRegister + uniformBlockElement))
+ for (unsigned int uniformBlockElement = 0; uniformBlockElement < elementCount; uniformBlockElement++)
{
- return false;
+ UniformBlock *uniformBlock = mUniformBlocks[blockIndex + uniformBlockElement];
+ ASSERT(uniformBlock->name == interfaceBlock.name);
+
+ if (!assignUniformBlockRegister(infoLog, uniformBlock, shader.getType(),
+ interfaceBlockRegister + uniformBlockElement, caps))
+ {
+ return false;
+ }
}
}
return true;
}
-bool ProgramBinary::assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex)
+bool ProgramBinary::assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex, const Caps &caps)
{
if (shader == GL_VERTEX_SHADER)
{
uniformBlock->vsRegisterIndex = registerIndex;
- unsigned int maximumBlocks = mRenderer->getMaxVertexShaderUniformBuffers();
-
- if (registerIndex - mRenderer->getReservedVertexUniformBuffers() >= maximumBlocks)
+ if (registerIndex - mProgram->getRenderer()->getReservedVertexUniformBuffers() >= caps.maxVertexUniformBlocks)
{
- infoLog.append("Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (%u)", maximumBlocks);
+ infoLog.append("Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (%u)", caps.maxVertexUniformBlocks);
return false;
}
}
else if (shader == GL_FRAGMENT_SHADER)
{
uniformBlock->psRegisterIndex = registerIndex;
- unsigned int maximumBlocks = mRenderer->getMaxFragmentShaderUniformBuffers();
-
- if (registerIndex - mRenderer->getReservedFragmentUniformBuffers() >= maximumBlocks)
+ if (registerIndex - mProgram->getRenderer()->getReservedFragmentUniformBuffers() >= caps.maxFragmentUniformBlocks)
{
- infoLog.append("Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (%u)", maximumBlocks);
+ infoLog.append("Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (%u)", caps.maxFragmentUniformBlocks);
return false;
}
}
@@ -2670,10 +2650,10 @@ GLuint ProgramBinary::getActiveUniformBlockMaxLength() const
return maxLength;
}
-void ProgramBinary::validate(InfoLog &infoLog)
+void ProgramBinary::validate(InfoLog &infoLog, const Caps &caps)
{
applyUniforms();
- if (!validateSamplers(&infoLog))
+ if (!validateSamplers(&infoLog, caps))
{
mValidated = false;
}
@@ -2683,20 +2663,14 @@ void ProgramBinary::validate(InfoLog &infoLog)
}
}
-bool ProgramBinary::validateSamplers(InfoLog *infoLog)
+bool ProgramBinary::validateSamplers(InfoLog *infoLog, const Caps &caps)
{
// if any two active samplers in a program are of different types, but refer to the same
// texture image unit, and this is the current program, then ValidateProgram will fail, and
// DrawArrays and DrawElements will issue the INVALID_OPERATION error.
updateSamplerMapping();
- const unsigned int maxCombinedTextureImageUnits = mRenderer->getMaxCombinedTextureImageUnits();
- TextureType textureUnitType[IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS];
-
- for (unsigned int i = 0; i < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++i)
- {
- textureUnitType[i] = TEXTURE_UNKNOWN;
- }
+ std::vector<GLenum> textureUnitTypes(caps.maxCombinedTextureImageUnits, GL_NONE);
for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i)
{
@@ -2704,19 +2678,19 @@ bool ProgramBinary::validateSamplers(InfoLog *infoLog)
{
unsigned int unit = mSamplersPS[i].logicalTextureUnit;
- if (unit >= maxCombinedTextureImageUnits)
+ if (unit >= textureUnitTypes.size())
{
if (infoLog)
{
- infoLog->append("Sampler uniform (%d) exceeds IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
+ infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size());
}
return false;
}
- if (textureUnitType[unit] != TEXTURE_UNKNOWN)
+ if (textureUnitTypes[unit] != GL_NONE)
{
- if (mSamplersPS[i].textureType != textureUnitType[unit])
+ if (mSamplersPS[i].textureType != textureUnitTypes[unit])
{
if (infoLog)
{
@@ -2728,7 +2702,7 @@ bool ProgramBinary::validateSamplers(InfoLog *infoLog)
}
else
{
- textureUnitType[unit] = mSamplersPS[i].textureType;
+ textureUnitTypes[unit] = mSamplersPS[i].textureType;
}
}
}
@@ -2739,19 +2713,19 @@ bool ProgramBinary::validateSamplers(InfoLog *infoLog)
{
unsigned int unit = mSamplersVS[i].logicalTextureUnit;
- if (unit >= maxCombinedTextureImageUnits)
+ if (unit >= textureUnitTypes.size())
{
if (infoLog)
{
- infoLog->append("Sampler uniform (%d) exceeds IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
+ infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size());
}
return false;
}
- if (textureUnitType[unit] != TEXTURE_UNKNOWN)
+ if (textureUnitTypes[unit] != GL_NONE)
{
- if (mSamplersVS[i].textureType != textureUnitType[unit])
+ if (mSamplersVS[i].textureType != textureUnitTypes[unit])
{
if (infoLog)
{
@@ -2763,7 +2737,7 @@ bool ProgramBinary::validateSamplers(InfoLog *infoLog)
}
else
{
- textureUnitType[unit] = mSamplersVS[i].textureType;
+ textureUnitTypes[unit] = mSamplersVS[i].textureType;
}
}
}
@@ -2771,7 +2745,7 @@ bool ProgramBinary::validateSamplers(InfoLog *infoLog)
return true;
}
-ProgramBinary::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(TEXTURE_2D)
+ProgramBinary::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(GL_TEXTURE_2D)
{
}
@@ -2819,42 +2793,9 @@ void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MA
}
}
-void ProgramBinary::initializeUniformStorage()
-{
- // Compute total default block size
- unsigned int vertexRegisters = 0;
- unsigned int fragmentRegisters = 0;
- for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
- {
- const LinkedUniform &uniform = *mUniforms[uniformIndex];
-
- if (!IsSampler(uniform.type))
- {
- if (uniform.isReferencedByVertexShader())
- {
- vertexRegisters = std::max(vertexRegisters, uniform.vsRegisterIndex + uniform.registerCount);
- }
- if (uniform.isReferencedByFragmentShader())
- {
- fragmentRegisters = std::max(fragmentRegisters, uniform.psRegisterIndex + uniform.registerCount);
- }
- }
- }
-
- mVertexUniformStorage = mRenderer->createUniformStorage(vertexRegisters * 16u);
- mFragmentUniformStorage = mRenderer->createUniformStorage(fragmentRegisters * 16u);
-}
-
void ProgramBinary::reset()
{
- mVertexHLSL.clear();
- mVertexWorkarounds = rx::ANGLE_D3D_WORKAROUND_NONE;
SafeDeleteContainer(mVertexExecutables);
-
- mPixelHLSL.clear();
- mPixelWorkarounds = rx::ANGLE_D3D_WORKAROUND_NONE;
- mUsesFragDepth = false;
- mPixelShaderKey.clear();
SafeDeleteContainer(mPixelExecutables);
SafeDelete(mGeometryExecutable);
@@ -2862,14 +2803,9 @@ void ProgramBinary::reset()
mTransformFeedbackBufferMode = GL_NONE;
mTransformFeedbackLinkedVaryings.clear();
- for (size_t i = 0; i < ArraySize(mSamplersPS); i++)
- {
- mSamplersPS[i] = Sampler();
- }
- for (size_t i = 0; i < ArraySize(mSamplersVS); i++)
- {
- mSamplersVS[i] = Sampler();
- }
+ mSamplersPS.clear();
+ mSamplersVS.clear();
+
mUsedVertexSamplerRange = 0;
mUsedPixelSamplerRange = 0;
mUsesPointSize = false;
@@ -2880,8 +2816,8 @@ void ProgramBinary::reset()
SafeDeleteContainer(mUniformBlocks);
mUniformIndex.clear();
mOutputVariables.clear();
- SafeDelete(mVertexUniformStorage);
- SafeDelete(mFragmentUniformStorage);
+
+ mProgram->reset();
mValidated = false;
}