Pass uniform buffers active bound to uniform blocks of the active program to…

Pass uniform buffers active bound to uniform blocks of the active program to HLSL/D3D constant buffers. TRAC #22892 Signed-off-by: Nicolas Capens Signed-off-by: Shannon Woods Author: Jamie Madill git-svn-id: https://angleproject.googlecode.com/svn/branches/es3proto@2339 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 1500f093
......@@ -2094,6 +2094,33 @@ void Context::applyTextures(SamplerType type)
}
}
bool Context::applyUniformBuffers()
{
Program *programObject = getProgram(mState.currentProgram);
ProgramBinary *programBinary = programObject->getProgramBinary();
std::vector<gl::Buffer*> boundBuffers;
for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++)
{
GLuint blockBinding = programObject->getUniformBlockBinding(uniformBlockIndex);
const OffsetBindingPointer<Buffer>& boundBuffer = mState.uniformBuffers[blockBinding];
if (boundBuffer.id() == 0)
{
// undefined behaviour
return false;
}
else
{
gl::Buffer *uniformBuffer = boundBuffer.get();
ASSERT(uniformBuffer);
boundBuffers.push_back(uniformBuffer);
}
}
return programBinary->applyUniformBuffers(boundBuffers);
}
void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
{
......@@ -2230,6 +2257,11 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan
applyShaders();
applyTextures();
if (!applyUniformBuffers())
{
return;
}
if (!programBinary->validateSamplers(NULL))
{
return gl::error(GL_INVALID_OPERATION);
......@@ -2284,6 +2316,11 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
applyShaders();
applyTextures();
if (!applyUniformBuffers())
{
return;
}
if (!programBinary->validateSamplers(NULL))
{
return gl::error(GL_INVALID_OPERATION);
......
......@@ -474,6 +474,7 @@ class Context
void applyShaders();
void applyTextures();
void applyTextures(SamplerType type);
bool applyUniformBuffers();
void detachBuffer(GLuint buffer);
void detachTexture(GLuint texture);
......
......@@ -22,6 +22,7 @@
#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/renderer/VertexDataManager.h"
#include "libGLESv2/Context.h"
#include "libGLESv2/Buffer.h"
#undef near
#undef far
......@@ -317,6 +318,12 @@ GLuint ProgramBinary::getUniformBlockIndex(std::string name)
return GL_INVALID_INDEX;
}
UniformBlock *ProgramBinary::getUniformBlockByIndex(GLuint blockIndex)
{
ASSERT(blockIndex < mUniformBlocks.size());
return mUniformBlocks[blockIndex];
}
template <typename T>
bool ProgramBinary::setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType)
{
......@@ -807,6 +814,51 @@ void ProgramBinary::applyUniforms()
mRenderer->applyUniforms(this, &mUniforms);
}
bool ProgramBinary::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers)
{
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();
ASSERT(boundBuffers.size() == mUniformBlocks.size());
for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); uniformBlockIndex++)
{
gl::UniformBlock *uniformBlock = getUniformBlockByIndex(uniformBlockIndex);
gl::Buffer *uniformBuffer = boundBuffers[uniformBlockIndex];
ASSERT(uniformBlock && uniformBuffer);
if (uniformBuffer->size() < uniformBlock->dataSize)
{
// undefined behaviour
return false;
}
ASSERT(uniformBlock->isReferencedByVertexShader() || uniformBlock->isReferencedByFragmentShader());
if (uniformBlock->isReferencedByVertexShader())
{
unsigned int registerIndex = uniformBlock->vsRegisterIndex - reservedBuffersInVS;
ASSERT(vertexUniformBuffers[registerIndex] == NULL);
ASSERT(registerIndex < mRenderer->getMaxVertexShaderUniformBuffers());
vertexUniformBuffers[registerIndex] = uniformBuffer;
}
if (uniformBlock->isReferencedByFragmentShader())
{
unsigned int registerIndex = uniformBlock->psRegisterIndex - reservedBuffersInFS;
ASSERT(fragmentUniformBuffers[registerIndex] == NULL);
ASSERT(registerIndex < mRenderer->getMaxFragmentShaderUniformBuffers());
fragmentUniformBuffers[registerIndex] = uniformBuffer;
}
}
return mRenderer->setUniformBuffers(vertexUniformBuffers, fragmentUniformBuffers);
}
// Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111
// Returns the number of used varying registers, or -1 if unsuccesful
int ProgramBinary::packVaryings(InfoLog &infoLog, const Varying *packing[][4], FragmentShader *fragmentShader)
......
......@@ -40,6 +40,7 @@ class VertexShader;
class InfoLog;
class AttributeBindings;
struct Varying;
class Buffer;
// Struct used for correlating uniforms/elements of uniform arrays to handles
struct UniformLocation
......@@ -107,6 +108,7 @@ class ProgramBinary : public RefCountObject
void dirtyAllUniforms();
void applyUniforms();
bool applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers);
bool load(InfoLog &infoLog, const void *binary, GLsizei length);
bool save(void* binary, GLsizei bufSize, GLsizei *length);
......@@ -128,6 +130,7 @@ class ProgramBinary : public RefCountObject
void getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const;
GLuint getActiveUniformBlockCount() const;
GLuint getActiveUniformBlockMaxLength() const;
UniformBlock *getUniformBlockByIndex(GLuint blockIndex);
void validate(InfoLog &infoLog);
bool validateSamplers(InfoLog *infoLog);
......
......@@ -115,6 +115,8 @@ class Renderer
virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler) = 0;
virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture) = 0;
virtual bool setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]) = 0;
virtual void setRasterizerState(const gl::RasterizerState &rasterState) = 0;
virtual void setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor,
unsigned int sampleMask) = 0;
......
......@@ -657,6 +657,52 @@ void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *textur
else UNREACHABLE();
}
bool Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[])
{
// convert buffers to ID3D11Buffer*
ID3D11Buffer *vertexConstantBuffers[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS] = { NULL };
ID3D11Buffer *pixelConstantBuffers[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS] = { NULL };
for (unsigned int uniformBufferIndex = 0; uniformBufferIndex < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; uniformBufferIndex++)
{
const gl::Buffer *uniformBuffer = vertexUniformBuffers[uniformBufferIndex];
if (uniformBuffer)
{
BufferStorage11 *bufferStorage = BufferStorage11::makeBufferStorage11(uniformBuffer->getStorage());
ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(GL_UNIFORM_BUFFER);
if (!constantBuffer)
{
return false;
}
vertexConstantBuffers[uniformBufferIndex] = constantBuffer;
}
}
for (unsigned int uniformBufferIndex = 0; uniformBufferIndex < gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS; uniformBufferIndex++)
{
const gl::Buffer *uniformBuffer = fragmentUniformBuffers[uniformBufferIndex];
if (uniformBuffer)
{
BufferStorage11 *bufferStorage = BufferStorage11::makeBufferStorage11(uniformBuffer->getStorage());
ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(GL_UNIFORM_BUFFER);
if (!constantBuffer)
{
return false;
}
pixelConstantBuffers[uniformBufferIndex] = constantBuffer;
}
}
mDeviceContext->VSSetConstantBuffers(getReservedVertexUniformBuffers(), getMaxVertexShaderUniformBuffers(), vertexConstantBuffers);
mDeviceContext->PSSetConstantBuffers(getReservedFragmentUniformBuffers(), getMaxFragmentShaderUniformBuffers(), pixelConstantBuffers);
return true;
}
void Renderer11::setRasterizerState(const gl::RasterizerState &rasterState)
{
if (mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0)
......
......@@ -57,6 +57,8 @@ class Renderer11 : public Renderer
virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler);
virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture);
virtual bool setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]);
virtual void setRasterizerState(const gl::RasterizerState &rasterState);
virtual void setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor,
unsigned int sampleMask);
......
......@@ -799,6 +799,12 @@ void Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *texture
appliedSerials[index] = serial;
}
bool Renderer9::setUniformBuffers(const gl::Buffer* /*vertexUniformBuffers*/[], const gl::Buffer* /*fragmentUniformBuffers*/[])
{
// No effect in ES2/D3D9
return true;
}
void Renderer9::setRasterizerState(const gl::RasterizerState &rasterState)
{
bool rasterStateChanged = mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0;
......
......@@ -71,6 +71,8 @@ class Renderer9 : public Renderer
virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler);
virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture);
virtual bool setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]);
virtual void setRasterizerState(const gl::RasterizerState &rasterState);
virtual void setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor,
unsigned int sampleMask);
......
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