Route shader creation through renderer GL
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#include "renderer_gl/opengl_capabilities.h"
|
||||
#include "renderer_gl/shader_bindings.h"
|
||||
|
||||
#include <array>
|
||||
#include <limits>
|
||||
@@ -1030,6 +1031,190 @@ pp::foundation::Result<std::int32_t> get_opengl_attribute_location(
|
||||
dispatch.get_attrib_location(program_id, attribute_name));
|
||||
}
|
||||
|
||||
pp::foundation::Result<OpenGlShaderCompileInfo> compile_opengl_shader_source(
|
||||
std::uint32_t stage,
|
||||
const char* source,
|
||||
char* info_log,
|
||||
std::int32_t info_log_capacity,
|
||||
OpenGlShaderCompileDispatch dispatch) noexcept
|
||||
{
|
||||
if (dispatch.create_shader == nullptr
|
||||
|| dispatch.shader_source == nullptr
|
||||
|| dispatch.compile_shader == nullptr
|
||||
|| dispatch.get_shader_integer == nullptr
|
||||
|| dispatch.get_shader_info_log == nullptr) {
|
||||
return pp::foundation::Result<OpenGlShaderCompileInfo>::failure(
|
||||
pp::foundation::Status::invalid_argument("OpenGL shader compile dispatch callbacks must not be null"));
|
||||
}
|
||||
|
||||
if (stage == 0U || source == nullptr || source[0] == '\0' || info_log == nullptr || info_log_capacity <= 0) {
|
||||
return pp::foundation::Result<OpenGlShaderCompileInfo>::failure(
|
||||
pp::foundation::Status::invalid_argument("OpenGL shader compile parameters are invalid"));
|
||||
}
|
||||
|
||||
const auto shader_id = dispatch.create_shader(stage);
|
||||
if (shader_id == 0U) {
|
||||
return pp::foundation::Result<OpenGlShaderCompileInfo>::failure(
|
||||
pp::foundation::Status::out_of_range("OpenGL shader allocation returned id 0"));
|
||||
}
|
||||
|
||||
const char* const sources[] { source };
|
||||
dispatch.shader_source(shader_id, 1, sources);
|
||||
dispatch.compile_shader(shader_id);
|
||||
|
||||
OpenGlShaderCompileInfo info {
|
||||
.shader_id = shader_id,
|
||||
};
|
||||
dispatch.get_shader_integer(shader_id, shader_compile_status_query(), &info.compile_status);
|
||||
dispatch.get_shader_info_log(shader_id, info_log_capacity, &info.info_log_length, info_log);
|
||||
return pp::foundation::Result<OpenGlShaderCompileInfo>::success(info);
|
||||
}
|
||||
|
||||
pp::foundation::Status delete_opengl_shader(
|
||||
std::uint32_t shader_id,
|
||||
OpenGlShaderDeleteDispatch dispatch) noexcept
|
||||
{
|
||||
if (dispatch.delete_shader == nullptr) {
|
||||
return pp::foundation::Status::invalid_argument("OpenGL shader delete dispatch callback must not be null");
|
||||
}
|
||||
|
||||
if (shader_id == 0U) {
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
dispatch.delete_shader(shader_id);
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Result<OpenGlProgramLinkInfo> link_opengl_shader_program(
|
||||
std::uint32_t vertex_shader_id,
|
||||
std::uint32_t fragment_shader_id,
|
||||
std::span<const OpenGlAttributeBinding> attribute_bindings,
|
||||
char* info_log,
|
||||
std::int32_t info_log_capacity,
|
||||
OpenGlProgramLinkDispatch dispatch) noexcept
|
||||
{
|
||||
if (dispatch.create_program == nullptr
|
||||
|| dispatch.attach_shader == nullptr
|
||||
|| dispatch.delete_shader == nullptr
|
||||
|| dispatch.link_program == nullptr
|
||||
|| dispatch.get_attrib_location == nullptr
|
||||
|| dispatch.bind_attrib_location == nullptr
|
||||
|| dispatch.get_program_integer == nullptr
|
||||
|| dispatch.get_program_info_log == nullptr) {
|
||||
return pp::foundation::Result<OpenGlProgramLinkInfo>::failure(
|
||||
pp::foundation::Status::invalid_argument("OpenGL program link dispatch callbacks must not be null"));
|
||||
}
|
||||
|
||||
if (vertex_shader_id == 0U
|
||||
|| fragment_shader_id == 0U
|
||||
|| attribute_bindings.empty()
|
||||
|| info_log == nullptr
|
||||
|| info_log_capacity <= 0) {
|
||||
return pp::foundation::Result<OpenGlProgramLinkInfo>::failure(
|
||||
pp::foundation::Status::invalid_argument("OpenGL program link parameters are invalid"));
|
||||
}
|
||||
|
||||
const auto program_id = dispatch.create_program();
|
||||
if (program_id == 0U) {
|
||||
return pp::foundation::Result<OpenGlProgramLinkInfo>::failure(
|
||||
pp::foundation::Status::out_of_range("OpenGL program allocation returned id 0"));
|
||||
}
|
||||
|
||||
dispatch.attach_shader(program_id, vertex_shader_id);
|
||||
dispatch.attach_shader(program_id, fragment_shader_id);
|
||||
dispatch.delete_shader(vertex_shader_id);
|
||||
dispatch.delete_shader(fragment_shader_id);
|
||||
dispatch.link_program(program_id);
|
||||
|
||||
for (const auto& binding : attribute_bindings) {
|
||||
if (binding.name != nullptr && dispatch.get_attrib_location(program_id, binding.name) != -1) {
|
||||
dispatch.bind_attrib_location(program_id, binding.location, binding.name);
|
||||
}
|
||||
}
|
||||
|
||||
OpenGlProgramLinkInfo info {
|
||||
.program_id = program_id,
|
||||
};
|
||||
dispatch.link_program(program_id);
|
||||
dispatch.get_program_integer(program_id, program_link_status_query(), &info.link_status);
|
||||
dispatch.get_program_info_log(program_id, info_log_capacity, &info.info_log_length, info_log);
|
||||
return pp::foundation::Result<OpenGlProgramLinkInfo>::success(info);
|
||||
}
|
||||
|
||||
pp::foundation::Result<std::int32_t> query_opengl_program_integer(
|
||||
std::uint32_t program_id,
|
||||
std::uint32_t query,
|
||||
OpenGlProgramIntegerDispatch dispatch) noexcept
|
||||
{
|
||||
if (dispatch.get_program_integer == nullptr) {
|
||||
return pp::foundation::Result<std::int32_t>::failure(
|
||||
pp::foundation::Status::invalid_argument("OpenGL program integer dispatch callback must not be null"));
|
||||
}
|
||||
|
||||
if (program_id == 0U || query == 0U) {
|
||||
return pp::foundation::Result<std::int32_t>::failure(
|
||||
pp::foundation::Status::invalid_argument("OpenGL program integer parameters are invalid"));
|
||||
}
|
||||
|
||||
std::int32_t value = 0;
|
||||
dispatch.get_program_integer(program_id, query, &value);
|
||||
return pp::foundation::Result<std::int32_t>::success(value);
|
||||
}
|
||||
|
||||
pp::foundation::Result<OpenGlActiveUniformInfo> get_opengl_active_uniform(
|
||||
std::uint32_t program_id,
|
||||
std::uint32_t index,
|
||||
char* name,
|
||||
std::int32_t name_capacity,
|
||||
OpenGlActiveUniformDispatch dispatch) noexcept
|
||||
{
|
||||
if (dispatch.get_active_uniform == nullptr) {
|
||||
return pp::foundation::Result<OpenGlActiveUniformInfo>::failure(
|
||||
pp::foundation::Status::invalid_argument("OpenGL active uniform dispatch callback must not be null"));
|
||||
}
|
||||
|
||||
if (program_id == 0U || name == nullptr || name_capacity <= 0) {
|
||||
return pp::foundation::Result<OpenGlActiveUniformInfo>::failure(
|
||||
pp::foundation::Status::invalid_argument("OpenGL active uniform parameters are invalid"));
|
||||
}
|
||||
|
||||
OpenGlActiveUniformInfo info {};
|
||||
dispatch.get_active_uniform(
|
||||
program_id,
|
||||
index,
|
||||
name_capacity,
|
||||
&info.length,
|
||||
&info.size,
|
||||
&info.type,
|
||||
name);
|
||||
if (info.length >= 0 && info.length < name_capacity) {
|
||||
name[info.length] = '\0';
|
||||
} else {
|
||||
name[name_capacity - 1] = '\0';
|
||||
}
|
||||
return pp::foundation::Result<OpenGlActiveUniformInfo>::success(info);
|
||||
}
|
||||
|
||||
pp::foundation::Result<std::int32_t> get_opengl_uniform_location(
|
||||
std::uint32_t program_id,
|
||||
const char* uniform_name,
|
||||
OpenGlUniformLocationDispatch dispatch) noexcept
|
||||
{
|
||||
if (dispatch.get_uniform_location == nullptr) {
|
||||
return pp::foundation::Result<std::int32_t>::failure(
|
||||
pp::foundation::Status::invalid_argument("OpenGL uniform-location dispatch callback must not be null"));
|
||||
}
|
||||
|
||||
if (program_id == 0U || uniform_name == nullptr || uniform_name[0] == '\0') {
|
||||
return pp::foundation::Result<std::int32_t>::failure(
|
||||
pp::foundation::Status::invalid_argument("OpenGL uniform-location parameters are invalid"));
|
||||
}
|
||||
|
||||
return pp::foundation::Result<std::int32_t>::success(
|
||||
dispatch.get_uniform_location(program_id, uniform_name));
|
||||
}
|
||||
|
||||
std::uint32_t extension_count_query() noexcept
|
||||
{
|
||||
return gl_num_extensions;
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
namespace pp::renderer::gl {
|
||||
|
||||
struct OpenGlAttributeBinding;
|
||||
|
||||
struct OpenGlRuntime {
|
||||
bool desktop_gl = false;
|
||||
bool gles = false;
|
||||
@@ -148,6 +150,24 @@ struct OpenGlTexture2DReadbackResult {
|
||||
bool pixels_read = false;
|
||||
};
|
||||
|
||||
struct OpenGlShaderCompileInfo {
|
||||
std::uint32_t shader_id = 0;
|
||||
std::int32_t compile_status = 0;
|
||||
std::int32_t info_log_length = 0;
|
||||
};
|
||||
|
||||
struct OpenGlProgramLinkInfo {
|
||||
std::uint32_t program_id = 0;
|
||||
std::int32_t link_status = 0;
|
||||
std::int32_t info_log_length = 0;
|
||||
};
|
||||
|
||||
struct OpenGlActiveUniformInfo {
|
||||
std::int32_t length = 0;
|
||||
std::int32_t size = 0;
|
||||
std::uint32_t type = 0;
|
||||
};
|
||||
|
||||
struct OpenGlFramebufferRect {
|
||||
std::int32_t x0 = 0;
|
||||
std::int32_t y0 = 0;
|
||||
@@ -232,6 +252,47 @@ using OpenGlUniformMatrix4fvFn = void (*)(
|
||||
using OpenGlUniform1iFn = void (*)(std::int32_t location, std::int32_t value) noexcept;
|
||||
using OpenGlUniform1fFn = void (*)(std::int32_t location, float value) noexcept;
|
||||
using OpenGlGetAttribLocationFn = std::int32_t (*)(std::uint32_t program, const char* name) noexcept;
|
||||
using OpenGlCreateShaderFn = std::uint32_t (*)(std::uint32_t stage) noexcept;
|
||||
using OpenGlShaderSourceFn = void (*)(
|
||||
std::uint32_t shader,
|
||||
std::int32_t count,
|
||||
const char* const* sources) noexcept;
|
||||
using OpenGlCompileShaderFn = void (*)(std::uint32_t shader) noexcept;
|
||||
using OpenGlGetShaderIntegerFn = void (*)(
|
||||
std::uint32_t shader,
|
||||
std::uint32_t query,
|
||||
std::int32_t* value) noexcept;
|
||||
using OpenGlGetShaderInfoLogFn = void (*)(
|
||||
std::uint32_t shader,
|
||||
std::int32_t capacity,
|
||||
std::int32_t* length,
|
||||
char* info_log) noexcept;
|
||||
using OpenGlDeleteShaderFn = void (*)(std::uint32_t shader) noexcept;
|
||||
using OpenGlCreateProgramFn = std::uint32_t (*)() noexcept;
|
||||
using OpenGlAttachShaderFn = void (*)(std::uint32_t program, std::uint32_t shader) noexcept;
|
||||
using OpenGlLinkProgramFn = void (*)(std::uint32_t program) noexcept;
|
||||
using OpenGlBindAttribLocationFn = void (*)(
|
||||
std::uint32_t program,
|
||||
std::uint32_t location,
|
||||
const char* name) noexcept;
|
||||
using OpenGlGetProgramIntegerFn = void (*)(
|
||||
std::uint32_t program,
|
||||
std::uint32_t query,
|
||||
std::int32_t* value) noexcept;
|
||||
using OpenGlGetProgramInfoLogFn = void (*)(
|
||||
std::uint32_t program,
|
||||
std::int32_t capacity,
|
||||
std::int32_t* length,
|
||||
char* info_log) noexcept;
|
||||
using OpenGlGetActiveUniformFn = void (*)(
|
||||
std::uint32_t program,
|
||||
std::uint32_t index,
|
||||
std::int32_t capacity,
|
||||
std::int32_t* length,
|
||||
std::int32_t* size,
|
||||
std::uint32_t* type,
|
||||
char* name) noexcept;
|
||||
using OpenGlGetUniformLocationFn = std::int32_t (*)(std::uint32_t program, const char* name) noexcept;
|
||||
using OpenGlBindFramebufferFn = void (*)(std::uint32_t target, std::uint32_t framebuffer) noexcept;
|
||||
using OpenGlBindTextureFn = void (*)(std::uint32_t target, std::uint32_t texture) noexcept;
|
||||
using OpenGlBindSamplerFn = void (*)(std::uint32_t unit, std::uint32_t sampler) noexcept;
|
||||
@@ -482,6 +543,41 @@ struct OpenGlAttributeLocationDispatch {
|
||||
OpenGlGetAttribLocationFn get_attrib_location = nullptr;
|
||||
};
|
||||
|
||||
struct OpenGlShaderCompileDispatch {
|
||||
OpenGlCreateShaderFn create_shader = nullptr;
|
||||
OpenGlShaderSourceFn shader_source = nullptr;
|
||||
OpenGlCompileShaderFn compile_shader = nullptr;
|
||||
OpenGlGetShaderIntegerFn get_shader_integer = nullptr;
|
||||
OpenGlGetShaderInfoLogFn get_shader_info_log = nullptr;
|
||||
};
|
||||
|
||||
struct OpenGlShaderDeleteDispatch {
|
||||
OpenGlDeleteShaderFn delete_shader = nullptr;
|
||||
};
|
||||
|
||||
struct OpenGlProgramLinkDispatch {
|
||||
OpenGlCreateProgramFn create_program = nullptr;
|
||||
OpenGlAttachShaderFn attach_shader = nullptr;
|
||||
OpenGlDeleteShaderFn delete_shader = nullptr;
|
||||
OpenGlLinkProgramFn link_program = nullptr;
|
||||
OpenGlGetAttribLocationFn get_attrib_location = nullptr;
|
||||
OpenGlBindAttribLocationFn bind_attrib_location = nullptr;
|
||||
OpenGlGetProgramIntegerFn get_program_integer = nullptr;
|
||||
OpenGlGetProgramInfoLogFn get_program_info_log = nullptr;
|
||||
};
|
||||
|
||||
struct OpenGlProgramIntegerDispatch {
|
||||
OpenGlGetProgramIntegerFn get_program_integer = nullptr;
|
||||
};
|
||||
|
||||
struct OpenGlActiveUniformDispatch {
|
||||
OpenGlGetActiveUniformFn get_active_uniform = nullptr;
|
||||
};
|
||||
|
||||
struct OpenGlUniformLocationDispatch {
|
||||
OpenGlGetUniformLocationFn get_uniform_location = nullptr;
|
||||
};
|
||||
|
||||
[[nodiscard]] OpenGlCapabilities detect_opengl_capabilities(
|
||||
std::span<const std::string_view> extensions,
|
||||
OpenGlRuntime runtime) noexcept;
|
||||
@@ -603,6 +699,36 @@ struct OpenGlAttributeLocationDispatch {
|
||||
std::uint32_t program_id,
|
||||
const char* attribute_name,
|
||||
OpenGlAttributeLocationDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Result<OpenGlShaderCompileInfo> compile_opengl_shader_source(
|
||||
std::uint32_t stage,
|
||||
const char* source,
|
||||
char* info_log,
|
||||
std::int32_t info_log_capacity,
|
||||
OpenGlShaderCompileDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status delete_opengl_shader(
|
||||
std::uint32_t shader_id,
|
||||
OpenGlShaderDeleteDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Result<OpenGlProgramLinkInfo> link_opengl_shader_program(
|
||||
std::uint32_t vertex_shader_id,
|
||||
std::uint32_t fragment_shader_id,
|
||||
std::span<const OpenGlAttributeBinding> attribute_bindings,
|
||||
char* info_log,
|
||||
std::int32_t info_log_capacity,
|
||||
OpenGlProgramLinkDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Result<std::int32_t> query_opengl_program_integer(
|
||||
std::uint32_t program_id,
|
||||
std::uint32_t query,
|
||||
OpenGlProgramIntegerDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Result<OpenGlActiveUniformInfo> get_opengl_active_uniform(
|
||||
std::uint32_t program_id,
|
||||
std::uint32_t index,
|
||||
char* name,
|
||||
std::int32_t name_capacity,
|
||||
OpenGlActiveUniformDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Result<std::int32_t> get_opengl_uniform_location(
|
||||
std::uint32_t program_id,
|
||||
const char* uniform_name,
|
||||
OpenGlUniformLocationDispatch dispatch) noexcept;
|
||||
|
||||
[[nodiscard]] std::uint32_t extension_count_query() noexcept;
|
||||
[[nodiscard]] std::uint32_t extension_string_name() noexcept;
|
||||
|
||||
Reference in New Issue
Block a user