mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-01-10 16:52:16 +00:00
rhi: Make some stencil state dynamic
The reference, compare mask and write mask for each face direction in the stencil test is now dynamic pipeline state and are implicitly set to default values when a pipeline is bound. This is implementable using Vulkan dynamic pipeline state bits and so there is no reason not to provide it. In the OpenGL implementation of RHI, this requires tracking some stencil state internally in the graphics context because the stencil state functions require multiple inputs that do not cleanly map to the Vulkan equivalents.
This commit is contained in:
parent
65511d6fdc
commit
20002f83c4
3 changed files with 106 additions and 9 deletions
|
|
@ -1414,26 +1414,32 @@ void GlCoreRhi::bind_pipeline(Handle<GraphicsContext> ctx, Handle<Pipeline> pipe
|
|||
if (desc.depth_stencil_state->stencil_test)
|
||||
{
|
||||
gl_->Enable(GL_STENCIL_TEST);
|
||||
stencil_front_reference_ = 0;
|
||||
stencil_back_reference_ = 0;
|
||||
stencil_front_compare_mask_ = 0xFF;
|
||||
stencil_back_compare_mask_ = 0xFF;
|
||||
stencil_front_write_mask_ = 0xFF;
|
||||
stencil_back_write_mask_ = 0xFF;
|
||||
GL_ASSERT;
|
||||
|
||||
gl_->StencilFuncSeparate(
|
||||
GL_FRONT,
|
||||
map_compare_func(desc.depth_stencil_state->front.stencil_compare),
|
||||
desc.depth_stencil_state->front.reference,
|
||||
desc.depth_stencil_state->front.compare_mask
|
||||
stencil_front_reference_,
|
||||
stencil_front_compare_mask_
|
||||
);
|
||||
GL_ASSERT;
|
||||
gl_->StencilFuncSeparate(
|
||||
GL_BACK,
|
||||
map_compare_func(desc.depth_stencil_state->back.stencil_compare),
|
||||
desc.depth_stencil_state->back.reference,
|
||||
desc.depth_stencil_state->back.compare_mask
|
||||
stencil_back_reference_,
|
||||
stencil_back_compare_mask_
|
||||
);
|
||||
GL_ASSERT;
|
||||
|
||||
gl_->StencilMaskSeparate(GL_FRONT, desc.depth_stencil_state->front.write_mask);
|
||||
gl_->StencilMaskSeparate(GL_FRONT, stencil_front_write_mask_);
|
||||
GL_ASSERT;
|
||||
gl_->StencilMaskSeparate(GL_BACK, desc.depth_stencil_state->back.write_mask);
|
||||
gl_->StencilMaskSeparate(GL_BACK, stencil_back_write_mask_);
|
||||
GL_ASSERT;
|
||||
}
|
||||
else
|
||||
|
|
@ -1732,6 +1738,87 @@ void GlCoreRhi::read_pixels(Handle<GraphicsContext> ctx, const Rect& rect, Pixel
|
|||
gl_->ReadPixels(rect.x, rect.y, rect.w, rect.h, layout, type, out.data());
|
||||
}
|
||||
|
||||
void GlCoreRhi::set_stencil_reference(Handle<GraphicsContext> ctx, CullMode face, uint8_t reference)
|
||||
{
|
||||
SRB2_ASSERT(face != CullMode::kNone);
|
||||
SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation());
|
||||
SRB2_ASSERT(current_render_pass_.has_value());
|
||||
SRB2_ASSERT(current_pipeline_.has_value());
|
||||
|
||||
auto& pl = pipeline_slab_[*current_pipeline_];
|
||||
|
||||
if (face == CullMode::kFront)
|
||||
{
|
||||
stencil_front_reference_ = reference;
|
||||
gl_->StencilFuncSeparate(
|
||||
GL_FRONT,
|
||||
map_compare_func(pl.desc.depth_stencil_state->front.stencil_compare),
|
||||
stencil_front_reference_,
|
||||
stencil_front_compare_mask_
|
||||
);
|
||||
}
|
||||
else if (face == CullMode::kBack)
|
||||
{
|
||||
stencil_back_reference_ = reference;
|
||||
gl_->StencilFuncSeparate(
|
||||
GL_BACK,
|
||||
map_compare_func(pl.desc.depth_stencil_state->back.stencil_compare),
|
||||
stencil_back_reference_,
|
||||
stencil_back_compare_mask_
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void GlCoreRhi::set_stencil_compare_mask(Handle<GraphicsContext> ctx, CullMode face, uint8_t compare_mask)
|
||||
{
|
||||
SRB2_ASSERT(face != CullMode::kNone);
|
||||
SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation());
|
||||
SRB2_ASSERT(current_render_pass_.has_value());
|
||||
SRB2_ASSERT(current_pipeline_.has_value());
|
||||
|
||||
auto& pl = pipeline_slab_[*current_pipeline_];
|
||||
|
||||
if (face == CullMode::kFront)
|
||||
{
|
||||
stencil_front_compare_mask_ = compare_mask;
|
||||
gl_->StencilFuncSeparate(
|
||||
GL_FRONT,
|
||||
map_compare_func(pl.desc.depth_stencil_state->front.stencil_compare),
|
||||
stencil_front_reference_,
|
||||
stencil_front_compare_mask_
|
||||
);
|
||||
}
|
||||
else if (face == CullMode::kBack)
|
||||
{
|
||||
stencil_back_compare_mask_ = compare_mask;
|
||||
gl_->StencilFuncSeparate(
|
||||
GL_BACK,
|
||||
map_compare_func(pl.desc.depth_stencil_state->back.stencil_compare),
|
||||
stencil_back_reference_,
|
||||
stencil_back_compare_mask_
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void GlCoreRhi::set_stencil_write_mask(Handle<GraphicsContext> ctx, CullMode face, uint8_t write_mask)
|
||||
{
|
||||
SRB2_ASSERT(face != CullMode::kNone);
|
||||
SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation());
|
||||
SRB2_ASSERT(current_render_pass_.has_value());
|
||||
SRB2_ASSERT(current_pipeline_.has_value());
|
||||
|
||||
if (face == CullMode::kFront)
|
||||
{
|
||||
stencil_front_write_mask_ = write_mask;
|
||||
gl_->StencilMaskSeparate(GL_FRONT, stencil_front_write_mask_);
|
||||
}
|
||||
else if (face == CullMode::kBack)
|
||||
{
|
||||
stencil_back_write_mask_ = write_mask;
|
||||
gl_->StencilMaskSeparate(GL_BACK, stencil_back_write_mask_);
|
||||
}
|
||||
}
|
||||
|
||||
TextureDetails GlCoreRhi::get_texture_details(Handle<Texture> texture)
|
||||
{
|
||||
SRB2_ASSERT(texture_slab_.is_valid(texture));
|
||||
|
|
|
|||
|
|
@ -164,6 +164,13 @@ class GlCoreRhi final : public Rhi
|
|||
uint32_t index_buffer_offset_ = 0;
|
||||
uint32_t transfer_context_generation_ = 0;
|
||||
|
||||
uint8_t stencil_front_reference_ = 0;
|
||||
uint8_t stencil_front_compare_mask_ = 0xFF;
|
||||
uint8_t stencil_front_write_mask_ = 0xFF;
|
||||
uint8_t stencil_back_reference_ = 0;
|
||||
uint8_t stencil_back_compare_mask_ = 0xFF;
|
||||
uint8_t stencil_back_write_mask_ = 0xFF;
|
||||
|
||||
std::vector<std::function<void()>> disposal_;
|
||||
|
||||
public:
|
||||
|
|
@ -225,6 +232,9 @@ public:
|
|||
virtual void draw_indexed(Handle<GraphicsContext> ctx, uint32_t index_count, uint32_t first_index) override;
|
||||
virtual void
|
||||
read_pixels(Handle<GraphicsContext> ctx, const Rect& rect, PixelFormat format, tcb::span<std::byte> out) override;
|
||||
virtual void set_stencil_reference(Handle<GraphicsContext> ctx, CullMode face, uint8_t reference) override;
|
||||
virtual void set_stencil_compare_mask(Handle<GraphicsContext> ctx, CullMode face, uint8_t mask) override;
|
||||
virtual void set_stencil_write_mask(Handle<GraphicsContext> ctx, CullMode face, uint8_t mask) override;
|
||||
|
||||
virtual void present() override;
|
||||
|
||||
|
|
|
|||
|
|
@ -424,9 +424,6 @@ struct PipelineStencilOpStateDesc
|
|||
StencilOp pass;
|
||||
StencilOp depth_fail;
|
||||
CompareFunc stencil_compare;
|
||||
uint32_t compare_mask;
|
||||
uint32_t write_mask;
|
||||
uint32_t reference;
|
||||
};
|
||||
|
||||
struct PipelineDepthStencilStateDesc
|
||||
|
|
@ -648,6 +645,9 @@ struct Rhi
|
|||
virtual void draw_indexed(Handle<GraphicsContext> ctx, uint32_t index_count, uint32_t first_index) = 0;
|
||||
virtual void
|
||||
read_pixels(Handle<GraphicsContext> ctx, const Rect& rect, PixelFormat format, tcb::span<std::byte> out) = 0;
|
||||
virtual void set_stencil_reference(Handle<GraphicsContext> ctx, CullMode face, uint8_t reference) = 0;
|
||||
virtual void set_stencil_compare_mask(Handle<GraphicsContext> ctx, CullMode face, uint8_t mask) = 0;
|
||||
virtual void set_stencil_write_mask(Handle<GraphicsContext> ctx, CullMode face, uint8_t mask) = 0;
|
||||
|
||||
virtual void present() = 0;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue