Commit 8ff21aea by Jamie Madill

Move storage for uniform blocks to the program binary.

With dynamic shaders we may have multiple shader executables per program binary. We must store the uniforms outside the executable, in the program binary, to be consistent between variations. Change-Id: I1b29a5d78c72dede8562d4878569b609536ba074 Reviewed-on: https://chromium-review.googlesource.com/183586Reviewed-by: 's avatarShannon Woods <shannonwoods@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent c47a678a
......@@ -83,7 +83,7 @@ namespace gl_d3d
namespace
{
unsigned int parseAndStripArrayIndex(std::string* name)
unsigned int ParseAndStripArrayIndex(std::string* name)
{
unsigned int subscript = GL_INVALID_INDEX;
......@@ -113,14 +113,21 @@ VariableLocation::VariableLocation(const std::string &name, unsigned int element
unsigned int ProgramBinary::mCurrentSerial = 1;
ProgramBinary::ProgramBinary(rx::Renderer *renderer) : mRenderer(renderer), RefCountObject(0), mSerial(issueSerial())
ProgramBinary::ProgramBinary(rx::Renderer *renderer)
: RefCountObject(0),
mRenderer(renderer),
mPixelExecutable(NULL),
mVertexExecutable(NULL),
mGeometryExecutable(NULL),
mUsedVertexSamplerRange(0),
mUsedPixelSamplerRange(0),
mUsesPointSize(false),
mShaderVersion(100),
mVertexUniformStorage(NULL),
mFragmentUniformStorage(NULL),
mValidated(false),
mSerial(issueSerial())
{
mPixelExecutable = NULL;
mVertexExecutable = NULL;
mGeometryExecutable = NULL;
mValidated = false;
for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
{
mSemanticIndex[index] = -1;
......@@ -135,23 +142,13 @@ ProgramBinary::ProgramBinary(rx::Renderer *renderer) : mRenderer(renderer), RefC
{
mSamplersVS[index].active = false;
}
mUsedVertexSamplerRange = 0;
mUsedPixelSamplerRange = 0;
mUsesPointSize = false;
mShaderVersion = 100;
}
ProgramBinary::~ProgramBinary()
{
delete mPixelExecutable;
mPixelExecutable = NULL;
delete mVertexExecutable;
mVertexExecutable = NULL;
delete mGeometryExecutable;
mGeometryExecutable = NULL;
SafeDelete(mPixelExecutable);
SafeDelete(mVertexExecutable);
SafeDelete(mGeometryExecutable);
while (!mUniforms.empty())
{
......@@ -164,6 +161,9 @@ ProgramBinary::~ProgramBinary()
delete mUniformBlocks.back();
mUniformBlocks.pop_back();
}
SafeDelete(mVertexUniformStorage);
SafeDelete(mFragmentUniformStorage);
}
unsigned int ProgramBinary::getSerial() const
......@@ -181,17 +181,17 @@ unsigned int ProgramBinary::issueSerial()
return mCurrentSerial++;
}
rx::ShaderExecutable *ProgramBinary::getPixelExecutable()
rx::ShaderExecutable *ProgramBinary::getPixelExecutable() const
{
return mPixelExecutable;
}
rx::ShaderExecutable *ProgramBinary::getVertexExecutable()
rx::ShaderExecutable *ProgramBinary::getVertexExecutable() const
{
return mVertexExecutable;
}
rx::ShaderExecutable *ProgramBinary::getGeometryExecutable()
rx::ShaderExecutable *ProgramBinary::getGeometryExecutable() const
{
return mGeometryExecutable;
}
......@@ -306,7 +306,7 @@ TextureType ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int
GLint ProgramBinary::getUniformLocation(std::string name)
{
unsigned int subscript = parseAndStripArrayIndex(&name);
unsigned int subscript = ParseAndStripArrayIndex(&name);
unsigned int numUniforms = mUniformIndex.size();
for (unsigned int location = 0; location < numUniforms; location++)
......@@ -329,7 +329,7 @@ GLint ProgramBinary::getUniformLocation(std::string name)
GLuint ProgramBinary::getUniformIndex(std::string name)
{
unsigned int subscript = parseAndStripArrayIndex(&name);
unsigned int subscript = ParseAndStripArrayIndex(&name);
// The app is not allowed to specify array indices other than 0 for arrays of basic types
if (subscript != 0 && subscript != GL_INVALID_INDEX)
......@@ -354,7 +354,7 @@ GLuint ProgramBinary::getUniformIndex(std::string name)
GLuint ProgramBinary::getUniformBlockIndex(std::string name)
{
unsigned int subscript = parseAndStripArrayIndex(&name);
unsigned int subscript = ParseAndStripArrayIndex(&name);
unsigned int numUniformBlocks = mUniformBlocks.size();
for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++)
......@@ -383,7 +383,7 @@ GLint ProgramBinary::getFragDataLocation(const char *name) const
{
std::string baseName(name);
unsigned int arrayIndex;
arrayIndex = parseAndStripArrayIndex(&baseName);
arrayIndex = ParseAndStripArrayIndex(&baseName);
for (auto locationIt = mOutputVariables.begin(); locationIt != mOutputVariables.end(); locationIt++)
{
......@@ -837,9 +837,9 @@ void ProgramBinary::dirtyAllUniforms()
void ProgramBinary::applyUniforms()
{
// Retrieve sampler uniform values
for (std::vector<Uniform*>::iterator ub = mUniforms.begin(), ue = mUniforms.end(); ub != ue; ++ub)
for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
{
Uniform *targetUniform = *ub;
Uniform *targetUniform = mUniforms[uniformIndex];
if (targetUniform->dirty)
{
......@@ -883,7 +883,12 @@ void ProgramBinary::applyUniforms()
}
}
mRenderer->applyUniforms(this, &mUniforms);
mRenderer->applyUniforms(*this);
for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
{
mUniforms[uniformIndex]->dirty = false;
}
}
bool ProgramBinary::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers)
......@@ -1860,6 +1865,8 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
mGeometryExecutable = NULL;
}
initializeUniformStorage();
return true;
}
......@@ -2338,6 +2345,8 @@ bool ProgramBinary::linkUniforms(InfoLog &infoLog, const std::vector<sh::Uniform
}
}
initializeUniformStorage();
return true;
}
......@@ -3275,4 +3284,30 @@ 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 Uniform &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);
}
}
......@@ -31,6 +31,7 @@ namespace rx
class ShaderExecutable;
class Renderer;
struct TranslatedAttribute;
class UniformStorage;
}
namespace gl
......@@ -62,9 +63,9 @@ class ProgramBinary : public RefCountObject
explicit ProgramBinary(rx::Renderer *renderer);
~ProgramBinary();
rx::ShaderExecutable *getPixelExecutable();
rx::ShaderExecutable *getVertexExecutable();
rx::ShaderExecutable *getGeometryExecutable();
rx::ShaderExecutable *getPixelExecutable() const;
rx::ShaderExecutable *getVertexExecutable() const;
rx::ShaderExecutable *getGeometryExecutable() const;
GLuint getAttributeLocation(const char *name);
int getSemanticIndex(int attributeIndex);
......@@ -145,6 +146,10 @@ class ProgramBinary : public RefCountObject
static std::string decorateAttribute(const std::string &name); // Prepend an underscore
const UniformArray &getUniforms() const { return mUniforms; }
const rx::UniformStorage &getVertexUniformStorage() const { return *mVertexUniformStorage; }
const rx::UniformStorage &getFragmentUniformStorage() const { return *mFragmentUniformStorage; }
private:
DISALLOW_COPY_AND_ASSIGN(ProgramBinary);
......@@ -173,6 +178,7 @@ class ProgramBinary : public RefCountObject
bool defineUniformBlock(InfoLog &infoLog, GLenum shader, const sh::InterfaceBlock &interfaceBlock);
bool assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex);
void defineOutputVariables(FragmentShader *fragmentShader);
void initializeUniformStorage();
std::string generateGeometryShaderHLSL(int registers, const sh::ShaderVariable *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const;
std::string generatePointSpriteHLSL(int registers, const sh::ShaderVariable *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const;
......@@ -220,6 +226,8 @@ class ProgramBinary : public RefCountObject
UniformIndex mUniformIndex;
typedef std::map<int, VariableLocation> ShaderVariableIndex;
ShaderVariableIndex mOutputVariables;
rx::UniformStorage *mVertexUniformStorage;
rx::UniformStorage *mFragmentUniformStorage;
bool mValidated;
......
......@@ -73,6 +73,11 @@ size_t Uniform::dataSize() const
return UniformInternalSize(type) * elementCount();
}
bool Uniform::isSampler() const
{
return gl::IsSampler(type);
}
UniformBlock::UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize)
: name(name),
elementIndex(elementIndex),
......
......@@ -34,6 +34,7 @@ struct Uniform
bool isReferencedByFragmentShader() const;
bool isInDefaultBlock() const;
size_t dataSize() const;
bool isSampler() const;
const GLenum type;
const GLenum precision;
......
......@@ -63,6 +63,7 @@ class SwapChain;
class RenderTarget;
class Image;
class TextureStorage;
class UniformStorage;
typedef void * ShaderBlob;
typedef void (*pCompileFunc)();
......@@ -136,7 +137,7 @@ class Renderer
virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer) = 0;
virtual void applyShaders(gl::ProgramBinary *programBinary) = 0;
virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray) = 0;
virtual void applyUniforms(const gl::ProgramBinary &programBinary) = 0;
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0;
virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
GLint first, GLsizei count, GLsizei instances) = 0;
......@@ -246,6 +247,7 @@ class Renderer
// Shader operations
virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type) = 0;
virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, D3DWorkaroundType workaround) = 0;
virtual UniformStorage *createUniformStorage(size_t storageSize) = 0;
// Image operations
virtual Image *createImage() = 0;
......
......@@ -1448,10 +1448,9 @@ void Renderer11::applyShaders(gl::ProgramBinary *programBinary)
}
}
void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray)
void Renderer11::applyUniforms(const gl::ProgramBinary &programBinary)
{
ShaderExecutable11 *vertexExecutable = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutable());
ShaderExecutable11 *pixelExecutable = ShaderExecutable11::makeShaderExecutable11(programBinary->getPixelExecutable());
const gl::UniformArray &uniformArray = programBinary.getUniforms();
unsigned int totalRegisterCountVS = 0;
unsigned int totalRegisterCountPS = 0;
......@@ -1459,25 +1458,30 @@ void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArra
bool vertexUniformsDirty = false;
bool pixelUniformsDirty = false;
for (gl::UniformArray::const_iterator uniform_iterator = uniformArray->begin(); uniform_iterator != uniformArray->end(); uniform_iterator++)
for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++)
{
const gl::Uniform *uniform = *uniform_iterator;
const gl::Uniform &uniform = *uniformArray[uniformIndex];
if (uniform->isReferencedByVertexShader())
if (uniform.isReferencedByVertexShader() && !uniform.isSampler())
{
totalRegisterCountVS += uniform->registerCount;
vertexUniformsDirty = vertexUniformsDirty || uniform->dirty;
totalRegisterCountVS += uniform.registerCount;
vertexUniformsDirty = (vertexUniformsDirty || uniform.dirty);
}
if (uniform->isReferencedByFragmentShader())
if (uniform.isReferencedByFragmentShader() && !uniform.isSampler())
{
totalRegisterCountPS += uniform->registerCount;
pixelUniformsDirty = pixelUniformsDirty || uniform->dirty;
totalRegisterCountPS += uniform.registerCount;
pixelUniformsDirty = (pixelUniformsDirty || uniform.dirty);
}
}
ID3D11Buffer *vertexConstantBuffer = vertexExecutable->getConstantBuffer(this, totalRegisterCountVS);
ID3D11Buffer *pixelConstantBuffer = pixelExecutable->getConstantBuffer(this, totalRegisterCountPS);
const UniformStorage11 *vertexUniformStorage = UniformStorage11::makeUniformStorage11(&programBinary.getVertexUniformStorage());
const UniformStorage11 *fragmentUniformStorage = UniformStorage11::makeUniformStorage11(&programBinary.getFragmentUniformStorage());
ASSERT(vertexUniformStorage);
ASSERT(fragmentUniformStorage);
ID3D11Buffer *vertexConstantBuffer = vertexUniformStorage->getConstantBuffer();
ID3D11Buffer *pixelConstantBuffer = fragmentUniformStorage->getConstantBuffer();
float (*mapVS)[4] = NULL;
float (*mapPS)[4] = NULL;
......@@ -1498,11 +1502,11 @@ void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArra
mapPS = (float(*)[4])map.pData;
}
for (size_t uniformIndex = 0; uniformIndex < uniformArray->size(); uniformIndex++)
for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++)
{
gl::Uniform *uniform = (*uniformArray)[uniformIndex];
gl::Uniform *uniform = uniformArray[uniformIndex];
if (!gl::IsSampler(uniform->type))
if (!uniform->isSampler())
{
unsigned int componentCount = (4 - uniform->registerElement);
......@@ -1519,8 +1523,6 @@ void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArra
memcpy(&mapPS[uniform->psRegisterIndex][uniform->registerElement], uniform->data, uniform->registerCount * sizeof(float) * componentCount);
}
}
uniform->dirty = false;
}
if (mapVS)
......@@ -2841,6 +2843,11 @@ ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const ch
return executable;
}
rx::UniformStorage *Renderer11::createUniformStorage(size_t storageSize)
{
return new UniformStorage11(this, storageSize);
}
VertexBuffer *Renderer11::createVertexBuffer()
{
return new VertexBuffer11(this);
......
......@@ -76,7 +76,7 @@ class Renderer11 : public Renderer
virtual bool applyPrimitiveType(GLenum mode, GLsizei count);
virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);
virtual void applyShaders(gl::ProgramBinary *programBinary);
virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray);
virtual void applyUniforms(const gl::ProgramBinary &programBinary);
virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
GLint first, GLsizei count, GLsizei instances);
virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
......@@ -185,6 +185,7 @@ class Renderer11 : public Renderer
// Shader operations
virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type);
virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, D3DWorkaroundType workaround);
virtual UniformStorage *createUniformStorage(size_t storageSize);
// Image operations
virtual Image *createImage();
......
......@@ -21,7 +21,6 @@ ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D
mPixelExecutable = executable;
mVertexExecutable = NULL;
mGeometryExecutable = NULL;
mUniformStorage = NULL;
}
ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11VertexShader *executable)
......@@ -30,7 +29,6 @@ ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D
mVertexExecutable = executable;
mPixelExecutable = NULL;
mGeometryExecutable = NULL;
mUniformStorage = NULL;
}
ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11GeometryShader *executable)
......@@ -39,7 +37,6 @@ ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D
mGeometryExecutable = executable;
mVertexExecutable = NULL;
mPixelExecutable = NULL;
mUniformStorage = NULL;
}
ShaderExecutable11::~ShaderExecutable11()
......@@ -47,7 +44,6 @@ ShaderExecutable11::~ShaderExecutable11()
SafeRelease(mVertexExecutable);
SafeRelease(mPixelExecutable);
SafeRelease(mGeometryExecutable);
SafeDelete(mUniformStorage);
}
ShaderExecutable11 *ShaderExecutable11::makeShaderExecutable11(ShaderExecutable *executable)
......@@ -71,19 +67,6 @@ ID3D11GeometryShader *ShaderExecutable11::getGeometryShader() const
return mGeometryExecutable;
}
ID3D11Buffer *ShaderExecutable11::getConstantBuffer(Renderer11 *renderer, unsigned int registerCount)
{
size_t desiredSize = registerCount * 16u;
if (!mUniformStorage)
{
mUniformStorage = new UniformStorage11(renderer, desiredSize);
}
ASSERT(mUniformStorage->size() == desiredSize);
return mUniformStorage->getConstantBuffer();
}
UniformStorage11::UniformStorage11(Renderer11 *renderer, size_t initialSize)
: UniformStorage(initialSize),
mConstantBuffer(NULL)
......
......@@ -32,16 +32,12 @@ class ShaderExecutable11 : public ShaderExecutable
ID3D11VertexShader *getVertexShader() const;
ID3D11GeometryShader *getGeometryShader() const;
ID3D11Buffer *getConstantBuffer(Renderer11 *renderer, unsigned int registerCount);
private:
DISALLOW_COPY_AND_ASSIGN(ShaderExecutable11);
ID3D11PixelShader *mPixelExecutable;
ID3D11VertexShader *mVertexExecutable;
ID3D11GeometryShader *mGeometryExecutable;
UniformStorage11 *mUniformStorage;
};
class UniformStorage11 : public UniformStorage
......
......@@ -1750,11 +1750,13 @@ void Renderer9::applyShaders(gl::ProgramBinary *programBinary)
}
}
void Renderer9::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray)
void Renderer9::applyUniforms(const gl::ProgramBinary &programBinary)
{
for (std::vector<gl::Uniform*>::const_iterator ub = uniformArray->begin(), ue = uniformArray->end(); ub != ue; ++ub)
const gl::UniformArray &uniformArray = programBinary.getUniforms();
for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++)
{
gl::Uniform *targetUniform = *ub;
gl::Uniform *targetUniform = uniformArray[uniformIndex];
if (targetUniform->dirty)
{
......@@ -1790,8 +1792,6 @@ void Renderer9::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray
default:
UNREACHABLE();
}
targetUniform->dirty = false;
}
}
......@@ -3328,6 +3328,11 @@ ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const cha
return executable;
}
rx::UniformStorage *Renderer9::createUniformStorage(size_t storageSize)
{
return new UniformStorage(storageSize);
}
bool Renderer9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
{
return mBlit->boxFilter(source, dest);
......
......@@ -87,7 +87,7 @@ class Renderer9 : public Renderer
virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);
virtual void applyShaders(gl::ProgramBinary *programBinary);
virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray);
virtual void applyUniforms(const gl::ProgramBinary &programBinary);
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount);
virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
GLint first, GLsizei count, GLsizei instances);
......@@ -201,6 +201,7 @@ class Renderer9 : public Renderer
// Shader operations
virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type);
virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, D3DWorkaroundType workaround);
virtual UniformStorage *createUniformStorage(size_t storageSize);
// Image operations
virtual Image *createImage();
......
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