Adding support for the resource buffer

This commit is contained in:
samcake 2017-04-12 19:07:27 -07:00
parent b07ed13023
commit d41f34ce8d
14 changed files with 148 additions and 7 deletions

View file

@ -101,6 +101,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
(&::gpu::gl::GLBackend::do_setStateScissorRect),
(&::gpu::gl::GLBackend::do_setUniformBuffer),
(&::gpu::gl::GLBackend::do_setResourceBuffer),
(&::gpu::gl::GLBackend::do_setResourceTexture),
(&::gpu::gl::GLBackend::do_setFramebuffer),

View file

@ -93,6 +93,8 @@ public:
// this is the maximum per shader stage on the low end apple
// TODO make it platform dependant at init time
static const int MAX_NUM_RESOURCE_BUFFERS = 16;
size_t getMaxNumResourceBuffers() const { return MAX_NUM_RESOURCE_BUFFERS; }
static const int MAX_NUM_RESOURCE_TEXTURES = 16;
size_t getMaxNumResourceTextures() const { return MAX_NUM_RESOURCE_TEXTURES; }
@ -122,6 +124,7 @@ public:
virtual void do_setUniformBuffer(const Batch& batch, size_t paramOffset) final;
// Resource Stage
virtual void do_setResourceBuffer(const Batch& batch, size_t paramOffset) final;
virtual void do_setResourceTexture(const Batch& batch, size_t paramOffset) final;
// Pipeline Stage
@ -357,13 +360,19 @@ protected:
void releaseUniformBuffer(uint32_t slot);
void resetUniformStage();
// update resource cache and do the gl bind/unbind call with the current gpu::Buffer cached at slot s
// This is using different gl object depending on the gl version
virtual bool bindResourceBuffer(uint32_t slot, BufferPointer& buffer) = 0;
virtual void releaseResourceBuffer(uint32_t slot) = 0;
// update resource cache and do the gl unbind call with the current gpu::Texture cached at slot s
void releaseResourceTexture(uint32_t slot);
void resetResourceStage();
struct ResourceStageState {
std::array<BufferPointer, MAX_NUM_RESOURCE_BUFFERS> _buffers;
std::array<TexturePointer, MAX_NUM_RESOURCE_TEXTURES> _textures;
//Textures _textures { { MAX_NUM_RESOURCE_TEXTURES } };
int findEmptyTextureSlot() const;

View file

@ -191,11 +191,45 @@ void GLBackend::releaseResourceTexture(uint32_t slot) {
}
void GLBackend::resetResourceStage() {
for (uint32_t i = 0; i < _resource._buffers.size(); i++) {
releaseResourceBuffer(i);
}
for (uint32_t i = 0; i < _resource._textures.size(); i++) {
releaseResourceTexture(i);
}
}
void GLBackend::do_setResourceBuffer(const Batch& batch, size_t paramOffset) {
GLuint slot = batch._params[paramOffset + 1]._uint;
if (slot >= (GLuint)MAX_NUM_RESOURCE_BUFFERS) {
// "GLBackend::do_setResourceBuffer: Trying to set a resource Buffer at slot #" + slot + " which doesn't exist. MaxNumResourceBuffers = " + getMaxNumResourceBuffers());
return;
}
auto resourceBuffer = batch._buffers.get(batch._params[paramOffset + 0]._uint);
if (!resourceBuffer) {
releaseResourceBuffer(slot);
return;
}
// check cache before thinking
if (_resource._buffers[slot] == resourceBuffer) {
return;
}
// One more True Buffer bound
_stats._RSNumResourceBufferBounded++;
// If successful bind then cache it
if (bindResourceBuffer(slot, resourceBuffer)) {
_resource._buffers[slot] = resourceBuffer;
} else { // else clear slot and cache
releaseResourceBuffer(slot);
return;
}
}
void GLBackend::do_setResourceTexture(const Batch& batch, size_t paramOffset) {
GLuint slot = batch._params[paramOffset + 1]._uint;
if (slot >= (GLuint) MAX_NUM_RESOURCE_TEXTURES) {

View file

@ -32,7 +32,8 @@ GLShader::~GLShader() {
// GLSL version
static const std::string glslVersion {
"#version 410 core"
// "#version 410 core"
"#version 450 core"
};
// Shader domain
@ -185,7 +186,8 @@ bool GLShader::makeProgram(GLBackend& backend, Shader& shader, const Shader::Bin
Shader::SlotSet uniforms;
Shader::SlotSet textures;
Shader::SlotSet samplers;
makeUniformSlots(shaderObject.glprogram, slotBindings, uniforms, textures, samplers);
Shader::SlotSet resourceBuffers;
makeUniformSlots(shaderObject.glprogram, slotBindings, uniforms, textures, samplers, resourceBuffers);
Shader::SlotSet inputs;
makeInputSlots(shaderObject.glprogram, slotBindings, inputs);

View file

@ -510,7 +510,7 @@ ElementResource getFormatFromGLUniform(GLenum gltype) {
};
int makeUniformSlots(GLuint glprogram, const Shader::BindingSet& slotBindings,
Shader::SlotSet& uniforms, Shader::SlotSet& textures, Shader::SlotSet& samplers) {
Shader::SlotSet& uniforms, Shader::SlotSet& textures, Shader::SlotSet& samplers, Shader::SlotSet& resourceBuffers) {
GLint uniformsCount = 0;
glGetProgramiv(glprogram, GL_ACTIVE_UNIFORMS, &uniformsCount);
@ -565,6 +565,24 @@ int makeUniformSlots(GLuint glprogram, const Shader::BindingSet& slotBindings,
}
}
GLint ssboCount = 0;
glGetProgramInterfaceiv(glprogram, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &ssboCount);
if (ssboCount > 0) {
GLint maxNameLength = 0;
glGetProgramInterfaceiv(glprogram, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, &maxNameLength);
std::vector<GLchar> nameBytes(maxNameLength);
for (GLint b = 0; b < ssboCount; b++) {
GLint length;
glGetProgramResourceName(glprogram, GL_SHADER_STORAGE_BLOCK, b, maxNameLength, &length, nameBytes.data());
std::string bufferName(nameBytes.data());
qCWarning(gpugllogging) << "GLShader::makeBindings - " << bufferName.c_str();
}
}
return uniformsCount;
}

View file

@ -42,7 +42,7 @@ struct ShaderObject {
};
int makeUniformSlots(GLuint glprogram, const Shader::BindingSet& slotBindings,
Shader::SlotSet& uniforms, Shader::SlotSet& textures, Shader::SlotSet& samplers);
Shader::SlotSet& uniforms, Shader::SlotSet& textures, Shader::SlotSet& samplers, Shader::SlotSet& resourceBuffers);
int makeUniformBlockSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, Shader::SlotSet& buffers);
int makeInputSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, Shader::SlotSet& inputs);
int makeOutputSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, Shader::SlotSet& outputs);

