Bringin the Framebuffer to GLBackend and refining the interface

This commit is contained in:
Sam Gateau 2015-04-13 11:13:30 -07:00
parent 69484ad00b
commit 05689c0413
9 changed files with 169 additions and 55 deletions

View file

@ -25,7 +25,8 @@ Batch::Batch() :
_textures(),
_streamFormats(),
_transforms(),
_pipelines()
_pipelines(),
_framebuffers()
{
}
@ -41,7 +42,8 @@ void Batch::clear() {
_textures.clear();
_streamFormats.clear();
_transforms.clear();
_pipelines.clear();
_pipelines.clear();
_framebuffers.clear();
}
uint32 Batch::cacheData(uint32 size, const void* data) {
@ -186,3 +188,10 @@ void Batch::setUniformTexture(uint32 slot, const TextureView& view) {
setUniformTexture(slot, view._texture);
}
void Batch::setFramebuffer(const FramebufferPointer& framebuffer) {
ADD_COMMAND(setUniformTexture);
_params.push_back(_framebuffers.cache(framebuffer));
}

View file

@ -23,6 +23,8 @@
#include "Pipeline.h"
#include "Framebuffer.h"
#if defined(NSIGHT_FOUND)
#include "nvToolsExt.h"
class ProfileRange {
@ -112,6 +114,8 @@ public:
void setUniformTexture(uint32 slot, const TexturePointer& view);
void setUniformTexture(uint32 slot, const TextureView& view); // not a command, just a shortcut from a TextureView
// Framebuffer Stage
void setFramebuffer(const FramebufferPointer& framebuffer);
// TODO: As long as we have gl calls explicitely issued from interface
// code, we need to be able to record and batch these calls. THe long
@ -170,6 +174,8 @@ public:
COMMAND_setUniformBuffer,
COMMAND_setUniformTexture,
COMMAND_setFramebuffer,
// TODO: As long as we have gl calls explicitely issued from interface
// code, we need to be able to record and batch these calls. THe long
// term strategy is to get rid of any GL calls in favor of the HIFI GPU API
@ -266,6 +272,7 @@ public:
typedef Cache<Stream::FormatPointer>::Vector StreamFormatCaches;
typedef Cache<Transform>::Vector TransformCaches;
typedef Cache<PipelinePointer>::Vector PipelineCaches;
typedef Cache<FramebufferPointer>::Vector FramebufferCaches;
// Cache Data in a byte array if too big to fit in Param
// FOr example Mat4s are going there
@ -289,6 +296,7 @@ public:
StreamFormatCaches _streamFormats;
TransformCaches _transforms;
PipelineCaches _pipelines;
FramebufferCaches _framebuffers;
protected:
};

View file

@ -15,8 +15,8 @@
#include "Resource.h"
#include "Texture.h"
#include "Shader.h"
#include "Pipeline.h"
#include "Framebuffer.h"
namespace gpu {
@ -47,8 +47,8 @@ public:
};
template< typename T >
static void setGPUObject(const Buffer& buffer, T* bo) {
buffer.setGPUObject(bo);
static void setGPUObject(const Buffer& buffer, T* object) {
buffer.setGPUObject(object);
}
template< typename T >
static T* getGPUObject(const Buffer& buffer) {
@ -56,8 +56,8 @@ public:
}
template< typename T >
static void setGPUObject(const Texture& texture, T* to) {
texture.setGPUObject(to);
static void setGPUObject(const Texture& texture, T* object) {
texture.setGPUObject(object);
}
template< typename T >
static T* getGPUObject(const Texture& texture) {
@ -65,8 +65,8 @@ public:
}
template< typename T >
static void setGPUObject(const Shader& shader, T* so) {
shader.setGPUObject(so);
static void setGPUObject(const Shader& shader, T* object) {
shader.setGPUObject(object);
}
template< typename T >
static T* getGPUObject(const Shader& shader) {
@ -74,8 +74,8 @@ public:
}
template< typename T >
static void setGPUObject(const Pipeline& pipeline, T* po) {
pipeline.setGPUObject(po);
static void setGPUObject(const Pipeline& pipeline, T* object) {
pipeline.setGPUObject(object);
}
template< typename T >
static T* getGPUObject(const Pipeline& pipeline) {
@ -83,14 +83,23 @@ public:
}
template< typename T >
static void setGPUObject(const State& state, T* so) {
state.setGPUObject(so);
static void setGPUObject(const State& state, T* object) {
state.setGPUObject(object);
}
template< typename T >
static T* getGPUObject(const State& state) {
return reinterpret_cast<T*>(state.getGPUObject());
}
template< typename T >
static void setGPUObject(const Framebuffer& framebuffer, T* object) {
framebuffer.setGPUObject(object);
}
template< typename T >
static T* getGPUObject(const Framebuffer& framebuffer) {
return reinterpret_cast<T*>(framebuffer.getGPUObject());
}
protected:
};

View file

@ -26,7 +26,6 @@ Framebuffer::~Framebuffer()
Framebuffer* Framebuffer::create() {
auto framebuffer = new Framebuffer();
framebuffer->_renderBuffers.resize(MAX_NUM_RENDER_BUFFERS);
framebuffer->_renderBuffersSubresource.resize(MAX_NUM_RENDER_BUFFERS, 0);
return framebuffer;
}
@ -96,14 +95,14 @@ void Framebuffer::resize(uint16 width, uint16 height, uint16 numSamples) {
if ((width != _width) || (height != _height) || (numSamples != _numSamples)) {
for (uint32 i = 0; i < _renderBuffers.size(); ++i) {
if (_renderBuffers[i]) {
_renderBuffers[i]->resize2D(width, height, numSamples);
_numSamples = _renderBuffers[i]->getNumSamples();
_renderBuffers[i]._texture->resize2D(width, height, numSamples);
_numSamples = _renderBuffers[i]._texture->getNumSamples();
}
}
if (_depthStencilBuffer) {
_depthStencilBuffer->resize2D(width, height, numSamples);
_numSamples = _depthStencilBuffer->getNumSamples();
_depthStencilBuffer._texture->resize2D(width, height, numSamples);
_numSamples = _depthStencilBuffer._texture->getNumSamples();
}
_width = width;
@ -155,20 +154,10 @@ int Framebuffer::setRenderBuffer(uint32 slot, const TexturePointer& texture, uin
}
}
// everything works, assign
// dereference the previously used buffer if exists
if (_renderBuffers[slot]) {
_renderBuffers[slot].reset();
_renderBuffersSubresource[slot] = 0;
}
updateSize(texture);
// assign the new one
_renderBuffers[slot] = texture;
// Assign the subresource
_renderBuffersSubresource[slot] = subresource;
_renderBuffers[slot] = TextureView(texture, subresource);
// update the mask
int mask = (1<<slot);
@ -188,7 +177,7 @@ void Framebuffer::removeRenderBuffers() {
_buffersMask = _buffersMask & BUFFER_DEPTHSTENCIL;
for (auto renderBuffer : _renderBuffers) {
renderBuffer.reset();
renderBuffer._texture.reset();
}
updateSize(TexturePointer(nullptr));
@ -205,7 +194,7 @@ uint32 Framebuffer::getNumRenderBuffers() const {
TexturePointer Framebuffer::getRenderBuffer(uint32 slot) const {
if (!isSwapchain() && (slot < getMaxNumRenderBuffers())) {
return _renderBuffers[slot];
return _renderBuffers[slot]._texture;
} else {
return TexturePointer();
}
@ -214,7 +203,7 @@ TexturePointer Framebuffer::getRenderBuffer(uint32 slot) const {
uint32 Framebuffer::getRenderBufferSubresource(uint32 slot) const {
if (!isSwapchain() && (slot < getMaxNumRenderBuffers())) {
return _renderBuffersSubresource[slot];
return _renderBuffers[slot]._subresource;
} else {
return 0;
}
@ -232,15 +221,10 @@ bool Framebuffer::setDepthStencilBuffer(const TexturePointer& texture, uint32 su
}
}
// Checks ok, assign
_depthStencilBuffer.reset();
_depthStencilBufferSubresource = 0;
updateSize(texture);
// assign the new one
_depthStencilBuffer = texture;
_depthStencilBufferSubresource = subresource;
_depthStencilBuffer = TextureView(texture, subresource);
_buffersMask = ( _buffersMask & ~BUFFER_DEPTHSTENCIL);
if (texture) {
@ -254,7 +238,7 @@ TexturePointer Framebuffer::getDepthStencilBuffer() const {
if (isSwapchain()) {
return TexturePointer();
} else {
return _depthStencilBuffer;
return _depthStencilBuffer._texture;
}
}
@ -262,6 +246,6 @@ uint32 Framebuffer::getDepthStencilBufferSubresource() const {
if (isSwapchain()) {
return 0;
} else {
return _depthStencilBufferSubresource;
return _depthStencilBuffer._subresource;
}
}

View file

@ -155,11 +155,9 @@ public:
// Get viewport covering the ful Canvas
Viewport getViewport() const { return Viewport(getWidth(), getHeight(), 0, 0); }
bool isDefined() const { return _isDefined; }
protected:
Viewport _viewport;
uint16 _width;
uint16 _height;
uint16 _numSamples;
@ -170,12 +168,10 @@ protected:
SwapchainPointer _swapchain;
Textures _renderBuffers;
std::vector<uint32> _renderBuffersSubresource;
TexturePointer _depthStencilBuffer;
uint32 _depthStencilBufferSubresource;
TextureViews _renderBuffers;
TextureView _depthStencilBuffer;
bool _isDefined = false;
void updateSize(const TexturePointer& texture);
@ -189,6 +185,7 @@ protected:
GPUObject* getGPUObject() const { return _gpuObject; }
friend class Backend;
};
typedef std::shared_ptr<Framebuffer> FramebufferPointer;
}

View file

@ -32,6 +32,9 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
(&::gpu::GLBackend::do_setUniformBuffer),
(&::gpu::GLBackend::do_setUniformTexture),
(&::gpu::GLBackend::do_setFramebuffer),
(&::gpu::GLBackend::do_glEnable),
(&::gpu::GLBackend::do_glDisable),
@ -67,7 +70,8 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
GLBackend::GLBackend() :
_input(),
_transform(),
_pipeline()
_pipeline(),
_output()
{
initTransform();
}

View file

@ -133,14 +133,25 @@ public:
class GLPipeline : public GPUObject {
public:
GLShader* _program;
GLState* _state;
GLShader* _program = 0;
GLState* _state = 0;
GLPipeline();
~GLPipeline();
};
static GLPipeline* syncGPUObject(const Pipeline& pipeline);
class GLFramebuffer : public GPUObject {
public:
GLuint _fbo = 0;
GLFramebuffer();
~GLFramebuffer();
};
static GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer);
static GLuint getFramebufferID(const FramebufferPointer& framebuffer);
static const int MAX_NUM_ATTRIBUTES = Stream::NUM_INPUT_SLOTS;
static const int MAX_NUM_INPUT_BUFFERS = 16;
@ -276,8 +287,8 @@ protected:
State::Signature _stateSignatureCache;
GLState* _state;
bool _invalidState;
bool _needStateSync;
bool _invalidState = false;
bool _needStateSync = true;
PipelineStageState() :
_pipeline(),
@ -291,6 +302,16 @@ protected:
{}
} _pipeline;
// Output stage
void do_setFramebuffer(Batch& batch, uint32 paramOffset);
struct OutputStageState {
FramebufferPointer _framebuffer = nullptr;
OutputStageState() {}
} _output;
// TODO: As long as we have gl calls explicitely issued from interface
// code, we need to be able to record and batch these calls. THe long
// term strategy is to get rid of any GL calls in favor of the HIFI GPU API

View file

@ -0,0 +1,72 @@
//
// GLBackendTexture.cpp
// libraries/gpu/src/gpu
//
// Created by Sam Gateau on 1/19/2015.
// Copyright 2014 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "GPULogging.h"
#include "GLBackendShared.h"
GLBackend::GLFramebuffer::GLFramebuffer()
{}
GLBackend::GLFramebuffer::~GLFramebuffer() {
if (_fbo != 0) {
glDeleteFramebuffers(1, &_fbo);
}
}
GLBackend::GLFramebuffer* GLBackend::syncGPUObject(const Framebuffer& framebuffer) {
GLFramebuffer* object = Backend::getGPUObject<GLBackend::GLFramebuffer>(framebuffer);
// If GPU object already created and in sync
bool needUpdate = false;
if (object) {
return object;
} else if (!framebuffer.isDefined()) {
// NO framebuffer definition yet so let's avoid thinking
return nullptr;
}
// need to have a gpu object?
if (!object) {
object = new GLFramebuffer();
glGenFramebuffers(1, &object->_fbo);
CHECK_GL_ERROR();
Backend::setGPUObject(framebuffer, object);
}
CHECK_GL_ERROR();
return object;
}
GLuint GLBackend::getFramebufferID(const FramebufferPointer& framebuffer) {
if (!framebuffer) {
return 0;
}
GLFramebuffer* object = GLBackend::syncGPUObject(*framebuffer);
if (object) {
return object->_fbo;
} else {
return 0;
}
}
void GLBackend::do_setFramebuffer(Batch& batch, uint32 paramOffset) {
auto framebuffer = batch._framebuffers.get(batch._params[paramOffset]._uint);
if (_output._framebuffer != framebuffer) {
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, getFramebufferID(framebuffer));
_output._framebuffer = framebuffer;
}
}

View file

@ -240,15 +240,25 @@ public:
_subresource(0),
_element(element)
{};
TextureView(const TexturePointer& texture, const Element& element) :
TextureView(const TexturePointer& texture, uint16 subresource, const Element& element) :
_texture(texture),
_subresource(0),
_subresource(subresource),
_element(element)
{};
TextureView(const TexturePointer& texture, uint16 subresource) :
_texture(texture),
_subresource(subresource)
{};
~TextureView() {}
TextureView(const TextureView& view) = default;
TextureView& operator=(const TextureView& view) = default;
explicit operator bool() const { return (_texture); }
bool operator !() const { return (!_texture); }
};
typedef std::vector<TextureView> TextureViews;
};