Add renderer render pass clear contract
This commit is contained in:
@@ -285,18 +285,19 @@ Known local toolchain state:
|
||||
source code reintroduces raw `GL_*`/`WGL_*` constants outside the allowed
|
||||
legacy OpenGL implementation files.
|
||||
- `pp_renderer_api` exposes a headless `RecordingRenderDevice` that validates
|
||||
backend-owned resource creation, command order, scissor state, depth state,
|
||||
blend state, texture-slot binding, sampler-state binding, texture-upload byte
|
||||
counts, shader-uniform writes, readback bounds, frame-capture sources,
|
||||
destination buffer sizes, and render-target blit regions, records
|
||||
render/scissor/depth/blend/shader-uniform/texture-bind/sampler-bind/upload/
|
||||
readback/frame-capture/blit commands, draw mesh inputs, and records trace
|
||||
markers without a window or GL context.
|
||||
backend-owned resource creation, command order, render-pass color/depth/
|
||||
stencil clear intent, scissor state, depth state, blend state, texture-slot
|
||||
binding, sampler-state binding, texture-upload byte counts,
|
||||
shader-uniform writes, readback bounds, frame-capture sources, destination
|
||||
buffer sizes, and render-target blit regions, records
|
||||
render-pass-clear/scissor/depth/blend/shader-uniform/texture-bind/
|
||||
sampler-bind/upload/readback/frame-capture/blit commands, draw mesh inputs,
|
||||
and records trace markers without a window or GL context.
|
||||
- `pano_cli record-render` exposes the recording renderer through JSON
|
||||
automation, including scissor/depth/blend/shader-uniform/texture-bind/
|
||||
sampler-bind/upload/readback/frame-capture/blit command and byte totals,
|
||||
backend resource creation counts, plus draw vertex/index totals, and is
|
||||
covered by
|
||||
automation, including render-pass/depth-clear counts, scissor/depth/blend/
|
||||
shader-uniform/texture-bind/sampler-bind/upload/readback/frame-capture/blit
|
||||
command and byte totals, backend resource creation counts, plus draw
|
||||
vertex/index totals, and is covered by
|
||||
`pano_cli_record_render_smoke` plus
|
||||
`pano_cli_record_render_rejects_oversized_target`.
|
||||
- `pano_cli simulate-document-history` exposes `pp_document::DocumentHistory`
|
||||
|
||||
@@ -724,10 +724,11 @@ Results:
|
||||
validation, texture-upload byte-count validation, frame-capture byte-size and
|
||||
command-order validation, render-target blit validation, texture-slot binding
|
||||
validation, blend-state validation, scissor-state validation,
|
||||
shader-uniform write validation, backend-neutral resource factory validation,
|
||||
recording scissor/depth/blend/shader-uniform/texture/sampler-bind/upload/
|
||||
readback/frame-capture/blit command capture, draw mesh-input capture, and
|
||||
invalid catalog rejection.
|
||||
render-pass color/depth/stencil clear validation, shader-uniform write
|
||||
validation, backend-neutral resource factory validation, recording
|
||||
render-pass clear/scissor/depth/blend/shader-uniform/texture/sampler-bind/
|
||||
upload/readback/frame-capture/blit command capture, draw mesh-input capture,
|
||||
and invalid catalog rejection.
|
||||
- `pp_paint_renderer_compositor_tests` passed.
|
||||
- `pp_ui_core_color_tests` passed.
|
||||
- `pp_ui_core_layout_value_tests` passed.
|
||||
@@ -822,20 +823,21 @@ Results:
|
||||
implementation files.
|
||||
- `pp_renderer_api` now includes a headless `RecordingRenderDevice` with strict
|
||||
renderer-owned resource factory and
|
||||
command-order/scissor-state/depth-state/blend-state/texture-bind/
|
||||
sampler-bind/shader-uniform/texture-upload/readback/frame-capture/blit
|
||||
validation; it creates validated textures, render targets, shaders, meshes,
|
||||
and readback buffers, then records commands, trace markers, scissor state,
|
||||
depth state, blend state, shader uniform writes, texture/sampler binds, draw
|
||||
mesh inputs, uploads/readbacks, frame captures, and render-target blits,
|
||||
giving automation a backend-neutral render path that does not require a
|
||||
window or GL context.
|
||||
command-order/render-pass-clear/scissor-state/depth-state/blend-state/
|
||||
texture-bind/sampler-bind/shader-uniform/texture-upload/readback/
|
||||
frame-capture/blit validation; it creates validated textures, render targets,
|
||||
shaders, meshes, and readback buffers, then records commands, trace markers,
|
||||
render-pass color/depth/stencil clear intent, scissor state, depth state,
|
||||
blend state, shader uniform writes, texture/sampler binds, draw mesh inputs,
|
||||
uploads/readbacks, frame captures, and render-target blits, giving automation
|
||||
a backend-neutral render path that does not require a window or GL context.
|
||||
- `pano_cli record-render` exercises that headless recording renderer and emits
|
||||
JSON command counts, resource creation counts, target dimensions, backend
|
||||
name, trace/draw summary, and draw vertex/index totals, scissor/depth/
|
||||
blend-state plus shader-uniform/texture/sampler-bind/upload/readback/
|
||||
frame-capture/blit command/byte totals for agent automation, with an
|
||||
expected-failure smoke for oversized render/readback targets.
|
||||
name, trace/draw summary, render-pass/depth-clear counts, and draw
|
||||
vertex/index totals, scissor/depth/blend-state plus shader-uniform/texture/
|
||||
sampler-bind/upload/readback/frame-capture/blit command/byte totals for
|
||||
agent automation, with an expected-failure smoke for oversized
|
||||
render/readback targets.
|
||||
- `pano_cli simulate-document-history` exercises pure document history
|
||||
apply/undo/redo behavior and emits JSON layer/frame/history state for agent
|
||||
automation.
|
||||
|
||||
@@ -94,7 +94,7 @@ RecordingCommandContext::RecordingCommandContext(std::vector<RecordedRenderComma
|
||||
|
||||
pp::foundation::Status RecordingCommandContext::begin_render_pass(
|
||||
IRenderTarget& target,
|
||||
ClearColor clear_color) noexcept
|
||||
RenderPassDesc desc) noexcept
|
||||
{
|
||||
if (in_render_pass_) {
|
||||
return pp::foundation::Status::invalid_argument("render pass is already active");
|
||||
@@ -110,6 +110,11 @@ pp::foundation::Status RecordingCommandContext::begin_render_pass(
|
||||
return size_status.status();
|
||||
}
|
||||
|
||||
const auto render_pass_status = validate_render_pass_desc(desc);
|
||||
if (!render_pass_status.ok()) {
|
||||
return render_pass_status;
|
||||
}
|
||||
|
||||
in_render_pass_ = true;
|
||||
shader_bound_ = false;
|
||||
mesh_bound_ = false;
|
||||
@@ -117,7 +122,12 @@ pp::foundation::Status RecordingCommandContext::begin_render_pass(
|
||||
push_command(commands_, RecordedRenderCommand {
|
||||
.kind = RecordedRenderCommandKind::begin_render_pass,
|
||||
.target_desc = active_target_,
|
||||
.clear_color = clear_color,
|
||||
.clear_color_enabled = desc.clear_color_enabled,
|
||||
.clear_color = desc.clear_color,
|
||||
.clear_depth_enabled = desc.clear_depth_enabled,
|
||||
.clear_depth = desc.clear_depth,
|
||||
.clear_stencil_enabled = desc.clear_stencil_enabled,
|
||||
.clear_stencil = desc.clear_stencil,
|
||||
});
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
@@ -30,7 +30,12 @@ enum class RecordedRenderCommandKind : std::uint8_t {
|
||||
struct RecordedRenderCommand {
|
||||
RecordedRenderCommandKind kind = RecordedRenderCommandKind::draw;
|
||||
TextureDesc target_desc {};
|
||||
bool clear_color_enabled = false;
|
||||
ClearColor clear_color {};
|
||||
bool clear_depth_enabled = false;
|
||||
float clear_depth = 1.0F;
|
||||
bool clear_stencil_enabled = false;
|
||||
std::uint8_t clear_stencil = 0;
|
||||
Viewport viewport {};
|
||||
ScissorRect scissor {};
|
||||
BlendState blend_state {};
|
||||
@@ -107,7 +112,7 @@ public:
|
||||
|
||||
[[nodiscard]] pp::foundation::Status begin_render_pass(
|
||||
IRenderTarget& target,
|
||||
ClearColor clear_color) noexcept override;
|
||||
RenderPassDesc desc) noexcept override;
|
||||
[[nodiscard]] pp::foundation::Status set_viewport(Viewport viewport) noexcept override;
|
||||
[[nodiscard]] pp::foundation::Status set_scissor(ScissorRect scissor) noexcept override;
|
||||
[[nodiscard]] pp::foundation::Status set_blend_state(BlendState state) noexcept override;
|
||||
|
||||
@@ -163,6 +163,27 @@ pp::foundation::Status validate_scissor(ScissorRect scissor, Extent2D target_ext
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Status validate_render_pass_desc(RenderPassDesc desc) noexcept
|
||||
{
|
||||
if (desc.clear_color_enabled
|
||||
&& (!std::isfinite(desc.clear_color.r)
|
||||
|| !std::isfinite(desc.clear_color.g)
|
||||
|| !std::isfinite(desc.clear_color.b)
|
||||
|| !std::isfinite(desc.clear_color.a))) {
|
||||
return pp::foundation::Status::invalid_argument("render pass clear color must be finite");
|
||||
}
|
||||
|
||||
if (desc.clear_depth_enabled && !std::isfinite(desc.clear_depth)) {
|
||||
return pp::foundation::Status::invalid_argument("render pass clear depth must be finite");
|
||||
}
|
||||
|
||||
if (desc.clear_depth_enabled && (desc.clear_depth < 0.0F || desc.clear_depth > 1.0F)) {
|
||||
return pp::foundation::Status::out_of_range("render pass clear depth must be within 0..1");
|
||||
}
|
||||
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Status validate_blend_factor(BlendFactor factor) noexcept
|
||||
{
|
||||
switch (factor) {
|
||||
|
||||
@@ -64,6 +64,15 @@ struct ClearColor {
|
||||
float a = 0.0F;
|
||||
};
|
||||
|
||||
struct RenderPassDesc {
|
||||
bool clear_color_enabled = true;
|
||||
ClearColor clear_color;
|
||||
bool clear_depth_enabled = false;
|
||||
float clear_depth = 1.0F;
|
||||
bool clear_stencil_enabled = false;
|
||||
std::uint8_t clear_stencil = 0;
|
||||
};
|
||||
|
||||
enum class PrimitiveTopology : std::uint8_t {
|
||||
triangles,
|
||||
triangle_strip,
|
||||
@@ -201,7 +210,7 @@ public:
|
||||
virtual ~ICommandContext() = default;
|
||||
[[nodiscard]] virtual pp::foundation::Status begin_render_pass(
|
||||
IRenderTarget& target,
|
||||
ClearColor clear_color) noexcept = 0;
|
||||
RenderPassDesc desc) noexcept = 0;
|
||||
[[nodiscard]] virtual pp::foundation::Status set_viewport(Viewport viewport) noexcept = 0;
|
||||
[[nodiscard]] virtual pp::foundation::Status set_scissor(ScissorRect scissor) noexcept = 0;
|
||||
[[nodiscard]] virtual pp::foundation::Status set_blend_state(BlendState state) noexcept = 0;
|
||||
@@ -260,6 +269,7 @@ public:
|
||||
[[nodiscard]] pp::foundation::Status validate_extent(Extent2D extent) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status validate_viewport(Viewport viewport, Extent2D target_extent) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status validate_scissor(ScissorRect scissor, Extent2D target_extent) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status validate_render_pass_desc(RenderPassDesc desc) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status validate_blend_factor(BlendFactor factor) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status validate_blend_op(BlendOp op) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status validate_blend_state(BlendState state) noexcept;
|
||||
|
||||
@@ -365,7 +365,7 @@ if(TARGET pano_cli)
|
||||
COMMAND pano_cli record-render --width 32 --height 16)
|
||||
set_tests_properties(pano_cli_record_render_smoke PROPERTIES
|
||||
LABELS "renderer;integration;desktop-fast"
|
||||
PASS_REGULAR_EXPRESSION "\"backend\":\"recording\".*\"width\":32.*\"height\":16.*\"createdResources\":6.*\"commands\":17.*\"drawCommands\":1.*\"drawVertices\":3.*\"drawIndices\":3.*\"scissorCommands\":1.*\"blendCommands\":1.*\"depthCommands\":1.*\"uniformCommands\":1.*\"uniformBytes\":64.*\"bindTextureCommands\":1.*\"bindSamplerCommands\":1.*\"boundTextureBytes\":2048.*\"uploadCommands\":1.*\"uploadBytes\":4.*\"readbackCommands\":1.*\"readbackBytes\":2048.*\"captureCommands\":1.*\"captureBytes\":2048.*\"blitCommands\":1.*\"blitSourceBytes\":2048.*\"blitDestinationBytes\":2048")
|
||||
PASS_REGULAR_EXPRESSION "\"backend\":\"recording\".*\"width\":32.*\"height\":16.*\"createdResources\":6.*\"commands\":17.*\"renderPasses\":1.*\"depthClears\":1.*\"stencilClears\":0.*\"drawCommands\":1.*\"drawVertices\":3.*\"drawIndices\":3.*\"scissorCommands\":1.*\"blendCommands\":1.*\"depthCommands\":1.*\"uniformCommands\":1.*\"uniformBytes\":64.*\"bindTextureCommands\":1.*\"bindSamplerCommands\":1.*\"boundTextureBytes\":2048.*\"uploadCommands\":1.*\"uploadBytes\":4.*\"readbackCommands\":1.*\"readbackBytes\":2048.*\"captureCommands\":1.*\"captureBytes\":2048.*\"blitCommands\":1.*\"blitSourceBytes\":2048.*\"blitDestinationBytes\":2048")
|
||||
|
||||
add_test(NAME pano_cli_record_render_rejects_oversized_target
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <new>
|
||||
#include <string_view>
|
||||
@@ -40,6 +41,7 @@ using pp::renderer::RecordingRenderDevice;
|
||||
using pp::renderer::RecordingRenderTarget;
|
||||
using pp::renderer::RecordingShaderProgram;
|
||||
using pp::renderer::RecordingTexture2D;
|
||||
using pp::renderer::RenderPassDesc;
|
||||
using pp::renderer::SamplerAddressMode;
|
||||
using pp::renderer::sampler_address_mode_name;
|
||||
using pp::renderer::SamplerDesc;
|
||||
@@ -72,6 +74,7 @@ using pp::renderer::validate_compare_op;
|
||||
using pp::renderer::validate_depth_state;
|
||||
using pp::renderer::validate_mesh_desc;
|
||||
using pp::renderer::validate_readback_region;
|
||||
using pp::renderer::validate_render_pass_desc;
|
||||
using pp::renderer::validate_sampler_address_mode;
|
||||
using pp::renderer::validate_sampler_desc;
|
||||
using pp::renderer::validate_sampler_filter;
|
||||
@@ -192,9 +195,14 @@ class FakeCommandContext final : public ICommandContext {
|
||||
public:
|
||||
[[nodiscard]] pp::foundation::Status begin_render_pass(
|
||||
IRenderTarget& target,
|
||||
ClearColor) noexcept override
|
||||
RenderPassDesc desc) noexcept override
|
||||
{
|
||||
const auto render_pass_status = validate_render_pass_desc(desc);
|
||||
if (!render_pass_status.ok()) {
|
||||
return render_pass_status;
|
||||
}
|
||||
in_render_pass = true;
|
||||
last_render_pass_desc = desc;
|
||||
return validate_extent(target.color_desc().extent);
|
||||
}
|
||||
|
||||
@@ -405,6 +413,7 @@ public:
|
||||
}
|
||||
|
||||
bool in_render_pass = false;
|
||||
RenderPassDesc last_render_pass_desc {};
|
||||
const char* shader_name = nullptr;
|
||||
const char* last_uniform_name = nullptr;
|
||||
std::size_t last_uniform_bytes = 0;
|
||||
@@ -801,6 +810,50 @@ void validates_viewports_and_mesh_descriptors(pp::tests::Harness& h)
|
||||
PP_EXPECT(h, invalid_slot.code == StatusCode::out_of_range);
|
||||
}
|
||||
|
||||
void validates_render_pass_descriptors(pp::tests::Harness& h)
|
||||
{
|
||||
const auto valid = validate_render_pass_desc(RenderPassDesc {
|
||||
.clear_color = ClearColor { .r = 0.1F, .g = 0.2F, .b = 0.3F, .a = 1.0F },
|
||||
.clear_depth_enabled = true,
|
||||
.clear_depth = 0.5F,
|
||||
.clear_stencil_enabled = true,
|
||||
.clear_stencil = 7,
|
||||
});
|
||||
const auto no_clear = validate_render_pass_desc(RenderPassDesc {
|
||||
.clear_color_enabled = false,
|
||||
.clear_color = ClearColor {},
|
||||
.clear_depth_enabled = false,
|
||||
.clear_stencil_enabled = false,
|
||||
});
|
||||
const auto bad_color = validate_render_pass_desc(RenderPassDesc {
|
||||
.clear_color = ClearColor {
|
||||
.r = std::numeric_limits<float>::infinity(),
|
||||
.g = 0.0F,
|
||||
.b = 0.0F,
|
||||
.a = 1.0F,
|
||||
},
|
||||
});
|
||||
const auto nan_depth = validate_render_pass_desc(RenderPassDesc {
|
||||
.clear_color = ClearColor {},
|
||||
.clear_depth_enabled = true,
|
||||
.clear_depth = std::numeric_limits<float>::quiet_NaN(),
|
||||
});
|
||||
const auto out_of_range_depth = validate_render_pass_desc(RenderPassDesc {
|
||||
.clear_color = ClearColor {},
|
||||
.clear_depth_enabled = true,
|
||||
.clear_depth = 1.5F,
|
||||
});
|
||||
|
||||
PP_EXPECT(h, valid.ok());
|
||||
PP_EXPECT(h, no_clear.ok());
|
||||
PP_EXPECT(h, !bad_color.ok());
|
||||
PP_EXPECT(h, bad_color.code == StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !nan_depth.ok());
|
||||
PP_EXPECT(h, nan_depth.code == StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !out_of_range_depth.ok());
|
||||
PP_EXPECT(h, out_of_range_depth.code == StatusCode::out_of_range);
|
||||
}
|
||||
|
||||
void validates_shader_program_descriptors(pp::tests::Harness& h)
|
||||
{
|
||||
constexpr char vertex_source[] = "#version 330 core\nvoid main(){}";
|
||||
@@ -951,7 +1004,12 @@ void renderer_interfaces_support_backend_neutral_dispatch(pp::tests::Harness& h)
|
||||
PP_EXPECT(h, device.trace_recorder.last_name == std::string_view("begin"));
|
||||
|
||||
auto& context = device.immediate_context();
|
||||
PP_EXPECT(h, context.begin_render_pass(target, ClearColor { .r = 0.1F, .g = 0.2F, .b = 0.3F, .a = 1.0F }).ok());
|
||||
PP_EXPECT(h, context.begin_render_pass(target, RenderPassDesc {
|
||||
.clear_color = ClearColor { .r = 0.1F, .g = 0.2F, .b = 0.3F, .a = 1.0F },
|
||||
.clear_depth_enabled = true,
|
||||
.clear_depth = 0.75F,
|
||||
})
|
||||
.ok());
|
||||
PP_EXPECT(h, context.set_viewport(Viewport { .x = 0, .y = 0, .width = 64, .height = 32 }).ok());
|
||||
PP_EXPECT(h, context.set_scissor(ScissorRect { .enabled = true, .x = 4, .y = 5, .width = 16, .height = 8 }).ok());
|
||||
PP_EXPECT(h, context.set_blend_state(BlendState {
|
||||
@@ -1007,6 +1065,9 @@ void renderer_interfaces_support_backend_neutral_dispatch(pp::tests::Harness& h)
|
||||
PP_EXPECT(h, device.context.last_blend_state.enabled);
|
||||
PP_EXPECT(h, device.context.last_blend_state.source_color == BlendFactor::source_alpha);
|
||||
PP_EXPECT(h, device.context.last_blend_state.destination_color == BlendFactor::one_minus_source_alpha);
|
||||
PP_EXPECT(h, device.context.last_render_pass_desc.clear_color.a == 1.0F);
|
||||
PP_EXPECT(h, device.context.last_render_pass_desc.clear_depth_enabled);
|
||||
PP_EXPECT(h, device.context.last_render_pass_desc.clear_depth == 0.75F);
|
||||
PP_EXPECT(h, device.context.last_depth_state.test_enabled);
|
||||
PP_EXPECT(h, device.context.last_depth_state.write_enabled);
|
||||
PP_EXPECT(h, device.context.last_depth_state.compare == CompareOp::less_or_equal);
|
||||
@@ -1109,7 +1170,7 @@ void recording_renderer_records_shader_uniform_writes(pp::tests::Harness& h)
|
||||
PP_EXPECT(h, !before_begin.ok());
|
||||
PP_EXPECT(h, before_begin.code == StatusCode::invalid_argument);
|
||||
|
||||
PP_EXPECT(h, context.begin_render_pass(target, ClearColor {}).ok());
|
||||
PP_EXPECT(h, context.begin_render_pass(target, RenderPassDesc {}).ok());
|
||||
const auto before_shader = context.set_shader_uniform("mvp", uniform_bytes);
|
||||
PP_EXPECT(h, !before_shader.ok());
|
||||
PP_EXPECT(h, before_shader.code == StatusCode::invalid_argument);
|
||||
@@ -1163,7 +1224,14 @@ void recording_renderer_records_valid_command_sequences(pp::tests::Harness& h)
|
||||
device.trace()->marker("renderer", "frame");
|
||||
|
||||
auto& context = device.immediate_context();
|
||||
PP_EXPECT(h, context.begin_render_pass(target, ClearColor { .r = 0.2F, .g = 0.3F, .b = 0.4F, .a = 1.0F }).ok());
|
||||
PP_EXPECT(h, context.begin_render_pass(target, RenderPassDesc {
|
||||
.clear_color = ClearColor { .r = 0.2F, .g = 0.3F, .b = 0.4F, .a = 1.0F },
|
||||
.clear_depth_enabled = true,
|
||||
.clear_depth = 1.0F,
|
||||
.clear_stencil_enabled = true,
|
||||
.clear_stencil = 7,
|
||||
})
|
||||
.ok());
|
||||
PP_EXPECT(h, context.set_viewport(Viewport { .x = 0, .y = 0, .width = 64, .height = 32 }).ok());
|
||||
PP_EXPECT(h, context.set_scissor(ScissorRect { .enabled = true, .x = 4, .y = 6, .width = 16, .height = 8 }).ok());
|
||||
PP_EXPECT(h, context.set_blend_state(BlendState {
|
||||
@@ -1201,7 +1269,12 @@ void recording_renderer_records_valid_command_sequences(pp::tests::Harness& h)
|
||||
PP_EXPECT(h, commands[0].name == std::string_view("frame"));
|
||||
PP_EXPECT(h, commands[1].kind == RecordedRenderCommandKind::begin_render_pass);
|
||||
PP_EXPECT(h, commands[1].target_desc.extent.width == 64U);
|
||||
PP_EXPECT(h, commands[1].clear_color_enabled);
|
||||
PP_EXPECT(h, commands[1].clear_color.a == 1.0F);
|
||||
PP_EXPECT(h, commands[1].clear_depth_enabled);
|
||||
PP_EXPECT(h, commands[1].clear_depth == 1.0F);
|
||||
PP_EXPECT(h, commands[1].clear_stencil_enabled);
|
||||
PP_EXPECT(h, commands[1].clear_stencil == 7U);
|
||||
PP_EXPECT(h, commands[2].kind == RecordedRenderCommandKind::set_viewport);
|
||||
PP_EXPECT(h, commands[2].viewport.height == 32U);
|
||||
PP_EXPECT(h, commands[3].kind == RecordedRenderCommandKind::set_scissor);
|
||||
@@ -1350,12 +1423,21 @@ void recording_renderer_rejects_invalid_command_order_and_targets(pp::tests::Har
|
||||
PP_EXPECT(h, !sampler_before_begin.ok());
|
||||
PP_EXPECT(h, sampler_before_begin.code == StatusCode::invalid_argument);
|
||||
|
||||
const auto invalid_target = context.begin_render_pass(non_render_target, ClearColor {});
|
||||
const auto invalid_target = context.begin_render_pass(non_render_target, RenderPassDesc {});
|
||||
PP_EXPECT(h, !invalid_target.ok());
|
||||
PP_EXPECT(h, invalid_target.code == StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, device.commands().empty());
|
||||
|
||||
PP_EXPECT(h, context.begin_render_pass(target, ClearColor {}).ok());
|
||||
const auto invalid_clear_depth = context.begin_render_pass(target, RenderPassDesc {
|
||||
.clear_color = ClearColor {},
|
||||
.clear_depth_enabled = true,
|
||||
.clear_depth = -0.25F,
|
||||
});
|
||||
PP_EXPECT(h, !invalid_clear_depth.ok());
|
||||
PP_EXPECT(h, invalid_clear_depth.code == StatusCode::out_of_range);
|
||||
PP_EXPECT(h, device.commands().empty());
|
||||
|
||||
PP_EXPECT(h, context.begin_render_pass(target, RenderPassDesc {}).ok());
|
||||
const auto upload_during_render_pass = context.upload_texture(
|
||||
texture,
|
||||
ReadbackRegion { .x = 0, .y = 0, .width = 1, .height = 1 },
|
||||
@@ -1383,7 +1465,7 @@ void recording_renderer_rejects_invalid_command_order_and_targets(pp::tests::Har
|
||||
PP_EXPECT(h, !blit_during_render_pass.ok());
|
||||
PP_EXPECT(h, blit_during_render_pass.code == StatusCode::invalid_argument);
|
||||
|
||||
const auto nested_begin = context.begin_render_pass(target, ClearColor {});
|
||||
const auto nested_begin = context.begin_render_pass(target, RenderPassDesc {});
|
||||
PP_EXPECT(h, !nested_begin.ok());
|
||||
PP_EXPECT(h, nested_begin.code == StatusCode::invalid_argument);
|
||||
|
||||
@@ -1577,6 +1659,7 @@ int main()
|
||||
harness.run("validates_depth_contract", validates_depth_contract);
|
||||
harness.run("validates_sampler_contract", validates_sampler_contract);
|
||||
harness.run("validates_viewports_and_mesh_descriptors", validates_viewports_and_mesh_descriptors);
|
||||
harness.run("validates_render_pass_descriptors", validates_render_pass_descriptors);
|
||||
harness.run("validates_shader_program_descriptors", validates_shader_program_descriptors);
|
||||
harness.run("validates_shader_uniform_writes", validates_shader_uniform_writes);
|
||||
harness.run("validates_panopainter_shader_catalog", validates_panopainter_shader_catalog);
|
||||
|
||||
@@ -2297,7 +2297,11 @@ int record_render(int argc, char** argv)
|
||||
|
||||
const auto begin_status = context.begin_render_pass(
|
||||
*target.value(),
|
||||
pp::renderer::ClearColor { .r = 0.0F, .g = 0.0F, .b = 0.0F, .a = 1.0F });
|
||||
pp::renderer::RenderPassDesc {
|
||||
.clear_color = pp::renderer::ClearColor { .r = 0.0F, .g = 0.0F, .b = 0.0F, .a = 1.0F },
|
||||
.clear_depth_enabled = true,
|
||||
.clear_depth = 1.0F,
|
||||
});
|
||||
if (!begin_status.ok()) {
|
||||
print_error("record-render", begin_status.message);
|
||||
return 2;
|
||||
@@ -2435,6 +2439,9 @@ int record_render(int argc, char** argv)
|
||||
std::size_t capture_commands = 0;
|
||||
std::size_t blit_commands = 0;
|
||||
std::size_t trace_markers = 0;
|
||||
std::size_t render_passes = 0;
|
||||
std::size_t depth_clears = 0;
|
||||
std::size_t stencil_clears = 0;
|
||||
std::uint64_t draw_vertices = 0;
|
||||
std::uint64_t draw_indices = 0;
|
||||
std::uint64_t uniform_bytes = 0;
|
||||
@@ -2446,7 +2453,15 @@ int record_render(int argc, char** argv)
|
||||
std::uint64_t blit_destination_bytes = 0;
|
||||
const auto commands = device.commands();
|
||||
for (const auto& command : commands) {
|
||||
if (command.kind == pp::renderer::RecordedRenderCommandKind::draw) {
|
||||
if (command.kind == pp::renderer::RecordedRenderCommandKind::begin_render_pass) {
|
||||
++render_passes;
|
||||
if (command.clear_depth_enabled) {
|
||||
++depth_clears;
|
||||
}
|
||||
if (command.clear_stencil_enabled) {
|
||||
++stencil_clears;
|
||||
}
|
||||
} else if (command.kind == pp::renderer::RecordedRenderCommandKind::draw) {
|
||||
++draw_commands;
|
||||
draw_vertices += command.mesh_desc.vertex_count;
|
||||
draw_indices += command.mesh_desc.index_count;
|
||||
@@ -2492,6 +2507,9 @@ int record_render(int argc, char** argv)
|
||||
<< ",\"format\":\"rgba8\"}"
|
||||
<< ",\"createdResources\":" << created_resources
|
||||
<< ",\"commands\":" << commands.size()
|
||||
<< ",\"renderPasses\":" << render_passes
|
||||
<< ",\"depthClears\":" << depth_clears
|
||||
<< ",\"stencilClears\":" << stencil_clears
|
||||
<< ",\"drawCommands\":" << draw_commands
|
||||
<< ",\"drawVertices\":" << draw_vertices
|
||||
<< ",\"drawIndices\":" << draw_indices
|
||||
|
||||
Reference in New Issue
Block a user