View file

@ -123,6 +123,10 @@ protected:
void initTransform() override;
void updateTransform(const Batch& batch) override;
// Resource Stage
bool bindResourceBuffer(uint32_t slot, BufferPointer& buffer) override;
void releaseResourceBuffer(uint32_t slot) override;
// Output stage
void do_blit(const Batch& batch, size_t paramOffset) override;
};

View file

@ -66,3 +66,26 @@ GLuint GL41Backend::getBufferID(const Buffer& buffer) {
GLBuffer* GL41Backend::syncGPUObject(const Buffer& buffer) {
return GL41Buffer::sync<GL41Buffer>(*this, buffer);
}
bool GL41Backend::bindResourceBuffer(uint32_t slot, BufferPointer& buffer) {
GLBuffer* object = syncGPUObject((*buffer));
if (object) {
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, slot, object->_id);
(void)CHECK_GL_ERROR();
_resource._buffers[slot] = buffer;
return true;
}
return false;
}
void GL41Backend::releaseResourceBuffer(uint32_t slot) {
auto& buf = _resource._buffers[slot];
if (buf) {
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, slot, 0);
buf.reset();
}
}

View file

@ -277,6 +277,10 @@ protected:
void initTransform() override;
void updateTransform(const Batch& batch) override;
// Resource Stage
bool bindResourceBuffer(uint32_t slot, BufferPointer& buffer) override;
void releaseResourceBuffer(uint32_t slot) override;
// Output stage
void do_blit(const Batch& batch, size_t paramOffset) override;

