X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=flavors%2Fgl%2Fsource%2Fglstate.cpp;h=4f9eba5b9d2bd11d499e7b0920403ee00de19e5f;hb=90368e53a94c6fa68cb678a1a03a9da7bf0c7dd8;hp=e3c9871c34c5ca5772a229f55c6c6107e288325d;hpb=fffbad8853e5849c64227635db70e5ce980d2f26;p=gldbg.git diff --git a/flavors/gl/source/glstate.cpp b/flavors/gl/source/glstate.cpp index e3c9871..4f9eba5 100644 --- a/flavors/gl/source/glstate.cpp +++ b/flavors/gl/source/glstate.cpp @@ -1,10 +1,3 @@ -/* $Id$ - -This file is part of gldbg -Copyright © 2009-2011 Mikko Rasa, Mikkosoft Productions -Distributed under the GPL -*/ - #include #include "glstate.h" @@ -73,7 +66,9 @@ GlState::GlState(): active_tex(0), client_active_tex(0), array_buffer(0), - element_buffer(0) + element_buffer(0), + uniform_buffer(0), + uniform_bind_points(64) { vertex_array.kind = GL_VERTEX_ARRAY; normal_array.kind = GL_NORMAL_ARRAY; @@ -129,6 +124,8 @@ GlState::GlState(): decoder->glBindBuffer = glBindBuffer; decoder->glBindBufferARB = glBindBuffer; + decoder->glBindBufferBase = glBindBufferBase; + decoder->glBindBufferRange = glBindBufferRange; decoder->glBufferData = glBufferData; decoder->glBufferDataARB = glBufferData; decoder->glBufferSubData = glBufferSubData; @@ -139,6 +136,27 @@ GlState::GlState(): decoder->glDrawElements = glDrawElements; decoder->glDrawRangeElements = glDrawRangeElements; decoder->glDrawRangeElementsEXT = glDrawRangeElements; + + decoder->glCreateShader = glCreateShader; + decoder->glCreateShaderObjectARB = glCreateShader; + decoder->glShaderSource = glShaderSource; + decoder->glShaderSourceARB = glShaderSource; + decoder->glCompileShader = glCompileShader; + decoder->glCompileShaderARB = glCompileShader; + decoder->glGetShaderiv = glGetShaderiv; + decoder->glGetShaderInfoLog = glGetShaderInfoLog; + decoder->glDeleteShader = glDeleteShader; + decoder->glCreateProgram = glCreateProgram; + decoder->glCreateProgramObjectARB = glCreateProgram; + decoder->glAttachShader = glAttachShader; + decoder->glAttachObjectARB = glAttachShader; + decoder->glLinkProgram = glLinkProgram; + decoder->glLinkProgramARB = glLinkProgram; + decoder->glGetProgramiv = glGetProgramiv; + decoder->glGetProgramInfoLog = glGetProgramInfoLog; + decoder->glDeleteObjectARB = glDeleteObjectARB; + decoder->glGetObjectParameterivARB = glGetObjectParameterivARB; + decoder->glGetInfoLogARB = glGetInfoLogARB; } GlState::~GlState() @@ -167,6 +185,13 @@ const BufferState &GlState::get_buffer(unsigned id) const return i->second; } +const BufferBindingState &GlState::get_buffer_binding(GLenum target, unsigned index) const +{ + if(target==GL_UNIFORM_BUFFER) + return uniform_bind_points[index]; + throw runtime_error("This buffer target does not have indexed binding points"); +} + const ArrayState &GlState::get_array(GLenum array) const { if(array==GL_VERTEX_ARRAY) @@ -196,6 +221,22 @@ const ArrayState &GlState::get_attrib_array(unsigned index) const throw runtime_error("Unknown attribute array"); } +const ShaderState &GlState::get_shader(unsigned id) const +{ + ShaderMap::const_iterator i = shaders.find(id); + if(i==shaders.end()) + throw runtime_error("Unknown shader"); + return i->second; +} + +const ProgramState &GlState::get_program(unsigned id) const +{ + ProgramMap::const_iterator i = programs.find(id); + if(i==programs.end()) + throw runtime_error("Unknown program"); + return i->second; +} + const BufferState *GlState::get_current_buffer(GLenum target) const { return const_cast(this)->get_current_buffer(target); @@ -221,12 +262,27 @@ TextureState *GlState::get_current_texture(GLenum target) return texunits[active_tex].get_current_texture(target); } +BufferState *GlState::get_buffer_object(unsigned id) +{ + BufferMap::iterator i = buffers.find(id); + return (i==buffers.end() ? 0 : &i->second); +} + BufferState *GlState::get_current_buffer(GLenum target) { if(target==GL_ARRAY_BUFFER) return array_buffer; else if(target==GL_ELEMENT_ARRAY_BUFFER) return element_buffer; + else if(target==GL_UNIFORM_BUFFER) + return uniform_buffer; + return 0; +} + +BufferBindingState *GlState::get_buffer_binding(GLenum target, unsigned index) +{ + if(target==GL_UNIFORM_BUFFER) + return &uniform_bind_points[index]; return 0; } @@ -262,6 +318,8 @@ void GlState::set_current_buffer(GLenum target, unsigned id) array_buffer = buf; else if(target==GL_ELEMENT_ARRAY_BUFFER) element_buffer = buf; + else if(target==GL_UNIFORM_BUFFER) + uniform_buffer = buf; } ArrayState &GlState::get_attrib_array(unsigned index) @@ -276,6 +334,61 @@ ArrayState &GlState::get_attrib_array(unsigned index) return array; } +ShaderState *GlState::get_shader(unsigned id, bool create) +{ + ShaderMap::iterator i = shaders.find(id); + if(i==shaders.end() && create) + { + i = shaders.insert(ShaderMap::value_type(id, ShaderState())).first; + i->second.id = id; + } + return (i!=shaders.end() ? &i->second : 0); +} + +void GlState::delete_shader(unsigned id) +{ + ShaderMap::iterator i = shaders.find(id); + if(i==shaders.end()) + return; + + for(ProgramMap::const_iterator j=programs.begin(); j!=programs.end(); ++j) + { + const vector &prog_shaders = j->second.shaders; + for(vector::const_iterator k=prog_shaders.begin(); k!=prog_shaders.end(); ++k) + if(*k==&i->second) + { + i->second.pending_delete = true; + return; + } + } + + shaders.erase(i); +} + +void GlState::delete_program(unsigned id) +{ + ProgramMap::iterator i = programs.find(id); + if(i==programs.end()) + return; + + vector prog_shaders = i->second.shaders; + programs.erase(i); + for(vector::const_iterator j=prog_shaders.begin(); j!=prog_shaders.end(); ++j) + if((*j)->pending_delete) + delete_shader((*j)->id); +} + +ProgramState *GlState::get_program(unsigned id, bool create) +{ + ProgramMap::iterator i = programs.find(id); + if(i==programs.end() && create) + { + i = programs.insert(ProgramMap::value_type(id, ProgramState())).first; + i->second.id = id; + } + return (i!=programs.end() ? &i->second : 0); +} + // Boolean state void GlState::glEnableClientState(void *user_data, GLenum state) @@ -419,6 +532,23 @@ void GlState::glVertexAttribPointer(void *user_data, unsigned index, int size, G void GlState::glBindBuffer(void *user_data, GLenum target, unsigned id) { reinterpret_cast(user_data)->set_current_buffer(target, id); } +void GlState::glBindBufferBase(void *user_data, GLenum target, unsigned index, unsigned id) +{ + if(BufferState *buffer = reinterpret_cast(user_data)->get_buffer_object(id)) + glBindBufferRange(user_data, target, index, id, 0, buffer->size); +} + +void GlState::glBindBufferRange(void *user_data, GLenum target, unsigned index, unsigned id, int offset, int size) +{ + GlState *self = reinterpret_cast(user_data); + if(BufferBindingState *binding = self->get_buffer_binding(target, index)) + { + binding->buffer = self->get_buffer_object(id); + binding->offset = offset; + binding->size = size; + } +} + void GlState::glBufferData(void *user_data, GLenum target, int size, const void *data, GLenum usage) { if(BufferState *buf = reinterpret_cast(user_data)->get_current_buffer(target)) @@ -448,3 +578,119 @@ void GlState::glDrawRangeElements(void *user_data, GLenum, unsigned, unsigned, i if(BufferState *buf = reinterpret_cast(user_data)->element_buffer) buf->content.update_elements(type); } + +// Shaders + +void GlState::glCreateShader(void *user_data, unsigned id, GLenum type) +{ + if(ShaderState *shader = reinterpret_cast(user_data)->get_shader(id, true)) + shader->type = type; +} + +void GlState::glShaderSource(void *user_data, unsigned id, int count, const char **str, const int *length) +{ + if(ShaderState *shader = reinterpret_cast(user_data)->get_shader(id, false)) + { + shader->source.clear(); + for(int i=0; isource.push_back(str[i]); + else + shader->source.push_back(string(str[i], length[i])); + } + shader->source_changed = true; + } +} + +void GlState::glCompileShader(void *user_data, unsigned id) +{ + if(ShaderState *shader = reinterpret_cast(user_data)->get_shader(id, false)) + shader->source_changed = false; +} + +void GlState::glGetShaderiv(void *user_data, unsigned id, GLenum pname, int *param) +{ + if(ShaderState *shader = reinterpret_cast(user_data)->get_shader(id, false)) + { + if(pname==GL_COMPILE_STATUS) + shader->compile_status = *param; + } +} + +void GlState::glGetShaderInfoLog(void *user_data, unsigned id, int, int *, char *log) +{ + if(ShaderState *shader = reinterpret_cast(user_data)->get_shader(id, false)) + shader->info_log = log; +} + +void GlState::glDeleteShader(void *user_data, unsigned id) +{ + reinterpret_cast(user_data)->delete_shader(id); +} + +void GlState::glCreateProgram(void *user_data, unsigned id) +{ + reinterpret_cast(user_data)->get_program(id, true); +} + +void GlState::glAttachShader(void *user_data, unsigned prog_id, unsigned shader_id) +{ + GlState *self = reinterpret_cast(user_data); + if(ProgramState *prog = self->get_program(prog_id, false)) + if(ShaderState *shader = self->get_shader(shader_id, false)) + prog->shaders.push_back(shader); +} + +void GlState::glLinkProgram(void *user_data, unsigned id) +{ + if(ProgramState *program = reinterpret_cast(user_data)->get_program(id, false)) + program->shaders_changed = false; +} + +void GlState::glGetProgramiv(void *user_data, unsigned id, GLenum pname, int *param) +{ + if(ProgramState *program = reinterpret_cast(user_data)->get_program(id, false)) + { + if(pname==GL_LINK_STATUS) + program->link_status = *param; + } +} + +void GlState::glGetProgramInfoLog(void *user_data, unsigned id, int, int *, char *log) +{ + if(ProgramState *program = reinterpret_cast(user_data)->get_program(id, false)) + program->info_log = log; +} + +void GlState::glDeleteProgram(void *user_data, unsigned id) +{ + reinterpret_cast(user_data)->delete_program(id); +} + +void GlState::glDeleteObjectARB(void *user_data, unsigned id) +{ + GlState *self = reinterpret_cast(user_data); + if(self->shaders.count(id)) + self->delete_shader(id); + else if(self->programs.count(id)) + self->delete_program(id); +} + +void GlState::glGetObjectParameterivARB(void *user_data, unsigned id, GLenum pname, int *param) +{ + GlState *self = reinterpret_cast(user_data); + if(self->shaders.count(id)) + glGetShaderiv(user_data, id, pname, param); + else if(self->programs.count(id)) + glGetProgramiv(user_data, id, pname, param); +} + +void GlState::glGetInfoLogARB(void *user_data, unsigned id, int bufsize, int *length, char *log) +{ + GlState *self = reinterpret_cast(user_data); + if(self->shaders.count(id)) + glGetShaderInfoLog(user_data, id, bufsize, length, log); + else if(self->programs.count(id)) + glGetProgramInfoLog(user_data, id, bufsize, length, log); +}