Commit fb53603c by Jamie Madill

Revert "Re^5-land "Move Uniform and UBO info to the gl::Program layer.""

Failing dEQP-GLES3.functional.uniform_api.random.22 and 23: There's a bug with arrays of tranpsosed matrix uniforms. BUG=angleproject:1123 This reverts commit 78d35692. Change-Id: If39b5908af39671dfe98965e6a1ba77fd18ea8fc Reviewed-on: https://chromium-review.googlesource.com/299320Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 2b835a6f
...@@ -69,13 +69,13 @@ inline int clampToInt(unsigned int x) ...@@ -69,13 +69,13 @@ inline int clampToInt(unsigned int x)
template <typename DestT, typename SrcT> template <typename DestT, typename SrcT>
inline DestT clampCast(SrcT value) inline DestT clampCast(SrcT value)
{ {
// This assumes SrcT can properly represent DestT::min/max
// Unfortunately we can't use META_ASSERT without C++11 constexpr support
ASSERT(static_cast<DestT>(static_cast<SrcT>(std::numeric_limits<DestT>::min())) == std::numeric_limits<DestT>::min());
ASSERT(static_cast<DestT>(static_cast<SrcT>(std::numeric_limits<DestT>::max())) == std::numeric_limits<DestT>::max());
SrcT lo = static_cast<SrcT>(std::numeric_limits<DestT>::min()); SrcT lo = static_cast<SrcT>(std::numeric_limits<DestT>::min());
SrcT hi = static_cast<SrcT>(std::numeric_limits<DestT>::max()); SrcT hi = static_cast<SrcT>(std::numeric_limits<DestT>::max());
// This assumes SrcT can properly represent DestT::min/max. Checking this is a bit tricky,
// especially given floating point representations.
ASSERT(lo < hi);
return static_cast<DestT>(value > lo ? (value > hi ? hi : value) : lo); return static_cast<DestT>(value > lo ? (value > hi ? hi : value) : lo);
} }
......
...@@ -26,8 +26,6 @@ struct InterfaceBlock; ...@@ -26,8 +26,6 @@ struct InterfaceBlock;
struct COMPILER_EXPORT BlockMemberInfo struct COMPILER_EXPORT BlockMemberInfo
{ {
BlockMemberInfo() : offset(-1), arrayStride(-1), matrixStride(-1), isRowMajorMatrix(false) {}
BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix) BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
: offset(offset), : offset(offset),
arrayStride(arrayStride), arrayStride(arrayStride),
......
...@@ -189,16 +189,6 @@ class Program : angle::NonCopyable ...@@ -189,16 +189,6 @@ class Program : angle::NonCopyable
{ {
return mOutputVariables; return mOutputVariables;
} }
const std::vector<LinkedUniform> &getUniforms() const { return mUniforms; }
const std::vector<VariableLocation> &getUniformLocations() const
{
return mUniformLocations;
}
const std::vector<UniformBlock> &getUniformBlocks() const { return mUniformBlocks; }
const LinkedUniform *getUniformByName(const std::string &name) const;
GLint getUniformLocation(const std::string &name) const;
GLuint getUniformIndex(const std::string &name) const;
private: private:
friend class Program; friend class Program;
...@@ -215,12 +205,10 @@ class Program : angle::NonCopyable ...@@ -215,12 +205,10 @@ class Program : angle::NonCopyable
std::vector<sh::Attribute> mAttributes; std::vector<sh::Attribute> mAttributes;
std::bitset<MAX_VERTEX_ATTRIBS> mActiveAttribLocationsMask; std::bitset<MAX_VERTEX_ATTRIBS> mActiveAttribLocationsMask;
std::vector<LinkedUniform> mUniforms;
std::vector<VariableLocation> mUniformLocations;
std::vector<UniformBlock> mUniformBlocks;
// TODO(jmadill): use unordered/hash map when available // TODO(jmadill): use unordered/hash map when available
std::map<int, VariableLocation> mOutputVariables; std::map<int, VariableLocation> mOutputVariables;
// TODO(jmadill): move more state into Data.
}; };
Program(rx::ImplFactory *factory, ResourceManager *manager, GLuint handle); Program(rx::ImplFactory *factory, ResourceManager *manager, GLuint handle);
...@@ -263,10 +251,11 @@ class Program : angle::NonCopyable ...@@ -263,10 +251,11 @@ class Program : angle::NonCopyable
GLint getActiveUniformMaxLength(); GLint getActiveUniformMaxLength();
GLint getActiveUniformi(GLuint index, GLenum pname) const; GLint getActiveUniformi(GLuint index, GLenum pname) const;
bool isValidUniformLocation(GLint location) const; bool isValidUniformLocation(GLint location) const;
const LinkedUniform &getUniformByLocation(GLint location) const; LinkedUniform *getUniformByLocation(GLint location) const;
LinkedUniform *getUniformByName(const std::string &name) const;
GLint getUniformLocation(const std::string &name) const; GLint getUniformLocation(const std::string &name);
GLuint getUniformIndex(const std::string &name) const; GLuint getUniformIndex(const std::string &name);
void setUniform1fv(GLint location, GLsizei count, const GLfloat *v); void setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
void setUniform2fv(GLint location, GLsizei count, const GLfloat *v); void setUniform2fv(GLint location, GLsizei count, const GLfloat *v);
void setUniform3fv(GLint location, GLsizei count, const GLfloat *v); void setUniform3fv(GLint location, GLsizei count, const GLfloat *v);
...@@ -303,7 +292,7 @@ class Program : angle::NonCopyable ...@@ -303,7 +292,7 @@ class Program : angle::NonCopyable
void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding); void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding);
GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const; GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const;
const UniformBlock &getUniformBlockByIndex(GLuint index) const; const UniformBlock *getUniformBlockByIndex(GLuint index) const;
void setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode); void setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode);
void getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const; void getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const;
...@@ -341,8 +330,7 @@ class Program : angle::NonCopyable ...@@ -341,8 +330,7 @@ class Program : angle::NonCopyable
static bool linkVaryings(InfoLog &infoLog, static bool linkVaryings(InfoLog &infoLog,
const Shader *vertexShader, const Shader *vertexShader,
const Shader *fragmentShader); const Shader *fragmentShader);
bool linkUniforms(gl::InfoLog &infoLog, const gl::Caps &caps); bool linkUniforms(gl::InfoLog &infoLog, const gl::Caps &caps) const;
void indexUniforms();
bool areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, bool areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock,
const sh::InterfaceBlock &fragmentInterfaceBlock); const sh::InterfaceBlock &fragmentInterfaceBlock);
...@@ -364,40 +352,6 @@ class Program : angle::NonCopyable ...@@ -364,40 +352,6 @@ class Program : angle::NonCopyable
std::vector<const sh::Varying *> getMergedVaryings() const; std::vector<const sh::Varying *> getMergedVaryings() const;
void linkOutputVariables(); void linkOutputVariables();
bool flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoLog);
struct VectorAndSamplerCount
{
VectorAndSamplerCount() : vectorCount(0), samplerCount(0) {}
VectorAndSamplerCount(const VectorAndSamplerCount &other) = default;
VectorAndSamplerCount &operator=(const VectorAndSamplerCount &other) = default;
VectorAndSamplerCount &operator+=(const VectorAndSamplerCount &other)
{
vectorCount += other.vectorCount;
samplerCount += other.samplerCount;
return *this;
}
unsigned int vectorCount;
unsigned int samplerCount;
};
VectorAndSamplerCount flattenUniform(const sh::ShaderVariable &uniform,
const std::string &fullName);
void gatherInterfaceBlockInfo();
void defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenum shaderType);
template <typename T>
void setUniformInternal(GLint location, GLsizei count, const T *v);
template <size_t cols, size_t rows, typename T>
void setMatrixUniformInternal(GLint location, GLsizei count, GLboolean transpose, const T *v);
template <typename DestT>
void getUniformInternal(GLint location, DestT *dataOut) const;
Data mData; Data mData;
rx::ProgramImpl *mProgram; rx::ProgramImpl *mProgram;
......
...@@ -13,51 +13,55 @@ ...@@ -13,51 +13,55 @@
namespace gl namespace gl
{ {
LinkedUniform::LinkedUniform() LinkedUniform::LinkedUniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize,
: blockIndex(-1), blockInfo(sh::BlockMemberInfo::getDefaultBlockInfo()) const int blockIndex, const sh::BlockMemberInfo &blockInfo)
: type(type),
precision(precision),
name(name),
arraySize(arraySize),
blockIndex(blockIndex),
blockInfo(blockInfo),
data(NULL),
dirty(true),
psRegisterIndex(GL_INVALID_INDEX),
vsRegisterIndex(GL_INVALID_INDEX),
registerCount(0),
registerElement(0)
{ {
// We use data storage for default block uniforms to cache values that are sent to D3D during rendering
// Uniform blocks/buffers are treated separately by the Renderer (ES3 path only)
if (isInDefaultBlock())
{
size_t bytes = dataSize();
data = new unsigned char[bytes];
memset(data, 0, bytes);
registerCount = VariableRowCount(type) * elementCount();
}
} }
LinkedUniform::LinkedUniform(GLenum typeIn, LinkedUniform::~LinkedUniform()
GLenum precisionIn,
const std::string &nameIn,
unsigned int arraySizeIn,
const int blockIndexIn,
const sh::BlockMemberInfo &blockInfoIn)
: blockIndex(blockIndexIn), blockInfo(blockInfoIn)
{ {
type = typeIn; delete[] data;
precision = precisionIn;
name = nameIn;
arraySize = arraySizeIn;
} }
LinkedUniform::LinkedUniform(const sh::Uniform &uniform) bool LinkedUniform::isArray() const
: sh::Uniform(uniform), blockIndex(-1), blockInfo(sh::BlockMemberInfo::getDefaultBlockInfo())
{ {
return arraySize > 0;
} }
LinkedUniform::LinkedUniform(const LinkedUniform &uniform) unsigned int LinkedUniform::elementCount() const
: sh::Uniform(uniform), blockIndex(uniform.blockIndex), blockInfo(uniform.blockInfo)
{ {
// This function is not intended to be called during runtime. return arraySize > 0 ? arraySize : 1;
ASSERT(uniform.mLazyData.empty());
} }
LinkedUniform &LinkedUniform::operator=(const LinkedUniform &uniform) bool LinkedUniform::isReferencedByVertexShader() const
{ {
// This function is not intended to be called during runtime. return vsRegisterIndex != GL_INVALID_INDEX;
ASSERT(uniform.mLazyData.empty());
sh::Uniform::operator=(uniform);
blockIndex = uniform.blockIndex;
blockInfo = uniform.blockInfo;
return *this;
} }
LinkedUniform::~LinkedUniform() bool LinkedUniform::isReferencedByFragmentShader() const
{ {
return psRegisterIndex != GL_INVALID_INDEX;
} }
bool LinkedUniform::isInDefaultBlock() const bool LinkedUniform::isInDefaultBlock() const
...@@ -68,30 +72,7 @@ bool LinkedUniform::isInDefaultBlock() const ...@@ -68,30 +72,7 @@ bool LinkedUniform::isInDefaultBlock() const
size_t LinkedUniform::dataSize() const size_t LinkedUniform::dataSize() const
{ {
ASSERT(type != GL_STRUCT_ANGLEX); ASSERT(type != GL_STRUCT_ANGLEX);
if (mLazyData.empty()) return VariableInternalSize(type) * elementCount();
{
mLazyData.resize(VariableExternalSize(type) * elementCount());
ASSERT(!mLazyData.empty());
}
return mLazyData.size();
}
uint8_t *LinkedUniform::data()
{
if (mLazyData.empty())
{
// dataSize() will init the data store.
size_t size = dataSize();
memset(mLazyData.data(), 0, size);
}
return mLazyData.data();
}
const uint8_t *LinkedUniform::data() const
{
return const_cast<LinkedUniform *>(this)->data();
} }
bool LinkedUniform::isSampler() const bool LinkedUniform::isSampler() const
...@@ -99,48 +80,33 @@ bool LinkedUniform::isSampler() const ...@@ -99,48 +80,33 @@ bool LinkedUniform::isSampler() const
return IsSamplerType(type); return IsSamplerType(type);
} }
bool LinkedUniform::isField() const bool LinkedUniform::isBuiltIn() const
{
return name.find('.') != std::string::npos;
}
size_t LinkedUniform::getElementSize() const
{ {
return VariableExternalSize(type); return name.compare(0, 3, "gl_") == 0;
} }
uint8_t *LinkedUniform::getDataPtrToElement(size_t elementIndex) UniformBlock::UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize)
: name(name),
elementIndex(elementIndex),
dataSize(dataSize),
psRegisterIndex(GL_INVALID_INDEX),
vsRegisterIndex(GL_INVALID_INDEX)
{ {
ASSERT((!isArray() && elementIndex == 0) || (isArray() && elementIndex < arraySize));
return data() + getElementSize() * elementIndex;
} }
const uint8_t *LinkedUniform::getDataPtrToElement(size_t elementIndex) const bool UniformBlock::isArrayElement() const
{ {
return const_cast<LinkedUniform *>(this)->getDataPtrToElement(elementIndex); return elementIndex != GL_INVALID_INDEX;
} }
UniformBlock::UniformBlock() bool UniformBlock::isReferencedByVertexShader() const
: isArray(false),
arrayElement(0),
dataSize(0),
vertexStaticUse(false),
fragmentStaticUse(false),
psRegisterIndex(GL_INVALID_INDEX),
vsRegisterIndex(GL_INVALID_INDEX)
{ {
return vsRegisterIndex != GL_INVALID_INDEX;
} }
UniformBlock::UniformBlock(const std::string &nameIn, bool isArrayIn, unsigned int arrayElementIn) bool UniformBlock::isReferencedByFragmentShader() const
: name(nameIn),
isArray(isArrayIn),
arrayElement(arrayElementIn),
dataSize(0),
vertexStaticUse(false),
fragmentStaticUse(false),
psRegisterIndex(GL_INVALID_INDEX),
vsRegisterIndex(GL_INVALID_INDEX)
{ {
return psRegisterIndex != GL_INVALID_INDEX;
} }
} }
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include "angle_gl.h" #include "angle_gl.h"
#include "common/debug.h" #include "common/debug.h"
#include "common/MemoryBuffer.h"
#include "compiler/translator/blocklayout.h" #include "compiler/translator/blocklayout.h"
#include "libANGLE/angletypes.h" #include "libANGLE/angletypes.h"
...@@ -20,47 +19,53 @@ namespace gl ...@@ -20,47 +19,53 @@ namespace gl
{ {
// Helper struct representing a single shader uniform // Helper struct representing a single shader uniform
struct LinkedUniform : public sh::Uniform struct LinkedUniform : angle::NonCopyable
{ {
LinkedUniform();
LinkedUniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, const int blockIndex, const sh::BlockMemberInfo &blockInfo); LinkedUniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, const int blockIndex, const sh::BlockMemberInfo &blockInfo);
LinkedUniform(const sh::Uniform &uniform);
LinkedUniform(const LinkedUniform &uniform);
LinkedUniform &operator=(const LinkedUniform &uniform);
~LinkedUniform(); ~LinkedUniform();
bool isArray() const;
unsigned int elementCount() const;
bool isReferencedByVertexShader() const;
bool isReferencedByFragmentShader() const;
bool isInDefaultBlock() const;
size_t dataSize() const; size_t dataSize() const;
uint8_t *data();
const uint8_t *data() const;
bool isSampler() const; bool isSampler() const;
bool isInDefaultBlock() const; bool isBuiltIn() const;
bool isField() const;
size_t getElementSize() const;
uint8_t *getDataPtrToElement(size_t elementIndex);
const uint8_t *getDataPtrToElement(size_t elementIndex) const;
int blockIndex; const GLenum type;
sh::BlockMemberInfo blockInfo; const GLenum precision;
const std::string name;
const unsigned int arraySize;
const int blockIndex;
const sh::BlockMemberInfo blockInfo;
private: unsigned char *data;
mutable rx::MemoryBuffer mLazyData; bool dirty;
unsigned int psRegisterIndex;
unsigned int vsRegisterIndex;
unsigned int registerCount;
// Register "elements" are used for uniform structs in ES3, to appropriately identify single uniforms
// inside aggregate types, which are packed according C-like structure rules.
unsigned int registerElement;
}; };
// Helper struct representing a single shader uniform block // Helper struct representing a single shader uniform block
struct UniformBlock struct UniformBlock : angle::NonCopyable
{ {
UniformBlock(); // use GL_INVALID_INDEX for non-array elements
UniformBlock(const std::string &nameIn, bool isArrayIn, unsigned int arrayElementIn); UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize);
UniformBlock(const UniformBlock &other) = default;
UniformBlock &operator=(const UniformBlock &other) = default; bool isArrayElement() const;
bool isReferencedByVertexShader() const;
std::string name; bool isReferencedByFragmentShader() const;
bool isArray;
unsigned int arrayElement; const std::string name;
unsigned int dataSize; const unsigned int elementIndex;
const unsigned int dataSize;
bool vertexStaticUse;
bool fragmentStaticUse;
std::vector<unsigned int> memberUniformIndexes; std::vector<unsigned int> memberUniformIndexes;
......
...@@ -6,24 +6,32 @@ ...@@ -6,24 +6,32 @@
// queryconversions.cpp: Implementation of state query cast conversions // queryconversions.cpp: Implementation of state query cast conversions
#include "libANGLE/queryconversions.h"
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "common/utilities.h" #include "common/utilities.h"
namespace gl namespace gl
{ {
namespace // Helper class for converting a GL type to a GLenum:
{ // We can't use CastStateValueEnum generally, because of GLboolean + GLubyte overlap.
// We restrict our use to CastStateValue, where it eliminates duplicate parameters.
template <typename GLType>
struct CastStateValueEnum { static GLenum mEnumForType; };
GLint64 ExpandFloatToInteger(GLfloat value) template <> GLenum CastStateValueEnum<GLint>::mEnumForType = GL_INT;
template <> GLenum CastStateValueEnum<GLuint>::mEnumForType = GL_UNSIGNED_INT;
template <> GLenum CastStateValueEnum<GLboolean>::mEnumForType = GL_BOOL;
template <> GLenum CastStateValueEnum<GLint64>::mEnumForType = GL_INT_64_ANGLEX;
template <> GLenum CastStateValueEnum<GLfloat>::mEnumForType = GL_FLOAT;
static GLint64 ExpandFloatToInteger(GLfloat value)
{ {
return static_cast<GLint64>((static_cast<double>(0xFFFFFFFFULL) * value - 1.0) / 2.0); return static_cast<GLint64>((static_cast<double>(0xFFFFFFFFULL) * value - 1.0) / 2.0);
} }
template <typename QueryT> template <typename QueryT>
QueryT ClampToQueryRange(GLint64 value) static QueryT ClampToQueryRange(GLint64 value)
{ {
const GLint64 min = static_cast<GLint64>(std::numeric_limits<QueryT>::min()); const GLint64 min = static_cast<GLint64>(std::numeric_limits<QueryT>::min());
const GLint64 max = static_cast<GLint64>(std::numeric_limits<QueryT>::max()); const GLint64 max = static_cast<GLint64>(std::numeric_limits<QueryT>::max());
...@@ -33,8 +41,8 @@ QueryT ClampToQueryRange(GLint64 value) ...@@ -33,8 +41,8 @@ QueryT ClampToQueryRange(GLint64 value)
template <typename QueryT, typename NativeT> template <typename QueryT, typename NativeT>
QueryT CastStateValueToInt(GLenum pname, NativeT value) QueryT CastStateValueToInt(GLenum pname, NativeT value)
{ {
GLenum queryType = GLTypeToGLenum<QueryT>::value; GLenum queryType = CastStateValueEnum<QueryT>::mEnumForType;
GLenum nativeType = GLTypeToGLenum<NativeT>::value; GLenum nativeType = CastStateValueEnum<NativeT>::mEnumForType;
if (nativeType == GL_FLOAT) if (nativeType == GL_FLOAT)
{ {
...@@ -64,37 +72,18 @@ QueryT CastStateValueToInt(GLenum pname, NativeT value) ...@@ -64,37 +72,18 @@ QueryT CastStateValueToInt(GLenum pname, NativeT value)
template <typename QueryT, typename NativeT> template <typename QueryT, typename NativeT>
QueryT CastStateValue(GLenum pname, NativeT value) QueryT CastStateValue(GLenum pname, NativeT value)
{ {
GLenum queryType = GLTypeToGLenum<QueryT>::value; GLenum queryType = CastStateValueEnum<QueryT>::mEnumForType;
switch (queryType) switch (queryType)
{ {
case GL_INT: case GL_INT: return CastStateValueToInt<QueryT, NativeT>(pname, value);
return CastStateValueToInt<QueryT, NativeT>(pname, value); case GL_INT_64_ANGLEX: return CastStateValueToInt<QueryT, NativeT>(pname, value);
case GL_INT_64_ANGLEX: case GL_FLOAT: return static_cast<QueryT>(value);
return CastStateValueToInt<QueryT, NativeT>(pname, value); case GL_BOOL: return static_cast<QueryT>(value == static_cast<NativeT>(0) ? GL_FALSE : GL_TRUE);
case GL_FLOAT: default: UNREACHABLE(); return 0;
return static_cast<QueryT>(value);
case GL_BOOL:
return static_cast<QueryT>(value == static_cast<NativeT>(0) ? GL_FALSE : GL_TRUE);
default:
UNREACHABLE();
return 0;
} }
} }
} // anonymous namespace
template <>
GLenum GLTypeToGLenum<GLint>::value = GL_INT;
template <>
GLenum GLTypeToGLenum<GLuint>::value = GL_UNSIGNED_INT;
template <>
GLenum GLTypeToGLenum<GLboolean>::value = GL_BOOL;
template <>
GLenum GLTypeToGLenum<GLint64>::value = GL_INT_64_ANGLEX;
template <>
GLenum GLTypeToGLenum<GLfloat>::value = GL_FLOAT;
template <typename QueryT> template <typename QueryT>
void CastStateValues(Context *context, GLenum nativeType, GLenum pname, void CastStateValues(Context *context, GLenum nativeType, GLenum pname,
unsigned int numParams, QueryT *outParams) unsigned int numParams, QueryT *outParams)
......
...@@ -6,25 +6,8 @@ ...@@ -6,25 +6,8 @@
// queryconversions.h: Declaration of state query cast conversions // queryconversions.h: Declaration of state query cast conversions
#ifndef LIBANGLE_QUERY_CONVERSIONS_H_
#define LIBANGLE_QUERY_CONVERSIONS_H_
#include "angle_gl.h"
#include "common/angleutils.h"
namespace gl namespace gl
{ {
class Context;
// Helper class for converting a GL type to a GLenum:
// We can't use CastStateValueEnum generally, because of GLboolean + GLubyte overlap.
// We restrict our use to CastStateValue, where it eliminates duplicate parameters.
template <typename GLType>
struct GLTypeToGLenum
{
static GLenum value;
};
// The GL state query API types are: bool, int, uint, float, int64 // The GL state query API types are: bool, int, uint, float, int64
template <typename QueryT> template <typename QueryT>
...@@ -32,5 +15,3 @@ void CastStateValues(Context *context, GLenum nativeType, GLenum pname, ...@@ -32,5 +15,3 @@ void CastStateValues(Context *context, GLenum nativeType, GLenum pname,
unsigned int numParams, QueryT *outParams); unsigned int numParams, QueryT *outParams);
} }
#endif // LIBANGLE_QUERY_CONVERSIONS_H_
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ProgramD3D.cpp: Defines the rx::ProgramD3D class which implements rx::ProgramImpl.
#include "libANGLE/renderer/ProgramImpl.h"
#include "common/utilities.h"
namespace rx
{
LinkResult::LinkResult(bool linkSuccess, const gl::Error &error)
: linkSuccess(linkSuccess),
error(error)
{
}
ProgramImpl::ProgramImpl(const gl::Program::Data &data) : mData(data)
{
}
ProgramImpl::~ProgramImpl()
{
// Ensure that reset was called by the inherited class during destruction
ASSERT(mUniformIndex.size() == 0);
}
gl::LinkedUniform *ProgramImpl::getUniformByLocation(GLint location) const
{
ASSERT(location >= 0 && mUniformIndex.find(location) != mUniformIndex.end());
return mUniforms[mUniformIndex.at(location).index];
}
gl::LinkedUniform *ProgramImpl::getUniformByName(const std::string &name) const
{
for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
{
if (mUniforms[uniformIndex]->name == name)
{
return mUniforms[uniformIndex];
}
}
return NULL;
}
gl::UniformBlock *ProgramImpl::getUniformBlockByIndex(GLuint blockIndex) const
{
ASSERT(blockIndex < mUniformBlocks.size());
return mUniformBlocks[blockIndex];
}
GLint ProgramImpl::getUniformLocation(const std::string &name) const
{
size_t subscript = GL_INVALID_INDEX;
std::string baseName = gl::ParseUniformName(name, &subscript);
for (const auto &info : mUniformIndex)
{
GLuint location = info.first;
const gl::VariableLocation &uniform = info.second;
if (uniform.name == baseName)
{
const bool isArray = mUniforms[uniform.index]->isArray();
if ((isArray && uniform.element == subscript) ||
(subscript == GL_INVALID_INDEX))
{
return location;
}
}
}
return -1;
}
GLuint ProgramImpl::getUniformIndex(const std::string &name) const
{
size_t subscript = GL_INVALID_INDEX;
std::string baseName = gl::ParseUniformName(name, &subscript);
// The app is not allowed to specify array indices other than 0 for arrays of basic types
if (subscript != 0 && subscript != GL_INVALID_INDEX)
{
return GL_INVALID_INDEX;
}
unsigned int numUniforms = static_cast<unsigned int>(mUniforms.size());
for (unsigned int index = 0; index < numUniforms; index++)
{
if (mUniforms[index]->name == baseName)
{
if (mUniforms[index]->isArray() || subscript == GL_INVALID_INDEX)
{
return index;
}
}
}
return GL_INVALID_INDEX;
}
GLuint ProgramImpl::getUniformBlockIndex(const std::string &name) const
{
size_t subscript = GL_INVALID_INDEX;
std::string baseName = gl::ParseUniformName(name, &subscript);
unsigned int numUniformBlocks = static_cast<unsigned int>(mUniformBlocks.size());
for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++)
{
const gl::UniformBlock &uniformBlock = *mUniformBlocks[blockIndex];
if (uniformBlock.name == baseName)
{
const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0);
if (subscript == uniformBlock.elementIndex || arrayElementZero)
{
return blockIndex;
}
}
}
return GL_INVALID_INDEX;
}
void ProgramImpl::reset()
{
SafeDeleteContainer(mUniforms);
mUniformIndex.clear();
SafeDeleteContainer(mUniformBlocks);
}
}
...@@ -23,17 +23,16 @@ namespace rx ...@@ -23,17 +23,16 @@ namespace rx
struct LinkResult struct LinkResult
{ {
LinkResult(bool linkSuccess, const gl::Error &error) : linkSuccess(linkSuccess), error(error) {}
bool linkSuccess; bool linkSuccess;
gl::Error error; gl::Error error;
LinkResult(bool linkSuccess, const gl::Error &error);
}; };
class ProgramImpl : angle::NonCopyable class ProgramImpl : angle::NonCopyable
{ {
public: public:
ProgramImpl(const gl::Program::Data &data) : mData(data) {} ProgramImpl(const gl::Program::Data &data);
virtual ~ProgramImpl() {} virtual ~ProgramImpl();
virtual int getShaderVersion() const = 0; virtual int getShaderVersion() const = 0;
...@@ -66,16 +65,41 @@ class ProgramImpl : angle::NonCopyable ...@@ -66,16 +65,41 @@ class ProgramImpl : angle::NonCopyable
virtual void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0; virtual void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0;
virtual void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0; virtual void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0;
virtual void getUniformfv(GLint location, GLfloat *params) = 0;
virtual void getUniformiv(GLint location, GLint *params) = 0;
virtual void getUniformuiv(GLint location, GLuint *params) = 0;
// TODO: The following functions are possibly only applicable to D3D backends. The should be carefully evaluated to // TODO: The following functions are possibly only applicable to D3D backends. The should be carefully evaluated to
// determine if they can be removed from this interface. // determine if they can be removed from this interface.
virtual bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps) = 0; virtual bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps) = 0;
// Gather uniform block active uniform indices, and uniform block offset info. const std::vector<gl::LinkedUniform*> &getUniforms() const { return mUniforms; }
virtual void gatherUniformBlockInfo(std::vector<gl::UniformBlock> *uniformBlocks, const std::map<GLuint, gl::VariableLocation> &getUniformIndices() const { return mUniformIndex; }
std::vector<gl::LinkedUniform> *uniforms) = 0; const std::vector<gl::UniformBlock*> &getUniformBlocks() const { return mUniformBlocks; }
std::vector<gl::LinkedUniform*> &getUniforms() { return mUniforms; }
std::map<GLuint, gl::VariableLocation> &getUniformIndices() { return mUniformIndex; }
std::vector<gl::UniformBlock*> &getUniformBlocks() { return mUniformBlocks; }
gl::LinkedUniform *getUniformByLocation(GLint location) const;
gl::LinkedUniform *getUniformByName(const std::string &name) const;
gl::UniformBlock *getUniformBlockByIndex(GLuint blockIndex) const;
GLint getUniformLocation(const std::string &name) const;
GLuint getUniformIndex(const std::string &name) const;
GLuint getUniformBlockIndex(const std::string &name) const;
virtual void reset();
protected: protected:
const gl::Program::Data &mData; const gl::Program::Data &mData;
std::vector<gl::LinkedUniform*> mUniforms;
// TODO: use a hash map
std::map<GLuint, gl::VariableLocation> mUniformIndex;
std::vector<gl::UniformBlock*> mUniformBlocks;
}; };
} }
......
...@@ -20,6 +20,13 @@ ...@@ -20,6 +20,13 @@
#include "libANGLE/renderer/d3d/DynamicHLSL.h" #include "libANGLE/renderer/d3d/DynamicHLSL.h"
#include "libANGLE/renderer/d3d/WorkaroundsD3D.h" #include "libANGLE/renderer/d3d/WorkaroundsD3D.h"
namespace gl
{
struct LinkedUniform;
struct VariableLocation;
struct VertexFormat;
}
namespace rx namespace rx
{ {
class RendererD3D; class RendererD3D;
...@@ -32,43 +39,6 @@ class ShaderExecutableD3D; ...@@ -32,43 +39,6 @@ class ShaderExecutableD3D;
#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL1 #define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL1
#endif #endif
// Helper struct representing a single shader uniform
struct D3DUniform
{
D3DUniform(GLenum typeIn,
const std::string &nameIn,
unsigned int arraySizeIn,
bool defaultBlock);
~D3DUniform();
bool isSampler() const;
unsigned int elementCount() const { return std::max(1u, arraySize); }
bool isReferencedByVertexShader() const;
bool isReferencedByFragmentShader() const;
// Duplicated from the GL layer
GLenum type;
std::string name;
unsigned int arraySize;
// Pointer to a system copy of the data.
// TODO(jmadill): remove this in favor of gl::LinkedUniform::data().
uint8_t *data;
// Has the data been updated since the last sync?
bool dirty;
// Register information.
unsigned int vsRegisterIndex;
unsigned int psRegisterIndex;
unsigned int registerCount;
// Register "elements" are used for uniform structs in ES3, to appropriately identify single
// uniforms
// inside aggregate types, which are packed according C-like structure rules.
unsigned int registerElement;
};
class ProgramD3D : public ProgramImpl class ProgramD3D : public ProgramImpl
{ {
public: public:
...@@ -103,12 +73,13 @@ class ProgramD3D : public ProgramImpl ...@@ -103,12 +73,13 @@ class ProgramD3D : public ProgramImpl
LinkResult link(const gl::Data &data, gl::InfoLog &infoLog) override; LinkResult link(const gl::Data &data, gl::InfoLog &infoLog) override;
GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override; GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
void gatherUniformBlockInfo(std::vector<gl::UniformBlock> *uniformBlocks,
std::vector<gl::LinkedUniform> *uniforms) override;
void initializeUniformStorage(); void initializeUniformStorage();
gl::Error applyUniforms(); gl::Error applyUniforms();
gl::Error applyUniformBuffers(const gl::Data &data); gl::Error applyUniformBuffers(const gl::Data &data);
void assignUniformBlockRegister(gl::UniformBlock *uniformBlock,
GLenum shader,
unsigned int registerIndex,
const gl::Caps &caps);
void dirtyAllUniforms(); void dirtyAllUniforms();
void setUniform1fv(GLint location, GLsizei count, const GLfloat *v); void setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
...@@ -133,9 +104,15 @@ class ProgramD3D : public ProgramImpl ...@@ -133,9 +104,15 @@ class ProgramD3D : public ProgramImpl
void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void getUniformfv(GLint location, GLfloat *params);
void getUniformiv(GLint location, GLint *params);
void getUniformuiv(GLint location, GLuint *params);
const UniformStorageD3D &getVertexUniformStorage() const { return *mVertexUniformStorage; } const UniformStorageD3D &getVertexUniformStorage() const { return *mVertexUniformStorage; }
const UniformStorageD3D &getFragmentUniformStorage() const { return *mFragmentUniformStorage; } const UniformStorageD3D &getFragmentUniformStorage() const { return *mFragmentUniformStorage; }
void reset();
unsigned int getSerial() const; unsigned int getSerial() const;
void sortAttributesByLayout(const std::vector<TranslatedAttribute> &unsortedAttributes, void sortAttributesByLayout(const std::vector<TranslatedAttribute> &unsortedAttributes,
...@@ -198,24 +175,19 @@ class ProgramD3D : public ProgramImpl ...@@ -198,24 +175,19 @@ class ProgramD3D : public ProgramImpl
GLenum textureType; GLenum textureType;
}; };
typedef std::map<std::string, sh::BlockMemberInfo> BlockInfoMap; bool defineUniforms(gl::InfoLog &infoLog, const gl::Caps &caps);
void defineUniformBase(const ShaderD3D *shader, const sh::Uniform &uniform, unsigned int uniformRegister);
void assignUniformRegisters(); void defineUniform(const ShaderD3D *shader, const sh::ShaderVariable &uniform, const std::string &fullName,
void assignUniformRegistersBase(const ShaderD3D *shader, const sh::Uniform &uniform); sh::HLSLBlockEncoder *encoder);
void assignUniformRegisters(const ShaderD3D *shader, bool indexSamplerUniform(const gl::LinkedUniform &uniform, gl::InfoLog &infoLog, const gl::Caps &caps);
const sh::ShaderVariable &uniform, bool indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps);
const std::string &fullName, static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount,
sh::HLSLBlockEncoder *encoder); std::vector<Sampler> &outSamplers, GLuint *outUsedRange);
void assignAllSamplerRegisters();
void assignSamplerRegisters(const D3DUniform *d3dUniform);
static void AssignSamplers(unsigned int startSamplerIndex, void defineUniformBlocks(const gl::Caps &caps);
GLenum samplerType, void defineUniformBlock(const gl::Shader &shader,
unsigned int samplerCount, const sh::InterfaceBlock &interfaceBlock,
std::vector<Sampler> &outSamplers, const gl::Caps &caps);
GLuint *outUsedRange);
size_t defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, BlockInfoMap *blockInfoOut);
template <typename T> template <typename T>
void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType); void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType);
...@@ -223,19 +195,23 @@ class ProgramD3D : public ProgramImpl ...@@ -223,19 +195,23 @@ class ProgramD3D : public ProgramImpl
template <int cols, int rows> template <int cols, int rows>
void setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType); void setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType);
template <typename T>
void getUniformv(GLint location, T *params, GLenum uniformType);
template <typename VarT>
void defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex,
sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
bool inRowMajorLayout);
LinkResult compileProgramExecutables(gl::InfoLog &infoLog, LinkResult compileProgramExecutables(gl::InfoLog &infoLog,
int registers, int registers,
const std::vector<PackedVarying> &packedVaryings); const std::vector<PackedVarying> &packedVaryings);
void gatherTransformFeedbackVaryings(const std::vector<gl::LinkedVarying> &varyings); void gatherTransformFeedbackVaryings(const std::vector<gl::LinkedVarying> &varyings);
D3DUniform *getD3DUniformByName(const std::string &name);
D3DUniform *getD3DUniformFromLocation(GLint location);
void initSemanticIndex(); void initSemanticIndex();
void initAttributesByLayout(); void initAttributesByLayout();
void reset();
RendererD3D *mRenderer; RendererD3D *mRenderer;
DynamicHLSL *mDynamicHLSL; DynamicHLSL *mDynamicHLSL;
...@@ -283,7 +259,6 @@ class ProgramD3D : public ProgramImpl ...@@ -283,7 +259,6 @@ class ProgramD3D : public ProgramImpl
gl::InputLayout mCachedInputLayout; gl::InputLayout mCachedInputLayout;
std::vector<gl::LinkedVarying> mTransformFeedbackLinkedVaryings; std::vector<gl::LinkedVarying> mTransformFeedbackLinkedVaryings;
std::vector<D3DUniform *> mD3DUniforms;
static unsigned int issueSerial(); static unsigned int issueSerial();
static unsigned int mCurrentSerial; static unsigned int mCurrentSerial;
......
...@@ -37,11 +37,9 @@ class DebugAnnotator; ...@@ -37,11 +37,9 @@ class DebugAnnotator;
namespace rx namespace rx
{ {
struct D3DUniform;
class EGLImageD3D; class EGLImageD3D;
class ImageD3D; class ImageD3D;
class IndexBuffer; class IndexBuffer;
class ProgramD3D;
class RenderTargetD3D; class RenderTargetD3D;
class ShaderExecutableD3D; class ShaderExecutableD3D;
class SwapChainD3D; class SwapChainD3D;
...@@ -160,8 +158,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D ...@@ -160,8 +158,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
const gl::Framebuffer *framebuffer, const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool rasterizerDiscard,
bool transformFeedbackActive) = 0; bool transformFeedbackActive) = 0;
virtual gl::Error applyUniforms(const ProgramD3D &programD3D, virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray) = 0;
const std::vector<D3DUniform *> &uniformArray) = 0;
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize) = 0; virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize) = 0;
virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances, SourceIndexData *sourceIndexInfo) = 0; virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances, SourceIndexData *sourceIndexInfo) = 0;
virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo, SourceIndexData *sourceIndexInfo) = 0; virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo, SourceIndexData *sourceIndexInfo) = 0;
......
...@@ -2101,8 +2101,7 @@ gl::Error Renderer11::applyShaders(gl::Program *program, ...@@ -2101,8 +2101,7 @@ gl::Error Renderer11::applyShaders(gl::Program *program,
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D, gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray)
const std::vector<D3DUniform *> &uniformArray)
{ {
unsigned int totalRegisterCountVS = 0; unsigned int totalRegisterCountVS = 0;
unsigned int totalRegisterCountPS = 0; unsigned int totalRegisterCountPS = 0;
...@@ -2110,25 +2109,26 @@ gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D, ...@@ -2110,25 +2109,26 @@ gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D,
bool vertexUniformsDirty = false; bool vertexUniformsDirty = false;
bool pixelUniformsDirty = false; bool pixelUniformsDirty = false;
for (const D3DUniform *uniform : uniformArray) for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++)
{ {
if (uniform->isReferencedByVertexShader() && !uniform->isSampler()) const gl::LinkedUniform &uniform = *uniformArray[uniformIndex];
if (uniform.isReferencedByVertexShader() && !uniform.isSampler())
{ {
totalRegisterCountVS += uniform->registerCount; totalRegisterCountVS += uniform.registerCount;
vertexUniformsDirty = (vertexUniformsDirty || uniform->dirty); vertexUniformsDirty = (vertexUniformsDirty || uniform.dirty);
} }
if (uniform->isReferencedByFragmentShader() && !uniform->isSampler()) if (uniform.isReferencedByFragmentShader() && !uniform.isSampler())
{ {
totalRegisterCountPS += uniform->registerCount; totalRegisterCountPS += uniform.registerCount;
pixelUniformsDirty = (pixelUniformsDirty || uniform->dirty); pixelUniformsDirty = (pixelUniformsDirty || uniform.dirty);
} }
} }
const UniformStorage11 *vertexUniformStorage = const ProgramD3D *programD3D = GetAs<ProgramD3D>(&program);
GetAs<UniformStorage11>(&programD3D.getVertexUniformStorage()); const UniformStorage11 *vertexUniformStorage = GetAs<UniformStorage11>(&programD3D->getVertexUniformStorage());
const UniformStorage11 *fragmentUniformStorage = const UniformStorage11 *fragmentUniformStorage = GetAs<UniformStorage11>(&programD3D->getFragmentUniformStorage());
GetAs<UniformStorage11>(&programD3D.getFragmentUniformStorage());
ASSERT(vertexUniformStorage); ASSERT(vertexUniformStorage);
ASSERT(fragmentUniformStorage); ASSERT(fragmentUniformStorage);
...@@ -2156,26 +2156,26 @@ gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D, ...@@ -2156,26 +2156,26 @@ gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D,
mapPS = (float(*)[4])map.pData; mapPS = (float(*)[4])map.pData;
} }
for (const D3DUniform *uniform : uniformArray) for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++)
{ {
if (uniform->isSampler()) gl::LinkedUniform *uniform = uniformArray[uniformIndex];
continue;
unsigned int componentCount = (4 - uniform->registerElement); if (!uniform->isSampler())
{
unsigned int componentCount = (4 - uniform->registerElement);
// we assume that uniforms from structs are arranged in struct order in our uniforms list. // we assume that uniforms from structs are arranged in struct order in our uniforms list. otherwise we would
// otherwise we would overwrite previously written regions of memory. // overwrite previously written regions of memory.
if (uniform->isReferencedByVertexShader() && mapVS) if (uniform->isReferencedByVertexShader() && mapVS)
{ {
memcpy(&mapVS[uniform->vsRegisterIndex][uniform->registerElement], uniform->data, memcpy(&mapVS[uniform->vsRegisterIndex][uniform->registerElement], uniform->data, uniform->registerCount * sizeof(float) * componentCount);
uniform->registerCount * sizeof(float) * componentCount); }
}
if (uniform->isReferencedByFragmentShader() && mapPS) if (uniform->isReferencedByFragmentShader() && mapPS)
{ {
memcpy(&mapPS[uniform->psRegisterIndex][uniform->registerElement], uniform->data, memcpy(&mapPS[uniform->psRegisterIndex][uniform->registerElement], uniform->data, uniform->registerCount * sizeof(float) * componentCount);
uniform->registerCount * sizeof(float) * componentCount); }
} }
} }
...@@ -2261,7 +2261,7 @@ gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D, ...@@ -2261,7 +2261,7 @@ gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D,
} }
// GSSetConstantBuffers triggers device removal on 9_3, so we should only call it if necessary // GSSetConstantBuffers triggers device removal on 9_3, so we should only call it if necessary
if (programD3D.usesGeometryShader()) if (programD3D->usesGeometryShader())
{ {
// needed for the point sprite geometry shader // needed for the point sprite geometry shader
if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS) if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS)
......
...@@ -137,8 +137,7 @@ class Renderer11 : public RendererD3D ...@@ -137,8 +137,7 @@ class Renderer11 : public RendererD3D
bool rasterizerDiscard, bool rasterizerDiscard,
bool transformFeedbackActive) override; bool transformFeedbackActive) override;
gl::Error applyUniforms(const ProgramD3D &programD3D, virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray);
const std::vector<D3DUniform *> &uniformArray) override;
virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances, SourceIndexData *sourceIndexInfo); virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances, SourceIndexData *sourceIndexInfo);
virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo, SourceIndexData *sourceIndexInfo); virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo, SourceIndexData *sourceIndexInfo);
void applyTransformFeedbackBuffers(const gl::State &state) override; void applyTransformFeedbackBuffers(const gl::State &state) override;
......
...@@ -1915,45 +1915,46 @@ gl::Error Renderer9::applyShaders(gl::Program *program, ...@@ -1915,45 +1915,46 @@ gl::Error Renderer9::applyShaders(gl::Program *program,
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error Renderer9::applyUniforms(const ProgramD3D &programD3D, gl::Error Renderer9::applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray)
const std::vector<D3DUniform *> &uniformArray)
{ {
for (const D3DUniform *targetUniform : uniformArray) for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++)
{ {
if (!targetUniform->dirty) gl::LinkedUniform *targetUniform = uniformArray[uniformIndex];
continue;
GLfloat *f = (GLfloat *)targetUniform->data; if (targetUniform->dirty)
GLint *i = (GLint *)targetUniform->data;
switch (targetUniform->type)
{ {
case GL_SAMPLER_2D: GLfloat *f = (GLfloat*)targetUniform->data;
case GL_SAMPLER_CUBE: GLint *i = (GLint*)targetUniform->data;
switch (targetUniform->type)
{
case GL_SAMPLER_2D:
case GL_SAMPLER_CUBE:
break; break;
case GL_BOOL: case GL_BOOL:
case GL_BOOL_VEC2: case GL_BOOL_VEC2:
case GL_BOOL_VEC3: case GL_BOOL_VEC3:
case GL_BOOL_VEC4: case GL_BOOL_VEC4:
applyUniformnbv(targetUniform, i); applyUniformnbv(targetUniform, i);
break; break;
case GL_FLOAT: case GL_FLOAT:
case GL_FLOAT_VEC2: case GL_FLOAT_VEC2:
case GL_FLOAT_VEC3: case GL_FLOAT_VEC3:
case GL_FLOAT_VEC4: case GL_FLOAT_VEC4:
case GL_FLOAT_MAT2: case GL_FLOAT_MAT2:
case GL_FLOAT_MAT3: case GL_FLOAT_MAT3:
case GL_FLOAT_MAT4: case GL_FLOAT_MAT4:
applyUniformnfv(targetUniform, f); applyUniformnfv(targetUniform, f);
break; break;
case GL_INT: case GL_INT:
case GL_INT_VEC2: case GL_INT_VEC2:
case GL_INT_VEC3: case GL_INT_VEC3:
case GL_INT_VEC4: case GL_INT_VEC4:
applyUniformniv(targetUniform, i); applyUniformniv(targetUniform, i);
break; break;
default: default:
UNREACHABLE(); UNREACHABLE();
}
} }
} }
...@@ -1968,7 +1969,7 @@ gl::Error Renderer9::applyUniforms(const ProgramD3D &programD3D, ...@@ -1968,7 +1969,7 @@ gl::Error Renderer9::applyUniforms(const ProgramD3D &programD3D,
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
void Renderer9::applyUniformnfv(const D3DUniform *targetUniform, const GLfloat *v) void Renderer9::applyUniformnfv(gl::LinkedUniform *targetUniform, const GLfloat *v)
{ {
if (targetUniform->isReferencedByFragmentShader()) if (targetUniform->isReferencedByFragmentShader())
{ {
...@@ -1981,7 +1982,7 @@ void Renderer9::applyUniformnfv(const D3DUniform *targetUniform, const GLfloat * ...@@ -1981,7 +1982,7 @@ void Renderer9::applyUniformnfv(const D3DUniform *targetUniform, const GLfloat *
} }
} }
void Renderer9::applyUniformniv(const D3DUniform *targetUniform, const GLint *v) void Renderer9::applyUniformniv(gl::LinkedUniform *targetUniform, const GLint *v)
{ {
ASSERT(targetUniform->registerCount <= MAX_VERTEX_CONSTANT_VECTORS_D3D9); ASSERT(targetUniform->registerCount <= MAX_VERTEX_CONSTANT_VECTORS_D3D9);
GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4]; GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4];
...@@ -1997,7 +1998,7 @@ void Renderer9::applyUniformniv(const D3DUniform *targetUniform, const GLint *v) ...@@ -1997,7 +1998,7 @@ void Renderer9::applyUniformniv(const D3DUniform *targetUniform, const GLint *v)
applyUniformnfv(targetUniform, (GLfloat*)vector); applyUniformnfv(targetUniform, (GLfloat*)vector);
} }
void Renderer9::applyUniformnbv(const D3DUniform *targetUniform, const GLint *v) void Renderer9::applyUniformnbv(gl::LinkedUniform *targetUniform, const GLint *v)
{ {
ASSERT(targetUniform->registerCount <= MAX_VERTEX_CONSTANT_VECTORS_D3D9); ASSERT(targetUniform->registerCount <= MAX_VERTEX_CONSTANT_VECTORS_D3D9);
GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4]; GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4];
......
...@@ -32,12 +32,10 @@ namespace rx ...@@ -32,12 +32,10 @@ namespace rx
{ {
class Blit9; class Blit9;
class IndexDataManager; class IndexDataManager;
class ProgramD3D;
class StreamingIndexBufferInterface; class StreamingIndexBufferInterface;
class StaticIndexBufferInterface; class StaticIndexBufferInterface;
class VertexDataManager; class VertexDataManager;
struct ClearParameters; struct ClearParameters;
struct D3DUniform;
struct TranslatedAttribute; struct TranslatedAttribute;
enum D3D9InitError enum D3D9InitError
...@@ -113,8 +111,7 @@ class Renderer9 : public RendererD3D ...@@ -113,8 +111,7 @@ class Renderer9 : public RendererD3D
const gl::Framebuffer *framebuffer, const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool rasterizerDiscard,
bool transformFeedbackActive) override; bool transformFeedbackActive) override;
gl::Error applyUniforms(const ProgramD3D &programD3D, virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray);
const std::vector<D3DUniform *> &uniformArray) override;
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize); virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize);
virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances, SourceIndexData *sourceInfo); virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances, SourceIndexData *sourceInfo);
virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo, SourceIndexData *sourceIndexInfo); virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo, SourceIndexData *sourceIndexInfo);
...@@ -263,9 +260,9 @@ class Renderer9 : public RendererD3D ...@@ -263,9 +260,9 @@ class Renderer9 : public RendererD3D
void release(); void release();
void applyUniformnfv(const D3DUniform *targetUniform, const GLfloat *v); void applyUniformnfv(gl::LinkedUniform *targetUniform, const GLfloat *v);
void applyUniformniv(const D3DUniform *targetUniform, const GLint *v); void applyUniformniv(gl::LinkedUniform *targetUniform, const GLint *v);
void applyUniformnbv(const D3DUniform *targetUniform, const GLint *v); void applyUniformnbv(gl::LinkedUniform *targetUniform, const GLint *v);
gl::Error drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); gl::Error drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer);
gl::Error drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); gl::Error drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer);
......
...@@ -62,31 +62,32 @@ class ProgramGL : public ProgramImpl ...@@ -62,31 +62,32 @@ class ProgramGL : public ProgramImpl
void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) override; void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) override;
void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) override; void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) override;
void getUniformfv(GLint location, GLfloat *params) override;
void getUniformiv(GLint location, GLint *params) override;
void getUniformuiv(GLint location, GLuint *params) override;
bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps) override; bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps) override;
void gatherUniformBlockInfo(std::vector<gl::UniformBlock> *uniformBlocks, void reset() override;
std::vector<gl::LinkedUniform> *uniforms) override;
GLuint getProgramID() const; GLuint getProgramID() const;
const std::vector<SamplerBindingGL> &getAppliedSamplerUniforms() const; const std::vector<SamplerBindingGL> &getAppliedSamplerUniforms() const;
private: private:
void reset();
// Helper function, makes it simpler to type.
GLint uniLoc(GLint glLocation) const { return mUniformRealLocationMap[glLocation]; }
const FunctionsGL *mFunctions; const FunctionsGL *mFunctions;
StateManagerGL *mStateManager; StateManagerGL *mStateManager;
std::vector<GLint> mUniformRealLocationMap; // A map from uniform location to index of mSamplerBindings and array index of the uniform
struct SamplerLocation
{
size_t samplerIndex;
size_t arrayIndex;
};
std::map<GLint, SamplerLocation> mSamplerUniformMap;
// An array of the samplers that are used by the program // An array of the samplers that are used by the program
std::vector<SamplerBindingGL> mSamplerBindings; std::vector<SamplerBindingGL> mSamplerBindings;
// A map from a mData.getUniforms() index to a mSamplerBindings index.
std::vector<size_t> mUniformIndexToSamplerIndex;
GLuint mProgramID; GLuint mProgramID;
}; };
......
...@@ -1145,11 +1145,8 @@ bool ValidateEndQuery(gl::Context *context, GLenum target) ...@@ -1145,11 +1145,8 @@ bool ValidateEndQuery(gl::Context *context, GLenum target)
return true; return true;
} }
static bool ValidateUniformCommonBase(gl::Context *context, static bool ValidateUniformCommonBase(gl::Context *context, GLenum targetUniformType,
GLenum targetUniformType, GLint location, GLsizei count, LinkedUniform **uniformOut)
GLint location,
GLsizei count,
const LinkedUniform **uniformOut)
{ {
if (count < 0) if (count < 0)
{ {
...@@ -1176,16 +1173,16 @@ static bool ValidateUniformCommonBase(gl::Context *context, ...@@ -1176,16 +1173,16 @@ static bool ValidateUniformCommonBase(gl::Context *context,
return false; return false;
} }
const LinkedUniform &uniform = program->getUniformByLocation(location); LinkedUniform *uniform = program->getUniformByLocation(location);
// attempting to write an array to a non-array uniform is an INVALID_OPERATION // attempting to write an array to a non-array uniform is an INVALID_OPERATION
if (!uniform.isArray() && count > 1) if (!uniform->isArray() && count > 1)
{ {
context->recordError(Error(GL_INVALID_OPERATION)); context->recordError(Error(GL_INVALID_OPERATION));
return false; return false;
} }
*uniformOut = &uniform; *uniformOut = uniform;
return true; return true;
} }
...@@ -1198,7 +1195,7 @@ bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, G ...@@ -1198,7 +1195,7 @@ bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, G
return false; return false;
} }
const LinkedUniform *uniform = nullptr; LinkedUniform *uniform = NULL;
if (!ValidateUniformCommonBase(context, uniformType, location, count, &uniform)) if (!ValidateUniformCommonBase(context, uniformType, location, count, &uniform))
{ {
return false; return false;
...@@ -1233,7 +1230,7 @@ bool ValidateUniformMatrix(gl::Context *context, GLenum matrixType, GLint locati ...@@ -1233,7 +1230,7 @@ bool ValidateUniformMatrix(gl::Context *context, GLenum matrixType, GLint locati
return false; return false;
} }
const LinkedUniform *uniform = nullptr; LinkedUniform *uniform = NULL;
if (!ValidateUniformCommonBase(context, matrixType, location, count, &uniform)) if (!ValidateUniformCommonBase(context, matrixType, location, count, &uniform))
{ {
return false; return false;
...@@ -1529,7 +1526,7 @@ static bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count, GLsiz ...@@ -1529,7 +1526,7 @@ static bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count, GLsiz
// Uniform buffer validation // Uniform buffer validation
for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++) for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++)
{ {
const gl::UniformBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex); const gl::UniformBlock *uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex);
GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex); GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex);
const gl::Buffer *uniformBuffer = state.getIndexedUniformBuffer(blockBinding); const gl::Buffer *uniformBuffer = state.getIndexedUniformBuffer(blockBinding);
...@@ -1548,7 +1545,7 @@ static bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count, GLsiz ...@@ -1548,7 +1545,7 @@ static bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count, GLsiz
uniformBufferSize = static_cast<size_t>(uniformBuffer->getSize()); uniformBufferSize = static_cast<size_t>(uniformBuffer->getSize());
} }
if (uniformBufferSize < uniformBlock.dataSize) if (uniformBufferSize < uniformBlock->dataSize)
{ {
// undefined behaviour // undefined behaviour
context->recordError(Error(GL_INVALID_OPERATION, "It is undefined behaviour to use a uniform buffer that is too small.")); context->recordError(Error(GL_INVALID_OPERATION, "It is undefined behaviour to use a uniform buffer that is too small."));
...@@ -1947,8 +1944,8 @@ static bool ValidateSizedGetUniform(Context *context, GLuint program, GLint loca ...@@ -1947,8 +1944,8 @@ static bool ValidateSizedGetUniform(Context *context, GLuint program, GLint loca
ASSERT(programObject); ASSERT(programObject);
// sized queries -- ensure the provided buffer is large enough // sized queries -- ensure the provided buffer is large enough
const LinkedUniform &uniform = programObject->getUniformByLocation(location); LinkedUniform *uniform = programObject->getUniformByLocation(location);
size_t requiredBytes = VariableExternalSize(uniform.type); size_t requiredBytes = VariableExternalSize(uniform->type);
if (static_cast<size_t>(bufSize) < requiredBytes) if (static_cast<size_t>(bufSize) < requiredBytes)
{ {
context->recordError(Error(GL_INVALID_OPERATION)); context->recordError(Error(GL_INVALID_OPERATION));
......
...@@ -140,6 +140,7 @@ ...@@ -140,6 +140,7 @@
'libANGLE/renderer/FramebufferImpl.h', 'libANGLE/renderer/FramebufferImpl.h',
'libANGLE/renderer/ImageImpl.h', 'libANGLE/renderer/ImageImpl.h',
'libANGLE/renderer/ImplFactory.h', 'libANGLE/renderer/ImplFactory.h',
'libANGLE/renderer/ProgramImpl.cpp',
'libANGLE/renderer/ProgramImpl.h', 'libANGLE/renderer/ProgramImpl.h',
'libANGLE/renderer/QueryImpl.h', 'libANGLE/renderer/QueryImpl.h',
'libANGLE/renderer/RenderbufferImpl.h', 'libANGLE/renderer/RenderbufferImpl.h',
......
...@@ -144,12 +144,9 @@ ...@@ -144,12 +144,9 @@
1031 WIN : dEQP-GLES2.functional.uniform_api.random.41 = FAIL 1031 WIN : dEQP-GLES2.functional.uniform_api.random.41 = FAIL
1031 WIN : dEQP-GLES2.functional.uniform_api.random.51 = FAIL 1031 WIN : dEQP-GLES2.functional.uniform_api.random.51 = FAIL
1031 WIN : dEQP-GLES2.functional.uniform_api.random.54 = FAIL 1031 WIN : dEQP-GLES2.functional.uniform_api.random.54 = FAIL
1031 WIN : dEQP-GLES2.functional.uniform_api.random.61 = FAIL
1031 WIN : dEQP-GLES2.functional.uniform_api.random.72 = FAIL 1031 WIN : dEQP-GLES2.functional.uniform_api.random.72 = FAIL
1031 WIN : dEQP-GLES2.functional.uniform_api.random.79 = FAIL 1031 WIN : dEQP-GLES2.functional.uniform_api.random.79 = FAIL
1031 WIN : dEQP-GLES2.functional.uniform_api.random.82 = FAIL 1031 WIN : dEQP-GLES2.functional.uniform_api.random.82 = FAIL
1031 WIN : dEQP-GLES2.functional.uniform_api.random.87 = FAIL
1031 WIN : dEQP-GLES2.functional.uniform_api.random.93 = FAIL
504 WIN : dEQP-GLES2.functional.uniform_api.value.initial.get_uniform.basic_struct.sampler2D_samplerCube_* = FAIL 504 WIN : dEQP-GLES2.functional.uniform_api.value.initial.get_uniform.basic_struct.sampler2D_samplerCube_* = FAIL
504 WIN : dEQP-GLES2.functional.uniform_api.value.initial.get_uniform.struct_in_array.sampler2D_samplerCube_* = FAIL 504 WIN : dEQP-GLES2.functional.uniform_api.value.initial.get_uniform.struct_in_array.sampler2D_samplerCube_* = FAIL
504 WIN : dEQP-GLES2.functional.uniform_api.value.initial.get_uniform.array_in_struct.sampler2D_samplerCube_* = FAIL 504 WIN : dEQP-GLES2.functional.uniform_api.value.initial.get_uniform.array_in_struct.sampler2D_samplerCube_* = FAIL
......
...@@ -982,14 +982,11 @@ ...@@ -982,14 +982,11 @@
1098 WIN : dEQP-GLES3.functional.uniform_api.random.3 = FAIL 1098 WIN : dEQP-GLES3.functional.uniform_api.random.3 = FAIL
1098 WIN : dEQP-GLES3.functional.uniform_api.random.6 = FAIL 1098 WIN : dEQP-GLES3.functional.uniform_api.random.6 = FAIL
1098 WIN : dEQP-GLES3.functional.uniform_api.random.8 = FAIL 1098 WIN : dEQP-GLES3.functional.uniform_api.random.8 = FAIL
1098 WIN : dEQP-GLES3.functional.uniform_api.random.17 = FAIL
1098 WIN : dEQP-GLES3.functional.uniform_api.random.20 = FAIL 1098 WIN : dEQP-GLES3.functional.uniform_api.random.20 = FAIL
1098 WIN : dEQP-GLES3.functional.uniform_api.random.21 = FAIL 1098 WIN : dEQP-GLES3.functional.uniform_api.random.21 = FAIL
1098 WIN : dEQP-GLES3.functional.uniform_api.random.29 = FAIL 1098 WIN : dEQP-GLES3.functional.uniform_api.random.29 = FAIL
1098 WIN : dEQP-GLES3.functional.uniform_api.random.54 = FAIL
1098 WIN : dEQP-GLES3.functional.uniform_api.random.81 = FAIL 1098 WIN : dEQP-GLES3.functional.uniform_api.random.81 = FAIL
1098 WIN : dEQP-GLES3.functional.uniform_api.random.83 = FAIL 1098 WIN : dEQP-GLES3.functional.uniform_api.random.83 = FAIL
1098 WIN : dEQP-GLES3.functional.uniform_api.random.87 = FAIL
1099 WIN : dEQP-GLES3.functional.attribute_location.bind_aliasing.cond_float = FAIL 1099 WIN : dEQP-GLES3.functional.attribute_location.bind_aliasing.cond_float = FAIL
1099 WIN : dEQP-GLES3.functional.attribute_location.bind_aliasing.max_cond_float = FAIL 1099 WIN : dEQP-GLES3.functional.attribute_location.bind_aliasing.max_cond_float = FAIL
1099 WIN : dEQP-GLES3.functional.attribute_location.bind_aliasing.cond_vec2 = FAIL 1099 WIN : dEQP-GLES3.functional.attribute_location.bind_aliasing.cond_vec2 = FAIL
......
...@@ -313,51 +313,6 @@ TEST_P(UniformBufferTest, ManyUniformBufferRange) ...@@ -313,51 +313,6 @@ TEST_P(UniformBufferTest, ManyUniformBufferRange)
} }
} }
// Tests that active uniforms have the right names.
TEST_P(UniformBufferTest, ActiveUniformNames)
{
const std::string &vertexShaderSource =
"#version 300 es\n"
"in vec2 position;\n"
"out float v;\n"
"uniform blockName {\n"
" float f;\n"
"} instanceName;\n"
"void main() {\n"
" v = instanceName.f;\n"
" gl_Position = vec4(position, 0, 1);\n"
"}";
const std::string &fragmentShaderSource =
"#version 300 es\n"
"precision highp float;\n"
"in float v;\n"
"out vec4 color;\n"
"void main() {\n"
" color = vec4(v, 0, 0, 1);\n"
"}";
GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
ASSERT_NE(0u, program);
GLint activeUniforms;
glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &activeUniforms);
ASSERT_EQ(1, activeUniforms);
GLint maxLength, size;
GLenum type;
GLsizei length;
glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
std::vector<GLchar> strBuffer(maxLength + 1, 0);
glGetActiveUniform(program, 0, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size);
EXPECT_GLENUM_EQ(GL_FLOAT, type);
EXPECT_EQ("blockName.f", std::string(&strBuffer[0]));
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_INSTANTIATE_TEST(UniformBufferTest, ES3_D3D11(), ES3_D3D11_FL11_1(), ES3_D3D11_FL11_1_REFERENCE()); ANGLE_INSTANTIATE_TEST(UniformBufferTest, ES3_D3D11(), ES3_D3D11_FL11_1(), ES3_D3D11_FL11_1_REFERENCE());
......
...@@ -16,7 +16,11 @@ namespace ...@@ -16,7 +16,11 @@ namespace
class UniformTest : public ANGLETest class UniformTest : public ANGLETest
{ {
protected: protected:
UniformTest() : mProgram(0), mUniformFLocation(-1), mUniformILocation(-1), mUniformBLocation(-1) UniformTest()
: mProgram(0),
mUniformFLocation(-1),
mUniformILocation(-1),
mUniformBLocation(-1)
{ {
setWindowWidth(128); setWindowWidth(128);
setWindowHeight(128); setWindowHeight(128);
...@@ -36,12 +40,7 @@ class UniformTest : public ANGLETest ...@@ -36,12 +40,7 @@ class UniformTest : public ANGLETest
"uniform float uniF;\n" "uniform float uniF;\n"
"uniform int uniI;\n" "uniform int uniI;\n"
"uniform bool uniB;\n" "uniform bool uniB;\n"
"uniform bool uniBArr[4];\n" "void main() { gl_FragColor = vec4(uniF + float(uniI) + (uniB ? 1.0 : 0.0)); }";
"void main() {\n"
" gl_FragColor = vec4(uniF + float(uniI));\n"
" gl_FragColor += vec4(uniB ? 1.0 : 0.0);\n"
" gl_FragColor += vec4(uniBArr[0] ? 1.0 : 0.0);\n"
"}";
mProgram = CompileProgram(vertexShader, fragShader); mProgram = CompileProgram(vertexShader, fragShader);
ASSERT_NE(mProgram, 0u); ASSERT_NE(mProgram, 0u);
...@@ -170,6 +169,13 @@ TEST_P(UniformTest, UniformArrayLocations) ...@@ -170,6 +169,13 @@ TEST_P(UniformTest, UniformArrayLocations)
// Test that float to integer GetUniform rounds values correctly. // Test that float to integer GetUniform rounds values correctly.
TEST_P(UniformTest, FloatUniformStateQuery) TEST_P(UniformTest, FloatUniformStateQuery)
{ {
// TODO(jmadill): remove this suppression once we support ANGLE-only state queries.
if (isAMD() && (GetParam() == ES2_OPENGL() || GetParam() == ES3_OPENGL()))
{
std::cout << "Skipping test due to a driver bug on AMD." << std::endl;
return;
}
std::vector<GLfloat> inValues; std::vector<GLfloat> inValues;
std::vector<GLfloat> expectedFValues; std::vector<GLfloat> expectedFValues;
std::vector<GLint> expectedIValues; std::vector<GLint> expectedIValues;
...@@ -208,7 +214,7 @@ TEST_P(UniformTest, FloatUniformStateQuery) ...@@ -208,7 +214,7 @@ TEST_P(UniformTest, FloatUniformStateQuery)
for (size_t index = 0; index < inValues.size(); ++index) for (size_t index = 0; index < inValues.size(); ++index)
{ {
GLfloat inValue = inValues[index]; GLfloat inValue = inValues[index];
GLfloat expectedValue = expectedFValues[index]; GLfloat expectedValue = expectedFValues[index];
glUniform1f(mUniformFLocation, inValue); glUniform1f(mUniformFLocation, inValue);
...@@ -220,7 +226,7 @@ TEST_P(UniformTest, FloatUniformStateQuery) ...@@ -220,7 +226,7 @@ TEST_P(UniformTest, FloatUniformStateQuery)
for (size_t index = 0; index < inValues.size(); ++index) for (size_t index = 0; index < inValues.size(); ++index)
{ {
GLfloat inValue = inValues[index]; GLfloat inValue = inValues[index];
GLint expectedValue = expectedIValues[index]; GLint expectedValue = expectedIValues[index];
glUniform1f(mUniformFLocation, inValue); glUniform1f(mUniformFLocation, inValue);
...@@ -234,6 +240,13 @@ TEST_P(UniformTest, FloatUniformStateQuery) ...@@ -234,6 +240,13 @@ TEST_P(UniformTest, FloatUniformStateQuery)
// Test that integer to float GetUniform rounds values correctly. // Test that integer to float GetUniform rounds values correctly.
TEST_P(UniformTest, IntUniformStateQuery) TEST_P(UniformTest, IntUniformStateQuery)
{ {
// TODO(jmadill): remove this suppression once we support ANGLE-only state queries.
if ((isAMD() || isIntel()) && (GetParam() == ES2_OPENGL() || GetParam() == ES3_OPENGL()))
{
std::cout << "Skipping test due to a driver bug." << std::endl;
return;
}
std::vector<GLint> inValues; std::vector<GLint> inValues;
std::vector<GLint> expectedIValues; std::vector<GLint> expectedIValues;
std::vector<GLfloat> expectedFValues; std::vector<GLfloat> expectedFValues;
...@@ -261,7 +274,7 @@ TEST_P(UniformTest, IntUniformStateQuery) ...@@ -261,7 +274,7 @@ TEST_P(UniformTest, IntUniformStateQuery)
for (size_t index = 0; index < inValues.size(); ++index) for (size_t index = 0; index < inValues.size(); ++index)
{ {
GLint inValue = inValues[index]; GLint inValue = inValues[index];
GLint expectedValue = expectedIValues[index]; GLint expectedValue = expectedIValues[index];
glUniform1i(mUniformILocation, inValue); glUniform1i(mUniformILocation, inValue);
...@@ -273,7 +286,7 @@ TEST_P(UniformTest, IntUniformStateQuery) ...@@ -273,7 +286,7 @@ TEST_P(UniformTest, IntUniformStateQuery)
for (size_t index = 0; index < inValues.size(); ++index) for (size_t index = 0; index < inValues.size(); ++index)
{ {
GLint inValue = inValues[index]; GLint inValue = inValues[index];
GLfloat expectedValue = expectedFValues[index]; GLfloat expectedValue = expectedFValues[index];
glUniform1i(mUniformILocation, inValue); glUniform1i(mUniformILocation, inValue);
...@@ -288,10 +301,9 @@ TEST_P(UniformTest, IntUniformStateQuery) ...@@ -288,10 +301,9 @@ TEST_P(UniformTest, IntUniformStateQuery)
TEST_P(UniformTest, BooleanUniformStateQuery) TEST_P(UniformTest, BooleanUniformStateQuery)
{ {
glUseProgram(mProgram); glUseProgram(mProgram);
GLint intValue = 0; GLint intValue = 0;
GLfloat floatValue = 0.0f; GLfloat floatValue = 0.0f;
// Calling Uniform1i
glUniform1i(mUniformBLocation, GL_FALSE); glUniform1i(mUniformBLocation, GL_FALSE);
glGetUniformiv(mProgram, mUniformBLocation, &intValue); glGetUniformiv(mProgram, mUniformBLocation, &intValue);
...@@ -308,67 +320,6 @@ TEST_P(UniformTest, BooleanUniformStateQuery) ...@@ -308,67 +320,6 @@ TEST_P(UniformTest, BooleanUniformStateQuery)
glGetUniformfv(mProgram, mUniformBLocation, &floatValue); glGetUniformfv(mProgram, mUniformBLocation, &floatValue);
EXPECT_EQ(1.0f, floatValue); EXPECT_EQ(1.0f, floatValue);
// Calling Uniform1f
glUniform1f(mUniformBLocation, 0.0f);
glGetUniformiv(mProgram, mUniformBLocation, &intValue);
EXPECT_EQ(0, intValue);
glGetUniformfv(mProgram, mUniformBLocation, &floatValue);
EXPECT_EQ(0.0f, floatValue);
glUniform1f(mUniformBLocation, 1.0f);
glGetUniformiv(mProgram, mUniformBLocation, &intValue);
EXPECT_EQ(1, intValue);
glGetUniformfv(mProgram, mUniformBLocation, &floatValue);
EXPECT_EQ(1.0f, floatValue);
ASSERT_GL_NO_ERROR();
}
// Test queries for arrays of boolean uniforms.
TEST_P(UniformTest, BooleanArrayUniformStateQuery)
{
glUseProgram(mProgram);
GLint intValues[4] = {0};
GLfloat floatValues[4] = {0.0f};
GLint boolValuesi[4] = {0, 1, 0, 1};
GLfloat boolValuesf[4] = {0, 1, 0, 1};
GLint location = glGetUniformLocation(mProgram, "uniBArr");
// Calling Uniform1iv
glUniform1iv(location, 4, boolValuesi);
glGetUniformiv(mProgram, location, intValues);
for (unsigned int idx = 0; idx < 4; ++idx)
{
EXPECT_EQ(boolValuesi[idx], intValues[idx]);
}
glGetUniformfv(mProgram, location, floatValues);
for (unsigned int idx = 0; idx < 4; ++idx)
{
EXPECT_EQ(boolValuesf[idx], floatValues[idx]);
}
// Calling Uniform1fv
glUniform1fv(location, 4, boolValuesf);
glGetUniformiv(mProgram, location, intValues);
for (unsigned int idx = 0; idx < 4; ++idx)
{
EXPECT_EQ(boolValuesi[idx], intValues[idx]);
}
glGetUniformfv(mProgram, location, floatValues);
for (unsigned int idx = 0; idx < 4; ++idx)
{
EXPECT_EQ(boolValuesf[idx], floatValues[idx]);
}
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
} }
......
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