View file

@ -54,3 +54,29 @@ GLuint GL45Backend::getBufferID(const Buffer& buffer) {
GLBuffer* GL45Backend::syncGPUObject(const Buffer& buffer) {
return GL45Buffer::sync<GL45Buffer>(*this, buffer);
}
bool GL45Backend::bindResourceBuffer(uint32_t slot, BufferPointer& buffer) {
GLBuffer* object = syncGPUObject((*buffer));
if (object) {
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, slot, object->_id);
(void)CHECK_GL_ERROR();
_resource._buffers[slot] = buffer;
return true;
}
return false;
}
void GL45Backend::releaseResourceBuffer(uint32_t slot) {
auto& buf = _resource._buffers[slot];
if (buf) {
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, slot, 0);
buf.reset();
}
}

View file

@ -292,8 +292,16 @@ void Batch::setUniformBuffer(uint32 slot, const BufferView& view) {
setUniformBuffer(slot, view._buffer, view._offset, view._size);
}
void Batch::setResourceBuffer(uint32 slot, const BufferPointer& buffer) {
ADD_COMMAND(setResourceBuffer);
_params.emplace_back(_buffers.cache(buffer));
_params.emplace_back(slot);
}
void Batch::setResourceTexture(uint32 slot, const TexturePointer& texture) {
ADD_COMMAND(setResourceTexture);
_params.emplace_back(_textures.cache(texture));
_params.emplace_back(slot);
}

View file

@ -189,9 +189,12 @@ public:
void setUniformBuffer(uint32 slot, const BufferPointer& buffer, Offset offset, Offset size);
void setUniformBuffer(uint32 slot, const BufferView& view); // not a command, just a shortcut from a BufferView
void setResourceTexture(uint32 slot, const TexturePointer& view);
void setResourceBuffer(uint32 slot, const BufferPointer& buffer);
void setResourceTexture(uint32 slot, const TexturePointer& texture);
void setResourceTexture(uint32 slot, const TextureView& view); // not a command, just a shortcut from a TextureView
// Ouput Stage
void setFramebuffer(const FramebufferPointer& framebuffer);
@ -290,6 +293,7 @@ public:
COMMAND_setStateScissorRect,
COMMAND_setUniformBuffer,
COMMAND_setResourceBuffer,
COMMAND_setResourceTexture,
COMMAND_setFramebuffer,

View file

@ -34,6 +34,7 @@ public:
int _ISNumInputBufferChanges = 0;
int _ISNumIndexBufferChanges = 0;
int _RSNumResourceBufferBounded = 0;
int _RSNumTextureBounded = 0;
int _RSAmountTextureMemoryBounded = 0;

View file

@ -22,6 +22,11 @@ uniform vec3 inBoundPos;
uniform vec3 inBoundDim;
uniform ivec4 inCellLocation;
layout(std140) buffer ssbo0Buffer {
vec4 perBoundData[];
};
out vec4 varColor;
out vec2 varTexcoord;
@ -52,6 +57,8 @@ void main(void) {
);
vec4 cubeVec = UNIT_BOX[UNIT_BOX_LINE_INDICES[gl_VertexID]];
vec4 offset = perBoundData[gl_VertexID];
vec4 pos = vec4(inBoundPos + inBoundDim * cubeVec.xyz, 1.0);
// standard transform
@ -61,7 +68,7 @@ void main(void) {
bool subcell = bool((inCellLocation.z));
float cellDepth = float(inCellLocation.w);
varColor = vec4(colorWheel(fract(cellDepth / 5.0)), 1.0 - float(subcell));
varColor = vec4(colorWheel(fract(cellDepth / 5.0)), 1.0 - float(subcell)) + offset;
varTexcoord = vec2(cubeVec.w, length(inBoundDim));
}