--- /dev/null
+extension KHR_debug
#include <msp/gl/extensions/arb_buffer_storage.h>
#include <msp/gl/extensions/arb_direct_state_access.h>
#include <msp/gl/extensions/arb_map_buffer_range.h>
+#include <msp/gl/extensions/khr_debug.h>
#include <msp/strings/format.h>
#include "buffer.h"
#include "error.h"
return true;
}
+void Buffer::set_debug_name(const string &name)
+{
+#ifdef DEBUG
+ if(KHR_debug)
+ glObjectLabel(GL_BUFFER, id, name.size(), name.c_str());
+#else
+ (void)name;
+#endif
+}
+
vector<const BufferRange *> BufferRange::bound_uniform;
private:
static const Buffer *&binding(BufferType);
static bool set_current(BufferType, const Buffer *);
+
+public:
+ void set_debug_name(const std::string &);
};
#include <msp/gl/extensions/arb_vertex_array_object.h>
#include <msp/gl/extensions/arb_vertex_buffer_object.h>
#include <msp/gl/extensions/arb_vertex_shader.h>
+#include <msp/gl/extensions/khr_debug.h>
#include "buffer.h"
#include "error.h"
#include "mesh.h"
vertices.use_buffer(vbuf);
vtx_setup.set_vertex_array(vertices);
dirty |= VERTEX_BUFFER;
+
+#ifdef DEBUG
+ if(!debug_name.empty())
+ vbuf->set_debug_name(debug_name+" [VBO]");
+#endif
}
}
batches.front().change_buffer(ibuf);
vtx_setup.set_index_buffer(*ibuf);
dirty |= INDEX_BUFFER;
+
+#ifdef DEBUG
+ if(!debug_name.empty())
+ vbuf->set_debug_name(debug_name+" [IBO]");
+#endif
}
}
}
ibuf = 0;
}
+void Mesh::set_debug_name(const string &name)
+{
+#ifdef DEBUG
+ debug_name = name;
+ if(vbuf)
+ vbuf->set_debug_name(name+" [VBO]");
+ if(ibuf)
+ ibuf->set_debug_name(name+" [IBO]");
+ vtx_setup.set_debug_name(name+" [VAO]");
+#else
+ (void)name;
+#endif
+}
+
Mesh::Loader::Loader(Mesh &m, bool g):
DataFile::ObjectLoader<Mesh>(m),
mutable unsigned short dirty;
bool disallow_rendering;
const WindingTest *winding;
+ std::string debug_name;
public:
Mesh(ResourceManager * = 0);
virtual Resource::AsyncLoader *load(IO::Seekable &, const Resources * = 0);
virtual UInt64 get_data_size() const;
virtual void unload();
+
+ void set_debug_name(const std::string &);
};
} // namespace GL
#include <msp/gl/extensions/arb_uniform_buffer_object.h>
#include <msp/gl/extensions/arb_vertex_shader.h>
#include <msp/gl/extensions/ext_gpu_shader4.h>
+#include <msp/gl/extensions/khr_debug.h>
#include <msp/gl/extensions/nv_non_square_matrices.h>
#include <msp/io/print.h>
#include <msp/strings/format.h>
stage_ids[type] = stage_id;
glAttachShader(id, stage_id);
+#ifdef DEBUG
+ if(!debug_name.empty() && KHR_debug)
+ set_stage_debug_name(stage_id, type);
+#endif
+
return stage_id;
}
glUseProgram(0);
}
+void Program::set_debug_name(const string &name)
+{
+#ifdef DEBUG
+ debug_name = name;
+ if(KHR_debug)
+ {
+ glObjectLabel(GL_PROGRAM, id, name.size(), name.c_str());
+ for(unsigned i=0; i<MAX_STAGES; ++i)
+ if(stage_ids[i])
+ set_stage_debug_name(stage_ids[i], static_cast<Stage>(i));
+ }
+#else
+ (void)name;
+#endif
+}
+
+void Program::set_stage_debug_name(unsigned stage_id, Stage type)
+{
+#ifdef DEBUG
+ static const char *const suffixes[] = { " [VS]", " [GS]", " [FS]" };
+ string name = debug_name+suffixes[type];
+ glObjectLabel(GL_SHADER, stage_id, name.size(), name.c_str());
+#else
+ (void)stage_id; (void)type;
+#endif
+}
+
Program::UniformInfo::UniformInfo():
block(0),
std::vector<UniformInfo> uniforms;
LayoutHash uniform_layout_hash;
std::vector<AttributeInfo> attributes;
+ std::string debug_name;
public:
/// Constructs an empty Program with no shader stages attached.
void bind() const;
static void unbind();
+
+ void set_debug_name(const std::string &);
+private:
+ void set_stage_debug_name(unsigned, Stage);
};
} // namespace GL
#include <msp/gl/extensions/arb_shadow.h>
#include <msp/gl/extensions/ext_texture_filter_anisotropic.h>
#include <msp/gl/extensions/ext_texture3d.h>
+#include <msp/gl/extensions/khr_debug.h>
#include <msp/strings/format.h>
#include "error.h"
#include "sampler.h"
}
}
+void Sampler::set_debug_name(const string &name)
+{
+#ifdef DEBUG
+ if(id && KHR_debug)
+ glObjectLabel(GL_SAMPLER, id, name.size(), name.c_str());
+#else
+ (void)name;
+#endif
+}
+
Sampler::Loader::Loader(Sampler &s):
DataFile::ObjectLoader<Sampler>(s)
static void unbind_from(unsigned);
void unload();
+
+ void set_debug_name(const std::string &);
};
#include <msp/gl/extensions/arb_direct_state_access.h>
#include <msp/gl/extensions/arb_texture_swizzle.h>
#include <msp/gl/extensions/ext_framebuffer_object.h>
+#include <msp/gl/extensions/khr_debug.h>
#include <msp/io/memory.h>
#include "bindable.h"
#include "error.h"
glCreateTextures(target, 1, &id);
else
glGenTextures(1, &id);
+
+#ifdef DEBUG
+ if(!debug_name.empty() && KHR_debug)
+ glObjectLabel(GL_TEXTURE, id, debug_name.size(), debug_name.c_str());
+#endif
}
void Texture::set_format(PixelFormat fmt)
}
}
+void Texture::set_debug_name(const string &name)
+{
+#ifdef DEBUG
+ debug_name = name;
+ if(id && KHR_debug)
+ glObjectLabel(GL_TEXTURE, id, name.size(), name.c_str());
+#else
+ (void)name;
+#endif
+}
+
Texture::Loader::Loader(Texture &t):
DataFile::CollectionObjectLoader<Texture>(t, 0)
bool use_srgb_format;
bool auto_gen_mipmap;
Sampler default_sampler;
+ std::string debug_name;
static int swizzle_orders[];
static void unbind_from(unsigned);
virtual UInt64 get_data_size() const { return 0; }
+
+ void set_debug_name(const std::string &);
};
} // namespace GL
#include <msp/gl/extensions/arb_vertex_attrib_binding.h>
#include <msp/gl/extensions/arb_vertex_buffer_object.h>
#include <msp/gl/extensions/arb_vertex_shader.h>
+#include <msp/gl/extensions/khr_debug.h>
#include "buffer.h"
#include "error.h"
#include "gl.h"
glBindVertexArray(0);
}
+void VertexSetup::set_debug_name(const string &name)
+{
+#ifdef DEBUG
+ if(KHR_debug)
+ glObjectLabel(GL_VERTEX_ARRAY, id, name.size(), name.c_str());
+#else
+ (void)name;
+#endif
+}
+
} // namespace GL
} // namespace Msp
public:
void bind() const;
static void unbind();
+
+ void set_debug_name(const std::string &);
};
} // namespace GL
}
#pragma GCC diagnostic pop
+void Material::set_debug_name(const string &name)
+{
+#ifdef DEBUG
+ shdata.set_debug_name(name+" [UBO]");
+#else
+ (void)name;
+#endif
+}
+
Material::MaterialRegistry &Material::get_material_registry()
{
static MaterialRegistry registry;
virtual const Texture *get_texture(Tag) const = 0;
const Sampler *get_sampler() const { return sampler; }
+ void set_debug_name(const std::string &);
+
template<typename T>
static void register_type(const std::string &);
private:
renderer.set_reverse_winding(back_faces);
}
+void RenderPass::set_debug_name(const string &name)
+{
+#ifdef DEBUG
+ if(shdata.refcount()==1)
+ shdata->set_debug_name(name+" [UBO]");
+#else
+ (void)name;
+#endif
+}
+
DataFile::Loader::ActionMap RenderPass::Loader::shared_actions;
bool get_receive_shadows() const { return receive_shadows; }
void apply(Renderer &) const;
+
+ void set_debug_name(const std::string &);
};
} // namespace GL
return false;
}
+void Technique::set_debug_name(const std::string &name)
+{
+#ifdef DEBUG
+ for(map<Tag, RenderPass>::iterator i=passes.begin(); i!=passes.end(); ++i)
+ i->second.set_debug_name(format("%s [pass:%s]", name, i->first.str()));
+#else
+ (void)name;
+#endif
+}
+
DataFile::Loader::ActionMap Technique::Loader::shared_actions;
bool replace_material(const std::string &, const Material &);
bool replace_uniforms(const ProgramData &);
bool has_shaders() const;
+
+ void set_debug_name(const std::string &);
};
} // namespace GL
if(info.bind_point>=0)
{
if(!buffer)
+ {
buffer = new Buffer(UNIFORM_BUFFER);
+#ifdef DEBUG
+ if(!debug_name.empty())
+ buffer->set_debug_name(debug_name);
+#endif
+ }
+
BufferBackedUniformBlock *bb_block = new BufferBackedUniformBlock(info.data_size);
block.block = bb_block;
bb_block->use_buffer(buffer, last_buffer_block);
delete buffer;
buffer = new Buffer(UNIFORM_BUFFER);
last_buffer_block->change_buffer(buffer);
+
+#ifdef DEBUG
+ if(!debug_name.empty())
+ buffer->set_debug_name(debug_name);
+#endif
}
buffer->storage(required_size);
i->block->apply(i->bind_point);
}
+void ProgramData::set_debug_name(const string &name)
+{
+#ifdef DEBUG
+ debug_name = name;
+ if(buffer)
+ buffer->set_debug_name(name);
+#else
+ (void)name;
+#endif
+}
+
ProgramData::TaggedUniform::TaggedUniform():
value(0)
mutable BufferBackedUniformBlock *last_buffer_block;
mutable Buffer *buffer;
mutable Mask dirty;
+ std::string debug_name;
public:
ProgramData(const Program * = 0);
/** Applies uniform blocks for the currently bound program, creating them
if needed. */
void apply() const;
+
+ void set_debug_name(const std::string &);
};
template<typename T, unsigned N>
add_type<KeyFrame>().suffix(".kframe").keyword("keyframe");
add_type<Light>().keyword("light");
add_type<Lighting>().suffix(".lightn").keyword("lighting");
- add_type<Material>().suffix(".mat").creator(&Resources::create_material);
- add_type<Mesh>().keyword("mesh").creator(&Resources::create_mesh);
- add_type<Module>().suffix(".glsl").suffix(".spv").creator(&Resources::create_module);
+ add_type<Material>().suffix(".mat")
+ .creator(&Resources::create_material).notify(&Resources::set_debug_name<Material>);
+ add_type<Mesh>().keyword("mesh")
+ .creator(&Resources::create_mesh).notify(&Resources::set_debug_name<Mesh>);
+ add_type<Module>().suffix(".glsl").suffix(".spv")
+ .creator(&Resources::create_module);
add_type<Object>().keyword("object");
add_type<SequenceTemplate>().suffix(".seq").keyword("sequence");
add_type<Pose>().keyword("pose");
- add_type<Program>().keyword("shader").creator(&Resources::create_program);
- add_type<Sampler>().suffix(".samp").keyword("sampler");
- add_type<Scene>().suffix(".scene").creator(&Resources::create_scene);
- add_type<Technique>().suffix(".tech").keyword("technique");
- add_type<Texture1D>().base<Texture>().suffix(".tex1d").keyword("texture1d");
- add_type<Texture2D>().base<Texture>().suffix(".tex2d").suffix(".png").suffix(".jpg").keyword("texture2d").creator(&Resources::create_texture2d);
- add_type<Texture3D>().base<Texture>().suffix(".tex3d").keyword("texture3d");
- add_type<TextureCube>().base<Texture>().suffix(".texcb").keyword("texture_cube");
- add_type<Texture2DArray>().base<Texture>().suffix(".tex2da").keyword("texture2d_array");
+ add_type<Program>().keyword("shader")
+ .creator(&Resources::create_program).notify(&Resources::set_debug_name<Program>);
+ add_type<Sampler>().suffix(".samp").keyword("sampler")
+ .notify(&Resources::set_debug_name<Sampler>);
+ add_type<Scene>().suffix(".scene")
+ .creator(&Resources::create_scene);
+ add_type<Technique>().suffix(".tech").keyword("technique")
+ .notify(&Resources::set_debug_name<Technique>);
+ add_type<Texture1D>().base<Texture>().suffix(".tex1d").keyword("texture1d")
+ .notify(&Resources::set_debug_name<Texture1D>);
+ add_type<Texture2D>().base<Texture>().suffix(".tex2d").suffix(".png").suffix(".jpg").keyword("texture2d")
+ .creator(&Resources::create_texture2d).notify(&Resources::set_debug_name<Texture2D>);
+ add_type<Texture3D>().base<Texture>().suffix(".tex3d").keyword("texture3d")
+ .notify(&Resources::set_debug_name<Texture3D>);
+ add_type<TextureCube>().base<Texture>().suffix(".texcb").keyword("texture_cube")
+ .notify(&Resources::set_debug_name<TextureCube>);
+ add_type<Texture2DArray>().base<Texture>().suffix(".tex2da").keyword("texture2d_array")
+ .notify(&Resources::set_debug_name<Texture2DArray>);
add_source(get_builtins());
}
return 0;
}
+template<typename T>
+void Resources::set_debug_name(const string &name, T &item)
+{
+#ifdef DEBUG
+ item.set_debug_name(name);
+#endif
+}
+
Resources::Loader::Loader(Resources &r):
DerivedObjectLoader<Resources, Collection::Loader>(r)
Texture2D *create_texture2d(const std::string &);
Module *create_module(const std::string &);
Program *create_program(const std::string &);
+
+ template<typename T>
+ void set_debug_name(const std::string &, T &);
};
} // namespace GL