rhi: use GL 2 instead of GL Core

Widens the hardware compat range without losing features (besides
debugging)
This commit is contained in:
Eidolon 2023-11-04 18:08:00 -05:00
parent 6e6c0cd71f
commit 187f30cc64
11 changed files with 2198 additions and 2408 deletions

View file

@ -6,4 +6,4 @@ target_sources(SRB2SDL2 PRIVATE
shader_load_context.hpp shader_load_context.hpp
) )
add_subdirectory(gl3_core) add_subdirectory(gl2)

View file

@ -0,0 +1,4 @@
target_sources(SRB2SDL2 PRIVATE
gl2_rhi.cpp
gl2_rhi.hpp
)

View file

@ -7,7 +7,7 @@
// See the 'LICENSE' file for more details. // See the 'LICENSE' file for more details.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "gl3_core_rhi.hpp" #include "gl2_rhi.hpp"
#include <memory> #include <memory>
#include <string> #include <string>
@ -51,9 +51,9 @@ constexpr GLenum map_pixel_format(rhi::PixelFormat format)
switch (format) switch (format)
{ {
case rhi::PixelFormat::kR8: case rhi::PixelFormat::kR8:
return GL_R8; return GL_LUMINANCE8;
case rhi::PixelFormat::kRG8: case rhi::PixelFormat::kRG8:
return GL_RG8; return GL_LUMINANCE8_ALPHA8;
case rhi::PixelFormat::kRGB8: case rhi::PixelFormat::kRGB8:
return GL_RGB8; return GL_RGB8;
case rhi::PixelFormat::kRGBA8: case rhi::PixelFormat::kRGBA8:
@ -75,12 +75,12 @@ constexpr std::tuple<GLenum, GLenum, GLuint> map_pixel_data_format(rhi::PixelFor
switch (format) switch (format)
{ {
case rhi::PixelFormat::kR8: case rhi::PixelFormat::kR8:
layout = GL_RED; layout = GL_LUMINANCE;
type = GL_UNSIGNED_BYTE; type = GL_UNSIGNED_BYTE;
size = 1; size = 1;
break; break;
case rhi::PixelFormat::kRG8: case rhi::PixelFormat::kRG8:
layout = GL_RG; layout = GL_LUMINANCE_ALPHA;
type = GL_UNSIGNED_BYTE; type = GL_UNSIGNED_BYTE;
size = 2; size = 2;
break; break;
@ -109,9 +109,9 @@ constexpr GLenum map_texture_format(rhi::TextureFormat format)
case rhi::TextureFormat::kRGB: case rhi::TextureFormat::kRGB:
return GL_RGB; return GL_RGB;
case rhi::TextureFormat::kLuminance: case rhi::TextureFormat::kLuminance:
return GL_RED; return GL_LUMINANCE;
case rhi::TextureFormat::kLuminanceAlpha: case rhi::TextureFormat::kLuminanceAlpha:
return GL_RG; return GL_LUMINANCE_ALPHA;
default: default:
return GL_ZERO; return GL_ZERO;
} }
@ -141,9 +141,9 @@ constexpr GLenum map_internal_texture_format(rhi::TextureFormat format)
case rhi::TextureFormat::kRGB: case rhi::TextureFormat::kRGB:
return GL_RGB8; return GL_RGB8;
case rhi::TextureFormat::kLuminance: case rhi::TextureFormat::kLuminance:
return GL_R8; return GL_LUMINANCE8;
case rhi::TextureFormat::kLuminanceAlpha: case rhi::TextureFormat::kLuminanceAlpha:
return GL_RG8; return GL_LUMINANCE8_ALPHA8;
default: default:
return GL_ZERO; return GL_ZERO;
} }
@ -561,30 +561,30 @@ constexpr GLenum map_uniform_format(rhi::UniformFormat format)
} // namespace } // namespace
GlCorePlatform::~GlCorePlatform() = default; Gl2Platform::~Gl2Platform() = default;
GlCoreRhi::GlCoreRhi(std::unique_ptr<GlCorePlatform>&& platform, GlLoadFunc load_func) : platform_(std::move(platform)) Gl2Rhi::Gl2Rhi(std::unique_ptr<Gl2Platform>&& platform, GlLoadFunc load_func) : platform_(std::move(platform))
{ {
gl_ = std::make_unique<GladGLContext>(); gl_ = std::make_unique<GladGLContext>();
gladLoadGLContext(gl_.get(), load_func); gladLoadGLContext(gl_.get(), load_func);
} }
GlCoreRhi::~GlCoreRhi() = default; Gl2Rhi::~Gl2Rhi() = default;
rhi::Handle<rhi::RenderPass> GlCoreRhi::create_render_pass(const rhi::RenderPassDesc& desc) rhi::Handle<rhi::RenderPass> Gl2Rhi::create_render_pass(const rhi::RenderPassDesc& desc)
{ {
// GL has no formal render pass object // GL has no formal render pass object
GlCoreRenderPass pass; Gl2RenderPass pass;
pass.desc = desc; pass.desc = desc;
return render_pass_slab_.insert(std::move(pass)); return render_pass_slab_.insert(std::move(pass));
} }
void GlCoreRhi::destroy_render_pass(rhi::Handle<rhi::RenderPass> handle) void Gl2Rhi::destroy_render_pass(rhi::Handle<rhi::RenderPass> handle)
{ {
render_pass_slab_.remove(handle); render_pass_slab_.remove(handle);
} }
rhi::Handle<rhi::Texture> GlCoreRhi::create_texture(const rhi::TextureDesc& desc) rhi::Handle<rhi::Texture> Gl2Rhi::create_texture(const rhi::TextureDesc& desc)
{ {
GLenum internal_format = map_internal_texture_format(desc.format); GLenum internal_format = map_internal_texture_format(desc.format);
SRB2_ASSERT(internal_format != GL_ZERO); SRB2_ASSERT(internal_format != GL_ZERO);
@ -606,22 +606,22 @@ rhi::Handle<rhi::Texture> GlCoreRhi::create_texture(const rhi::TextureDesc& desc
gl_->TexImage2D(GL_TEXTURE_2D, 0, internal_format, desc.width, desc.height, 0, format, GL_UNSIGNED_BYTE, nullptr); gl_->TexImage2D(GL_TEXTURE_2D, 0, internal_format, desc.width, desc.height, 0, format, GL_UNSIGNED_BYTE, nullptr);
GL_ASSERT; GL_ASSERT;
GlCoreTexture texture; Gl2Texture texture;
texture.texture = name; texture.texture = name;
texture.desc = desc; texture.desc = desc;
return texture_slab_.insert(std::move(texture)); return texture_slab_.insert(std::move(texture));
} }
void GlCoreRhi::destroy_texture(rhi::Handle<rhi::Texture> handle) void Gl2Rhi::destroy_texture(rhi::Handle<rhi::Texture> handle)
{ {
SRB2_ASSERT(texture_slab_.is_valid(handle) == true); SRB2_ASSERT(texture_slab_.is_valid(handle) == true);
GlCoreTexture casted = texture_slab_.remove(handle); Gl2Texture casted = texture_slab_.remove(handle);
GLuint name = casted.texture; GLuint name = casted.texture;
gl_->DeleteTextures(1, &name); gl_->DeleteTextures(1, &name);
GL_ASSERT; GL_ASSERT;
} }
void GlCoreRhi::update_texture( void Gl2Rhi::update_texture(
Handle<GraphicsContext> ctx, Handle<GraphicsContext> ctx,
Handle<Texture> texture, Handle<Texture> texture,
Rect region, Rect region,
@ -672,7 +672,7 @@ void GlCoreRhi::update_texture(
GL_ASSERT; GL_ASSERT;
} }
rhi::Handle<rhi::Buffer> GlCoreRhi::create_buffer(const rhi::BufferDesc& desc) rhi::Handle<rhi::Buffer> Gl2Rhi::create_buffer(const rhi::BufferDesc& desc)
{ {
GLenum target = map_buffer_type(desc.type); GLenum target = map_buffer_type(desc.type);
SRB2_ASSERT(target != GL_ZERO); SRB2_ASSERT(target != GL_ZERO);
@ -690,23 +690,23 @@ rhi::Handle<rhi::Buffer> GlCoreRhi::create_buffer(const rhi::BufferDesc& desc)
gl_->BufferData(target, desc.size, nullptr, usage); gl_->BufferData(target, desc.size, nullptr, usage);
GL_ASSERT; GL_ASSERT;
GlCoreBuffer buffer; Gl2Buffer buffer;
buffer.buffer = name; buffer.buffer = name;
buffer.desc = desc; buffer.desc = desc;
return buffer_slab_.insert(std::move(buffer)); return buffer_slab_.insert(std::move(buffer));
} }
void GlCoreRhi::destroy_buffer(rhi::Handle<rhi::Buffer> handle) void Gl2Rhi::destroy_buffer(rhi::Handle<rhi::Buffer> handle)
{ {
SRB2_ASSERT(buffer_slab_.is_valid(handle) == true); SRB2_ASSERT(buffer_slab_.is_valid(handle) == true);
GlCoreBuffer casted = buffer_slab_.remove(handle); Gl2Buffer casted = buffer_slab_.remove(handle);
GLuint name = casted.buffer; GLuint name = casted.buffer;
gl_->DeleteBuffers(1, &name); gl_->DeleteBuffers(1, &name);
GL_ASSERT; GL_ASSERT;
} }
void GlCoreRhi::update_buffer( void Gl2Rhi::update_buffer(
rhi::Handle<GraphicsContext> ctx, rhi::Handle<GraphicsContext> ctx,
rhi::Handle<rhi::Buffer> handle, rhi::Handle<rhi::Buffer> handle,
uint32_t offset, uint32_t offset,
@ -744,12 +744,12 @@ void GlCoreRhi::update_buffer(
} }
rhi::Handle<rhi::UniformSet> rhi::Handle<rhi::UniformSet>
GlCoreRhi::create_uniform_set(rhi::Handle<rhi::GraphicsContext> ctx, const rhi::CreateUniformSetInfo& info) Gl2Rhi::create_uniform_set(rhi::Handle<rhi::GraphicsContext> ctx, const rhi::CreateUniformSetInfo& info)
{ {
SRB2_ASSERT(graphics_context_active_ == true); SRB2_ASSERT(graphics_context_active_ == true);
SRB2_ASSERT(ctx.generation() == graphics_context_generation_); SRB2_ASSERT(ctx.generation() == graphics_context_generation_);
GlCoreUniformSet uniform_set; Gl2UniformSet uniform_set;
for (auto& uniform : info.uniforms) for (auto& uniform : info.uniforms)
{ {
@ -759,7 +759,7 @@ GlCoreRhi::create_uniform_set(rhi::Handle<rhi::GraphicsContext> ctx, const rhi::
return uniform_set_slab_.insert(std::move(uniform_set)); return uniform_set_slab_.insert(std::move(uniform_set));
} }
rhi::Handle<rhi::BindingSet> GlCoreRhi::create_binding_set( rhi::Handle<rhi::BindingSet> Gl2Rhi::create_binding_set(
rhi::Handle<rhi::GraphicsContext> ctx, rhi::Handle<rhi::GraphicsContext> ctx,
Handle<Pipeline> pipeline, Handle<Pipeline> pipeline,
const rhi::CreateBindingSetInfo& info const rhi::CreateBindingSetInfo& info
@ -773,47 +773,13 @@ rhi::Handle<rhi::BindingSet> GlCoreRhi::create_binding_set(
SRB2_ASSERT(info.vertex_buffers.size() == pl.desc.vertex_input.buffer_layouts.size()); SRB2_ASSERT(info.vertex_buffers.size() == pl.desc.vertex_input.buffer_layouts.size());
GlCoreBindingSet binding_set; Gl2BindingSet binding_set;
GLuint vao = 0; for (auto& vertex_buffer : info.vertex_buffers)
gl_->GenVertexArrays(1, &vao);
GL_ASSERT;
gl_->BindVertexArray(vao);
GL_ASSERT;
for (auto& attr_layout : pl.desc.vertex_input.attr_layouts)
{ {
SRB2_ASSERT(buffer_slab_.is_valid(info.vertex_buffers[attr_layout.buffer_index].vertex_buffer)); binding_set.vertex_buffer_bindings.push_back(vertex_buffer);
auto& buf = buffer_slab_[info.vertex_buffers[attr_layout.buffer_index].vertex_buffer];
SRB2_ASSERT(buf.desc.type == rhi::BufferType::kVertexBuffer);
auto& buffer_layout = pl.desc.vertex_input.buffer_layouts[attr_layout.buffer_index];
gl_->BindBuffer(GL_ARRAY_BUFFER, buf.buffer);
GL_ASSERT;
GLuint attrib_location = pl.attrib_locations[attr_layout.name];
VertexAttributeFormat vert_attr_format = rhi::vertex_attribute_format(attr_layout.name);
GLenum vertex_attr_type = map_vertex_attribute_type(vert_attr_format);
SRB2_ASSERT(vertex_attr_type != GL_ZERO);
GLint vertex_attr_size = map_vertex_attribute_format_size(vert_attr_format);
SRB2_ASSERT(vertex_attr_size != 0);
uint32_t vertex_buffer_offset = 0; // TODO allow binding set to specify
gl_->EnableVertexAttribArray(pl.attrib_locations[attr_layout.name]);
GL_ASSERT;
gl_->VertexAttribPointer(
attrib_location,
vertex_attr_size,
vertex_attr_type,
GL_FALSE,
buffer_layout.stride,
reinterpret_cast<const void*>(vertex_buffer_offset + attr_layout.offset)
);
GL_ASSERT;
} }
binding_set.vao = vao;
// Set textures // Set textures
for (size_t i = 0; i < info.sampler_textures.size(); i++) for (size_t i = 0; i < info.sampler_textures.size(); i++)
{ {
@ -829,7 +795,7 @@ rhi::Handle<rhi::BindingSet> GlCoreRhi::create_binding_set(
return binding_set_slab_.insert(std::move(binding_set)); return binding_set_slab_.insert(std::move(binding_set));
} }
rhi::Handle<rhi::Renderbuffer> GlCoreRhi::create_renderbuffer(const rhi::RenderbufferDesc& desc) rhi::Handle<rhi::Renderbuffer> Gl2Rhi::create_renderbuffer(const rhi::RenderbufferDesc& desc)
{ {
GLuint name = 0; GLuint name = 0;
gl_->GenRenderbuffers(1, &name); gl_->GenRenderbuffers(1, &name);
@ -855,22 +821,22 @@ rhi::Handle<rhi::Renderbuffer> GlCoreRhi::create_renderbuffer(const rhi::Renderb
gl_->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, desc.width, desc.height); gl_->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, desc.width, desc.height);
GL_ASSERT; GL_ASSERT;
GlCoreRenderbuffer rb; Gl2Renderbuffer rb;
rb.renderbuffer = name; rb.renderbuffer = name;
rb.desc = desc; rb.desc = desc;
return renderbuffer_slab_.insert(std::move(rb)); return renderbuffer_slab_.insert(std::move(rb));
} }
void GlCoreRhi::destroy_renderbuffer(rhi::Handle<rhi::Renderbuffer> handle) void Gl2Rhi::destroy_renderbuffer(rhi::Handle<rhi::Renderbuffer> handle)
{ {
SRB2_ASSERT(renderbuffer_slab_.is_valid(handle) == true); SRB2_ASSERT(renderbuffer_slab_.is_valid(handle) == true);
GlCoreRenderbuffer casted = renderbuffer_slab_.remove(handle); Gl2Renderbuffer casted = renderbuffer_slab_.remove(handle);
GLuint name = casted.renderbuffer; GLuint name = casted.renderbuffer;
gl_->DeleteRenderbuffers(1, &name); gl_->DeleteRenderbuffers(1, &name);
GL_ASSERT; GL_ASSERT;
} }
rhi::Handle<rhi::Pipeline> GlCoreRhi::create_pipeline(const PipelineDesc& desc) rhi::Handle<rhi::Pipeline> Gl2Rhi::create_pipeline(const PipelineDesc& desc)
{ {
SRB2_ASSERT(platform_ != nullptr); SRB2_ASSERT(platform_ != nullptr);
// TODO assert compatibility of pipeline description with program using ProgramRequirements // TODO assert compatibility of pipeline description with program using ProgramRequirements
@ -880,14 +846,18 @@ rhi::Handle<rhi::Pipeline> GlCoreRhi::create_pipeline(const PipelineDesc& desc)
GLuint vertex = 0; GLuint vertex = 0;
GLuint fragment = 0; GLuint fragment = 0;
GLuint program = 0; GLuint program = 0;
GlCorePipeline pipeline; Gl2Pipeline pipeline;
auto [vert_srcs, frag_srcs] = platform_->find_shader_sources(desc.program); auto [vert_srcs, frag_srcs] = platform_->find_shader_sources(desc.program);
// GL 2 note:
// Do not explicitly set GLSL version. Unversioned sources are required to be treated as 110, but writing 110
// breaks the AMD driver's program linker in a bizarre way.
// Process vertex shader sources // Process vertex shader sources
std::vector<const char*> vert_sources; std::vector<const char*> vert_sources;
ShaderLoadContext vert_ctx; ShaderLoadContext vert_ctx;
vert_ctx.set_version("150 core"); vert_ctx.set_version("120");
for (auto& attribute : desc.vertex_input.attr_layouts) for (auto& attribute : desc.vertex_input.attr_layouts)
{ {
for (auto const& require_attr : reqs.vertex_input.attributes) for (auto const& require_attr : reqs.vertex_input.attributes)
@ -923,7 +893,7 @@ rhi::Handle<rhi::Pipeline> GlCoreRhi::create_pipeline(const PipelineDesc& desc)
// Process vertex shader sources // Process vertex shader sources
std::vector<const char*> frag_sources; std::vector<const char*> frag_sources;
ShaderLoadContext frag_ctx; ShaderLoadContext frag_ctx;
frag_ctx.set_version("150 core"); frag_ctx.set_version("120");
for (auto& sampler : desc.sampler_input.enabled_samplers) for (auto& sampler : desc.sampler_input.enabled_samplers)
{ {
for (auto const& require_sampler : reqs.samplers.samplers) for (auto const& require_sampler : reqs.samplers.samplers)
@ -1010,7 +980,7 @@ rhi::Handle<rhi::Pipeline> GlCoreRhi::create_pipeline(const PipelineDesc& desc)
throw std::runtime_error(fmt::format("Pipeline program link failed: {}", std::string(link_error.data()))); throw std::runtime_error(fmt::format("Pipeline program link failed: {}", std::string(link_error.data())));
} }
std::unordered_map<std::string, GlCoreActiveUniform> active_attributes; std::unordered_map<std::string, Gl2ActiveUniform> active_attributes;
GLint active_attribute_total = -1; GLint active_attribute_total = -1;
gl_->GetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &active_attribute_total); gl_->GetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &active_attribute_total);
if (active_attribute_total < 0) if (active_attribute_total < 0)
@ -1041,10 +1011,10 @@ rhi::Handle<rhi::Pipeline> GlCoreRhi::create_pipeline(const PipelineDesc& desc)
GL_ASSERT; GL_ASSERT;
GLint location = gl_->GetAttribLocation(program, name); GLint location = gl_->GetAttribLocation(program, name);
GL_ASSERT; GL_ASSERT;
active_attributes.insert({std::string(name), GlCoreActiveUniform {type, static_cast<GLuint>(location)}}); active_attributes.insert({std::string(name), Gl2ActiveUniform {type, static_cast<GLuint>(location)}});
} }
std::unordered_map<std::string, GlCoreActiveUniform> active_uniforms; std::unordered_map<std::string, Gl2ActiveUniform> active_uniforms;
size_t total_enabled_uniforms = 0; size_t total_enabled_uniforms = 0;
for (auto g = desc.uniform_input.enabled_uniforms.cbegin(); g != desc.uniform_input.enabled_uniforms.cend(); for (auto g = desc.uniform_input.enabled_uniforms.cbegin(); g != desc.uniform_input.enabled_uniforms.cend();
g = std::next(g)) g = std::next(g))
@ -1083,7 +1053,7 @@ rhi::Handle<rhi::Pipeline> GlCoreRhi::create_pipeline(const PipelineDesc& desc)
GL_ASSERT; GL_ASSERT;
GLint location = gl_->GetUniformLocation(program, name); GLint location = gl_->GetUniformLocation(program, name);
GL_ASSERT; GL_ASSERT;
active_uniforms.insert({std::string(name), GlCoreActiveUniform {type, static_cast<GLuint>(location)}}); active_uniforms.insert({std::string(name), Gl2ActiveUniform {type, static_cast<GLuint>(location)}});
} }
for (auto& attr : desc.vertex_input.attr_layouts) for (auto& attr : desc.vertex_input.attr_layouts)
@ -1176,10 +1146,10 @@ rhi::Handle<rhi::Pipeline> GlCoreRhi::create_pipeline(const PipelineDesc& desc)
return pipeline_slab_.insert(std::move(pipeline)); return pipeline_slab_.insert(std::move(pipeline));
} }
void GlCoreRhi::destroy_pipeline(rhi::Handle<rhi::Pipeline> handle) void Gl2Rhi::destroy_pipeline(rhi::Handle<rhi::Pipeline> handle)
{ {
SRB2_ASSERT(pipeline_slab_.is_valid(handle) == true); SRB2_ASSERT(pipeline_slab_.is_valid(handle) == true);
GlCorePipeline casted = pipeline_slab_.remove(handle); Gl2Pipeline casted = pipeline_slab_.remove(handle);
GLuint vertex_shader = casted.vertex_shader; GLuint vertex_shader = casted.vertex_shader;
GLuint fragment_shader = casted.fragment_shader; GLuint fragment_shader = casted.fragment_shader;
GLuint program = casted.program; GLuint program = casted.program;
@ -1192,14 +1162,14 @@ void GlCoreRhi::destroy_pipeline(rhi::Handle<rhi::Pipeline> handle)
GL_ASSERT; GL_ASSERT;
} }
rhi::Handle<rhi::GraphicsContext> GlCoreRhi::begin_graphics() rhi::Handle<rhi::GraphicsContext> Gl2Rhi::begin_graphics()
{ {
SRB2_ASSERT(graphics_context_active_ == false); SRB2_ASSERT(graphics_context_active_ == false);
graphics_context_active_ = true; graphics_context_active_ = true;
return rhi::Handle<rhi::GraphicsContext>(0, graphics_context_generation_); return rhi::Handle<rhi::GraphicsContext>(0, graphics_context_generation_);
} }
void GlCoreRhi::end_graphics(rhi::Handle<rhi::GraphicsContext> handle) void Gl2Rhi::end_graphics(rhi::Handle<rhi::GraphicsContext> handle)
{ {
SRB2_ASSERT(graphics_context_active_ == true); SRB2_ASSERT(graphics_context_active_ == true);
SRB2_ASSERT(current_pipeline_.has_value() == false && current_render_pass_.has_value() == false); SRB2_ASSERT(current_pipeline_.has_value() == false && current_render_pass_.has_value() == false);
@ -1213,7 +1183,7 @@ void GlCoreRhi::end_graphics(rhi::Handle<rhi::GraphicsContext> handle)
GL_ASSERT; GL_ASSERT;
} }
void GlCoreRhi::present() void Gl2Rhi::present()
{ {
SRB2_ASSERT(platform_ != nullptr); SRB2_ASSERT(platform_ != nullptr);
SRB2_ASSERT(graphics_context_active_ == false); SRB2_ASSERT(graphics_context_active_ == false);
@ -1221,7 +1191,7 @@ void GlCoreRhi::present()
platform_->present(); platform_->present();
} }
void GlCoreRhi::begin_default_render_pass(Handle<GraphicsContext> ctx, bool clear) void Gl2Rhi::begin_default_render_pass(Handle<GraphicsContext> ctx, bool clear)
{ {
SRB2_ASSERT(platform_ != nullptr); SRB2_ASSERT(platform_ != nullptr);
SRB2_ASSERT(graphics_context_active_ == true); SRB2_ASSERT(graphics_context_active_ == true);
@ -1245,10 +1215,10 @@ void GlCoreRhi::begin_default_render_pass(Handle<GraphicsContext> ctx, bool clea
GL_ASSERT; GL_ASSERT;
} }
current_render_pass_ = GlCoreRhi::DefaultRenderPassState {}; current_render_pass_ = Gl2Rhi::DefaultRenderPassState {};
} }
void GlCoreRhi::begin_render_pass(Handle<GraphicsContext> ctx, const RenderPassBeginInfo& info) void Gl2Rhi::begin_render_pass(Handle<GraphicsContext> ctx, const RenderPassBeginInfo& info)
{ {
SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation()); SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation());
SRB2_ASSERT(current_render_pass_.has_value() == false); SRB2_ASSERT(current_render_pass_.has_value() == false);
@ -1257,7 +1227,7 @@ void GlCoreRhi::begin_render_pass(Handle<GraphicsContext> ctx, const RenderPassB
auto& rp = render_pass_slab_[info.render_pass]; auto& rp = render_pass_slab_[info.render_pass];
SRB2_ASSERT(rp.desc.use_depth_stencil == info.depth_stencil_attachment.has_value()); SRB2_ASSERT(rp.desc.use_depth_stencil == info.depth_stencil_attachment.has_value());
auto fb_itr = framebuffers_.find(GlCoreFramebufferKey {info.color_attachment, info.depth_stencil_attachment}); auto fb_itr = framebuffers_.find(Gl2FramebufferKey {info.color_attachment, info.depth_stencil_attachment});
if (fb_itr == framebuffers_.end()) if (fb_itr == framebuffers_.end())
{ {
// Create a new framebuffer for this color-depth pair // Create a new framebuffer for this color-depth pair
@ -1268,7 +1238,7 @@ void GlCoreRhi::begin_render_pass(Handle<GraphicsContext> ctx, const RenderPassB
GL_ASSERT; GL_ASSERT;
fb_itr = framebuffers_ fb_itr = framebuffers_
.insert( .insert(
{GlCoreFramebufferKey {info.color_attachment, info.depth_stencil_attachment}, {Gl2FramebufferKey {info.color_attachment, info.depth_stencil_attachment},
static_cast<uint32_t>(fb_name)} static_cast<uint32_t>(fb_name)}
) )
.first; .first;
@ -1328,7 +1298,7 @@ void GlCoreRhi::begin_render_pass(Handle<GraphicsContext> ctx, const RenderPassB
current_render_pass_ = info; current_render_pass_ = info;
} }
void GlCoreRhi::end_render_pass(Handle<GraphicsContext> ctx) void Gl2Rhi::end_render_pass(Handle<GraphicsContext> ctx)
{ {
SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation()); SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation());
SRB2_ASSERT(current_render_pass_.has_value() == true); SRB2_ASSERT(current_render_pass_.has_value() == true);
@ -1337,7 +1307,7 @@ void GlCoreRhi::end_render_pass(Handle<GraphicsContext> ctx)
current_render_pass_ = std::nullopt; current_render_pass_ = std::nullopt;
} }
void GlCoreRhi::bind_pipeline(Handle<GraphicsContext> ctx, Handle<Pipeline> pipeline) void Gl2Rhi::bind_pipeline(Handle<GraphicsContext> ctx, Handle<Pipeline> pipeline)
{ {
SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation()); SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation());
SRB2_ASSERT(current_render_pass_.has_value() == true); SRB2_ASSERT(current_render_pass_.has_value() == true);
@ -1479,7 +1449,7 @@ void GlCoreRhi::bind_pipeline(Handle<GraphicsContext> ctx, Handle<Pipeline> pipe
current_primitive_type_ = desc.primitive; current_primitive_type_ = desc.primitive;
} }
void GlCoreRhi::bind_uniform_set(Handle<GraphicsContext> ctx, uint32_t slot, Handle<UniformSet> set) void Gl2Rhi::bind_uniform_set(Handle<GraphicsContext> ctx, uint32_t slot, Handle<UniformSet> set)
{ {
SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation()); SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation());
SRB2_ASSERT(current_render_pass_.has_value() == true && current_pipeline_.has_value() == true); SRB2_ASSERT(current_render_pass_.has_value() == true && current_pipeline_.has_value() == true);
@ -1575,7 +1545,7 @@ void GlCoreRhi::bind_uniform_set(Handle<GraphicsContext> ctx, uint32_t slot, Han
} }
} }
void GlCoreRhi::bind_binding_set(Handle<GraphicsContext> ctx, Handle<BindingSet> set) void Gl2Rhi::bind_binding_set(Handle<GraphicsContext> ctx, Handle<BindingSet> set)
{ {
SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation()); SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation());
SRB2_ASSERT(current_render_pass_.has_value() == true && current_pipeline_.has_value() == true); SRB2_ASSERT(current_render_pass_.has_value() == true && current_pipeline_.has_value() == true);
@ -1588,11 +1558,53 @@ void GlCoreRhi::bind_binding_set(Handle<GraphicsContext> ctx, Handle<BindingSet>
SRB2_ASSERT(bs.textures.size() == pl.desc.sampler_input.enabled_samplers.size()); SRB2_ASSERT(bs.textures.size() == pl.desc.sampler_input.enabled_samplers.size());
// Bind the vertex array for drawing // TODO only disable the vertex attributes of the previously bound pipeline (performance)
// TODO assert compatibility of binding set. The VAO's attributes must match the pipeline. for (GLuint i = 0; i < kMaxVertexAttributes; i++)
gl_->BindVertexArray(bs.vao); {
gl_->DisableVertexAttribArray(i);
}
// Update the vertex attributes with the new vertex buffer bindings.
// OpenGL 2 does not require binding buffers to the pipeline the same way Vulkan does.
// Instead, we need to find the pipeline vertex attributes which would be affected by
// the changing set of vertex buffers, and reassign their Vertex Attribute Pointers.
for (size_t i = 0; i < pl.desc.vertex_input.attr_layouts.size(); i++)
{
auto& attr_layout = pl.desc.vertex_input.attr_layouts[i];
uint32_t attr_buffer_index = attr_layout.buffer_index;
VertexAttributeName attr_name = attr_layout.name;
auto& buffer_layout = pl.desc.vertex_input.buffer_layouts[attr_buffer_index];
SRB2_ASSERT(pl.attrib_locations.find(attr_name) != pl.attrib_locations.end());
auto gl_attr_location = pl.attrib_locations[pl.desc.vertex_input.attr_layouts[i].name];
VertexAttributeFormat vert_attr_format = rhi::vertex_attribute_format(attr_name);
GLenum vertex_attr_type = map_vertex_attribute_type(vert_attr_format);
SRB2_ASSERT(vertex_attr_type != GL_ZERO);
GLint vertex_attr_size = map_vertex_attribute_format_size(vert_attr_format);
SRB2_ASSERT(vertex_attr_size != 0);
uint32_t vertex_buffer_offset = 0;
auto& vertex_binding = bs.vertex_buffer_bindings[attr_layout.buffer_index];
rhi::Handle<rhi::Buffer> vertex_buffer_handle = vertex_binding.vertex_buffer;
SRB2_ASSERT(buffer_slab_.is_valid(vertex_binding.vertex_buffer) == true);
auto& buffer = *static_cast<Gl2Buffer*>(&buffer_slab_[vertex_buffer_handle]);
SRB2_ASSERT(buffer.desc.type == rhi::BufferType::kVertexBuffer);
gl_->BindBuffer(GL_ARRAY_BUFFER, buffer.buffer);
gl_->EnableVertexAttribArray(gl_attr_location);
gl_->VertexAttribPointer(
gl_attr_location,
vertex_attr_size,
vertex_attr_type,
GL_FALSE,
buffer_layout.stride,
reinterpret_cast<const void*>(vertex_buffer_offset + attr_layout.offset)
);
}
// Index buffer is part of VAO.
gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// Bind the samplers to the uniforms // Bind the samplers to the uniforms
@ -1631,7 +1643,7 @@ void GlCoreRhi::bind_binding_set(Handle<GraphicsContext> ctx, Handle<BindingSet>
} }
} }
void GlCoreRhi::bind_index_buffer(Handle<GraphicsContext> ctx, Handle<Buffer> buffer) void Gl2Rhi::bind_index_buffer(Handle<GraphicsContext> ctx, Handle<Buffer> buffer)
{ {
SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation()); SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation());
SRB2_ASSERT(current_render_pass_.has_value() == true && current_pipeline_.has_value() == true); SRB2_ASSERT(current_render_pass_.has_value() == true && current_pipeline_.has_value() == true);
@ -1646,7 +1658,7 @@ void GlCoreRhi::bind_index_buffer(Handle<GraphicsContext> ctx, Handle<Buffer> bu
gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib.buffer); gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib.buffer);
} }
void GlCoreRhi::set_scissor(Handle<GraphicsContext> ctx, const Rect& rect) void Gl2Rhi::set_scissor(Handle<GraphicsContext> ctx, const Rect& rect)
{ {
SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation()); SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation());
SRB2_ASSERT(current_render_pass_.has_value() == true && current_pipeline_.has_value() == true); SRB2_ASSERT(current_render_pass_.has_value() == true && current_pipeline_.has_value() == true);
@ -1655,7 +1667,7 @@ void GlCoreRhi::set_scissor(Handle<GraphicsContext> ctx, const Rect& rect)
gl_->Scissor(rect.x, rect.y, rect.w, rect.h); gl_->Scissor(rect.x, rect.y, rect.w, rect.h);
} }
void GlCoreRhi::set_viewport(Handle<GraphicsContext> ctx, const Rect& rect) void Gl2Rhi::set_viewport(Handle<GraphicsContext> ctx, const Rect& rect)
{ {
SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation()); SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation());
SRB2_ASSERT(current_render_pass_.has_value() == true && current_pipeline_.has_value() == true); SRB2_ASSERT(current_render_pass_.has_value() == true && current_pipeline_.has_value() == true);
@ -1664,7 +1676,7 @@ void GlCoreRhi::set_viewport(Handle<GraphicsContext> ctx, const Rect& rect)
GL_ASSERT; GL_ASSERT;
} }
void GlCoreRhi::draw(Handle<GraphicsContext> ctx, uint32_t vertex_count, uint32_t first_vertex) void Gl2Rhi::draw(Handle<GraphicsContext> ctx, uint32_t vertex_count, uint32_t first_vertex)
{ {
SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation()); SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation());
SRB2_ASSERT(current_render_pass_.has_value() == true && current_pipeline_.has_value() == true); SRB2_ASSERT(current_render_pass_.has_value() == true && current_pipeline_.has_value() == true);
@ -1673,7 +1685,7 @@ void GlCoreRhi::draw(Handle<GraphicsContext> ctx, uint32_t vertex_count, uint32_
GL_ASSERT; GL_ASSERT;
} }
void GlCoreRhi::draw_indexed(Handle<GraphicsContext> ctx, uint32_t index_count, uint32_t first_index) void Gl2Rhi::draw_indexed(Handle<GraphicsContext> ctx, uint32_t index_count, uint32_t first_index)
{ {
SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation()); SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation());
@ -1694,7 +1706,7 @@ void GlCoreRhi::draw_indexed(Handle<GraphicsContext> ctx, uint32_t index_count,
GL_ASSERT; GL_ASSERT;
} }
void GlCoreRhi::read_pixels(Handle<GraphicsContext> ctx, const Rect& rect, PixelFormat format, tcb::span<std::byte> out) void Gl2Rhi::read_pixels(Handle<GraphicsContext> ctx, const Rect& rect, PixelFormat format, tcb::span<std::byte> out)
{ {
SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation()); SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation());
SRB2_ASSERT(current_render_pass_.has_value()); SRB2_ASSERT(current_render_pass_.has_value());
@ -1738,7 +1750,7 @@ void GlCoreRhi::read_pixels(Handle<GraphicsContext> ctx, const Rect& rect, Pixel
GL_ASSERT; GL_ASSERT;
} }
void GlCoreRhi::set_stencil_reference(Handle<GraphicsContext> ctx, CullMode face, uint8_t reference) void Gl2Rhi::set_stencil_reference(Handle<GraphicsContext> ctx, CullMode face, uint8_t reference)
{ {
SRB2_ASSERT(face != CullMode::kNone); SRB2_ASSERT(face != CullMode::kNone);
SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation()); SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation());
@ -1769,7 +1781,7 @@ void GlCoreRhi::set_stencil_reference(Handle<GraphicsContext> ctx, CullMode face
} }
} }
void GlCoreRhi::set_stencil_compare_mask(Handle<GraphicsContext> ctx, CullMode face, uint8_t compare_mask) void Gl2Rhi::set_stencil_compare_mask(Handle<GraphicsContext> ctx, CullMode face, uint8_t compare_mask)
{ {
SRB2_ASSERT(face != CullMode::kNone); SRB2_ASSERT(face != CullMode::kNone);
SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation()); SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation());
@ -1800,7 +1812,7 @@ void GlCoreRhi::set_stencil_compare_mask(Handle<GraphicsContext> ctx, CullMode f
} }
} }
void GlCoreRhi::set_stencil_write_mask(Handle<GraphicsContext> ctx, CullMode face, uint8_t write_mask) void Gl2Rhi::set_stencil_write_mask(Handle<GraphicsContext> ctx, CullMode face, uint8_t write_mask)
{ {
SRB2_ASSERT(face != CullMode::kNone); SRB2_ASSERT(face != CullMode::kNone);
SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation()); SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation());
@ -1819,7 +1831,7 @@ void GlCoreRhi::set_stencil_write_mask(Handle<GraphicsContext> ctx, CullMode fac
} }
} }
TextureDetails GlCoreRhi::get_texture_details(Handle<Texture> texture) TextureDetails Gl2Rhi::get_texture_details(Handle<Texture> texture)
{ {
SRB2_ASSERT(texture_slab_.is_valid(texture)); SRB2_ASSERT(texture_slab_.is_valid(texture));
auto& t = texture_slab_[texture]; auto& t = texture_slab_[texture];
@ -1832,7 +1844,7 @@ TextureDetails GlCoreRhi::get_texture_details(Handle<Texture> texture)
return ret; return ret;
} }
Rect GlCoreRhi::get_renderbuffer_size(Handle<Renderbuffer> renderbuffer) Rect Gl2Rhi::get_renderbuffer_size(Handle<Renderbuffer> renderbuffer)
{ {
SRB2_ASSERT(renderbuffer_slab_.is_valid(renderbuffer)); SRB2_ASSERT(renderbuffer_slab_.is_valid(renderbuffer));
auto& rb = renderbuffer_slab_[renderbuffer]; auto& rb = renderbuffer_slab_[renderbuffer];
@ -1846,7 +1858,7 @@ Rect GlCoreRhi::get_renderbuffer_size(Handle<Renderbuffer> renderbuffer)
return ret; return ret;
} }
uint32_t GlCoreRhi::get_buffer_size(Handle<Buffer> buffer) uint32_t Gl2Rhi::get_buffer_size(Handle<Buffer> buffer)
{ {
SRB2_ASSERT(buffer_slab_.is_valid(buffer)); SRB2_ASSERT(buffer_slab_.is_valid(buffer));
auto& buf = buffer_slab_[buffer]; auto& buf = buffer_slab_[buffer];
@ -1854,18 +1866,10 @@ uint32_t GlCoreRhi::get_buffer_size(Handle<Buffer> buffer)
return buf.desc.size; return buf.desc.size;
} }
void GlCoreRhi::finish() void Gl2Rhi::finish()
{ {
SRB2_ASSERT(graphics_context_active_ == false); SRB2_ASSERT(graphics_context_active_ == false);
for (auto it = binding_set_slab_.cbegin(); it != binding_set_slab_.cend(); it++)
{
gl_->BindVertexArray(0);
GL_ASSERT;
GLuint vao = reinterpret_cast<const GlCoreBindingSet&>(*it).vao;
gl_->DeleteVertexArrays(1, &vao);
GL_ASSERT;
}
binding_set_slab_.clear(); binding_set_slab_.clear();
uniform_set_slab_.clear(); uniform_set_slab_.clear();
@ -1878,7 +1882,7 @@ void GlCoreRhi::finish()
framebuffers_.clear(); framebuffers_.clear();
} }
void GlCoreRhi::copy_framebuffer_to_texture( void Gl2Rhi::copy_framebuffer_to_texture(
Handle<GraphicsContext> ctx, Handle<GraphicsContext> ctx,
Handle<Texture> dst_tex, Handle<Texture> dst_tex,
const Rect& dst_region, const Rect& dst_region,

View file

@ -7,8 +7,8 @@
// See the 'LICENSE' file for more details. // See the 'LICENSE' file for more details.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#ifndef __SRB2_RHI_GLES2_RHI_HPP__ #ifndef __SRB2_RHI_GL2_RHI_HPP__
#define __SRB2_RHI_GLES2_RHI_HPP__ #define __SRB2_RHI_GL2_RHI_HPP__
#include <functional> #include <functional>
#include <memory> #include <memory>
@ -23,28 +23,28 @@
namespace srb2::rhi namespace srb2::rhi
{ {
struct GlCoreFramebufferKey struct Gl2FramebufferKey
{ {
Handle<Texture> color; Handle<Texture> color;
std::optional<Handle<Renderbuffer>> depth_stencil; std::optional<Handle<Renderbuffer>> depth_stencil;
bool operator==(const GlCoreFramebufferKey& rhs) const noexcept bool operator==(const Gl2FramebufferKey& rhs) const noexcept
{ {
return color == rhs.color && depth_stencil == rhs.depth_stencil; return color == rhs.color && depth_stencil == rhs.depth_stencil;
} }
bool operator!=(const GlCoreFramebufferKey& rhs) const noexcept { return !(*this == rhs); } bool operator!=(const Gl2FramebufferKey& rhs) const noexcept { return !(*this == rhs); }
}; };
} // namespace srb2::rhi } // namespace srb2::rhi
// To make sure the compiler selects the struct specialization of std::hash for GlCoreFramebufferKey, // To make sure the compiler selects the struct specialization of std::hash for Gl2FramebufferKey,
// we need to split the namespace declarations _before_ the instantiation of std::unordered_map. // we need to split the namespace declarations _before_ the instantiation of std::unordered_map.
template <> template <>
struct std::hash<srb2::rhi::GlCoreFramebufferKey> struct std::hash<srb2::rhi::Gl2FramebufferKey>
{ {
std::size_t operator()(const srb2::rhi::GlCoreFramebufferKey& key) const std::size_t operator()(const srb2::rhi::Gl2FramebufferKey& key) const
{ {
std::size_t color_hash = std::hash<srb2::rhi::Handle<srb2::rhi::Texture>>()(key.color); std::size_t color_hash = std::hash<srb2::rhi::Handle<srb2::rhi::Texture>>()(key.color);
std::size_t depth_stencil_hash = 0; std::size_t depth_stencil_hash = 0;
@ -64,51 +64,51 @@ namespace srb2::rhi
typedef void (*GlProc)(void); typedef void (*GlProc)(void);
typedef GlProc (*GlLoadFunc)(const char* name); typedef GlProc (*GlLoadFunc)(const char* name);
/// @brief Platform-specific implementation details for the GLES2 backend. /// @brief Platform-specific implementation details for the GL2 backend.
struct GlCorePlatform struct Gl2Platform
{ {
virtual ~GlCorePlatform(); virtual ~Gl2Platform();
virtual void present() = 0; virtual void present() = 0;
virtual std::tuple<std::vector<std::string>, std::vector<std::string>> find_shader_sources(PipelineProgram program) = 0; virtual std::tuple<std::vector<std::string>, std::vector<std::string>> find_shader_sources(PipelineProgram program) = 0;
virtual Rect get_default_framebuffer_dimensions() = 0; virtual Rect get_default_framebuffer_dimensions() = 0;
}; };
struct GlCoreTexture : public rhi::Texture struct Gl2Texture : public rhi::Texture
{ {
uint32_t texture; uint32_t texture;
rhi::TextureDesc desc; rhi::TextureDesc desc;
}; };
struct GlCoreBuffer : public rhi::Buffer struct Gl2Buffer : public rhi::Buffer
{ {
uint32_t buffer; uint32_t buffer;
rhi::BufferDesc desc; rhi::BufferDesc desc;
}; };
struct GlCoreRenderPass : public rhi::RenderPass struct Gl2RenderPass : public rhi::RenderPass
{ {
rhi::RenderPassDesc desc; rhi::RenderPassDesc desc;
}; };
struct GlCoreRenderbuffer : public rhi::Renderbuffer struct Gl2Renderbuffer : public rhi::Renderbuffer
{ {
uint32_t renderbuffer; uint32_t renderbuffer;
rhi::RenderbufferDesc desc; rhi::RenderbufferDesc desc;
}; };
struct GlCoreUniformSet : public rhi::UniformSet struct Gl2UniformSet : public rhi::UniformSet
{ {
std::vector<rhi::UniformVariant> uniforms; std::vector<rhi::UniformVariant> uniforms;
}; };
struct GlCoreBindingSet : public rhi::BindingSet struct Gl2BindingSet : public rhi::BindingSet
{ {
uint32_t vao; std::vector<rhi::VertexAttributeBufferBinding> vertex_buffer_bindings;
std::unordered_map<rhi::SamplerName, uint32_t> textures {4}; std::unordered_map<rhi::SamplerName, uint32_t> textures {4};
}; };
struct GlCorePipeline : public rhi::Pipeline struct Gl2Pipeline : public rhi::Pipeline
{ {
uint32_t vertex_shader = 0; uint32_t vertex_shader = 0;
uint32_t fragment_shader = 0; uint32_t fragment_shader = 0;
@ -119,33 +119,33 @@ struct GlCorePipeline : public rhi::Pipeline
rhi::PipelineDesc desc; rhi::PipelineDesc desc;
}; };
struct GlCoreGraphicsContext : public rhi::GraphicsContext struct Gl2GraphicsContext : public rhi::GraphicsContext
{ {
}; };
struct GlCoreActiveUniform struct Gl2ActiveUniform
{ {
uint32_t type; uint32_t type;
uint32_t location; uint32_t location;
}; };
class GlCoreRhi final : public Rhi class Gl2Rhi final : public Rhi
{ {
std::unique_ptr<GlCorePlatform> platform_; std::unique_ptr<Gl2Platform> platform_;
std::unique_ptr<GladGLContext> gl_; std::unique_ptr<GladGLContext> gl_;
Slab<GlCoreRenderPass> render_pass_slab_; Slab<Gl2RenderPass> render_pass_slab_;
Slab<GlCoreTexture> texture_slab_; Slab<Gl2Texture> texture_slab_;
Slab<GlCoreBuffer> buffer_slab_; Slab<Gl2Buffer> buffer_slab_;
Slab<GlCoreRenderbuffer> renderbuffer_slab_; Slab<Gl2Renderbuffer> renderbuffer_slab_;
Slab<GlCorePipeline> pipeline_slab_; Slab<Gl2Pipeline> pipeline_slab_;
Slab<GlCoreUniformSet> uniform_set_slab_; Slab<Gl2UniformSet> uniform_set_slab_;
Slab<GlCoreBindingSet> binding_set_slab_; Slab<Gl2BindingSet> binding_set_slab_;
Handle<Buffer> current_index_buffer_; Handle<Buffer> current_index_buffer_;
std::unordered_map<GlCoreFramebufferKey, uint32_t> framebuffers_ {16}; std::unordered_map<Gl2FramebufferKey, uint32_t> framebuffers_ {16};
struct DefaultRenderPassState struct DefaultRenderPassState
{ {
@ -166,8 +166,8 @@ class GlCoreRhi final : public Rhi
uint8_t stencil_back_write_mask_ = 0xFF; uint8_t stencil_back_write_mask_ = 0xFF;
public: public:
GlCoreRhi(std::unique_ptr<GlCorePlatform>&& platform, GlLoadFunc load_func); Gl2Rhi(std::unique_ptr<Gl2Platform>&& platform, GlLoadFunc load_func);
virtual ~GlCoreRhi(); virtual ~Gl2Rhi();
virtual Handle<RenderPass> create_render_pass(const RenderPassDesc& desc) override; virtual Handle<RenderPass> create_render_pass(const RenderPassDesc& desc) override;
virtual void destroy_render_pass(Handle<RenderPass> handle) override; virtual void destroy_render_pass(Handle<RenderPass> handle) override;
@ -238,4 +238,4 @@ public:
} // namespace srb2::rhi } // namespace srb2::rhi
#endif // __SRB2_RHI_GLES2_RHI_HPP__ #endif // __SRB2_RHI_GL2_RHI_HPP__

View file

@ -1,4 +0,0 @@
target_sources(SRB2SDL2 PRIVATE
gl3_core_rhi.cpp
gl3_core_rhi.hpp
)

View file

@ -3,8 +3,8 @@
target_sources(SRB2SDL2 PRIVATE target_sources(SRB2SDL2 PRIVATE
new_sound.cpp new_sound.cpp
ogl_sdl.c ogl_sdl.c
rhi_gl3_core_platform.cpp rhi_gl2_platform.cpp
rhi_gl3_core_platform.hpp rhi_gl2_platform.hpp
i_threads.c i_threads.c
i_net.c i_net.c
i_system.cpp i_system.cpp

View file

@ -28,8 +28,8 @@
#include <imgui.h> #include <imgui.h>
#include "../rhi/rhi.hpp" #include "../rhi/rhi.hpp"
#include "../rhi/gl3_core/gl3_core_rhi.hpp" #include "../rhi/gl2/gl2_rhi.hpp"
#include "rhi_gl3_core_platform.hpp" #include "rhi_gl2_platform.hpp"
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(disable : 4214 4244) #pragma warning(disable : 4214 4244)
@ -1413,14 +1413,13 @@ static SDL_bool Impl_CreateContext(void)
} }
#endif #endif
// RHI always uses OpenGL 3.2 Core (for now) // RHI always uses OpenGL 2.0 (for now)
if (!sdlglcontext) if (!sdlglcontext)
{ {
SDL_GL_ResetAttributes(); SDL_GL_ResetAttributes();
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
sdlglcontext = SDL_GL_CreateContext(window); sdlglcontext = SDL_GL_CreateContext(window);
} }
if (sdlglcontext == NULL) if (sdlglcontext == NULL)
@ -1433,9 +1432,9 @@ static SDL_bool Impl_CreateContext(void)
if (!g_rhi) if (!g_rhi)
{ {
std::unique_ptr<rhi::SdlGlCorePlatform> platform = std::make_unique<rhi::SdlGlCorePlatform>(); std::unique_ptr<rhi::SdlGl2Platform> platform = std::make_unique<rhi::SdlGl2Platform>();
platform->window = window; platform->window = window;
g_rhi = std::make_unique<rhi::GlCoreRhi>(std::move(platform), reinterpret_cast<rhi::GlLoadFunc>(SDL_GL_GetProcAddress)); g_rhi = std::make_unique<rhi::Gl2Rhi>(std::move(platform), reinterpret_cast<rhi::GlLoadFunc>(SDL_GL_GetProcAddress));
g_rhi_generation += 1; g_rhi_generation += 1;
} }

View file

@ -7,7 +7,7 @@
// See the 'LICENSE' file for more details. // See the 'LICENSE' file for more details.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "rhi_gl3_core_platform.hpp" #include "rhi_gl2_platform.hpp"
#include <array> #include <array>
#include <sstream> #include <sstream>
@ -22,9 +22,9 @@
using namespace srb2; using namespace srb2;
using namespace srb2::rhi; using namespace srb2::rhi;
SdlGlCorePlatform::~SdlGlCorePlatform() = default; SdlGl2Platform::~SdlGl2Platform() = default;
void SdlGlCorePlatform::present() void SdlGl2Platform::present()
{ {
SRB2_ASSERT(window != nullptr); SRB2_ASSERT(window != nullptr);
SRB2_ASSERT(SDL_GetWindowID(window) != 0); SRB2_ASSERT(SDL_GetWindowID(window) != 0);
@ -95,7 +95,7 @@ static std::vector<std::string> get_sources_from_glsllist_lump(const char* lumpn
} }
std::tuple<std::vector<std::string>, std::vector<std::string>> std::tuple<std::vector<std::string>, std::vector<std::string>>
SdlGlCorePlatform::find_shader_sources(rhi::PipelineProgram program) SdlGl2Platform::find_shader_sources(rhi::PipelineProgram program)
{ {
std::array<std::string, 2> glsllist_names = glsllist_lump_names(program); std::array<std::string, 2> glsllist_names = glsllist_lump_names(program);
@ -105,7 +105,7 @@ SdlGlCorePlatform::find_shader_sources(rhi::PipelineProgram program)
return std::make_tuple(std::move(vertex_sources), std::move(fragment_sources)); return std::make_tuple(std::move(vertex_sources), std::move(fragment_sources));
} }
rhi::Rect SdlGlCorePlatform::get_default_framebuffer_dimensions() rhi::Rect SdlGl2Platform::get_default_framebuffer_dimensions()
{ {
SRB2_ASSERT(window != nullptr); SRB2_ASSERT(window != nullptr);
int w; int w;

View file

@ -7,10 +7,10 @@
// See the 'LICENSE' file for more details. // See the 'LICENSE' file for more details.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#ifndef __SRB2_SDL_RHI_GLES2_PLATFORM_HPP__ #ifndef __SRB2_SDL_RHI_GL2_PLATFORM_HPP__
#define __SRB2_SDL_RHI_GLES2_PLATFORM_HPP__ #define __SRB2_SDL_RHI_GL2_PLATFORM_HPP__
#include "../rhi/gl3_core/gl3_core_rhi.hpp" #include "../rhi/gl2/gl2_rhi.hpp"
#include "../rhi/rhi.hpp" #include "../rhi/rhi.hpp"
#include <SDL.h> #include <SDL.h>
@ -18,11 +18,11 @@
namespace srb2::rhi namespace srb2::rhi
{ {
struct SdlGlCorePlatform final : public GlCorePlatform struct SdlGl2Platform final : public Gl2Platform
{ {
SDL_Window* window = nullptr; SDL_Window* window = nullptr;
virtual ~SdlGlCorePlatform(); virtual ~SdlGl2Platform();
virtual void present() override; virtual void present() override;
virtual std::tuple<std::vector<std::string>, std::vector<std::string>> virtual std::tuple<std::vector<std::string>, std::vector<std::string>>
@ -32,4 +32,4 @@ struct SdlGlCorePlatform final : public GlCorePlatform
} // namespace srb2::rhi } // namespace srb2::rhi
#endif // __SRB2_SDL_RHI_GLES2_PLATFORM_HPP__ #endif // __SRB2_SDL_RHI_GL2_PLATFORM_HPP__

File diff suppressed because it is too large Load diff

1504
thirdparty/glad/src/gl.c vendored

File diff suppressed because it is too large Load diff