Merge pull request #5439 from samcake/punk

Remove alias gl calls from Batch and Introduce a ResetStage Batch command
This commit is contained in:
Brad Hefta-Gaub 2015-07-29 20:05:06 -07:00
commit 398bace83c
18 changed files with 294 additions and 404 deletions

View file

@ -1000,7 +1000,8 @@ void Application::paintGL() {
_compositor.displayOverlayTexture(&renderArgs);
}
if (!OculusManager::isConnected() || OculusManager::allowSwap()) {
PROFILE_RANGE(__FUNCTION__ "/bufferSwap");
_glWidget->swapBuffers();
@ -1012,6 +1013,13 @@ void Application::paintGL() {
_frameCount++;
_numFramesSinceLastResize++;
Stats::getInstance()->setRenderDetails(renderArgs._details);
// Reset the gpu::Context Stages
// Back to the default framebuffer;
gpu::Batch batch;
batch.resetStages();
renderArgs._context->render(batch);
}
void Application::runTests() {

View file

@ -154,6 +154,7 @@ void Stars::render(RenderArgs* renderArgs, float alpha) {
auto state = gpu::StatePointer(new gpu::State());
// enable decal blend
state->setDepthTest(gpu::State::DepthTest(false));
state->setAntialiasedLineEnable(true); // line smoothing also smooth points
state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA);
_starsPipeline.reset(gpu::Pipeline::create(program, state));
@ -217,10 +218,6 @@ void Stars::render(RenderArgs* renderArgs, float alpha) {
// Render the stars
batch.setPipeline(_starsPipeline);
batch._glEnable(GL_PROGRAM_POINT_SIZE_EXT);
batch._glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
batch._glEnable(GL_POINT_SMOOTH);
batch.setInputFormat(streamFormat);
batch.setInputBuffer(VERTICES_SLOT, posView);
batch.setInputBuffer(COLOR_SLOT, colView);

View file

@ -117,7 +117,7 @@ void ApplicationOverlay::renderQmlUi(RenderArgs* renderArgs) {
batch.setProjectionTransform(mat4());
batch.setModelTransform(Transform());
batch.setViewTransform(Transform());
batch._glBindTexture(GL_TEXTURE_2D, _uiTexture);
batch._glActiveBindTexture(GL_TEXTURE0, GL_TEXTURE_2D, _uiTexture);
geometryCache->renderUnitQuad(batch, glm::vec4(1));
}

View file

@ -178,8 +178,7 @@ void RenderableWebEntityItem::render(RenderArgs* args) {
batch.setModelTransform(getTransformToCenter());
bool textured = false, culled = false, emissive = false;
if (_texture) {
batch._glActiveTexture(GL_TEXTURE0);
batch._glBindTexture(GL_TEXTURE_2D, _texture);
batch._glActiveBindTexture(GL_TEXTURE0, GL_TEXTURE_2D, _texture);
textured = emissive = true;
}

View file

@ -288,6 +288,10 @@ void Batch::getQuery(const QueryPointer& query) {
_params.push_back(_queries.cache(query));
}
void Batch::resetStages() {
ADD_COMMAND(resetStages);
}
void push_back(Batch::Params& params, const vec3& v) {
params.push_back(v.x);
params.push_back(v.y);

View file

@ -94,7 +94,7 @@ public:
void setResourceTexture(uint32 slot, const TexturePointer& view);
void setResourceTexture(uint32 slot, const TextureView& view); // not a command, just a shortcut from a TextureView
// Framebuffer Stage
// Ouput Stage
void setFramebuffer(const FramebufferPointer& framebuffer);
// Clear framebuffer layers
@ -113,34 +113,17 @@ public:
void endQuery(const QueryPointer& query);
void getQuery(const QueryPointer& query);
// Reset the stage caches and states
void resetStages();
// 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
// For now, instead of calling the raw gl Call, use the equivalent call on the batch so the call is beeing recorded
// THe implementation of these functions is in GLBackend.cpp
void _glEnable(unsigned int cap);
void _glDisable(unsigned int cap);
void _glActiveBindTexture(unsigned int unit, unsigned int target, unsigned int texture);
void _glEnableClientState(unsigned int array);
void _glDisableClientState(unsigned int array);
void _glCullFace(unsigned int mode);
void _glAlphaFunc(unsigned int func, float ref);
void _glDepthFunc(unsigned int func);
void _glDepthMask(unsigned char flag);
void _glDepthRange(float zNear, float zFar);
void _glBindBuffer(unsigned int target, unsigned int buffer);
void _glBindTexture(unsigned int target, unsigned int texture);
void _glActiveTexture(unsigned int texture);
void _glTexParameteri(unsigned int target, unsigned int pname, int param);
void _glDrawBuffers(int n, const unsigned int* bufs);
void _glUseProgram(unsigned int program);
void _glUniform1i(int location, int v0);
void _glUniform1f(int location, float v0);
void _glUniform2f(int location, float v0, float v1);
@ -150,9 +133,6 @@ public:
void _glUniform4iv(int location, int count, const int* value);
void _glUniformMatrix4fv(int location, int count, unsigned char transpose, const float* value);
void _glEnableVertexAttribArray(int location);
void _glDisableVertexAttribArray(int location);
void _glColor4f(float red, float green, float blue, float alpha);
void _glLineWidth(float width);
@ -186,31 +166,13 @@ public:
COMMAND_endQuery,
COMMAND_getQuery,
COMMAND_resetStages,
// 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
COMMAND_glEnable,
COMMAND_glDisable,
COMMAND_glActiveBindTexture,
COMMAND_glEnableClientState,
COMMAND_glDisableClientState,
COMMAND_glCullFace,
COMMAND_glAlphaFunc,
COMMAND_glDepthFunc,
COMMAND_glDepthMask,
COMMAND_glDepthRange,
COMMAND_glBindBuffer,
COMMAND_glBindTexture,
COMMAND_glActiveTexture,
COMMAND_glTexParameteri,
COMMAND_glDrawBuffers,
COMMAND_glUseProgram,
COMMAND_glUniform1i,
COMMAND_glUniform1f,
COMMAND_glUniform2f,
@ -220,9 +182,6 @@ public:
COMMAND_glUniform4iv,
COMMAND_glUniformMatrix4fv,
COMMAND_glEnableVertexAttribArray,
COMMAND_glDisableVertexAttribArray,
COMMAND_glColor4f,
COMMAND_glLineWidth,

View file

@ -45,3 +45,4 @@ void Context::syncCache() {
void Context::downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) {
_backend->downloadFramebuffer(srcFramebuffer, region, destImage);
}

View file

@ -46,28 +46,10 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
(&::gpu::GLBackend::do_endQuery),
(&::gpu::GLBackend::do_getQuery),
(&::gpu::GLBackend::do_glEnable),
(&::gpu::GLBackend::do_glDisable),
(&::gpu::GLBackend::do_resetStages),
(&::gpu::GLBackend::do_glEnableClientState),
(&::gpu::GLBackend::do_glDisableClientState),
(&::gpu::GLBackend::do_glActiveBindTexture),
(&::gpu::GLBackend::do_glCullFace),
(&::gpu::GLBackend::do_glAlphaFunc),
(&::gpu::GLBackend::do_glDepthFunc),
(&::gpu::GLBackend::do_glDepthMask),
(&::gpu::GLBackend::do_glDepthRange),
(&::gpu::GLBackend::do_glBindBuffer),
(&::gpu::GLBackend::do_glBindTexture),
(&::gpu::GLBackend::do_glActiveTexture),
(&::gpu::GLBackend::do_glTexParameteri),
(&::gpu::GLBackend::do_glDrawBuffers),
(&::gpu::GLBackend::do_glUseProgram),
(&::gpu::GLBackend::do_glUniform1i),
(&::gpu::GLBackend::do_glUniform1f),
(&::gpu::GLBackend::do_glUniform2f),
@ -77,9 +59,6 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
(&::gpu::GLBackend::do_glUniform4iv),
(&::gpu::GLBackend::do_glUniformMatrix4fv),
(&::gpu::GLBackend::do_glEnableVertexAttribArray),
(&::gpu::GLBackend::do_glDisableVertexAttribArray),
(&::gpu::GLBackend::do_glColor4f),
(&::gpu::GLBackend::do_glLineWidth),
};
@ -128,6 +107,8 @@ GLBackend::GLBackend() :
}
GLBackend::~GLBackend() {
resetStages();
killInput();
killTransform();
}
@ -246,6 +227,22 @@ void GLBackend::do_drawIndexedInstanced(Batch& batch, uint32 paramOffset) {
(void) CHECK_GL_ERROR();
}
void GLBackend::do_resetStages(Batch& batch, uint32 paramOffset) {
resetStages();
}
void GLBackend::resetStages() {
resetInputStage();
resetPipelineStage();
resetTransformStage();
resetUniformStage();
resetResourceStage();
resetOutputStage();
resetQueryStage();
(void) CHECK_GL_ERROR();
}
// 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
@ -255,211 +252,24 @@ void GLBackend::do_drawIndexedInstanced(Batch& batch, uint32 paramOffset) {
//#define DO_IT_NOW(call, offset) runLastCommand();
#define DO_IT_NOW(call, offset)
void Batch::_glEnable(GLenum cap) {
ADD_COMMAND_GL(glEnable);
_params.push_back(cap);
DO_IT_NOW(_glEnable, 1);
}
void GLBackend::do_glEnable(Batch& batch, uint32 paramOffset) {
glEnable(batch._params[paramOffset]._uint);
(void) CHECK_GL_ERROR();
}
void Batch::_glDisable(GLenum cap) {
ADD_COMMAND_GL(glDisable);
_params.push_back(cap);
DO_IT_NOW(_glDisable, 1);
}
void GLBackend::do_glDisable(Batch& batch, uint32 paramOffset) {
glDisable(batch._params[paramOffset]._uint);
(void) CHECK_GL_ERROR();
}
void Batch::_glEnableClientState(GLenum array) {
ADD_COMMAND_GL(glEnableClientState);
_params.push_back(array);
DO_IT_NOW(_glEnableClientState, 1);
}
void GLBackend::do_glEnableClientState(Batch& batch, uint32 paramOffset) {
glEnableClientState(batch._params[paramOffset]._uint);
(void) CHECK_GL_ERROR();
}
void Batch::_glDisableClientState(GLenum array) {
ADD_COMMAND_GL(glDisableClientState);
_params.push_back(array);
DO_IT_NOW(_glDisableClientState, 1);
}
void GLBackend::do_glDisableClientState(Batch& batch, uint32 paramOffset) {
glDisableClientState(batch._params[paramOffset]._uint);
(void) CHECK_GL_ERROR();
}
void Batch::_glCullFace(GLenum mode) {
ADD_COMMAND_GL(glCullFace);
_params.push_back(mode);
DO_IT_NOW(_glCullFace, 1);
}
void GLBackend::do_glCullFace(Batch& batch, uint32 paramOffset) {
glCullFace(batch._params[paramOffset]._uint);
(void) CHECK_GL_ERROR();
}
void Batch::_glAlphaFunc(GLenum func, GLclampf ref) {
ADD_COMMAND_GL(glAlphaFunc);
_params.push_back(ref);
_params.push_back(func);
DO_IT_NOW(_glAlphaFunc, 2);
}
void GLBackend::do_glAlphaFunc(Batch& batch, uint32 paramOffset) {
glAlphaFunc(
batch._params[paramOffset + 1]._uint,
batch._params[paramOffset + 0]._float);
(void) CHECK_GL_ERROR();
}
void Batch::_glDepthFunc(GLenum func) {
ADD_COMMAND_GL(glDepthFunc);
_params.push_back(func);
DO_IT_NOW(_glDepthFunc, 1);
}
void GLBackend::do_glDepthFunc(Batch& batch, uint32 paramOffset) {
glDepthFunc(batch._params[paramOffset]._uint);
(void) CHECK_GL_ERROR();
}
void Batch::_glDepthMask(GLboolean flag) {
ADD_COMMAND_GL(glDepthMask);
_params.push_back(flag);
DO_IT_NOW(_glDepthMask, 1);
}
void GLBackend::do_glDepthMask(Batch& batch, uint32 paramOffset) {
glDepthMask(batch._params[paramOffset]._uint);
(void) CHECK_GL_ERROR();
}
void Batch::_glDepthRange(GLfloat zNear, GLfloat zFar) {
ADD_COMMAND_GL(glDepthRange);
_params.push_back(zFar);
_params.push_back(zNear);
DO_IT_NOW(_glDepthRange, 2);
}
void GLBackend::do_glDepthRange(Batch& batch, uint32 paramOffset) {
glDepthRange(
batch._params[paramOffset + 1]._float,
batch._params[paramOffset + 0]._float);
(void) CHECK_GL_ERROR();
}
void Batch::_glBindBuffer(GLenum target, GLuint buffer) {
ADD_COMMAND_GL(glBindBuffer);
_params.push_back(buffer);
_params.push_back(target);
DO_IT_NOW(_glBindBuffer, 2);
}
void GLBackend::do_glBindBuffer(Batch& batch, uint32 paramOffset) {
glBindBuffer(
batch._params[paramOffset + 1]._uint,
batch._params[paramOffset + 0]._uint);
(void) CHECK_GL_ERROR();
}
void Batch::_glBindTexture(GLenum target, GLuint texture) {
ADD_COMMAND_GL(glBindTexture);
void Batch::_glActiveBindTexture(GLenum unit, GLenum target, GLuint texture) {
ADD_COMMAND_GL(glActiveBindTexture);
_params.push_back(texture);
_params.push_back(target);
_params.push_back(unit);
DO_IT_NOW(_glBindTexture, 2);
DO_IT_NOW(_glActiveBindTexture, 3);
}
void GLBackend::do_glBindTexture(Batch& batch, uint32 paramOffset) {
void GLBackend::do_glActiveBindTexture(Batch& batch, uint32 paramOffset) {
glActiveTexture(batch._params[paramOffset + 2]._uint);
glBindTexture(
batch._params[paramOffset + 1]._uint,
batch._params[paramOffset + 0]._uint);
(void) CHECK_GL_ERROR();
}
void Batch::_glActiveTexture(GLenum texture) {
ADD_COMMAND_GL(glActiveTexture);
_params.push_back(texture);
DO_IT_NOW(_glActiveTexture, 1);
}
void GLBackend::do_glActiveTexture(Batch& batch, uint32 paramOffset) {
glActiveTexture(batch._params[paramOffset]._uint);
(void) CHECK_GL_ERROR();
}
void Batch::_glTexParameteri(GLenum target, GLenum pname, GLint param) {
ADD_COMMAND_GL(glTexParameteri);
_params.push_back(param);
_params.push_back(pname);
_params.push_back(target);
DO_IT_NOW(glTexParameteri, 3);
}
void GLBackend::do_glTexParameteri(Batch& batch, uint32 paramOffset) {
glTexParameteri(batch._params[paramOffset + 2]._uint,
batch._params[paramOffset + 1]._uint,
batch._params[paramOffset + 0]._int);
(void) CHECK_GL_ERROR();
}
void Batch::_glDrawBuffers(GLsizei n, const GLenum* bufs) {
ADD_COMMAND_GL(glDrawBuffers);
_params.push_back(cacheData(n * sizeof(GLenum), bufs));
_params.push_back(n);
DO_IT_NOW(_glDrawBuffers, 2);
}
void GLBackend::do_glDrawBuffers(Batch& batch, uint32 paramOffset) {
glDrawBuffers(
batch._params[paramOffset + 1]._uint,
(const GLenum*)batch.editData(batch._params[paramOffset + 0]._uint));
(void) CHECK_GL_ERROR();
}
void Batch::_glUseProgram(GLuint program) {
ADD_COMMAND_GL(glUseProgram);
_params.push_back(program);
DO_IT_NOW(_glUseProgram, 1);
}
void GLBackend::do_glUseProgram(Batch& batch, uint32 paramOffset) {
_pipeline._program = batch._params[paramOffset]._uint;
// for this call we still want to execute the glUseProgram in the order of the glCOmmand to avoid any issue
_pipeline._invalidProgram = false;
glUseProgram(_pipeline._program);
(void) CHECK_GL_ERROR();
}
void Batch::_glUniform1i(GLint location, GLint v0) {
if (location < 0) {
return;
@ -660,30 +470,6 @@ void GLBackend::do_glUniformMatrix4fv(Batch& batch, uint32 paramOffset) {
(void) CHECK_GL_ERROR();
}
void Batch::_glEnableVertexAttribArray(GLint location) {
ADD_COMMAND_GL(glEnableVertexAttribArray);
_params.push_back(location);
DO_IT_NOW(_glEnableVertexAttribArray, 1);
}
void GLBackend::do_glEnableVertexAttribArray(Batch& batch, uint32 paramOffset) {
glEnableVertexAttribArray(batch._params[paramOffset]._uint);
(void) CHECK_GL_ERROR();
}
void Batch::_glDisableVertexAttribArray(GLint location) {
ADD_COMMAND_GL(glDisableVertexAttribArray);
_params.push_back(location);
DO_IT_NOW(_glDisableVertexAttribArray, 1);
}
void GLBackend::do_glDisableVertexAttribArray(Batch& batch, uint32 paramOffset) {
glDisableVertexAttribArray(batch._params[paramOffset]._uint);
(void) CHECK_GL_ERROR();
}
void Batch::_glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
ADD_COMMAND_GL(glColor4f);

View file

@ -195,8 +195,17 @@ public:
static const int MAX_NUM_ATTRIBUTES = Stream::NUM_INPUT_SLOTS;
static const int MAX_NUM_INPUT_BUFFERS = 16;
uint32 getNumInputBuffers() const { return _input._buffersState.size(); }
uint32 getNumInputBuffers() const { return _input._invalidBuffers.size(); }
// 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_UNIFORM_BUFFERS = 12;
uint32 getMaxNumUniformBuffers() const { return MAX_NUM_UNIFORM_BUFFERS; }
// 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_TEXTURES = 16;
uint32 getMaxNumResourceTextures() const { return MAX_NUM_RESOURCE_TEXTURES; }
// The State setters called by the GLState::Commands when a new state is assigned
void do_setStateFillMode(int32 mode);
@ -250,12 +259,16 @@ protected:
void killInput();
void syncInputStateCache();
void updateInput();
void resetInputStage();
struct InputStageState {
bool _invalidFormat = true;
Stream::FormatPointer _format;
typedef std::bitset<MAX_NUM_ATTRIBUTES> ActivationCache;
ActivationCache _attributeActivation;
typedef std::bitset<MAX_NUM_INPUT_BUFFERS> BuffersState;
BuffersState _buffersState;
BuffersState _invalidBuffers;
Buffers _buffers;
Offsets _bufferOffsets;
@ -266,23 +279,20 @@ protected:
Offset _indexBufferOffset;
Type _indexBufferType;
typedef std::bitset<MAX_NUM_ATTRIBUTES> ActivationCache;
ActivationCache _attributeActivation;
GLuint _defaultVAO;
InputStageState() :
_invalidFormat(true),
_format(0),
_buffersState(0),
_buffers(_buffersState.size(), BufferPointer(0)),
_bufferOffsets(_buffersState.size(), 0),
_bufferStrides(_buffersState.size(), 0),
_bufferVBOs(_buffersState.size(), 0),
_attributeActivation(0),
_invalidBuffers(0),
_buffers(_invalidBuffers.size(), BufferPointer(0)),
_bufferOffsets(_invalidBuffers.size(), 0),
_bufferStrides(_invalidBuffers.size(), 0),
_bufferVBOs(_invalidBuffers.size(), 0),
_indexBuffer(0),
_indexBufferOffset(0),
_indexBufferType(UINT32),
_attributeActivation(0),
_defaultVAO(0)
{}
} _input;
@ -298,6 +308,7 @@ protected:
// Synchronize the state cache of this Backend with the actual real state of the GL Context
void syncTransformStateCache();
void updateTransform();
void resetTransformStage();
struct TransformStageState {
TransformObject _transformObject;
TransformCamera _transformCamera;
@ -330,12 +341,31 @@ protected:
// Uniform Stage
void do_setUniformBuffer(Batch& batch, uint32 paramOffset);
void releaseUniformBuffer(int slot);
void resetUniformStage();
struct UniformStageState {
Buffers _buffers;
UniformStageState():
_buffers(MAX_NUM_UNIFORM_BUFFERS, nullptr)
{}
} _uniform;
// Resource Stage
void do_setResourceTexture(Batch& batch, uint32 paramOffset);
struct UniformStageState {
};
void releaseResourceTexture(int slot);
void resetResourceStage();
struct ResourceStageState {
Textures _textures;
ResourceStageState():
_textures(MAX_NUM_RESOURCE_TEXTURES, nullptr)
{}
} _resource;
// Pipeline Stage
void do_setPipeline(Batch& batch, uint32 paramOffset);
void do_setStateBlendFactor(Batch& batch, uint32 paramOffset);
@ -349,6 +379,7 @@ protected:
void syncPipelineStateCache();
// Grab the actual gl state into it's gpu::State equivalent. THis is used by the above call syncPipleineStateCache()
void getCurrentGLState(State::Data& state);
void resetPipelineStage();
struct PipelineStageState {
@ -388,6 +419,7 @@ protected:
// Synchronize the state cache of this Backend with the actual real state of the GL Context
void syncOutputStateCache();
void resetOutputStage();
struct OutputStageState {
@ -402,31 +434,20 @@ protected:
void do_endQuery(Batch& batch, uint32 paramOffset);
void do_getQuery(Batch& batch, uint32 paramOffset);
void resetQueryStage();
struct QueryStageState {
};
// Reset stages
void do_resetStages(Batch& batch, uint32 paramOffset);
void resetStages();
// 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
void do_glEnable(Batch& batch, uint32 paramOffset);
void do_glDisable(Batch& batch, uint32 paramOffset);
void do_glActiveBindTexture(Batch& batch, uint32 paramOffset);
void do_glEnableClientState(Batch& batch, uint32 paramOffset);
void do_glDisableClientState(Batch& batch, uint32 paramOffset);
void do_glCullFace(Batch& batch, uint32 paramOffset);
void do_glAlphaFunc(Batch& batch, uint32 paramOffset);
void do_glDepthFunc(Batch& batch, uint32 paramOffset);
void do_glDepthMask(Batch& batch, uint32 paramOffset);
void do_glDepthRange(Batch& batch, uint32 paramOffset);
void do_glBindBuffer(Batch& batch, uint32 paramOffset);
void do_glBindTexture(Batch& batch, uint32 paramOffset);
void do_glActiveTexture(Batch& batch, uint32 paramOffset);
void do_glTexParameteri(Batch& batch, uint32 paramOffset);
void do_glDrawBuffers(Batch& batch, uint32 paramOffset);
void do_glUseProgram(Batch& batch, uint32 paramOffset);
void do_glUniform1i(Batch& batch, uint32 paramOffset);
void do_glUniform1f(Batch& batch, uint32 paramOffset);
void do_glUniform2f(Batch& batch, uint32 paramOffset);
@ -436,9 +457,6 @@ protected:
void do_glUniform4iv(Batch& batch, uint32 paramOffset);
void do_glUniformMatrix4fv(Batch& batch, uint32 paramOffset);
void do_glEnableVertexAttribArray(Batch& batch, uint32 paramOffset);
void do_glDisableVertexAttribArray(Batch& batch, uint32 paramOffset);
void do_glColor4f(Batch& batch, uint32 paramOffset);
void do_glLineWidth(Batch& batch, uint32 paramOffset);

View file

@ -52,7 +52,7 @@ void GLBackend::do_setInputBuffer(Batch& batch, uint32 paramOffset) {
}
if (isModified) {
_input._buffersState.set(channel);
_input._invalidBuffers.set(channel);
}
}
}
@ -154,7 +154,7 @@ void GLBackend::updateInput() {
_stats._ISNumFormatChanges++;
}
if (_input._buffersState.any()) {
if (_input._invalidBuffers.any()) {
int numBuffers = _input._buffers.size();
auto buffer = _input._buffers.data();
auto vbo = _input._bufferVBOs.data();
@ -162,7 +162,7 @@ void GLBackend::updateInput() {
auto stride = _input._bufferStrides.data();
for (int bufferNum = 0; bufferNum < numBuffers; bufferNum++) {
if (_input._buffersState.test(bufferNum)) {
if (_input._invalidBuffers.test(bufferNum)) {
glBindVertexBuffer(bufferNum, (*vbo), (*offset), (*stride));
}
buffer++;
@ -170,11 +170,11 @@ void GLBackend::updateInput() {
offset++;
stride++;
}
_input._buffersState.reset();
_input._invalidBuffers.reset();
(void) CHECK_GL_ERROR();
}
#else
if (_input._invalidFormat || _input._buffersState.any()) {
if (_input._invalidFormat || _input._invalidBuffers.any()) {
if (_input._invalidFormat) {
InputStageState::ActivationCache newActivation;
@ -232,7 +232,7 @@ void GLBackend::updateInput() {
if ((channelIt).first < buffers.size()) {
int bufferNum = (channelIt).first;
if (_input._buffersState.test(bufferNum) || _input._invalidFormat) {
if (_input._invalidBuffers.test(bufferNum) || _input._invalidFormat) {
// GLuint vbo = gpu::GLBackend::getBufferID((*buffers[bufferNum]));
GLuint vbo = _input._bufferVBOs[bufferNum];
if (boundVBO != vbo) {
@ -240,7 +240,7 @@ void GLBackend::updateInput() {
(void) CHECK_GL_ERROR();
boundVBO = vbo;
}
_input._buffersState[bufferNum] = false;
_input._invalidBuffers[bufferNum] = false;
for (unsigned int i = 0; i < channel._slots.size(); i++) {
const Stream::Attribute& attrib = attributes.at(channel._slots[i]);
@ -285,6 +285,51 @@ void GLBackend::updateInput() {
#endif
}
void GLBackend::resetInputStage() {
// Reset index buffer
_input._indexBufferType = UINT32;
_input._indexBufferOffset = 0;
_input._indexBuffer.reset();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
(void) CHECK_GL_ERROR();
#if defined(SUPPORT_VAO)
// TODO
#else
glBindBuffer(GL_ARRAY_BUFFER, 0);
size_t i = 0;
#if defined(SUPPORT_LEGACY_OPENGL)
for (; i < NUM_CLASSIC_ATTRIBS; i++) {
glDisableClientState(attributeSlotToClassicAttribName[i]);
}
glVertexPointer(4, GL_FLOAT, 0, 0);
glNormalPointer(GL_FLOAT, 0, 0);
glColorPointer(4, GL_FLOAT, 0, 0);
glTexCoordPointer(4, GL_FLOAT, 0, 0);
#endif
for (; i < _input._attributeActivation.size(); i++) {
glDisableVertexAttribArray(i);
glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, 0, 0);
}
#endif
// Reset vertex buffer and format
_input._format.reset();
_input._invalidFormat = false;
_input._attributeActivation.reset();
for (int i = 0; i < _input._buffers.size(); i++) {
_input._buffers[i].reset();
_input._bufferOffsets[i] = 0;
_input._bufferStrides[i] = 0;
_input._bufferVBOs[i] = 0;
}
_input._invalidBuffers.reset();
}
void GLBackend::do_setIndexBuffer(Batch& batch, uint32 paramOffset) {
_input._indexBufferType = (Type) batch._params[paramOffset + 2]._uint;

View file

@ -177,6 +177,13 @@ void GLBackend::syncOutputStateCache() {
_output._framebuffer.reset();
}
void GLBackend::resetOutputStage() {
if (_output._framebuffer) {
_output._framebuffer.reset();
_output._drawFBO = 0;
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}
}
void GLBackend::do_setFramebuffer(Batch& batch, uint32 paramOffset) {
auto framebuffer = batch._framebuffers.get(batch._params[paramOffset]._uint);
@ -206,12 +213,21 @@ void GLBackend::do_clearFramebuffer(Batch& batch, uint32 paramOffset) {
if (masks & Framebuffer::BUFFER_STENCIL) {
glClearStencil(stencil);
glmask |= GL_STENCIL_BUFFER_BIT;
// TODO: we will probably need to also check the write mask of stencil like we do
// for depth buffer, but as would say a famous Fez owner "We'll cross that bridge when we come to it"
}
bool restoreDepthMask = false;
if (masks & Framebuffer::BUFFER_DEPTH) {
glClearDepth(depth);
glmask |= GL_DEPTH_BUFFER_BIT;
}
bool cacheDepthMask = _pipeline._stateCache.depthTest.getWriteMask();
if (!cacheDepthMask) {
restoreDepthMask = true;
glDepthMask(GL_TRUE);
}
}
std::vector<GLenum> drawBuffers;
if (masks & Framebuffer::BUFFER_COLORS) {
@ -245,6 +261,11 @@ void GLBackend::do_clearFramebuffer(Batch& batch, uint32 paramOffset) {
glDisable(GL_SCISSOR_TEST);
}
// Restore write mask meaning turn back off
if (restoreDepthMask) {
glDepthMask(GL_FALSE);
}
// Restore the color draw buffers only if a frmaebuffer is bound
if (_output._framebuffer && !drawBuffers.empty()) {
auto glFramebuffer = syncGPUObject(*_output._framebuffer);

View file

@ -164,15 +164,74 @@ void GLBackend::updatePipeline() {
#endif
}
void GLBackend::resetPipelineStage() {
// First reset State to default
State::Signature resetSignature(0);
resetPipelineState(resetSignature);
_pipeline._state = nullptr;
_pipeline._invalidState = false;
// Second the shader side
_pipeline._invalidProgram = false;
_pipeline._program = 0;
_pipeline._pipeline.reset();
glUseProgram(0);
}
void GLBackend::releaseUniformBuffer(int slot) {
#if (GPU_FEATURE_PROFILE == GPU_CORE)
auto& buf = _uniform._buffers[slot];
if (buf) {
auto* object = Backend::getGPUObject<GLBackend::GLBuffer>(*buf);
if (object) {
GLuint bo = object->_buffer;
glBindBufferBase(GL_UNIFORM_BUFFER, slot, 0); // RELEASE
(void) CHECK_GL_ERROR();
}
buf.reset();
}
#endif
}
void GLBackend::resetUniformStage() {
for (int i = 0; i < _uniform._buffers.size(); i++) {
releaseUniformBuffer(i);
}
}
void GLBackend::do_setUniformBuffer(Batch& batch, uint32 paramOffset) {
GLuint slot = batch._params[paramOffset + 3]._uint;
BufferPointer uniformBuffer = batch._buffers.get(batch._params[paramOffset + 2]._uint);
GLintptr rangeStart = batch._params[paramOffset + 1]._uint;
GLsizeiptr rangeSize = batch._params[paramOffset + 0]._uint;
#if (GPU_FEATURE_PROFILE == GPU_CORE)
GLuint bo = getBufferID(*uniformBuffer);
glBindBufferRange(GL_UNIFORM_BUFFER, slot, bo, rangeStart, rangeSize);
if (!uniformBuffer) {
releaseUniformBuffer(slot);
return;
}
// check cache before thinking
if (_uniform._buffers[slot] == uniformBuffer) {
return;
}
// Sync BufferObject
auto* object = GLBackend::syncGPUObject(*uniformBuffer);
if (object) {
glBindBufferRange(GL_UNIFORM_BUFFER, slot, object->_buffer, rangeStart, rangeSize);
_uniform._buffers[slot] = uniformBuffer;
(void) CHECK_GL_ERROR();
} else {
releaseResourceTexture(slot);
return;
}
#else
// because we rely on the program uniform mechanism we need to have
// the program bound, thank you MacOSX Legacy profile.
@ -184,19 +243,49 @@ void GLBackend::do_setUniformBuffer(Batch& batch, uint32 paramOffset) {
// NOT working so we ll stick to the uniform float array until we move to core profile
// GLuint bo = getBufferID(*uniformBuffer);
//glUniformBufferEXT(_shader._program, slot, bo);
#endif
(void) CHECK_GL_ERROR();
#endif
}
void GLBackend::releaseResourceTexture(int slot) {
auto& tex = _resource._textures[slot];
if (tex) {
auto* object = Backend::getGPUObject<GLBackend::GLTexture>(*tex);
if (object) {
GLuint to = object->_texture;
GLuint target = object->_target;
glActiveTexture(GL_TEXTURE0 + slot);
glBindTexture(target, 0); // RELEASE
(void) CHECK_GL_ERROR();
}
tex.reset();
}
}
void GLBackend::resetResourceStage() {
for (int i = 0; i < _resource._textures.size(); i++) {
releaseResourceTexture(i);
}
}
void GLBackend::do_setResourceTexture(Batch& batch, uint32 paramOffset) {
GLuint slot = batch._params[paramOffset + 1]._uint;
TexturePointer uniformTexture = batch._textures.get(batch._params[paramOffset + 0]._uint);
TexturePointer resourceTexture = batch._textures.get(batch._params[paramOffset + 0]._uint);
if (!uniformTexture) {
if (!resourceTexture) {
releaseResourceTexture(slot);
return;
}
// check cache before thinking
if (_resource._textures[slot] == resourceTexture) {
return;
}
GLTexture* object = GLBackend::syncGPUObject(*uniformTexture);
// Always make sure the GLObject is in sync
GLTexture* object = GLBackend::syncGPUObject(*resourceTexture);
if (object) {
GLuint to = object->_texture;
GLuint target = object->_target;
@ -205,7 +294,10 @@ void GLBackend::do_setResourceTexture(Batch& batch, uint32 paramOffset) {
(void) CHECK_GL_ERROR();
_resource._textures[slot] = resourceTexture;
} else {
releaseResourceTexture(slot);
return;
}
}

View file

@ -104,3 +104,7 @@ void GLBackend::do_getQuery(Batch& batch, uint32 paramOffset) {
(void)CHECK_GL_ERROR();
}
}
void GLBackend::resetQueryStage() {
}

View file

@ -482,9 +482,14 @@ void GLBackend::syncPipelineStateCache() {
State::Data state;
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
// Point size is always on
glEnable(GL_PROGRAM_POINT_SIZE_EXT);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
getCurrentGLState(state);
State::Signature signature = State::evalSignature(state);
_pipeline._stateCache = state;
_pipeline._stateSignatureCache = signature;
}

View file

@ -184,4 +184,6 @@ void GLBackend::updateTransform() {
_transform._invalidView = _transform._invalidProj = _transform._invalidModel = _transform._invalidViewport = false;
}
void GLBackend::resetTransformStage() {
}

View file

@ -113,9 +113,6 @@ RenderDeferredTask::RenderDeferredTask() : Task() {
_drawHitEffectJobIndex = _jobs.size() -1;
_jobs.push_back(Job(new ResetGLState::JobModel()));
// Give ourselves 3 frmaes of timer queries
_timerQueries.push_back(std::make_shared<gpu::Query>());
_timerQueries.push_back(std::make_shared<gpu::Query>());

View file

@ -216,46 +216,6 @@ void render::renderItems(const SceneContextPointer& sceneContext, const RenderCo
}
}
void addClearStateCommands(gpu::Batch& batch) {
batch._glDepthMask(true);
batch._glDepthFunc(GL_LESS);
batch._glDisable(GL_CULL_FACE);
batch._glActiveTexture(GL_TEXTURE0 + 1);
batch._glBindTexture(GL_TEXTURE_2D, 0);
batch._glActiveTexture(GL_TEXTURE0 + 2);
batch._glBindTexture(GL_TEXTURE_2D, 0);
batch._glActiveTexture(GL_TEXTURE0 + 3);
batch._glBindTexture(GL_TEXTURE_2D, 0);
batch._glActiveTexture(GL_TEXTURE0);
batch._glBindTexture(GL_TEXTURE_2D, 0);
// deactivate vertex arrays after drawing
batch._glDisableClientState(GL_NORMAL_ARRAY);
batch._glDisableClientState(GL_VERTEX_ARRAY);
batch._glDisableClientState(GL_TEXTURE_COORD_ARRAY);
batch._glDisableClientState(GL_COLOR_ARRAY);
batch._glDisableVertexAttribArray(gpu::Stream::TANGENT);
batch._glDisableVertexAttribArray(gpu::Stream::SKIN_CLUSTER_INDEX);
batch._glDisableVertexAttribArray(gpu::Stream::SKIN_CLUSTER_WEIGHT);
// bind with 0 to switch back to normal operation
batch._glBindBuffer(GL_ARRAY_BUFFER, 0);
batch._glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
batch._glBindTexture(GL_TEXTURE_2D, 0);
// Back to no program
batch._glUseProgram(0);
}
void ResetGLState::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
gpu::Batch theBatch;
addClearStateCommands(theBatch);
assert(renderContext->args);
renderContext->args->_context->render(theBatch);
}
void DrawLight::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
assert(renderContext->args);
assert(renderContext->args->_viewFrustum);

View file

@ -260,14 +260,6 @@ public:
typedef Job::Model<DrawBackground> JobModel;
};
class ResetGLState {
public:
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);
typedef Job::Model<ResetGLState> JobModel;
};
class DrawSceneTask : public Task {
public: