Move canvas depth renderbuffers into GL backend
This commit is contained in:
@@ -286,7 +286,9 @@ Known local toolchain state:
|
|||||||
render-target texture parameters, texture/renderbuffer targets, depth format,
|
render-target texture parameters, texture/renderbuffer targets, depth format,
|
||||||
framebuffer targets, binding queries, attachment points, and completion
|
framebuffer targets, binding queries, attachment points, and completion
|
||||||
status used by `RTT::create` and framebuffer bind/restore paths, plus RTT
|
status used by `RTT::create` and framebuffer bind/restore paths, plus RTT
|
||||||
clear color/depth masks, renderer API render-pass color/depth/stencil
|
clear color/depth masks. Canvas object-drawing depth renderbuffer
|
||||||
|
allocation/storage/delete and framebuffer depth attach/detach also execute
|
||||||
|
through tested dispatch contracts here. Renderer API render-pass color/depth/stencil
|
||||||
clear-mask and clear-value mapping, and color-write-mask query tokens. `RTT` no longer
|
clear-mask and clear-value mapping, and color-write-mask query tokens. `RTT` no longer
|
||||||
spells GL enum names directly. It also
|
spells GL enum names directly. It also
|
||||||
validates renderer API primitive-topology to OpenGL draw-mode mapping, Shape
|
validates renderer API primitive-topology to OpenGL draw-mode mapping, Shape
|
||||||
@@ -421,9 +423,9 @@ Known local toolchain state:
|
|||||||
backend-owned depth/blend state and active texture units.
|
backend-owned depth/blend state and active texture units.
|
||||||
Canvas thumbnail generation and object-drawing helpers also consume
|
Canvas thumbnail generation and object-drawing helpers also consume
|
||||||
backend-owned saved viewport/clear/blend state, active texture units,
|
backend-owned saved viewport/clear/blend state, active texture units,
|
||||||
readback format/type, framebuffer copy targets, and renderbuffer/depth
|
readback format/type, framebuffer copy targets, and depth renderbuffer
|
||||||
attachment parameters; `src/canvas.cpp` no longer contains raw `GL_*`
|
allocation plus framebuffer depth attach/detach dispatch contracts;
|
||||||
constants.
|
`src/canvas.cpp` no longer contains raw `GL_*` constants.
|
||||||
Windows desktop OpenGL context creation now consumes a tested
|
Windows desktop OpenGL context creation now consumes a tested
|
||||||
`windows_wgl_core_context_3_3_config()` catalog from `pp_renderer_gl` instead
|
`windows_wgl_core_context_3_3_config()` catalog from `pp_renderer_gl` instead
|
||||||
of owning active WGL context/pixel-format attribute literals in `main.cpp`.
|
of owning active WGL context/pixel-format attribute literals in `main.cpp`.
|
||||||
@@ -610,7 +612,9 @@ Known local toolchain state:
|
|||||||
the retained `Texture2D` utility, tested framebuffer blit/readback dispatch
|
the retained `Texture2D` utility, tested framebuffer blit/readback dispatch
|
||||||
consumed by retained `RTT` resize/copy/readback paths, tested framebuffer
|
consumed by retained `RTT` resize/copy/readback paths, tested framebuffer
|
||||||
bind/restore dispatch consumed by retained `RTT` render-target pass entry
|
bind/restore dispatch consumed by retained `RTT` render-target pass entry
|
||||||
and exit paths, tested convert-command state dispatch consumed by
|
and exit paths, tested depth renderbuffer allocation/delete and framebuffer
|
||||||
|
depth attach/detach dispatch consumed by canvas object-drawing helpers,
|
||||||
|
tested convert-command state dispatch consumed by
|
||||||
`App::cmd_convert`, tested render platform hint dispatch consumed by
|
`App::cmd_convert`, tested render platform hint dispatch consumed by
|
||||||
`WindowsPlatformServices` and the retained macOS legacy fallback, tested
|
`WindowsPlatformServices` and the retained macOS legacy fallback, tested
|
||||||
debug-output state dispatch consumed by `WindowsPlatformServices`, plus
|
debug-output state dispatch consumed by `WindowsPlatformServices`, plus
|
||||||
|
|||||||
@@ -999,7 +999,9 @@ to OpenGL token mapping, plus the default
|
|||||||
render-target texture parameters, texture/renderbuffer targets, depth format,
|
render-target texture parameters, texture/renderbuffer targets, depth format,
|
||||||
framebuffer targets, binding queries, attachment points, and completion status
|
framebuffer targets, binding queries, attachment points, and completion status
|
||||||
used by `RTT::create` and framebuffer bind/restore paths, also live in
|
used by `RTT::create` and framebuffer bind/restore paths, also live in
|
||||||
`pp_renderer_gl`. RTT clear color/depth masks, renderer API render-pass
|
`pp_renderer_gl`. Depth renderbuffer allocation/storage/delete and framebuffer
|
||||||
|
depth attach/detach sequences used by canvas object-drawing helpers now execute
|
||||||
|
through tested `pp_renderer_gl` dispatch contracts. RTT clear color/depth masks, renderer API render-pass
|
||||||
color/depth/stencil clear-mask and clear-value mapping, and color-write-mask query tokens also
|
color/depth/stencil clear-mask and clear-value mapping, and color-write-mask query tokens also
|
||||||
live in `pp_renderer_gl`. `RTT` no longer spells GL enum names directly.
|
live in `pp_renderer_gl`. `RTT` no longer spells GL enum names directly.
|
||||||
Renderer API primitive-topology to OpenGL draw-mode mapping, mesh index-type
|
Renderer API primitive-topology to OpenGL draw-mode mapping, mesh index-type
|
||||||
@@ -2021,9 +2023,9 @@ Results:
|
|||||||
mapping.
|
mapping.
|
||||||
- Canvas thumbnail generation and object-drawing helpers now route saved
|
- Canvas thumbnail generation and object-drawing helpers now route saved
|
||||||
viewport/clear/blend state, active texture units, readback format/type,
|
viewport/clear/blend state, active texture units, readback format/type,
|
||||||
framebuffer copy targets, and renderbuffer/depth attachment parameters through
|
framebuffer copy targets, and depth renderbuffer allocation plus framebuffer
|
||||||
the renderer GL backend mapping; `src/canvas.cpp` no longer contains raw
|
depth attach/detach through tested renderer GL backend dispatch contracts;
|
||||||
`GL_*` constants.
|
`src/canvas.cpp` no longer contains raw `GL_*` constants.
|
||||||
- Windows desktop OpenGL context creation now consumes a tested
|
- Windows desktop OpenGL context creation now consumes a tested
|
||||||
`windows_wgl_core_context_3_3_config()` catalog from `pp_renderer_gl`, moving
|
`windows_wgl_core_context_3_3_config()` catalog from `pp_renderer_gl`, moving
|
||||||
the active WGL context/pixel-format attribute literals out of the platform
|
the active WGL context/pixel-format attribute literals out of the platform
|
||||||
|
|||||||
122
src/canvas.cpp
122
src/canvas.cpp
@@ -135,26 +135,6 @@ GLenum blend_state()
|
|||||||
return static_cast<GLenum>(pp::renderer::gl::blend_state());
|
return static_cast<GLenum>(pp::renderer::gl::blend_state());
|
||||||
}
|
}
|
||||||
|
|
||||||
GLenum renderbuffer_target()
|
|
||||||
{
|
|
||||||
return static_cast<GLenum>(pp::renderer::gl::renderbuffer_target());
|
|
||||||
}
|
|
||||||
|
|
||||||
GLenum depth_component24_format()
|
|
||||||
{
|
|
||||||
return static_cast<GLenum>(pp::renderer::gl::depth_component24_format());
|
|
||||||
}
|
|
||||||
|
|
||||||
GLenum framebuffer_target()
|
|
||||||
{
|
|
||||||
return static_cast<GLenum>(pp::renderer::gl::framebuffer_target());
|
|
||||||
}
|
|
||||||
|
|
||||||
GLenum framebuffer_depth_attachment()
|
|
||||||
{
|
|
||||||
return static_cast<GLenum>(pp::renderer::gl::framebuffer_depth_attachment());
|
|
||||||
}
|
|
||||||
|
|
||||||
GLint texture_filter_linear()
|
GLint texture_filter_linear()
|
||||||
{
|
{
|
||||||
return static_cast<GLint>(pp::renderer::gl::linear_texture_filter());
|
return static_cast<GLint>(pp::renderer::gl::linear_texture_filter());
|
||||||
@@ -195,6 +175,86 @@ void unbind_texture_2d()
|
|||||||
glBindTexture(texture_2d_target(), 0);
|
glBindTexture(texture_2d_target(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gen_opengl_renderbuffers(std::uint32_t count, std::uint32_t* ids) noexcept
|
||||||
|
{
|
||||||
|
glGenRenderbuffers(static_cast<GLsizei>(count), reinterpret_cast<GLuint*>(ids));
|
||||||
|
}
|
||||||
|
|
||||||
|
void delete_opengl_renderbuffers(std::uint32_t count, const std::uint32_t* ids) noexcept
|
||||||
|
{
|
||||||
|
glDeleteRenderbuffers(static_cast<GLsizei>(count), reinterpret_cast<const GLuint*>(ids));
|
||||||
|
}
|
||||||
|
|
||||||
|
void bind_opengl_renderbuffer(std::uint32_t target, std::uint32_t renderbuffer) noexcept
|
||||||
|
{
|
||||||
|
glBindRenderbuffer(static_cast<GLenum>(target), static_cast<GLuint>(renderbuffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_opengl_renderbuffer_storage(
|
||||||
|
std::uint32_t target,
|
||||||
|
std::uint32_t internal_format,
|
||||||
|
std::int32_t width,
|
||||||
|
std::int32_t height) noexcept
|
||||||
|
{
|
||||||
|
glRenderbufferStorage(
|
||||||
|
static_cast<GLenum>(target),
|
||||||
|
static_cast<GLenum>(internal_format),
|
||||||
|
static_cast<GLsizei>(width),
|
||||||
|
static_cast<GLsizei>(height));
|
||||||
|
}
|
||||||
|
|
||||||
|
void attach_opengl_framebuffer_renderbuffer(
|
||||||
|
std::uint32_t target,
|
||||||
|
std::uint32_t attachment,
|
||||||
|
std::uint32_t renderbuffer_target,
|
||||||
|
std::uint32_t renderbuffer) noexcept
|
||||||
|
{
|
||||||
|
glFramebufferRenderbuffer(
|
||||||
|
static_cast<GLenum>(target),
|
||||||
|
static_cast<GLenum>(attachment),
|
||||||
|
static_cast<GLenum>(renderbuffer_target),
|
||||||
|
static_cast<GLuint>(renderbuffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint allocate_canvas_depth_renderbuffer(int width, int height)
|
||||||
|
{
|
||||||
|
const auto result = pp::renderer::gl::allocate_opengl_depth_renderbuffer(
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
pp::renderer::gl::OpenGlDepthRenderbufferAllocationDispatch {
|
||||||
|
.gen_renderbuffers = gen_opengl_renderbuffers,
|
||||||
|
.bind_renderbuffer = bind_opengl_renderbuffer,
|
||||||
|
.renderbuffer_storage = set_opengl_renderbuffer_storage,
|
||||||
|
});
|
||||||
|
if (!result.ok()) {
|
||||||
|
LOG("OpenGL canvas depth renderbuffer allocation failed: %s", result.status().message);
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
|
return static_cast<GLuint>(result.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
void attach_canvas_depth_renderbuffer(GLuint renderbuffer)
|
||||||
|
{
|
||||||
|
const auto status = pp::renderer::gl::attach_opengl_depth_renderbuffer(
|
||||||
|
static_cast<std::uint32_t>(renderbuffer),
|
||||||
|
pp::renderer::gl::OpenGlDepthRenderbufferAttachmentDispatch {
|
||||||
|
.framebuffer_renderbuffer = attach_opengl_framebuffer_renderbuffer,
|
||||||
|
});
|
||||||
|
if (!status.ok())
|
||||||
|
LOG("OpenGL canvas depth renderbuffer attachment failed: %s", status.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void delete_canvas_renderbuffer(GLuint renderbuffer)
|
||||||
|
{
|
||||||
|
const auto status = pp::renderer::gl::delete_opengl_renderbuffer(
|
||||||
|
static_cast<std::uint32_t>(renderbuffer),
|
||||||
|
pp::renderer::gl::OpenGlRenderbufferDeleteDispatch {
|
||||||
|
.delete_renderbuffers = delete_opengl_renderbuffers,
|
||||||
|
});
|
||||||
|
if (!status.ok())
|
||||||
|
LOG("OpenGL canvas renderbuffer delete failed: %s", status.message);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2963,29 +3023,25 @@ void Canvas::draw_objects_direct(std::function<void(const glm::mat4& camera, con
|
|||||||
glViewport(0, 0, layer.w, layer.h);
|
glViewport(0, 0, layer.w, layer.h);
|
||||||
glDisable(blend_state());
|
glDisable(blend_state());
|
||||||
|
|
||||||
GLuint rboID;
|
GLuint rboID = allocate_canvas_depth_renderbuffer(layer.w, layer.h);
|
||||||
glGenRenderbuffers(1, &rboID);
|
|
||||||
glBindRenderbuffer(renderbuffer_target(), rboID);
|
|
||||||
glRenderbufferStorage(renderbuffer_target(), depth_component24_format(), layer.w, layer.h);
|
|
||||||
glBindRenderbuffer(renderbuffer_target(), 0);
|
|
||||||
|
|
||||||
glm::mat4 proj = glm::perspective(glm::radians(90.f), 1.f, .01f, 1000.f);
|
glm::mat4 proj = glm::perspective(glm::radians(90.f), 1.f, .01f, 1000.f);
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
glm::mat4 plane_camera = glm::lookAt(glm::vec3(0), m_plane_origin[i], m_plane_tangent[i]);
|
glm::mat4 plane_camera = glm::lookAt(glm::vec3(0), m_plane_origin[i], m_plane_tangent[i]);
|
||||||
layer.rtt(i, frame).bindFramebuffer();
|
layer.rtt(i, frame).bindFramebuffer();
|
||||||
glFramebufferRenderbuffer(framebuffer_target(), framebuffer_depth_attachment(), renderbuffer_target(), rboID);
|
attach_canvas_depth_renderbuffer(rboID);
|
||||||
|
|
||||||
observer(plane_camera, proj, i);
|
observer(plane_camera, proj, i);
|
||||||
|
|
||||||
glFramebufferRenderbuffer(framebuffer_target(), framebuffer_depth_attachment(), renderbuffer_target(), 0);
|
attach_canvas_depth_renderbuffer(0);
|
||||||
layer.rtt(i, frame).unbindFramebuffer();
|
layer.rtt(i, frame).unbindFramebuffer();
|
||||||
|
|
||||||
layer.face(i, frame) = true;
|
layer.face(i, frame) = true;
|
||||||
layer.box(i, frame) = { 0, 0, layer.w, layer.h };
|
layer.box(i, frame) = { 0, 0, layer.w, layer.h };
|
||||||
}
|
}
|
||||||
|
|
||||||
glDeleteRenderbuffers(1, &rboID);
|
delete_canvas_renderbuffer(rboID);
|
||||||
|
|
||||||
// restore viewport and clear color states
|
// restore viewport and clear color states
|
||||||
blend ? glEnable(blend_state()) : glDisable(blend_state());
|
blend ? glEnable(blend_state()) : glDisable(blend_state());
|
||||||
@@ -3010,16 +3066,12 @@ void Canvas::draw_objects(std::function<void(const glm::mat4& camera, const glm:
|
|||||||
glViewport(0, 0, layer.w, layer.h);
|
glViewport(0, 0, layer.w, layer.h);
|
||||||
glDisable(blend_state());
|
glDisable(blend_state());
|
||||||
|
|
||||||
GLuint rboID;
|
GLuint rboID = allocate_canvas_depth_renderbuffer(layer.w, layer.h);
|
||||||
glGenRenderbuffers(1, &rboID);
|
|
||||||
glBindRenderbuffer(renderbuffer_target(), rboID);
|
|
||||||
glRenderbufferStorage(renderbuffer_target(), depth_component24_format(), layer.w, layer.h);
|
|
||||||
glBindRenderbuffer(renderbuffer_target(), 0);
|
|
||||||
|
|
||||||
RTT rtt;
|
RTT rtt;
|
||||||
rtt.create(layer.w, layer.h);
|
rtt.create(layer.w, layer.h);
|
||||||
rtt.bindFramebuffer();
|
rtt.bindFramebuffer();
|
||||||
glFramebufferRenderbuffer(framebuffer_target(), framebuffer_depth_attachment(), renderbuffer_target(), rboID);
|
attach_canvas_depth_renderbuffer(rboID);
|
||||||
rtt.unbindFramebuffer();
|
rtt.unbindFramebuffer();
|
||||||
|
|
||||||
// allocate action to add to history
|
// allocate action to add to history
|
||||||
@@ -3089,7 +3141,7 @@ void Canvas::draw_objects(std::function<void(const glm::mat4& camera, const glm:
|
|||||||
ActionManager::add(action);
|
ActionManager::add(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
glDeleteRenderbuffers(1, &rboID);
|
delete_canvas_renderbuffer(rboID);
|
||||||
rtt.destroy();
|
rtt.destroy();
|
||||||
|
|
||||||
// restore viewport and clear color states
|
// restore viewport and clear color states
|
||||||
|
|||||||
@@ -939,6 +939,70 @@ pp::foundation::Status restore_opengl_framebuffer_binding(
|
|||||||
return pp::foundation::Status::success();
|
return pp::foundation::Status::success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pp::foundation::Result<std::uint32_t> allocate_opengl_depth_renderbuffer(
|
||||||
|
std::int32_t width,
|
||||||
|
std::int32_t height,
|
||||||
|
OpenGlDepthRenderbufferAllocationDispatch dispatch) noexcept
|
||||||
|
{
|
||||||
|
if (dispatch.gen_renderbuffers == nullptr
|
||||||
|
|| dispatch.bind_renderbuffer == nullptr
|
||||||
|
|| dispatch.renderbuffer_storage == nullptr) {
|
||||||
|
return pp::foundation::Result<std::uint32_t>::failure(
|
||||||
|
pp::foundation::Status::invalid_argument(
|
||||||
|
"OpenGL depth renderbuffer allocation dispatch callbacks must not be null"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width <= 0 || height <= 0) {
|
||||||
|
return pp::foundation::Result<std::uint32_t>::failure(
|
||||||
|
pp::foundation::Status::invalid_argument("OpenGL depth renderbuffer dimensions are invalid"));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint32_t renderbuffer_id = 0U;
|
||||||
|
dispatch.gen_renderbuffers(1U, &renderbuffer_id);
|
||||||
|
if (renderbuffer_id == 0U) {
|
||||||
|
return pp::foundation::Result<std::uint32_t>::failure(
|
||||||
|
pp::foundation::Status::out_of_range("OpenGL renderbuffer allocation returned id 0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch.bind_renderbuffer(renderbuffer_target(), renderbuffer_id);
|
||||||
|
dispatch.renderbuffer_storage(renderbuffer_target(), depth_component24_format(), width, height);
|
||||||
|
dispatch.bind_renderbuffer(renderbuffer_target(), default_framebuffer_id());
|
||||||
|
return pp::foundation::Result<std::uint32_t>::success(renderbuffer_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
pp::foundation::Status delete_opengl_renderbuffer(
|
||||||
|
std::uint32_t renderbuffer_id,
|
||||||
|
OpenGlRenderbufferDeleteDispatch dispatch) noexcept
|
||||||
|
{
|
||||||
|
if (dispatch.delete_renderbuffers == nullptr) {
|
||||||
|
return pp::foundation::Status::invalid_argument("OpenGL renderbuffer delete callback must not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renderbuffer_id == 0U) {
|
||||||
|
return pp::foundation::Status::success();
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch.delete_renderbuffers(1U, &renderbuffer_id);
|
||||||
|
return pp::foundation::Status::success();
|
||||||
|
}
|
||||||
|
|
||||||
|
pp::foundation::Status attach_opengl_depth_renderbuffer(
|
||||||
|
std::uint32_t renderbuffer_id,
|
||||||
|
OpenGlDepthRenderbufferAttachmentDispatch dispatch) noexcept
|
||||||
|
{
|
||||||
|
if (dispatch.framebuffer_renderbuffer == nullptr) {
|
||||||
|
return pp::foundation::Status::invalid_argument(
|
||||||
|
"OpenGL depth renderbuffer attachment callback must not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch.framebuffer_renderbuffer(
|
||||||
|
framebuffer_target(),
|
||||||
|
framebuffer_depth_attachment(),
|
||||||
|
renderbuffer_target(),
|
||||||
|
renderbuffer_id);
|
||||||
|
return pp::foundation::Status::success();
|
||||||
|
}
|
||||||
|
|
||||||
pp::foundation::Result<std::uint32_t> create_opengl_sampler(
|
pp::foundation::Result<std::uint32_t> create_opengl_sampler(
|
||||||
std::span<const OpenGlTextureParameter> parameters,
|
std::span<const OpenGlTextureParameter> parameters,
|
||||||
OpenGlSamplerCreateDispatch dispatch) noexcept
|
OpenGlSamplerCreateDispatch dispatch) noexcept
|
||||||
|
|||||||
@@ -364,8 +364,14 @@ using OpenGlGetActiveUniformFn = void (*)(
|
|||||||
char* name) noexcept;
|
char* name) noexcept;
|
||||||
using OpenGlGetUniformLocationFn = std::int32_t (*)(std::uint32_t program, const 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 OpenGlBindFramebufferFn = void (*)(std::uint32_t target, std::uint32_t framebuffer) noexcept;
|
||||||
|
using OpenGlBindRenderbufferFn = void (*)(std::uint32_t target, std::uint32_t renderbuffer) noexcept;
|
||||||
using OpenGlBindTextureFn = void (*)(std::uint32_t target, std::uint32_t texture) 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;
|
using OpenGlBindSamplerFn = void (*)(std::uint32_t unit, std::uint32_t sampler) noexcept;
|
||||||
|
using OpenGlRenderbufferStorageFn = void (*)(
|
||||||
|
std::uint32_t target,
|
||||||
|
std::uint32_t internal_format,
|
||||||
|
std::int32_t width,
|
||||||
|
std::int32_t height) noexcept;
|
||||||
using OpenGlSamplerParameteriFn = void (*)(
|
using OpenGlSamplerParameteriFn = void (*)(
|
||||||
std::uint32_t sampler,
|
std::uint32_t sampler,
|
||||||
std::uint32_t parameter,
|
std::uint32_t parameter,
|
||||||
@@ -427,6 +433,11 @@ using OpenGlFramebufferTexture2DFn = void (*)(
|
|||||||
std::uint32_t texture_target,
|
std::uint32_t texture_target,
|
||||||
std::uint32_t texture,
|
std::uint32_t texture,
|
||||||
std::int32_t level) noexcept;
|
std::int32_t level) noexcept;
|
||||||
|
using OpenGlFramebufferRenderbufferFn = void (*)(
|
||||||
|
std::uint32_t target,
|
||||||
|
std::uint32_t attachment,
|
||||||
|
std::uint32_t renderbuffer_target,
|
||||||
|
std::uint32_t renderbuffer) noexcept;
|
||||||
using OpenGlCheckFramebufferStatusFn = std::uint32_t (*)(std::uint32_t target) noexcept;
|
using OpenGlCheckFramebufferStatusFn = std::uint32_t (*)(std::uint32_t target) noexcept;
|
||||||
using OpenGlReadPixelsFn = void (*)(
|
using OpenGlReadPixelsFn = void (*)(
|
||||||
std::int32_t x,
|
std::int32_t x,
|
||||||
@@ -608,6 +619,20 @@ struct OpenGlFramebufferRestoreDispatch {
|
|||||||
OpenGlBindFramebufferFn bind_framebuffer = nullptr;
|
OpenGlBindFramebufferFn bind_framebuffer = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct OpenGlDepthRenderbufferAllocationDispatch {
|
||||||
|
OpenGlGenObjectsFn gen_renderbuffers = nullptr;
|
||||||
|
OpenGlBindRenderbufferFn bind_renderbuffer = nullptr;
|
||||||
|
OpenGlRenderbufferStorageFn renderbuffer_storage = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OpenGlRenderbufferDeleteDispatch {
|
||||||
|
OpenGlDeleteObjectsFn delete_renderbuffers = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OpenGlDepthRenderbufferAttachmentDispatch {
|
||||||
|
OpenGlFramebufferRenderbufferFn framebuffer_renderbuffer = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
struct OpenGlSamplerCreateDispatch {
|
struct OpenGlSamplerCreateDispatch {
|
||||||
OpenGlGenObjectsFn gen_samplers = nullptr;
|
OpenGlGenObjectsFn gen_samplers = nullptr;
|
||||||
OpenGlSamplerParameteriFn sampler_parameter_i = nullptr;
|
OpenGlSamplerParameteriFn sampler_parameter_i = nullptr;
|
||||||
@@ -813,6 +838,16 @@ struct OpenGlMeshDeleteDispatch {
|
|||||||
[[nodiscard]] pp::foundation::Status restore_opengl_framebuffer_binding(
|
[[nodiscard]] pp::foundation::Status restore_opengl_framebuffer_binding(
|
||||||
OpenGlFramebufferBindingState binding,
|
OpenGlFramebufferBindingState binding,
|
||||||
OpenGlFramebufferRestoreDispatch dispatch) noexcept;
|
OpenGlFramebufferRestoreDispatch dispatch) noexcept;
|
||||||
|
[[nodiscard]] pp::foundation::Result<std::uint32_t> allocate_opengl_depth_renderbuffer(
|
||||||
|
std::int32_t width,
|
||||||
|
std::int32_t height,
|
||||||
|
OpenGlDepthRenderbufferAllocationDispatch dispatch) noexcept;
|
||||||
|
[[nodiscard]] pp::foundation::Status delete_opengl_renderbuffer(
|
||||||
|
std::uint32_t renderbuffer_id,
|
||||||
|
OpenGlRenderbufferDeleteDispatch dispatch) noexcept;
|
||||||
|
[[nodiscard]] pp::foundation::Status attach_opengl_depth_renderbuffer(
|
||||||
|
std::uint32_t renderbuffer_id,
|
||||||
|
OpenGlDepthRenderbufferAttachmentDispatch dispatch) noexcept;
|
||||||
[[nodiscard]] pp::foundation::Result<std::uint32_t> create_opengl_sampler(
|
[[nodiscard]] pp::foundation::Result<std::uint32_t> create_opengl_sampler(
|
||||||
std::span<const OpenGlTextureParameter> parameters,
|
std::span<const OpenGlTextureParameter> parameters,
|
||||||
OpenGlSamplerCreateDispatch dispatch) noexcept;
|
OpenGlSamplerCreateDispatch dispatch) noexcept;
|
||||||
|
|||||||
@@ -63,6 +63,13 @@ struct RecordedOpenGlFramebufferAttachmentCall {
|
|||||||
std::int32_t level = 0;
|
std::int32_t level = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RecordedOpenGlRenderbufferStorageCall {
|
||||||
|
std::uint32_t target = 0;
|
||||||
|
std::uint32_t internal_format = 0;
|
||||||
|
std::int32_t width = 0;
|
||||||
|
std::int32_t height = 0;
|
||||||
|
};
|
||||||
|
|
||||||
struct RecordedOpenGlReadPixelsCall {
|
struct RecordedOpenGlReadPixelsCall {
|
||||||
std::int32_t x = 0;
|
std::int32_t x = 0;
|
||||||
std::int32_t y = 0;
|
std::int32_t y = 0;
|
||||||
@@ -184,6 +191,10 @@ std::vector<std::uint32_t> recorded_generated_framebuffer_counts;
|
|||||||
std::vector<std::uint32_t> recorded_deleted_framebuffers;
|
std::vector<std::uint32_t> recorded_deleted_framebuffers;
|
||||||
std::vector<RecordedOpenGlFramebufferAttachmentCall> recorded_framebuffer_attachment_calls;
|
std::vector<RecordedOpenGlFramebufferAttachmentCall> recorded_framebuffer_attachment_calls;
|
||||||
std::vector<std::uint32_t> recorded_framebuffer_status_queries;
|
std::vector<std::uint32_t> recorded_framebuffer_status_queries;
|
||||||
|
std::vector<std::uint32_t> recorded_generated_renderbuffer_counts;
|
||||||
|
std::vector<std::uint32_t> recorded_deleted_renderbuffers;
|
||||||
|
std::vector<std::uint32_t> recorded_bound_renderbuffers;
|
||||||
|
std::vector<RecordedOpenGlRenderbufferStorageCall> recorded_renderbuffer_storage_calls;
|
||||||
std::vector<RecordedOpenGlReadPixelsCall> recorded_read_pixels_calls;
|
std::vector<RecordedOpenGlReadPixelsCall> recorded_read_pixels_calls;
|
||||||
std::vector<RecordedOpenGlBlitFramebufferCall> recorded_blit_framebuffer_calls;
|
std::vector<RecordedOpenGlBlitFramebufferCall> recorded_blit_framebuffer_calls;
|
||||||
std::vector<std::uint32_t> recorded_generated_sampler_counts;
|
std::vector<std::uint32_t> recorded_generated_sampler_counts;
|
||||||
@@ -220,6 +231,7 @@ std::vector<RecordedOpenGlVertexAttribPointerCall> recorded_vertex_attrib_pointe
|
|||||||
std::vector<RecordedOpenGlMeshDrawCall> recorded_mesh_draw_calls;
|
std::vector<RecordedOpenGlMeshDrawCall> recorded_mesh_draw_calls;
|
||||||
std::uint32_t next_texture_id = 91U;
|
std::uint32_t next_texture_id = 91U;
|
||||||
std::uint32_t next_framebuffer_id = 44U;
|
std::uint32_t next_framebuffer_id = 44U;
|
||||||
|
std::uint32_t next_renderbuffer_id = 81U;
|
||||||
std::uint32_t next_sampler_id = 71U;
|
std::uint32_t next_sampler_id = 71U;
|
||||||
std::uint32_t next_shader_id = 301U;
|
std::uint32_t next_shader_id = 301U;
|
||||||
std::uint32_t next_program_id = 401U;
|
std::uint32_t next_program_id = 401U;
|
||||||
@@ -532,6 +544,41 @@ void record_delete_framebuffers(std::uint32_t count, const std::uint32_t* ids) n
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void record_gen_renderbuffers(std::uint32_t count, std::uint32_t* ids) noexcept
|
||||||
|
{
|
||||||
|
recorded_generated_renderbuffer_counts.push_back(count);
|
||||||
|
for (std::uint32_t i = 0U; i < count; ++i) {
|
||||||
|
ids[i] = next_renderbuffer_id + i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void record_delete_renderbuffers(std::uint32_t count, const std::uint32_t* ids) noexcept
|
||||||
|
{
|
||||||
|
for (std::uint32_t i = 0U; i < count; ++i) {
|
||||||
|
recorded_deleted_renderbuffers.push_back(ids[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void record_bind_renderbuffer(std::uint32_t target, std::uint32_t renderbuffer) noexcept
|
||||||
|
{
|
||||||
|
recorded_bound_renderbuffers.push_back(target);
|
||||||
|
recorded_bound_renderbuffers.push_back(renderbuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void record_renderbuffer_storage(
|
||||||
|
std::uint32_t target,
|
||||||
|
std::uint32_t internal_format,
|
||||||
|
std::int32_t width,
|
||||||
|
std::int32_t height) noexcept
|
||||||
|
{
|
||||||
|
recorded_renderbuffer_storage_calls.push_back(RecordedOpenGlRenderbufferStorageCall {
|
||||||
|
.target = target,
|
||||||
|
.internal_format = internal_format,
|
||||||
|
.width = width,
|
||||||
|
.height = height,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void record_framebuffer_texture_2d(
|
void record_framebuffer_texture_2d(
|
||||||
std::uint32_t target,
|
std::uint32_t target,
|
||||||
std::uint32_t attachment,
|
std::uint32_t attachment,
|
||||||
@@ -548,6 +595,20 @@ void record_framebuffer_texture_2d(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void record_framebuffer_renderbuffer(
|
||||||
|
std::uint32_t target,
|
||||||
|
std::uint32_t attachment,
|
||||||
|
std::uint32_t renderbuffer_target,
|
||||||
|
std::uint32_t renderbuffer) noexcept
|
||||||
|
{
|
||||||
|
recorded_framebuffer_attachment_calls.push_back(RecordedOpenGlFramebufferAttachmentCall {
|
||||||
|
.target = target,
|
||||||
|
.attachment = attachment,
|
||||||
|
.texture_target = renderbuffer_target,
|
||||||
|
.texture = renderbuffer,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
std::uint32_t record_check_framebuffer_status(std::uint32_t target) noexcept
|
std::uint32_t record_check_framebuffer_status(std::uint32_t target) noexcept
|
||||||
{
|
{
|
||||||
recorded_framebuffer_status_queries.push_back(target);
|
recorded_framebuffer_status_queries.push_back(target);
|
||||||
@@ -4060,6 +4121,99 @@ void rejects_incomplete_framebuffer_binding_dispatch(pp::tests::Harness& h)
|
|||||||
PP_EXPECT(h, restore.code == pp::foundation::StatusCode::invalid_argument);
|
PP_EXPECT(h, restore.code == pp::foundation::StatusCode::invalid_argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void allocates_attaches_and_deletes_depth_renderbuffer(pp::tests::Harness& h)
|
||||||
|
{
|
||||||
|
recorded_generated_renderbuffer_counts.clear();
|
||||||
|
recorded_bound_renderbuffers.clear();
|
||||||
|
recorded_renderbuffer_storage_calls.clear();
|
||||||
|
recorded_framebuffer_attachment_calls.clear();
|
||||||
|
recorded_deleted_renderbuffers.clear();
|
||||||
|
next_renderbuffer_id = 81U;
|
||||||
|
|
||||||
|
const auto renderbuffer = pp::renderer::gl::allocate_opengl_depth_renderbuffer(
|
||||||
|
64,
|
||||||
|
32,
|
||||||
|
pp::renderer::gl::OpenGlDepthRenderbufferAllocationDispatch {
|
||||||
|
.gen_renderbuffers = record_gen_renderbuffers,
|
||||||
|
.bind_renderbuffer = record_bind_renderbuffer,
|
||||||
|
.renderbuffer_storage = record_renderbuffer_storage,
|
||||||
|
});
|
||||||
|
const auto attach = pp::renderer::gl::attach_opengl_depth_renderbuffer(
|
||||||
|
renderbuffer.ok() ? renderbuffer.value() : 0U,
|
||||||
|
pp::renderer::gl::OpenGlDepthRenderbufferAttachmentDispatch {
|
||||||
|
.framebuffer_renderbuffer = record_framebuffer_renderbuffer,
|
||||||
|
});
|
||||||
|
const auto detach = pp::renderer::gl::attach_opengl_depth_renderbuffer(
|
||||||
|
0U,
|
||||||
|
pp::renderer::gl::OpenGlDepthRenderbufferAttachmentDispatch {
|
||||||
|
.framebuffer_renderbuffer = record_framebuffer_renderbuffer,
|
||||||
|
});
|
||||||
|
const auto deleted = pp::renderer::gl::delete_opengl_renderbuffer(
|
||||||
|
renderbuffer.ok() ? renderbuffer.value() : 0U,
|
||||||
|
pp::renderer::gl::OpenGlRenderbufferDeleteDispatch {
|
||||||
|
.delete_renderbuffers = record_delete_renderbuffers,
|
||||||
|
});
|
||||||
|
|
||||||
|
PP_EXPECT(h, renderbuffer.ok());
|
||||||
|
PP_EXPECT(h, renderbuffer.value() == 81U);
|
||||||
|
PP_EXPECT(h, recorded_generated_renderbuffer_counts.size() == 1U);
|
||||||
|
PP_EXPECT(h, recorded_generated_renderbuffer_counts[0] == 1U);
|
||||||
|
PP_EXPECT(h, recorded_bound_renderbuffers.size() == 4U);
|
||||||
|
PP_EXPECT(h, recorded_bound_renderbuffers[0] == 0x8D41U);
|
||||||
|
PP_EXPECT(h, recorded_bound_renderbuffers[1] == 81U);
|
||||||
|
PP_EXPECT(h, recorded_bound_renderbuffers[2] == 0x8D41U);
|
||||||
|
PP_EXPECT(h, recorded_bound_renderbuffers[3] == 0U);
|
||||||
|
PP_EXPECT(h, recorded_renderbuffer_storage_calls.size() == 1U);
|
||||||
|
PP_EXPECT(h, recorded_renderbuffer_storage_calls[0].target == 0x8D41U);
|
||||||
|
PP_EXPECT(h, recorded_renderbuffer_storage_calls[0].internal_format == 0x81A6U);
|
||||||
|
PP_EXPECT(h, recorded_renderbuffer_storage_calls[0].width == 64);
|
||||||
|
PP_EXPECT(h, recorded_renderbuffer_storage_calls[0].height == 32);
|
||||||
|
PP_EXPECT(h, attach.ok());
|
||||||
|
PP_EXPECT(h, detach.ok());
|
||||||
|
PP_EXPECT(h, recorded_framebuffer_attachment_calls.size() == 2U);
|
||||||
|
PP_EXPECT(h, recorded_framebuffer_attachment_calls[0].target == 0x8D40U);
|
||||||
|
PP_EXPECT(h, recorded_framebuffer_attachment_calls[0].attachment == 0x8D00U);
|
||||||
|
PP_EXPECT(h, recorded_framebuffer_attachment_calls[0].texture_target == 0x8D41U);
|
||||||
|
PP_EXPECT(h, recorded_framebuffer_attachment_calls[0].texture == 81U);
|
||||||
|
PP_EXPECT(h, recorded_framebuffer_attachment_calls[1].texture == 0U);
|
||||||
|
PP_EXPECT(h, deleted.ok());
|
||||||
|
PP_EXPECT(h, recorded_deleted_renderbuffers.size() == 1U);
|
||||||
|
PP_EXPECT(h, recorded_deleted_renderbuffers[0] == 81U);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rejects_invalid_depth_renderbuffer_dispatch(pp::tests::Harness& h)
|
||||||
|
{
|
||||||
|
const auto missing_allocate_dispatch = pp::renderer::gl::allocate_opengl_depth_renderbuffer(
|
||||||
|
64,
|
||||||
|
32,
|
||||||
|
pp::renderer::gl::OpenGlDepthRenderbufferAllocationDispatch {
|
||||||
|
.gen_renderbuffers = record_gen_renderbuffers,
|
||||||
|
});
|
||||||
|
const auto invalid_dimensions = pp::renderer::gl::allocate_opengl_depth_renderbuffer(
|
||||||
|
0,
|
||||||
|
32,
|
||||||
|
pp::renderer::gl::OpenGlDepthRenderbufferAllocationDispatch {
|
||||||
|
.gen_renderbuffers = record_gen_renderbuffers,
|
||||||
|
.bind_renderbuffer = record_bind_renderbuffer,
|
||||||
|
.renderbuffer_storage = record_renderbuffer_storage,
|
||||||
|
});
|
||||||
|
const auto missing_attach_dispatch = pp::renderer::gl::attach_opengl_depth_renderbuffer(
|
||||||
|
81U,
|
||||||
|
pp::renderer::gl::OpenGlDepthRenderbufferAttachmentDispatch {});
|
||||||
|
const auto missing_delete_dispatch = pp::renderer::gl::delete_opengl_renderbuffer(
|
||||||
|
81U,
|
||||||
|
pp::renderer::gl::OpenGlRenderbufferDeleteDispatch {});
|
||||||
|
|
||||||
|
PP_EXPECT(h, !missing_allocate_dispatch.ok());
|
||||||
|
PP_EXPECT(h, missing_allocate_dispatch.status().code == pp::foundation::StatusCode::invalid_argument);
|
||||||
|
PP_EXPECT(h, !invalid_dimensions.ok());
|
||||||
|
PP_EXPECT(h, invalid_dimensions.status().code == pp::foundation::StatusCode::invalid_argument);
|
||||||
|
PP_EXPECT(h, !missing_attach_dispatch.ok());
|
||||||
|
PP_EXPECT(h, missing_attach_dispatch.code == pp::foundation::StatusCode::invalid_argument);
|
||||||
|
PP_EXPECT(h, !missing_delete_dispatch.ok());
|
||||||
|
PP_EXPECT(h, missing_delete_dispatch.code == pp::foundation::StatusCode::invalid_argument);
|
||||||
|
}
|
||||||
|
|
||||||
void maps_renderer_viewports_and_scissors(pp::tests::Harness& h)
|
void maps_renderer_viewports_and_scissors(pp::tests::Harness& h)
|
||||||
{
|
{
|
||||||
const auto viewport = pp::renderer::gl::viewport_for_renderer_viewport(
|
const auto viewport = pp::renderer::gl::viewport_for_renderer_viewport(
|
||||||
@@ -4513,6 +4667,8 @@ int main()
|
|||||||
harness.run("binds_framebuffer_draw_read_through_dispatch", binds_framebuffer_draw_read_through_dispatch);
|
harness.run("binds_framebuffer_draw_read_through_dispatch", binds_framebuffer_draw_read_through_dispatch);
|
||||||
harness.run("restores_framebuffer_draw_read_through_dispatch", restores_framebuffer_draw_read_through_dispatch);
|
harness.run("restores_framebuffer_draw_read_through_dispatch", restores_framebuffer_draw_read_through_dispatch);
|
||||||
harness.run("rejects_incomplete_framebuffer_binding_dispatch", rejects_incomplete_framebuffer_binding_dispatch);
|
harness.run("rejects_incomplete_framebuffer_binding_dispatch", rejects_incomplete_framebuffer_binding_dispatch);
|
||||||
|
harness.run("allocates_attaches_and_deletes_depth_renderbuffer", allocates_attaches_and_deletes_depth_renderbuffer);
|
||||||
|
harness.run("rejects_invalid_depth_renderbuffer_dispatch", rejects_invalid_depth_renderbuffer_dispatch);
|
||||||
harness.run("maps_renderer_viewports_and_scissors", maps_renderer_viewports_and_scissors);
|
harness.run("maps_renderer_viewports_and_scissors", maps_renderer_viewports_and_scissors);
|
||||||
harness.run("maps_renderer_blend_state_tokens", maps_renderer_blend_state_tokens);
|
harness.run("maps_renderer_blend_state_tokens", maps_renderer_blend_state_tokens);
|
||||||
harness.run("maps_renderer_color_write_masks", maps_renderer_color_write_masks);
|
harness.run("maps_renderer_color_write_masks", maps_renderer_color_write_masks);
|
||||||
|
|||||||
Reference in New Issue
Block a user