Validate shader resource label bounds
This commit is contained in:
@@ -301,7 +301,7 @@ Known local toolchain state:
|
|||||||
explicit texture usage flags, command order,
|
explicit texture usage flags, command order,
|
||||||
render-pass color/depth/stencil clear intent, scissor state, depth state,
|
render-pass color/depth/stencil clear intent, scissor state, depth state,
|
||||||
blend state, texture-slot binding, sampler-state binding, texture-upload byte
|
blend state, texture-slot binding, sampler-state binding, texture-upload byte
|
||||||
counts, texture mip-level counts, resource debug labels, mipmap-generation commands,
|
counts, texture mip-level counts, texture/mesh/shader resource debug labels, mipmap-generation commands,
|
||||||
texture-state transitions, shader-uniform writes, explicit draw descriptor ranges, texture-copy regions,
|
texture-state transitions, shader-uniform writes, explicit draw descriptor ranges, texture-copy regions,
|
||||||
readback bounds, frame-capture sources, destination buffer sizes, and
|
readback bounds, frame-capture sources, destination buffer sizes, and
|
||||||
render-target blit regions, records
|
render-target blit regions, records
|
||||||
|
|||||||
@@ -431,6 +431,7 @@ mipmap-generation command validation, texture-state transition validation, frame
|
|||||||
frame-capture command validation, render-target blit validation, texture-slot
|
frame-capture command validation, render-target blit validation, texture-slot
|
||||||
binding validation, blend-state validation, scissor-state validation,
|
binding validation, blend-state validation, scissor-state validation,
|
||||||
depth-state validation, trace marker/scope validation, sampler-state validation,
|
depth-state validation, trace marker/scope validation, sampler-state validation,
|
||||||
|
texture/mesh/shader resource-label validation,
|
||||||
recording-device reuse/reset validation, and the canonical PanoPainter shader
|
recording-device reuse/reset validation, and the canonical PanoPainter shader
|
||||||
catalog now consumed by the legacy OpenGL app initialization path.
|
catalog now consumed by the legacy OpenGL app initialization path.
|
||||||
`pp_renderer_gl` now exists as the first OpenGL backend library and owns pure
|
`pp_renderer_gl` now exists as the first OpenGL backend library and owns pure
|
||||||
|
|||||||
@@ -503,8 +503,9 @@ pp::foundation::Status validate_texture_slot(std::uint32_t slot) noexcept
|
|||||||
|
|
||||||
pp::foundation::Status validate_shader_program_desc(ShaderProgramDesc desc) noexcept
|
pp::foundation::Status validate_shader_program_desc(ShaderProgramDesc desc) noexcept
|
||||||
{
|
{
|
||||||
if (desc.debug_name == nullptr) {
|
const auto label_status = validate_resource_label(desc.debug_name);
|
||||||
return pp::foundation::Status::invalid_argument("shader debug name must not be null");
|
if (!label_status.ok()) {
|
||||||
|
return label_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto vertex_status = validate_shader_stage_source(
|
const auto vertex_status = validate_shader_stage_source(
|
||||||
|
|||||||
@@ -801,6 +801,13 @@ void validates_resource_labels(pp::tests::Harness& h)
|
|||||||
.debug_name = "brush-quad",
|
.debug_name = "brush-quad",
|
||||||
})
|
})
|
||||||
.ok());
|
.ok());
|
||||||
|
static constexpr char shader_source[] = "void main() {}";
|
||||||
|
PP_EXPECT(h, validate_shader_program_desc(ShaderProgramDesc {
|
||||||
|
.debug_name = "brush-shader",
|
||||||
|
.vertex = ShaderStageSource { .source = shader_source, .source_size = sizeof(shader_source) - 1U },
|
||||||
|
.fragment = ShaderStageSource { .source = shader_source, .source_size = sizeof(shader_source) - 1U },
|
||||||
|
})
|
||||||
|
.ok());
|
||||||
|
|
||||||
const auto null_label = validate_resource_label(nullptr);
|
const auto null_label = validate_resource_label(nullptr);
|
||||||
const auto oversized = validate_resource_label(oversized_label.data());
|
const auto oversized = validate_resource_label(oversized_label.data());
|
||||||
@@ -814,6 +821,16 @@ void validates_resource_labels(pp::tests::Harness& h)
|
|||||||
.topology = PrimitiveTopology::triangles,
|
.topology = PrimitiveTopology::triangles,
|
||||||
.debug_name = oversized_label.data(),
|
.debug_name = oversized_label.data(),
|
||||||
});
|
});
|
||||||
|
const auto null_shader_label = validate_shader_program_desc(ShaderProgramDesc {
|
||||||
|
.debug_name = nullptr,
|
||||||
|
.vertex = ShaderStageSource { .source = shader_source, .source_size = sizeof(shader_source) - 1U },
|
||||||
|
.fragment = ShaderStageSource { .source = shader_source, .source_size = sizeof(shader_source) - 1U },
|
||||||
|
});
|
||||||
|
const auto oversized_shader_label = validate_shader_program_desc(ShaderProgramDesc {
|
||||||
|
.debug_name = oversized_label.data(),
|
||||||
|
.vertex = ShaderStageSource { .source = shader_source, .source_size = sizeof(shader_source) - 1U },
|
||||||
|
.fragment = ShaderStageSource { .source = shader_source, .source_size = sizeof(shader_source) - 1U },
|
||||||
|
});
|
||||||
|
|
||||||
PP_EXPECT(h, !null_label.ok());
|
PP_EXPECT(h, !null_label.ok());
|
||||||
PP_EXPECT(h, null_label.code == StatusCode::invalid_argument);
|
PP_EXPECT(h, null_label.code == StatusCode::invalid_argument);
|
||||||
@@ -823,6 +840,10 @@ void validates_resource_labels(pp::tests::Harness& h)
|
|||||||
PP_EXPECT(h, null_texture_label.code == StatusCode::invalid_argument);
|
PP_EXPECT(h, null_texture_label.code == StatusCode::invalid_argument);
|
||||||
PP_EXPECT(h, !oversized_mesh_label.ok());
|
PP_EXPECT(h, !oversized_mesh_label.ok());
|
||||||
PP_EXPECT(h, oversized_mesh_label.code == StatusCode::out_of_range);
|
PP_EXPECT(h, oversized_mesh_label.code == StatusCode::out_of_range);
|
||||||
|
PP_EXPECT(h, !null_shader_label.ok());
|
||||||
|
PP_EXPECT(h, null_shader_label.code == StatusCode::invalid_argument);
|
||||||
|
PP_EXPECT(h, !oversized_shader_label.ok());
|
||||||
|
PP_EXPECT(h, oversized_shader_label.code == StatusCode::out_of_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
void validates_mipmap_generation_contract(pp::tests::Harness& h)
|
void validates_mipmap_generation_contract(pp::tests::Harness& h)
|
||||||
@@ -1686,6 +1707,9 @@ void renderer_interfaces_support_backend_neutral_dispatch(pp::tests::Harness& h)
|
|||||||
void render_devices_create_validated_resources(pp::tests::Harness& h)
|
void render_devices_create_validated_resources(pp::tests::Harness& h)
|
||||||
{
|
{
|
||||||
static constexpr char shader_source[] = "void main() {}";
|
static constexpr char shader_source[] = "void main() {}";
|
||||||
|
std::array<char, max_resource_label_bytes + 2U> oversized_label {};
|
||||||
|
oversized_label.fill('s');
|
||||||
|
oversized_label[max_resource_label_bytes + 1U] = '\0';
|
||||||
|
|
||||||
RecordingRenderDevice device;
|
RecordingRenderDevice device;
|
||||||
const auto texture = device.create_texture(TextureDesc {
|
const auto texture = device.create_texture(TextureDesc {
|
||||||
@@ -1750,6 +1774,11 @@ void render_devices_create_validated_resources(pp::tests::Harness& h)
|
|||||||
.vertex = ShaderStageSource {},
|
.vertex = ShaderStageSource {},
|
||||||
.fragment = ShaderStageSource {},
|
.fragment = ShaderStageSource {},
|
||||||
});
|
});
|
||||||
|
const auto oversized_shader_label = device.create_shader_program(ShaderProgramDesc {
|
||||||
|
.debug_name = oversized_label.data(),
|
||||||
|
.vertex = ShaderStageSource { .source = shader_source, .source_size = sizeof(shader_source) - 1U },
|
||||||
|
.fragment = ShaderStageSource { .source = shader_source, .source_size = sizeof(shader_source) - 1U },
|
||||||
|
});
|
||||||
const auto bad_mesh = device.create_mesh(MeshDesc {});
|
const auto bad_mesh = device.create_mesh(MeshDesc {});
|
||||||
const auto bad_readback = device.create_readback_buffer(0);
|
const auto bad_readback = device.create_readback_buffer(0);
|
||||||
|
|
||||||
@@ -1759,6 +1788,8 @@ void render_devices_create_validated_resources(pp::tests::Harness& h)
|
|||||||
PP_EXPECT(h, bad_target.status().code == StatusCode::invalid_argument);
|
PP_EXPECT(h, bad_target.status().code == StatusCode::invalid_argument);
|
||||||
PP_EXPECT(h, !bad_shader.ok());
|
PP_EXPECT(h, !bad_shader.ok());
|
||||||
PP_EXPECT(h, bad_shader.status().code == StatusCode::invalid_argument);
|
PP_EXPECT(h, bad_shader.status().code == StatusCode::invalid_argument);
|
||||||
|
PP_EXPECT(h, !oversized_shader_label.ok());
|
||||||
|
PP_EXPECT(h, oversized_shader_label.status().code == StatusCode::out_of_range);
|
||||||
PP_EXPECT(h, !bad_mesh.ok());
|
PP_EXPECT(h, !bad_mesh.ok());
|
||||||
PP_EXPECT(h, bad_mesh.status().code == StatusCode::invalid_argument);
|
PP_EXPECT(h, bad_mesh.status().code == StatusCode::invalid_argument);
|
||||||
PP_EXPECT(h, !bad_readback.ok());
|
PP_EXPECT(h, !bad_readback.ok());
|
||||||
|
|||||||
Reference in New Issue
Block a user