#include "renderer_gl/command_plan.h" namespace pp::renderer::gl { namespace { [[nodiscard]] bool texture_format_supported(OpenGlRendererTextureFormat format) noexcept { return format.internal_format != 0U && format.pixel_format != 0U && format.component_type != 0U && format.bytes_per_pixel != 0U; } [[nodiscard]] bool requires_render_pass(pp::renderer::RecordedRenderCommandKind kind) noexcept { switch (kind) { case pp::renderer::RecordedRenderCommandKind::set_viewport: case pp::renderer::RecordedRenderCommandKind::set_scissor: case pp::renderer::RecordedRenderCommandKind::set_blend_state: case pp::renderer::RecordedRenderCommandKind::set_depth_state: case pp::renderer::RecordedRenderCommandKind::bind_shader: case pp::renderer::RecordedRenderCommandKind::set_shader_uniform: case pp::renderer::RecordedRenderCommandKind::bind_texture: case pp::renderer::RecordedRenderCommandKind::bind_sampler: case pp::renderer::RecordedRenderCommandKind::bind_mesh: case pp::renderer::RecordedRenderCommandKind::draw: return true; default: return false; } } } const char* planned_command_kind_name(OpenGlPlannedCommandKind kind) noexcept { switch (kind) { case OpenGlPlannedCommandKind::unknown: return "unknown"; case OpenGlPlannedCommandKind::begin_render_pass: return "begin_render_pass"; case OpenGlPlannedCommandKind::set_viewport: return "set_viewport"; case OpenGlPlannedCommandKind::set_scissor: return "set_scissor"; case OpenGlPlannedCommandKind::set_blend_state: return "set_blend_state"; case OpenGlPlannedCommandKind::set_depth_state: return "set_depth_state"; case OpenGlPlannedCommandKind::bind_texture: return "bind_texture"; case OpenGlPlannedCommandKind::bind_sampler: return "bind_sampler"; case OpenGlPlannedCommandKind::bind_mesh: return "bind_mesh"; case OpenGlPlannedCommandKind::draw: return "draw"; case OpenGlPlannedCommandKind::blit_render_target: return "blit_render_target"; case OpenGlPlannedCommandKind::end_render_pass: return "end_render_pass"; case OpenGlPlannedCommandKind::trace: return "trace"; case OpenGlPlannedCommandKind::passthrough: return "passthrough"; } return "unknown"; } OpenGlPlannedCommand plan_recorded_render_command(pp::renderer::RecordedRenderCommand command) noexcept { OpenGlPlannedCommand planned {}; planned.requires_render_pass = requires_render_pass(command.kind); planned.supported = true; switch (command.kind) { case pp::renderer::RecordedRenderCommandKind::begin_render_pass: planned.kind = OpenGlPlannedCommandKind::begin_render_pass; planned.clear_mask = clear_mask_for_render_pass(pp::renderer::RenderPassDesc { .clear_color_enabled = command.clear_color_enabled, .clear_color = command.clear_color, .clear_depth_enabled = command.clear_depth_enabled, .clear_depth = command.clear_depth, .clear_stencil_enabled = command.clear_stencil_enabled, .clear_stencil = command.clear_stencil, }); planned.clear_values = clear_values_for_render_pass(pp::renderer::RenderPassDesc { .clear_color_enabled = command.clear_color_enabled, .clear_color = command.clear_color, .clear_depth_enabled = command.clear_depth_enabled, .clear_depth = command.clear_depth, .clear_stencil_enabled = command.clear_stencil_enabled, .clear_stencil = command.clear_stencil, }); planned.texture_format = texture_format_for_renderer_format(command.target_desc.format); planned.supported = texture_format_supported(planned.texture_format); break; case pp::renderer::RecordedRenderCommandKind::set_viewport: planned.kind = OpenGlPlannedCommandKind::set_viewport; planned.viewport = viewport_for_renderer_viewport(command.viewport); break; case pp::renderer::RecordedRenderCommandKind::set_scissor: planned.kind = OpenGlPlannedCommandKind::set_scissor; planned.scissor = scissor_rect_for_renderer_scissor(command.scissor); break; case pp::renderer::RecordedRenderCommandKind::set_blend_state: planned.kind = OpenGlPlannedCommandKind::set_blend_state; planned.blend = blend_state_for_renderer_blend_state(command.blend_state); planned.supported = planned.blend.supported; break; case pp::renderer::RecordedRenderCommandKind::set_depth_state: planned.kind = OpenGlPlannedCommandKind::set_depth_state; planned.depth = depth_state_for_renderer_depth_state(command.depth_state); planned.supported = planned.depth.supported; break; case pp::renderer::RecordedRenderCommandKind::bind_texture: planned.kind = OpenGlPlannedCommandKind::bind_texture; planned.texture_format = texture_format_for_renderer_format(command.texture_desc.format); planned.supported = texture_format_supported(planned.texture_format); break; case pp::renderer::RecordedRenderCommandKind::bind_sampler: planned.kind = OpenGlPlannedCommandKind::bind_sampler; planned.sampler = sampler_state_for_renderer_sampler_desc(command.sampler_desc); planned.supported = planned.sampler.supported; break; case pp::renderer::RecordedRenderCommandKind::bind_mesh: planned.kind = OpenGlPlannedCommandKind::bind_mesh; planned.primitive_mode = primitive_mode_for_renderer_topology(command.mesh_desc.topology); planned.supported = planned.primitive_mode != 0U; break; case pp::renderer::RecordedRenderCommandKind::draw: planned.kind = OpenGlPlannedCommandKind::draw; planned.primitive_mode = primitive_mode_for_renderer_topology(command.mesh_desc.topology); planned.draw_vertex_count = command.draw_desc.vertex_count; planned.draw_index_count = command.draw_desc.index_count; planned.supported = planned.primitive_mode != 0U; break; case pp::renderer::RecordedRenderCommandKind::blit_render_target: planned.kind = OpenGlPlannedCommandKind::blit_render_target; planned.blit_filter = blit_filter_for_renderer_filter(command.blit_filter); planned.supported = planned.blit_filter.supported; break; case pp::renderer::RecordedRenderCommandKind::end_render_pass: planned.kind = OpenGlPlannedCommandKind::end_render_pass; break; case pp::renderer::RecordedRenderCommandKind::trace_marker: case pp::renderer::RecordedRenderCommandKind::trace_begin_scope: case pp::renderer::RecordedRenderCommandKind::trace_end_scope: planned.kind = OpenGlPlannedCommandKind::trace; break; case pp::renderer::RecordedRenderCommandKind::bind_shader: case pp::renderer::RecordedRenderCommandKind::set_shader_uniform: case pp::renderer::RecordedRenderCommandKind::upload_texture: case pp::renderer::RecordedRenderCommandKind::generate_mipmaps: case pp::renderer::RecordedRenderCommandKind::transition_texture: case pp::renderer::RecordedRenderCommandKind::copy_texture: case pp::renderer::RecordedRenderCommandKind::read_texture: case pp::renderer::RecordedRenderCommandKind::capture_frame: planned.kind = OpenGlPlannedCommandKind::passthrough; break; default: planned.kind = OpenGlPlannedCommandKind::unknown; planned.supported = false; break; } return planned; } }