Validate OpenGL command pass barriers
This commit is contained in:
@@ -279,12 +279,13 @@ Known local toolchain state:
|
|||||||
uploads, mipmap generation, texture transitions, texture copies, texture
|
uploads, mipmap generation, texture transitions, texture copies, texture
|
||||||
readbacks, frame captures, passthrough commands, trace commands, unsupported
|
readbacks, frame captures, passthrough commands, trace commands, unsupported
|
||||||
commands, and render-pass ordering errors such as state changes outside a
|
commands, and render-pass ordering errors such as state changes outside a
|
||||||
pass, nested passes, and unclosed passes. It also validates executable
|
pass, nested passes, texture I/O or blits inside a pass, and unclosed passes.
|
||||||
command dependencies, including shader-before-uniform and shader-plus-mesh
|
It also validates executable command dependencies, including
|
||||||
before draw within each render pass, and rejects invalid texture/sampler bind
|
shader-before-uniform and shader-plus-mesh before draw within each render
|
||||||
slots in malformed recorded streams. `pano_cli record-render` emits the
|
pass, and rejects invalid texture/sampler bind slots in malformed recorded
|
||||||
OpenGL plan texture/sampler bind counts so automation can assert backend
|
streams. `pano_cli record-render` emits the OpenGL plan texture/sampler bind
|
||||||
interpretation without an OpenGL context.
|
counts so automation can assert backend interpretation without an OpenGL
|
||||||
|
context.
|
||||||
Desktop VR drawing also consumes backend-owned scissor/depth/blend state,
|
Desktop VR drawing also consumes backend-owned scissor/depth/blend state,
|
||||||
depth clear masks, active texture units, and fallback 2D texture unbind
|
depth clear masks, active texture units, and fallback 2D texture unbind
|
||||||
targets while retaining the existing VR SDK/platform bridge shape.
|
targets while retaining the existing VR SDK/platform bridge shape.
|
||||||
|
|||||||
@@ -538,10 +538,10 @@ passes, draws, shader binds, shader uniforms, texture/sampler binds, texture
|
|||||||
uploads, mipmap generation, texture transitions, texture copies, texture
|
uploads, mipmap generation, texture transitions, texture copies, texture
|
||||||
readbacks, frame captures, passthrough commands, trace commands, unsupported
|
readbacks, frame captures, passthrough commands, trace commands, unsupported
|
||||||
commands, and render-pass ordering errors such as state changes outside a pass,
|
commands, and render-pass ordering errors such as state changes outside a pass,
|
||||||
nested passes, and unclosed passes. It also validates executable command
|
nested passes, texture I/O or blits inside a pass, and unclosed passes. It
|
||||||
dependencies, including shader-before-uniform and shader-plus-mesh before draw
|
also validates executable command dependencies, including shader-before-uniform
|
||||||
within each render pass, and rejects invalid texture/sampler bind slots in
|
and shader-plus-mesh before draw within each render pass, and rejects invalid
|
||||||
malformed recorded streams.
|
texture/sampler bind slots in malformed recorded streams.
|
||||||
The existing renderer classes are not yet fully
|
The existing renderer classes are not yet fully
|
||||||
behind the renderer interfaces.
|
behind the renderer interfaces.
|
||||||
|
|
||||||
|
|||||||
@@ -370,21 +370,39 @@ OpenGlCommandPlan plan_recorded_render_commands(
|
|||||||
break;
|
break;
|
||||||
case OpenGlPlannedCommandKind::upload_texture:
|
case OpenGlPlannedCommandKind::upload_texture:
|
||||||
++plan.upload_command_count;
|
++plan.upload_command_count;
|
||||||
|
if (in_render_pass) {
|
||||||
|
record_render_pass_order_error(plan, index);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OpenGlPlannedCommandKind::generate_mipmaps:
|
case OpenGlPlannedCommandKind::generate_mipmaps:
|
||||||
++plan.mipmap_command_count;
|
++plan.mipmap_command_count;
|
||||||
|
if (in_render_pass) {
|
||||||
|
record_render_pass_order_error(plan, index);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OpenGlPlannedCommandKind::transition_texture:
|
case OpenGlPlannedCommandKind::transition_texture:
|
||||||
++plan.transition_command_count;
|
++plan.transition_command_count;
|
||||||
|
if (in_render_pass) {
|
||||||
|
record_render_pass_order_error(plan, index);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OpenGlPlannedCommandKind::copy_texture:
|
case OpenGlPlannedCommandKind::copy_texture:
|
||||||
++plan.copy_command_count;
|
++plan.copy_command_count;
|
||||||
|
if (in_render_pass) {
|
||||||
|
record_render_pass_order_error(plan, index);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OpenGlPlannedCommandKind::read_texture:
|
case OpenGlPlannedCommandKind::read_texture:
|
||||||
++plan.readback_command_count;
|
++plan.readback_command_count;
|
||||||
|
if (in_render_pass) {
|
||||||
|
record_render_pass_order_error(plan, index);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OpenGlPlannedCommandKind::capture_frame:
|
case OpenGlPlannedCommandKind::capture_frame:
|
||||||
++plan.capture_command_count;
|
++plan.capture_command_count;
|
||||||
|
if (in_render_pass) {
|
||||||
|
record_render_pass_order_error(plan, index);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OpenGlPlannedCommandKind::passthrough:
|
case OpenGlPlannedCommandKind::passthrough:
|
||||||
++plan.passthrough_command_count;
|
++plan.passthrough_command_count;
|
||||||
@@ -395,6 +413,11 @@ OpenGlCommandPlan plan_recorded_render_commands(
|
|||||||
case OpenGlPlannedCommandKind::trace:
|
case OpenGlPlannedCommandKind::trace:
|
||||||
++plan.trace_command_count;
|
++plan.trace_command_count;
|
||||||
break;
|
break;
|
||||||
|
case OpenGlPlannedCommandKind::blit_render_target:
|
||||||
|
if (in_render_pass) {
|
||||||
|
record_render_pass_order_error(plan, index);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (planned.requires_render_pass && !in_render_pass) {
|
if (planned.requires_render_pass && !in_render_pass) {
|
||||||
record_render_pass_order_error(plan, index);
|
record_render_pass_order_error(plan, index);
|
||||||
|
|||||||
@@ -476,6 +476,86 @@ void counts_texture_and_sampler_bindings_in_streams(pp::tests::Harness& h)
|
|||||||
PP_EXPECT(h, plan.commands[3].sampler_slot == 2U);
|
PP_EXPECT(h, plan.commands[3].sampler_slot == 2U);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void expect_inside_pass_order_error(
|
||||||
|
pp::tests::Harness& h,
|
||||||
|
pp::renderer::RecordedRenderCommand command,
|
||||||
|
pp::renderer::gl::OpenGlPlannedCommandKind expected_kind)
|
||||||
|
{
|
||||||
|
const std::vector<pp::renderer::RecordedRenderCommand> commands {
|
||||||
|
begin_render_pass_command(),
|
||||||
|
command,
|
||||||
|
command_with_kind(pp::renderer::RecordedRenderCommandKind::end_render_pass),
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto plan = pp::renderer::gl::plan_recorded_render_commands(commands);
|
||||||
|
|
||||||
|
PP_EXPECT(h, !plan.supported);
|
||||||
|
PP_EXPECT(h, plan.unsupported_command_count == 0U);
|
||||||
|
PP_EXPECT(h, plan.render_pass_order_error_count == 1U);
|
||||||
|
PP_EXPECT(h, plan.first_render_pass_order_error == 1U);
|
||||||
|
PP_EXPECT(h, plan.dependency_error_count == 0U);
|
||||||
|
PP_EXPECT(h, plan.commands[1].kind == expected_kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
void flags_texture_io_inside_render_pass(pp::tests::Harness& h)
|
||||||
|
{
|
||||||
|
pp::renderer::RecordedRenderCommand upload_command;
|
||||||
|
upload_command.kind = pp::renderer::RecordedRenderCommandKind::upload_texture;
|
||||||
|
upload_command.texture_desc.format = pp::renderer::TextureFormat::rgba8;
|
||||||
|
|
||||||
|
pp::renderer::RecordedRenderCommand mipmap_command;
|
||||||
|
mipmap_command.kind = pp::renderer::RecordedRenderCommandKind::generate_mipmaps;
|
||||||
|
mipmap_command.texture_desc.format = pp::renderer::TextureFormat::rgba8;
|
||||||
|
|
||||||
|
pp::renderer::RecordedRenderCommand transition_command;
|
||||||
|
transition_command.kind = pp::renderer::RecordedRenderCommandKind::transition_texture;
|
||||||
|
transition_command.texture_desc.format = pp::renderer::TextureFormat::rgba8;
|
||||||
|
transition_command.before_state = pp::renderer::TextureState::upload_destination;
|
||||||
|
transition_command.after_state = pp::renderer::TextureState::shader_read;
|
||||||
|
|
||||||
|
pp::renderer::RecordedRenderCommand copy_command;
|
||||||
|
copy_command.kind = pp::renderer::RecordedRenderCommandKind::copy_texture;
|
||||||
|
copy_command.source_desc.format = pp::renderer::TextureFormat::rgba8;
|
||||||
|
copy_command.destination_desc.format = pp::renderer::TextureFormat::rgba8;
|
||||||
|
|
||||||
|
pp::renderer::RecordedRenderCommand read_command;
|
||||||
|
read_command.kind = pp::renderer::RecordedRenderCommandKind::read_texture;
|
||||||
|
read_command.texture_desc.format = pp::renderer::TextureFormat::rgba8;
|
||||||
|
|
||||||
|
pp::renderer::RecordedRenderCommand capture_command;
|
||||||
|
capture_command.kind = pp::renderer::RecordedRenderCommandKind::capture_frame;
|
||||||
|
capture_command.target_desc.format = pp::renderer::TextureFormat::rgba8;
|
||||||
|
|
||||||
|
expect_inside_pass_order_error(
|
||||||
|
h,
|
||||||
|
upload_command,
|
||||||
|
pp::renderer::gl::OpenGlPlannedCommandKind::upload_texture);
|
||||||
|
expect_inside_pass_order_error(
|
||||||
|
h,
|
||||||
|
mipmap_command,
|
||||||
|
pp::renderer::gl::OpenGlPlannedCommandKind::generate_mipmaps);
|
||||||
|
expect_inside_pass_order_error(
|
||||||
|
h,
|
||||||
|
transition_command,
|
||||||
|
pp::renderer::gl::OpenGlPlannedCommandKind::transition_texture);
|
||||||
|
expect_inside_pass_order_error(
|
||||||
|
h,
|
||||||
|
copy_command,
|
||||||
|
pp::renderer::gl::OpenGlPlannedCommandKind::copy_texture);
|
||||||
|
expect_inside_pass_order_error(
|
||||||
|
h,
|
||||||
|
read_command,
|
||||||
|
pp::renderer::gl::OpenGlPlannedCommandKind::read_texture);
|
||||||
|
expect_inside_pass_order_error(
|
||||||
|
h,
|
||||||
|
capture_command,
|
||||||
|
pp::renderer::gl::OpenGlPlannedCommandKind::capture_frame);
|
||||||
|
expect_inside_pass_order_error(
|
||||||
|
h,
|
||||||
|
blit_command(pp::renderer::BlitFilter::nearest),
|
||||||
|
pp::renderer::gl::OpenGlPlannedCommandKind::blit_render_target);
|
||||||
|
}
|
||||||
|
|
||||||
void flags_broken_render_pass_command_order(pp::tests::Harness& h)
|
void flags_broken_render_pass_command_order(pp::tests::Harness& h)
|
||||||
{
|
{
|
||||||
const std::vector<pp::renderer::RecordedRenderCommand> outside_pass {
|
const std::vector<pp::renderer::RecordedRenderCommand> outside_pass {
|
||||||
@@ -650,6 +730,7 @@ int main()
|
|||||||
harness.run("names_planned_command_kinds", names_planned_command_kinds);
|
harness.run("names_planned_command_kinds", names_planned_command_kinds);
|
||||||
harness.run("plans_valid_recorded_command_streams", plans_valid_recorded_command_streams);
|
harness.run("plans_valid_recorded_command_streams", plans_valid_recorded_command_streams);
|
||||||
harness.run("counts_texture_and_sampler_bindings_in_streams", counts_texture_and_sampler_bindings_in_streams);
|
harness.run("counts_texture_and_sampler_bindings_in_streams", counts_texture_and_sampler_bindings_in_streams);
|
||||||
|
harness.run("flags_texture_io_inside_render_pass", flags_texture_io_inside_render_pass);
|
||||||
harness.run("flags_broken_render_pass_command_order", flags_broken_render_pass_command_order);
|
harness.run("flags_broken_render_pass_command_order", flags_broken_render_pass_command_order);
|
||||||
harness.run("flags_missing_render_dependencies", flags_missing_render_dependencies);
|
harness.run("flags_missing_render_dependencies", flags_missing_render_dependencies);
|
||||||
harness.run("tracks_unsupported_commands_in_streams", tracks_unsupported_commands_in_streams);
|
harness.run("tracks_unsupported_commands_in_streams", tracks_unsupported_commands_in_streams);
|
||||||
|
|||||||
Reference in New Issue
Block a user