Merge pull request #14379 from Cristo86/gles_use_tbo_no_ssbo

case 19562: GLES - Use TBO instead of SSBO and make shaders use it when it is not gl45 (master)
This commit is contained in:
John Conklin II 2018-11-12 10:45:52 -08:00 committed by GitHub
commit 9d404a6cf3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 71 additions and 25 deletions

View file

@ -2809,6 +2809,7 @@ void Application::initializeGL() {
} }
// Build a shared canvas / context for the QML rendering // Build a shared canvas / context for the QML rendering
#if !defined(DISABLE_QML)
{ {
_qmlShareContext = new OffscreenGLCanvas(); _qmlShareContext = new OffscreenGLCanvas();
_qmlShareContext->setObjectName("QmlShareContext"); _qmlShareContext->setObjectName("QmlShareContext");
@ -2822,6 +2823,8 @@ void Application::initializeGL() {
qCWarning(interfaceapp, "Unable to make window context current"); qCWarning(interfaceapp, "Unable to make window context current");
} }
} }
#endif
_renderEventHandler = new RenderEventHandler(); _renderEventHandler = new RenderEventHandler();

View file

@ -49,7 +49,7 @@ void GL41Backend::postLinkProgram(ShaderObject& programObject, const Shader& pro
const auto resourceBufferUniforms = ::gl::Uniform::loadByName(glprogram, names); const auto resourceBufferUniforms = ::gl::Uniform::loadByName(glprogram, names);
for (const auto& resourceBuffer : resourceBufferUniforms) { for (const auto& resourceBuffer : resourceBufferUniforms) {
const auto& targetBinding = expectedResourceBuffers.at(resourceBuffer.name); const auto& targetBinding = expectedResourceBuffers.at(resourceBuffer.name);
glProgramUniform1i(glprogram, resourceBuffer.binding, targetBinding + GL41Backend::RESOURCE_BUFFER_SLOT0_TEX_UNIT); glProgramUniform1i(glprogram, resourceBuffer.binding, targetBinding);
} }
} }

View file

@ -28,6 +28,10 @@ class GLESBackend : public GLBackend {
public: public:
static const GLint RESOURCE_TRANSFER_TEX_UNIT { 32 }; static const GLint RESOURCE_TRANSFER_TEX_UNIT { 32 };
static const GLint RESOURCE_TRANSFER_EXTRA_TEX_UNIT { 33 };
static const GLint RESOURCE_BUFFER_TEXBUF_TEX_UNIT { 34 };
static const GLint RESOURCE_BUFFER_SLOT0_TEX_UNIT { 35 };
explicit GLESBackend(bool syncCache) : Parent(syncCache) {} explicit GLESBackend(bool syncCache) : Parent(syncCache) {}
GLESBackend() : Parent() {} GLESBackend() : Parent() {}
virtual ~GLESBackend() { virtual ~GLESBackend() {

View file

@ -10,7 +10,6 @@
namespace gpu { namespace gpu {
namespace gles { namespace gles {
class GLESBuffer : public gpu::gl::GLBuffer { class GLESBuffer : public gpu::gl::GLBuffer {
using Parent = gpu::gl::GLBuffer; using Parent = gpu::gl::GLBuffer;
static GLuint allocate() { static GLuint allocate() {
@ -19,11 +18,20 @@ namespace gpu {
return result; return result;
} }
~GLESBuffer() {
if (_texBuffer) {
auto backend = _backend.lock();
if (backend) {
backend->releaseTexture(_texBuffer, 0);
}
}
}
public: public:
GLESBuffer(const std::weak_ptr<gl::GLBackend>& backend, const Buffer& buffer, GLESBuffer* original) : Parent(backend, buffer, allocate()) { GLESBuffer(const std::weak_ptr<gl::GLBackend>& backend, const Buffer& buffer, GLESBuffer* original) : Parent(backend, buffer, allocate()) {
glBindBuffer(GL_ARRAY_BUFFER, _buffer); glBindBuffer(GL_COPY_WRITE_BUFFER, _buffer);
glBufferData(GL_ARRAY_BUFFER, _size, nullptr, GL_DYNAMIC_DRAW); glBufferData(GL_COPY_WRITE_BUFFER, _size, nullptr, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_COPY_WRITE_BUFFER, 0);
if (original && original->_size) { if (original && original->_size) {
glBindBuffer(GL_COPY_WRITE_BUFFER, _buffer); glBindBuffer(GL_COPY_WRITE_BUFFER, _buffer);
@ -37,20 +45,34 @@ namespace gpu {
} }
void transfer() override { void transfer() override {
glBindBuffer(GL_ARRAY_BUFFER, _buffer); glBindBuffer(GL_COPY_WRITE_BUFFER, _buffer);
(void)CHECK_GL_ERROR(); (void)CHECK_GL_ERROR();
Size offset; Size offset;
Size size; Size size;
Size currentPage { 0 }; Size currentPage { 0 };
auto data = _gpuObject._renderSysmem.readData(); auto data = _gpuObject._renderSysmem.readData();
while (_gpuObject._renderPages.getNextTransferBlock(offset, size, currentPage)) { while (_gpuObject._renderPages.getNextTransferBlock(offset, size, currentPage)) {
glBufferSubData(GL_ARRAY_BUFFER, offset, size, data + offset); glBufferSubData(GL_COPY_WRITE_BUFFER, offset, size, data + offset);
(void)CHECK_GL_ERROR(); (void)CHECK_GL_ERROR();
} }
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_COPY_WRITE_BUFFER, 0);
(void)CHECK_GL_ERROR(); (void)CHECK_GL_ERROR();
_gpuObject._renderPages._flags &= ~PageManager::DIRTY; _gpuObject._renderPages._flags &= ~PageManager::DIRTY;
} }
// REsource BUffer are implemented with TextureBuffer
GLuint _texBuffer { 0 };
GLuint getTexBufferId() {
if (!_texBuffer) {
glGenTextures(1, &_texBuffer);
glActiveTexture(GL_TEXTURE0 + GLESBackend::RESOURCE_BUFFER_TEXBUF_TEX_UNIT);
glBindTexture(GL_TEXTURE_BUFFER, _texBuffer);
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, _buffer);
glBindTexture(GL_TEXTURE_BUFFER, 0);
(void)CHECK_GL_ERROR();
}
return _texBuffer;
}
}; };
} }
} }
@ -68,14 +90,24 @@ GLuint GLESBackend::getBufferIDUnsynced(const Buffer& buffer) {
return GLESBuffer::getIdUnsynced<GLESBuffer>(*this, buffer); return GLESBuffer::getIdUnsynced<GLESBuffer>(*this, buffer);
} }
GLuint GLESBackend::getResourceBufferID(const Buffer& buffer) {
auto* object = GLESBuffer::sync<GLESBuffer>(*this, buffer);
if (object) {
return object->getTexBufferId();
} else {
return 0;
}
}
GLBuffer* GLESBackend::syncGPUObject(const Buffer& buffer) { GLBuffer* GLESBackend::syncGPUObject(const Buffer& buffer) {
return GLESBuffer::sync<GLESBuffer>(*this, buffer); return GLESBuffer::sync<GLESBuffer>(*this, buffer);
} }
bool GLESBackend::bindResourceBuffer(uint32_t slot, const BufferPointer& buffer) { bool GLESBackend::bindResourceBuffer(uint32_t slot, const BufferPointer& buffer) {
GLBuffer* object = syncGPUObject((*buffer)); GLuint texBuffer = GLESBackend::getResourceBufferID((*buffer));
if (object) { if (texBuffer) {
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, slot, object->_id); glActiveTexture(GL_TEXTURE0 + GLESBackend::RESOURCE_BUFFER_SLOT0_TEX_UNIT + slot);
glBindTexture(GL_TEXTURE_BUFFER, texBuffer);
(void)CHECK_GL_ERROR(); (void)CHECK_GL_ERROR();
@ -89,9 +121,10 @@ bool GLESBackend::bindResourceBuffer(uint32_t slot, const BufferPointer& buffer)
void GLESBackend::releaseResourceBuffer(uint32_t slot) { void GLESBackend::releaseResourceBuffer(uint32_t slot) {
auto& bufferReference = _resource._buffers[slot]; auto& bufferReference = _resource._buffers[slot];
if (valid(bufferReference)) { auto buffer = acquire(bufferReference);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, slot, 0); if (buffer) {
glActiveTexture(GL_TEXTURE0 + GLESBackend::RESOURCE_BUFFER_SLOT0_TEX_UNIT + slot);
glBindTexture(GL_TEXTURE_BUFFER, 0);
reset(bufferReference); reset(bufferReference);
} }
} }

View file

@ -21,6 +21,12 @@
#define GPU_TEXTURE_TRANSFORM_OBJECT 31 #define GPU_TEXTURE_TRANSFORM_OBJECT 31
#define GPU_RESOURCE_BUFFER_SLOT0_TEXTURE 35
#define GPU_RESOURCE_BUFFER_SLOT1_TEXTURE 36
#define GPU_RESOURCE_BUFFER_SLOT0_STORAGE 0
#define GPU_RESOURCE_BUFFER_SLOT1_STORAGE 1
// Mip creation // Mip creation
#define GPU_TEXTURE_MIP_CREATION_INPUT 30 #define GPU_TEXTURE_MIP_CREATION_INPUT 30

View file

@ -11,12 +11,12 @@
<@func declareBlendshape(USE_NORMAL, USE_TANGENT)@> <@func declareBlendshape(USE_NORMAL, USE_TANGENT)@>
#if !defined(GPU_SSBO_TRANSFORM_OBJECT) #if !defined(GPU_SSBO_TRANSFORM_OBJECT)
LAYOUT(binding=0) uniform samplerBuffer blendshapeOffsetsBuffer; LAYOUT(binding=GPU_RESOURCE_BUFFER_SLOT0_TEXTURE) uniform samplerBuffer blendshapeOffsetsBuffer;
uvec4 getPackedBlendshapeOffset(int i) { uvec4 getPackedBlendshapeOffset(int i) {
return floatBitsToUint(texelFetch(blendshapeOffsetsBuffer, i)); return floatBitsToUint(texelFetch(blendshapeOffsetsBuffer, i));
} }
#else #else
LAYOUT_STD140(binding=0) buffer blendshapeOffsetsBuffer { LAYOUT_STD140(binding=GPU_RESOURCE_BUFFER_SLOT0_STORAGE) buffer blendshapeOffsetsBuffer {
uvec4 _packedBlendshapeOffsets[]; uvec4 _packedBlendshapeOffsets[];
}; };
uvec4 getPackedBlendshapeOffset(int i) { uvec4 getPackedBlendshapeOffset(int i) {

View file

@ -23,7 +23,7 @@ struct ItemBound {
}; };
#if !defined(GPU_SSBO_TRANSFORM_OBJECT) #if !defined(GPU_SSBO_TRANSFORM_OBJECT)
LAYOUT(binding=0) uniform samplerBuffer ssbo0Buffer; LAYOUT(binding=GPU_RESOURCE_BUFFER_SLOT0_TEXTURE) uniform samplerBuffer ssbo0Buffer;
ItemBound getItemBound(int i) { ItemBound getItemBound(int i) {
int offset = 2 * i; int offset = 2 * i;
ItemBound bound; ItemBound bound;
@ -32,7 +32,7 @@ ItemBound getItemBound(int i) {
return bound; return bound;
} }
#else #else
LAYOUT_STD140(binding=0) buffer ssbo0Buffer { LAYOUT_STD140(binding=GPU_RESOURCE_BUFFER_SLOT0_STORAGE) buffer ssbo0Buffer {
ItemBound bounds[]; ItemBound bounds[];
}; };
ItemBound getItemBound(int i) { ItemBound getItemBound(int i) {

View file

@ -239,7 +239,7 @@ ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int meshIndex, in
initCache(model); initCache(model);
#ifdef Q_OS_MAC #if defined(Q_OS_MAC) || defined(Q_OS_ANDROID)
// On mac AMD, we specifically need to have a _meshBlendshapeBuffer bound when using a deformed mesh pipeline // On mac AMD, we specifically need to have a _meshBlendshapeBuffer bound when using a deformed mesh pipeline
// it cannot be null otherwise we crash in the drawcall using a deformed pipeline with a skinned only (not blendshaped) mesh // it cannot be null otherwise we crash in the drawcall using a deformed pipeline with a skinned only (not blendshaped) mesh
if (_isBlendShaped) { if (_isBlendShaped) {

View file

@ -26,7 +26,7 @@ struct WorkloadProxy {
}; };
#if !defined(GPU_SSBO_TRANSFORM_OBJECT) #if !defined(GPU_SSBO_TRANSFORM_OBJECT)
LAYOUT(binding=0) uniform samplerBuffer workloadProxiesBuffer; LAYOUT(binding=GPU_RESOURCE_BUFFER_SLOT0_TEXTURE) uniform samplerBuffer workloadProxiesBuffer;
WorkloadProxy getWorkloadProxy(int i) { WorkloadProxy getWorkloadProxy(int i) {
int offset = 2 * i; int offset = 2 * i;
WorkloadProxy proxy; WorkloadProxy proxy;
@ -35,7 +35,7 @@ WorkloadProxy getWorkloadProxy(int i) {
return proxy; return proxy;
} }
#else #else
LAYOUT_STD140(binding=0) buffer workloadProxiesBuffer { LAYOUT_STD140(binding=GPU_RESOURCE_BUFFER_SLOT0_STORAGE) buffer workloadProxiesBuffer {
WorkloadProxy _proxies[]; WorkloadProxy _proxies[];
}; };
WorkloadProxy getWorkloadProxy(int i) { WorkloadProxy getWorkloadProxy(int i) {
@ -58,7 +58,7 @@ struct WorkloadView {
}; };
#if !defined(GPU_SSBO_TRANSFORM_OBJECT) #if !defined(GPU_SSBO_TRANSFORM_OBJECT)
LAYOUT(binding=1) uniform samplerBuffer workloadViewsBuffer; LAYOUT(binding=GPU_RESOURCE_BUFFER_SLOT1_TEXTURE) uniform samplerBuffer workloadViewsBuffer;
WorkloadView getWorkloadView(int i) { WorkloadView getWorkloadView(int i) {
int offset = 8 * i; int offset = 8 * i;
WorkloadView view; WorkloadView view;
@ -73,7 +73,7 @@ WorkloadView getWorkloadView(int i) {
return view; return view;
} }
#else #else
LAYOUT_STD140(binding=1) buffer workloadViewsBuffer { LAYOUT_STD140(binding=GPU_RESOURCE_BUFFER_SLOT1_STORAGE) buffer workloadViewsBuffer {
WorkloadView _views[]; WorkloadView _views[];
}; };
WorkloadView getWorkloadView(int i) { WorkloadView getWorkloadView(int i) {

View file

@ -35,7 +35,7 @@ struct ItemBound {
}; };
#if !defined(GPU_SSBO_TRANSFORM_OBJECT) #if !defined(GPU_SSBO_TRANSFORM_OBJECT)
LAYOUT(binding=0) uniform samplerBuffer ssbo0Buffer; LAYOUT(binding=GPU_RESOURCE_BUFFER_SLOT0_TEXTURE) uniform samplerBuffer ssbo0Buffer;
ItemBound getItemBound(int i) { ItemBound getItemBound(int i) {
int offset = 2 * i; int offset = 2 * i;
ItemBound bound; ItemBound bound;
@ -44,7 +44,7 @@ ItemBound getItemBound(int i) {
return bound; return bound;
} }
#else #else
LAYOUT_STD140(binding=0) buffer ssbo0Buffer { LAYOUT_STD140(binding=GPU_RESOURCE_BUFFER_SLOT0_STORAGE) buffer ssbo0Buffer {
ItemBound bounds[]; ItemBound bounds[];
}; };
ItemBound getItemBound(int i) { ItemBound getItemBound(int i) {