mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'rhi-depth-stencil' into 'master'
RHI Depth Stencil and Texture Wrap Mode See merge request KartKrew/Kart!1095
This commit is contained in:
commit
000c505444
11 changed files with 409 additions and 195 deletions
|
|
@ -47,7 +47,7 @@ static const PipelineDesc kPalettedPipelineDescription = {
|
||||||
// 256x1 palette texture
|
// 256x1 palette texture
|
||||||
SamplerName::kSampler1}},
|
SamplerName::kSampler1}},
|
||||||
std::nullopt,
|
std::nullopt,
|
||||||
{PixelFormat::kRGBA8, std::nullopt, {true, true, true, true}},
|
{std::nullopt, {true, true, true, true}},
|
||||||
PrimitiveType::kTriangles,
|
PrimitiveType::kTriangles,
|
||||||
CullMode::kNone,
|
CullMode::kNone,
|
||||||
FaceWinding::kCounterClockwise,
|
FaceWinding::kCounterClockwise,
|
||||||
|
|
@ -61,7 +61,7 @@ static const PipelineDesc kUnshadedPipelineDescription = {
|
||||||
{{// RGB/A texture
|
{{// RGB/A texture
|
||||||
SamplerName::kSampler0}},
|
SamplerName::kSampler0}},
|
||||||
std::nullopt,
|
std::nullopt,
|
||||||
{PixelFormat::kRGBA8, std::nullopt, {true, true, true, true}},
|
{std::nullopt, {true, true, true, true}},
|
||||||
PrimitiveType::kTriangles,
|
PrimitiveType::kTriangles,
|
||||||
CullMode::kNone,
|
CullMode::kNone,
|
||||||
FaceWinding::kCounterClockwise,
|
FaceWinding::kCounterClockwise,
|
||||||
|
|
@ -111,10 +111,15 @@ void BlitRectPass::prepass(Rhi& rhi)
|
||||||
if (!render_pass_)
|
if (!render_pass_)
|
||||||
{
|
{
|
||||||
render_pass_ = rhi.create_render_pass(
|
render_pass_ = rhi.create_render_pass(
|
||||||
{std::nullopt,
|
{
|
||||||
PixelFormat::kRGBA8,
|
false,
|
||||||
output_clear_ ? AttachmentLoadOp::kClear : AttachmentLoadOp::kLoad,
|
output_clear_ ? AttachmentLoadOp::kClear : AttachmentLoadOp::kLoad,
|
||||||
AttachmentStoreOp::kStore}
|
AttachmentStoreOp::kStore,
|
||||||
|
AttachmentLoadOp::kDontCare,
|
||||||
|
AttachmentStoreOp::kDontCare,
|
||||||
|
AttachmentLoadOp::kDontCare,
|
||||||
|
AttachmentStoreOp::kDontCare
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -160,7 +165,7 @@ void BlitRectPass::transfer(Rhi& rhi, Handle<TransferContext> ctx)
|
||||||
glm::mat3(
|
glm::mat3(
|
||||||
glm::vec3(1.f, 0.f, 0.f),
|
glm::vec3(1.f, 0.f, 0.f),
|
||||||
glm::vec3(0.f, output_flip_ ? -1.f : 1.f, 0.f),
|
glm::vec3(0.f, output_flip_ ? -1.f : 1.f, 0.f),
|
||||||
glm::vec3(0.f, 0.f, 1.f)
|
glm::vec3(0.f, output_flip_ ? 1.f : 0.f, 1.f)
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,8 @@ static const PipelineDesc kPipelineDesc = {
|
||||||
{VertexAttributeName::kColor, 0, 24}}},
|
{VertexAttributeName::kColor, 0, 24}}},
|
||||||
{{{{UniformName::kProjection}}, {{UniformName::kModelView, UniformName::kTexCoord0Transform}}}},
|
{{{{UniformName::kProjection}}, {{UniformName::kModelView, UniformName::kTexCoord0Transform}}}},
|
||||||
{{SamplerName::kSampler0}},
|
{{SamplerName::kSampler0}},
|
||||||
PipelineDepthAttachmentDesc {PixelFormat::kDepth16, CompareFunc::kAlways, true},
|
PipelineDepthStencilStateDesc {true, true, CompareFunc::kAlways, false, {}, {}},
|
||||||
{PixelFormat::kRGBA8,
|
{BlendDesc {
|
||||||
BlendDesc {
|
|
||||||
BlendFactor::kSourceAlpha,
|
BlendFactor::kSourceAlpha,
|
||||||
BlendFactor::kOneMinusSourceAlpha,
|
BlendFactor::kOneMinusSourceAlpha,
|
||||||
BlendFunction::kAdd,
|
BlendFunction::kAdd,
|
||||||
|
|
@ -65,7 +64,13 @@ void ImguiPass::prepass(Rhi& rhi)
|
||||||
uint32_t uwidth = static_cast<uint32_t>(width);
|
uint32_t uwidth = static_cast<uint32_t>(width);
|
||||||
uint32_t uheight = static_cast<uint32_t>(height);
|
uint32_t uheight = static_cast<uint32_t>(height);
|
||||||
|
|
||||||
font_atlas_ = rhi.create_texture({TextureFormat::kRGBA, uwidth, uheight});
|
font_atlas_ = rhi.create_texture({
|
||||||
|
TextureFormat::kRGBA,
|
||||||
|
uwidth,
|
||||||
|
uheight,
|
||||||
|
TextureWrapMode::kRepeat,
|
||||||
|
TextureWrapMode::kRepeat
|
||||||
|
});
|
||||||
io.Fonts->SetTexID(font_atlas_);
|
io.Fonts->SetTexID(font_atlas_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ static const PipelineDesc kWipePipelineDesc = {
|
||||||
{{{{UniformName::kProjection, UniformName::kWipeColorizeMode, UniformName::kWipeEncoreSwizzle}}}},
|
{{{{UniformName::kProjection, UniformName::kWipeColorizeMode, UniformName::kWipeEncoreSwizzle}}}},
|
||||||
{{SamplerName::kSampler0, SamplerName::kSampler1, SamplerName::kSampler2}},
|
{{SamplerName::kSampler0, SamplerName::kSampler1, SamplerName::kSampler2}},
|
||||||
std::nullopt,
|
std::nullopt,
|
||||||
{PixelFormat::kRGBA8, std::nullopt, {true, true, true, true}},
|
{std::nullopt, {true, true, true, true}},
|
||||||
PrimitiveType::kTriangles,
|
PrimitiveType::kTriangles,
|
||||||
CullMode::kNone,
|
CullMode::kNone,
|
||||||
FaceWinding::kCounterClockwise,
|
FaceWinding::kCounterClockwise,
|
||||||
|
|
@ -67,7 +67,15 @@ void PostprocessWipePass::prepass(Rhi& rhi)
|
||||||
if (!render_pass_)
|
if (!render_pass_)
|
||||||
{
|
{
|
||||||
render_pass_ = rhi.create_render_pass(
|
render_pass_ = rhi.create_render_pass(
|
||||||
{std::nullopt, PixelFormat::kRGBA8, AttachmentLoadOp::kLoad, AttachmentStoreOp::kStore}
|
{
|
||||||
|
false,
|
||||||
|
AttachmentLoadOp::kLoad,
|
||||||
|
AttachmentStoreOp::kStore,
|
||||||
|
AttachmentLoadOp::kDontCare,
|
||||||
|
AttachmentStoreOp::kDontCare,
|
||||||
|
AttachmentLoadOp::kDontCare,
|
||||||
|
AttachmentStoreOp::kDontCare
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -158,7 +166,13 @@ void PostprocessWipePass::prepass(Rhi& rhi)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wipe_tex_ = rhi.create_texture({TextureFormat::kLuminance, mask_w_, mask_h_});
|
wipe_tex_ = rhi.create_texture({
|
||||||
|
TextureFormat::kLuminance,
|
||||||
|
mask_w_,
|
||||||
|
mask_h_,
|
||||||
|
TextureWrapMode::kClamp,
|
||||||
|
TextureWrapMode::kClamp
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void PostprocessWipePass::transfer(Rhi& rhi, Handle<TransferContext> ctx)
|
void PostprocessWipePass::transfer(Rhi& rhi, Handle<TransferContext> ctx)
|
||||||
|
|
|
||||||
|
|
@ -71,29 +71,59 @@ void FramebufferManager::prepass(Rhi& rhi)
|
||||||
// Recreate the framebuffer textures
|
// Recreate the framebuffer textures
|
||||||
if (main_color_ == kNullHandle)
|
if (main_color_ == kNullHandle)
|
||||||
{
|
{
|
||||||
main_color_ = rhi.create_texture({TextureFormat::kRGBA, current_width, current_height});
|
main_color_ = rhi.create_texture({
|
||||||
|
TextureFormat::kRGBA,
|
||||||
|
current_width,
|
||||||
|
current_height,
|
||||||
|
TextureWrapMode::kClamp,
|
||||||
|
TextureWrapMode::kClamp
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (main_depth_ == kNullHandle)
|
if (main_depth_ == kNullHandle)
|
||||||
{
|
{
|
||||||
main_depth_ = rhi.create_renderbuffer({PixelFormat::kDepth16, current_width, current_height});
|
main_depth_ = rhi.create_renderbuffer({current_width, current_height});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (post_colors_[0] == kNullHandle)
|
if (post_colors_[0] == kNullHandle)
|
||||||
{
|
{
|
||||||
post_colors_[0] = rhi.create_texture({TextureFormat::kRGBA, current_width, current_height});
|
post_colors_[0] = rhi.create_texture({
|
||||||
|
TextureFormat::kRGBA,
|
||||||
|
current_width,
|
||||||
|
current_height,
|
||||||
|
TextureWrapMode::kClamp,
|
||||||
|
TextureWrapMode::kClamp
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (post_colors_[1] == kNullHandle)
|
if (post_colors_[1] == kNullHandle)
|
||||||
{
|
{
|
||||||
post_colors_[1] = rhi.create_texture({TextureFormat::kRGBA, current_width, current_height});
|
post_colors_[1] = rhi.create_texture({
|
||||||
|
TextureFormat::kRGBA,
|
||||||
|
current_width,
|
||||||
|
current_height,
|
||||||
|
TextureWrapMode::kClamp,
|
||||||
|
TextureWrapMode::kClamp
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wipe_start_color_ == kNullHandle)
|
if (wipe_start_color_ == kNullHandle)
|
||||||
{
|
{
|
||||||
wipe_start_color_ = rhi.create_texture({TextureFormat::kRGBA, current_width, current_height});
|
wipe_start_color_ = rhi.create_texture({
|
||||||
|
TextureFormat::kRGBA,
|
||||||
|
current_width,
|
||||||
|
current_height,
|
||||||
|
TextureWrapMode::kClamp,
|
||||||
|
TextureWrapMode::kClamp
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (wipe_end_color_ == kNullHandle)
|
if (wipe_end_color_ == kNullHandle)
|
||||||
{
|
{
|
||||||
wipe_end_color_ = rhi.create_texture({TextureFormat::kRGBA, current_width, current_height});
|
wipe_end_color_ = rhi.create_texture({
|
||||||
|
TextureFormat::kRGBA,
|
||||||
|
current_width,
|
||||||
|
current_height,
|
||||||
|
TextureWrapMode::kClamp,
|
||||||
|
TextureWrapMode::kClamp
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -119,7 +149,7 @@ void MainPaletteManager::prepass(Rhi& rhi)
|
||||||
{
|
{
|
||||||
if (!palette_)
|
if (!palette_)
|
||||||
{
|
{
|
||||||
palette_ = rhi.create_texture({TextureFormat::kRGBA, 256, 1});
|
palette_ = rhi.create_texture({TextureFormat::kRGBA, 256, 1, TextureWrapMode::kClamp, TextureWrapMode::kClamp});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -148,9 +178,15 @@ void CommonResourcesManager::prepass(Rhi& rhi)
|
||||||
{
|
{
|
||||||
if (!init_)
|
if (!init_)
|
||||||
{
|
{
|
||||||
black_ = rhi.create_texture({TextureFormat::kRGBA, 1, 1});
|
black_ = rhi.create_texture({TextureFormat::kRGBA, 1, 1, TextureWrapMode::kClamp, TextureWrapMode::kClamp});
|
||||||
white_ = rhi.create_texture({TextureFormat::kRGBA, 1, 1});
|
white_ = rhi.create_texture({TextureFormat::kRGBA, 1, 1, TextureWrapMode::kClamp, TextureWrapMode::kClamp});
|
||||||
transparent_ = rhi.create_texture({TextureFormat::kRGBA, 1, 1});
|
transparent_ = rhi.create_texture({
|
||||||
|
TextureFormat::kRGBA,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
TextureWrapMode::kClamp,
|
||||||
|
TextureWrapMode::kClamp
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -266,7 +302,13 @@ Handle<Texture> FlatTextureManager::find_or_create_indexed(Rhi& rhi, lumpnum_t l
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t flat_size = get_flat_size(lump);
|
uint32_t flat_size = get_flat_size(lump);
|
||||||
Handle<Texture> new_tex = rhi.create_texture({TextureFormat::kLuminanceAlpha, flat_size, flat_size});
|
Handle<Texture> new_tex = rhi.create_texture({
|
||||||
|
TextureFormat::kLuminanceAlpha,
|
||||||
|
flat_size,
|
||||||
|
flat_size,
|
||||||
|
TextureWrapMode::kRepeat,
|
||||||
|
TextureWrapMode::kRepeat
|
||||||
|
});
|
||||||
flats_.insert({lump, new_tex});
|
flats_.insert({lump, new_tex});
|
||||||
to_upload_.push_back(lump);
|
to_upload_.push_back(lump);
|
||||||
return new_tex;
|
return new_tex;
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,13 @@ void ScreenshotPass::prepass(Rhi& rhi)
|
||||||
{
|
{
|
||||||
render_pass_ = rhi.create_render_pass(
|
render_pass_ = rhi.create_render_pass(
|
||||||
{
|
{
|
||||||
std::nullopt,
|
false,
|
||||||
PixelFormat::kRGBA8,
|
|
||||||
AttachmentLoadOp::kLoad,
|
AttachmentLoadOp::kLoad,
|
||||||
AttachmentStoreOp::kStore
|
AttachmentStoreOp::kStore,
|
||||||
|
AttachmentLoadOp::kDontCare,
|
||||||
|
AttachmentStoreOp::kDontCare,
|
||||||
|
AttachmentLoadOp::kDontCare,
|
||||||
|
AttachmentStoreOp::kDontCare
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,13 @@ void SoftwarePass::prepass(Rhi& rhi)
|
||||||
|
|
||||||
if (!screen_texture_)
|
if (!screen_texture_)
|
||||||
{
|
{
|
||||||
screen_texture_ = rhi.create_texture({TextureFormat::kLuminance, width_, height_});
|
screen_texture_ = rhi.create_texture({
|
||||||
|
TextureFormat::kLuminance,
|
||||||
|
width_,
|
||||||
|
height_,
|
||||||
|
TextureWrapMode::kClamp,
|
||||||
|
TextureWrapMode::kClamp
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the screen width won't fit the unpack alignment, we need to copy the screen.
|
// If the screen width won't fit the unpack alignment, we need to copy the screen.
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,13 @@ static Rect trimmed_patch_dim(const patch_t* patch);
|
||||||
static void create_atlas(Rhi& rhi, TwodeePassData& pass_data)
|
static void create_atlas(Rhi& rhi, TwodeePassData& pass_data)
|
||||||
{
|
{
|
||||||
Atlas new_atlas;
|
Atlas new_atlas;
|
||||||
new_atlas.tex = rhi.create_texture({TextureFormat::kLuminanceAlpha, 2048, 2048});
|
new_atlas.tex = rhi.create_texture({
|
||||||
|
TextureFormat::kLuminanceAlpha,
|
||||||
|
2048,
|
||||||
|
2048,
|
||||||
|
TextureWrapMode::kClamp,
|
||||||
|
TextureWrapMode::kClamp
|
||||||
|
});
|
||||||
new_atlas.tex_width = 2048;
|
new_atlas.tex_width = 2048;
|
||||||
new_atlas.tex_height = 2048;
|
new_atlas.tex_height = 2048;
|
||||||
new_atlas.rp_ctx = std::make_unique<stbrp_context>();
|
new_atlas.rp_ctx = std::make_unique<stbrp_context>();
|
||||||
|
|
@ -345,7 +351,7 @@ static PipelineDesc make_pipeline_desc(TwodeePipelineKey key)
|
||||||
{{UniformName::kModelView, UniformName::kTexCoord0Transform, UniformName::kSampler0IsIndexedAlpha}}}},
|
{{UniformName::kModelView, UniformName::kTexCoord0Transform, UniformName::kSampler0IsIndexedAlpha}}}},
|
||||||
{{SamplerName::kSampler0, SamplerName::kSampler1, SamplerName::kSampler2}},
|
{{SamplerName::kSampler0, SamplerName::kSampler1, SamplerName::kSampler2}},
|
||||||
std::nullopt,
|
std::nullopt,
|
||||||
{PixelFormat::kRGBA8, blend_desc, {true, true, true, true}},
|
{blend_desc, {true, true, true, true}},
|
||||||
key.lines ? PrimitiveType::kLines : PrimitiveType::kTriangles,
|
key.lines ? PrimitiveType::kLines : PrimitiveType::kTriangles,
|
||||||
CullMode::kNone,
|
CullMode::kNone,
|
||||||
FaceWinding::kCounterClockwise,
|
FaceWinding::kCounterClockwise,
|
||||||
|
|
@ -501,18 +507,38 @@ void TwodeePass::prepass(Rhi& rhi)
|
||||||
|
|
||||||
if (!data_->default_tex)
|
if (!data_->default_tex)
|
||||||
{
|
{
|
||||||
data_->default_tex = rhi.create_texture({TextureFormat::kLuminanceAlpha, 2, 1});
|
data_->default_tex = rhi.create_texture({
|
||||||
|
TextureFormat::kLuminanceAlpha,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
TextureWrapMode::kClamp,
|
||||||
|
TextureWrapMode::kClamp
|
||||||
|
});
|
||||||
data_->upload_default_tex = true;
|
data_->upload_default_tex = true;
|
||||||
}
|
}
|
||||||
if (!data_->default_colormap_tex)
|
if (!data_->default_colormap_tex)
|
||||||
{
|
{
|
||||||
data_->default_colormap_tex = rhi.create_texture({TextureFormat::kLuminance, 256, 1});
|
data_->default_colormap_tex = rhi.create_texture({
|
||||||
|
TextureFormat::kLuminance,
|
||||||
|
256,
|
||||||
|
1,
|
||||||
|
TextureWrapMode::kClamp,
|
||||||
|
TextureWrapMode::kClamp
|
||||||
|
});
|
||||||
data_->upload_default_tex = true;
|
data_->upload_default_tex = true;
|
||||||
}
|
}
|
||||||
if (!render_pass_)
|
if (!render_pass_)
|
||||||
{
|
{
|
||||||
render_pass_ = rhi.create_render_pass(
|
render_pass_ = rhi.create_render_pass(
|
||||||
{std::nullopt, PixelFormat::kRGBA8, AttachmentLoadOp::kLoad, AttachmentStoreOp::kStore}
|
{
|
||||||
|
false,
|
||||||
|
AttachmentLoadOp::kLoad,
|
||||||
|
AttachmentStoreOp::kStore,
|
||||||
|
AttachmentLoadOp::kDontCare,
|
||||||
|
AttachmentStoreOp::kDontCare,
|
||||||
|
AttachmentLoadOp::kDontCare,
|
||||||
|
AttachmentStoreOp::kDontCare
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,21 @@ constexpr GLenum map_texture_format(rhi::TextureFormat format)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr GLenum map_texture_wrap(rhi::TextureWrapMode wrap)
|
||||||
|
{
|
||||||
|
switch (wrap)
|
||||||
|
{
|
||||||
|
case rhi::TextureWrapMode::kClamp:
|
||||||
|
return GL_CLAMP_TO_EDGE;
|
||||||
|
case rhi::TextureWrapMode::kRepeat:
|
||||||
|
return GL_REPEAT;
|
||||||
|
case rhi::TextureWrapMode::kMirroredRepeat:
|
||||||
|
return GL_MIRRORED_REPEAT;
|
||||||
|
default:
|
||||||
|
return GL_NEAREST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
constexpr GLenum map_internal_texture_format(rhi::TextureFormat format)
|
constexpr GLenum map_internal_texture_format(rhi::TextureFormat format)
|
||||||
{
|
{
|
||||||
switch (format)
|
switch (format)
|
||||||
|
|
@ -122,8 +137,6 @@ constexpr GLenum map_internal_texture_format(rhi::TextureFormat format)
|
||||||
return GL_R8;
|
return GL_R8;
|
||||||
case rhi::TextureFormat::kLuminanceAlpha:
|
case rhi::TextureFormat::kLuminanceAlpha:
|
||||||
return GL_RG8;
|
return GL_RG8;
|
||||||
case rhi::TextureFormat::kDepth:
|
|
||||||
return GL_DEPTH_COMPONENT24;
|
|
||||||
default:
|
default:
|
||||||
return GL_ZERO;
|
return GL_ZERO;
|
||||||
}
|
}
|
||||||
|
|
@ -519,10 +532,6 @@ rhi::Handle<rhi::Texture> GlCoreRhi::create_texture(const rhi::TextureDesc& desc
|
||||||
GLenum internal_format = map_internal_texture_format(desc.format);
|
GLenum internal_format = map_internal_texture_format(desc.format);
|
||||||
SRB2_ASSERT(internal_format != GL_ZERO);
|
SRB2_ASSERT(internal_format != GL_ZERO);
|
||||||
GLenum format = GL_RGBA;
|
GLenum format = GL_RGBA;
|
||||||
if (desc.format == TextureFormat::kDepth)
|
|
||||||
{
|
|
||||||
format = GL_DEPTH_COMPONENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLuint name = 0;
|
GLuint name = 0;
|
||||||
gl_->GenTextures(1, &name);
|
gl_->GenTextures(1, &name);
|
||||||
|
|
@ -530,15 +539,15 @@ rhi::Handle<rhi::Texture> GlCoreRhi::create_texture(const rhi::TextureDesc& desc
|
||||||
gl_->BindTexture(GL_TEXTURE_2D, name);
|
gl_->BindTexture(GL_TEXTURE_2D, name);
|
||||||
|
|
||||||
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, map_texture_wrap(desc.u_wrap));
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, map_texture_wrap(desc.v_wrap));
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
gl_->TexImage2D(GL_TEXTURE_2D, 0, internal_format, desc.width, desc.height, 0, format, GL_UNSIGNED_BYTE, nullptr);
|
gl_->TexImage2D(GL_TEXTURE_2D, 0, internal_format, desc.width, desc.height, 0, format, GL_UNSIGNED_BYTE, nullptr);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
|
|
||||||
GlCoreTexture texture;
|
GlCoreTexture texture;
|
||||||
texture.texture = name;
|
texture.texture = name;
|
||||||
|
|
@ -592,9 +601,9 @@ void GlCoreRhi::update_texture(
|
||||||
SRB2_ASSERT(region.x + region.w <= t.desc.width && region.y + region.h <= t.desc.height);
|
SRB2_ASSERT(region.x + region.w <= t.desc.width && region.y + region.h <= t.desc.height);
|
||||||
|
|
||||||
gl_->ActiveTexture(GL_TEXTURE0);
|
gl_->ActiveTexture(GL_TEXTURE0);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
gl_->BindTexture(GL_TEXTURE_2D, t.texture);
|
gl_->BindTexture(GL_TEXTURE_2D, t.texture);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
gl_->TexSubImage2D(
|
gl_->TexSubImage2D(
|
||||||
GL_TEXTURE_2D,
|
GL_TEXTURE_2D,
|
||||||
0,
|
0,
|
||||||
|
|
@ -606,7 +615,7 @@ void GlCoreRhi::update_texture(
|
||||||
type,
|
type,
|
||||||
reinterpret_cast<const void*>(data.data())
|
reinterpret_cast<const void*>(data.data())
|
||||||
);
|
);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
}
|
}
|
||||||
|
|
||||||
rhi::Handle<rhi::Buffer> GlCoreRhi::create_buffer(const rhi::BufferDesc& desc)
|
rhi::Handle<rhi::Buffer> GlCoreRhi::create_buffer(const rhi::BufferDesc& desc)
|
||||||
|
|
@ -621,13 +630,13 @@ rhi::Handle<rhi::Buffer> GlCoreRhi::create_buffer(const rhi::BufferDesc& desc)
|
||||||
|
|
||||||
GLuint name = 0;
|
GLuint name = 0;
|
||||||
gl_->GenBuffers(1, &name);
|
gl_->GenBuffers(1, &name);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
|
|
||||||
gl_->BindBuffer(target, name);
|
gl_->BindBuffer(target, name);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
|
|
||||||
gl_->BufferData(target, desc.size, nullptr, usage);
|
gl_->BufferData(target, desc.size, nullptr, usage);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
|
|
||||||
GlCoreBuffer buffer;
|
GlCoreBuffer buffer;
|
||||||
buffer.buffer = name;
|
buffer.buffer = name;
|
||||||
|
|
@ -680,9 +689,9 @@ void GlCoreRhi::update_buffer(
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_->BindBuffer(target, b.buffer);
|
gl_->BindBuffer(target, b.buffer);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
gl_->BufferSubData(target, offset, data.size(), data.data());
|
gl_->BufferSubData(target, offset, data.size(), data.data());
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
}
|
}
|
||||||
|
|
||||||
rhi::Handle<rhi::UniformSet>
|
rhi::Handle<rhi::UniformSet>
|
||||||
|
|
@ -721,9 +730,9 @@ rhi::Handle<rhi::BindingSet> GlCoreRhi::create_binding_set(
|
||||||
|
|
||||||
GLuint vao = 0;
|
GLuint vao = 0;
|
||||||
gl_->GenVertexArrays(1, &vao);
|
gl_->GenVertexArrays(1, &vao);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
gl_->BindVertexArray(vao);
|
gl_->BindVertexArray(vao);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
|
|
||||||
for (auto& attr_layout : pl.desc.vertex_input.attr_layouts)
|
for (auto& attr_layout : pl.desc.vertex_input.attr_layouts)
|
||||||
{
|
{
|
||||||
|
|
@ -734,7 +743,7 @@ rhi::Handle<rhi::BindingSet> GlCoreRhi::create_binding_set(
|
||||||
auto& buffer_layout = pl.desc.vertex_input.buffer_layouts[attr_layout.buffer_index];
|
auto& buffer_layout = pl.desc.vertex_input.buffer_layouts[attr_layout.buffer_index];
|
||||||
|
|
||||||
gl_->BindBuffer(GL_ARRAY_BUFFER, buf.buffer);
|
gl_->BindBuffer(GL_ARRAY_BUFFER, buf.buffer);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
|
|
||||||
GLuint attrib_location = pl.attrib_locations[attr_layout.name];
|
GLuint attrib_location = pl.attrib_locations[attr_layout.name];
|
||||||
VertexAttributeFormat vert_attr_format = rhi::vertex_attribute_format(attr_layout.name);
|
VertexAttributeFormat vert_attr_format = rhi::vertex_attribute_format(attr_layout.name);
|
||||||
|
|
@ -744,7 +753,7 @@ rhi::Handle<rhi::BindingSet> GlCoreRhi::create_binding_set(
|
||||||
SRB2_ASSERT(vertex_attr_size != 0);
|
SRB2_ASSERT(vertex_attr_size != 0);
|
||||||
uint32_t vertex_buffer_offset = 0; // TODO allow binding set to specify
|
uint32_t vertex_buffer_offset = 0; // TODO allow binding set to specify
|
||||||
gl_->EnableVertexAttribArray(pl.attrib_locations[attr_layout.name]);
|
gl_->EnableVertexAttribArray(pl.attrib_locations[attr_layout.name]);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
gl_->VertexAttribPointer(
|
gl_->VertexAttribPointer(
|
||||||
attrib_location,
|
attrib_location,
|
||||||
vertex_attr_size,
|
vertex_attr_size,
|
||||||
|
|
@ -753,7 +762,7 @@ rhi::Handle<rhi::BindingSet> GlCoreRhi::create_binding_set(
|
||||||
buffer_layout.stride,
|
buffer_layout.stride,
|
||||||
reinterpret_cast<const void*>(vertex_buffer_offset + attr_layout.offset)
|
reinterpret_cast<const void*>(vertex_buffer_offset + attr_layout.offset)
|
||||||
);
|
);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
}
|
}
|
||||||
|
|
||||||
binding_set.vao = vao;
|
binding_set.vao = vao;
|
||||||
|
|
@ -782,9 +791,24 @@ rhi::Handle<rhi::Renderbuffer> GlCoreRhi::create_renderbuffer(const rhi::Renderb
|
||||||
|
|
||||||
// Obtain storage up-front.
|
// Obtain storage up-front.
|
||||||
gl_->BindRenderbuffer(GL_RENDERBUFFER, name);
|
gl_->BindRenderbuffer(GL_RENDERBUFFER, name);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
gl_->RenderbufferStorage(GL_RENDERBUFFER, map_pixel_format(desc.format), desc.width, desc.height);
|
|
||||||
GL_ASSERT
|
// For consistency, while RHI does not specify the bit size of the depth or stencil components,
|
||||||
|
// nor if they are packed or separate, each backend should be expected to create a packed depth-stencil
|
||||||
|
// D24S8 format image.
|
||||||
|
// This is despite modern AMD apparently not supporting this format in hardware. It ensures the
|
||||||
|
// depth behavior between backends is the same. We should not brush up against performance issues in practice.
|
||||||
|
|
||||||
|
// - GL Core requires both D24S8 and D32FS8 format support.
|
||||||
|
// - GL 2 via ARB_framebuffer_object requires D24S8. Backend must require this extension.
|
||||||
|
// - GLES 2 via OES_packed_depth_stencil requires D24S8. Backend must require this extension.
|
||||||
|
// - Vulkan requires **one of** D24S8 or D32FS8. The backend must decide which format to use based on caps.
|
||||||
|
// (Even if D32FS8 is available, D24S8 should be preferred)
|
||||||
|
|
||||||
|
// For reference, D32FS8 at 4k requires 64 MiB of linear memory. D24S8 is 32 MiB.
|
||||||
|
|
||||||
|
gl_->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, desc.width, desc.height);
|
||||||
|
GL_ASSERT;
|
||||||
|
|
||||||
GlCoreRenderbuffer rb;
|
GlCoreRenderbuffer rb;
|
||||||
rb.renderbuffer = name;
|
rb.renderbuffer = name;
|
||||||
|
|
@ -1000,9 +1024,9 @@ rhi::Handle<rhi::Pipeline> GlCoreRhi::create_pipeline(const PipelineDesc& desc)
|
||||||
GLenum type = GL_ZERO;
|
GLenum type = GL_ZERO;
|
||||||
char name[256];
|
char name[256];
|
||||||
gl_->GetActiveAttrib(program, i, 255, &name_len, &size, &type, name);
|
gl_->GetActiveAttrib(program, i, 255, &name_len, &size, &type, name);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
GLint location = gl_->GetAttribLocation(program, name);
|
GLint location = gl_->GetAttribLocation(program, name);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
active_attributes.insert({std::string(name), GlCoreActiveUniform {type, static_cast<GLuint>(location)}});
|
active_attributes.insert({std::string(name), GlCoreActiveUniform {type, static_cast<GLuint>(location)}});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1042,9 +1066,9 @@ rhi::Handle<rhi::Pipeline> GlCoreRhi::create_pipeline(const PipelineDesc& desc)
|
||||||
GLenum type = GL_ZERO;
|
GLenum type = GL_ZERO;
|
||||||
char name[256];
|
char name[256];
|
||||||
gl_->GetActiveUniform(program, i, 255, &name_len, &size, &type, name);
|
gl_->GetActiveUniform(program, i, 255, &name_len, &size, &type, name);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
GLint location = gl_->GetUniformLocation(program, name);
|
GLint location = gl_->GetUniformLocation(program, name);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
active_uniforms.insert({std::string(name), GlCoreActiveUniform {type, static_cast<GLuint>(location)}});
|
active_uniforms.insert({std::string(name), GlCoreActiveUniform {type, static_cast<GLuint>(location)}});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1167,7 +1191,7 @@ void GlCoreRhi::end_graphics(rhi::Handle<rhi::GraphicsContext> handle)
|
||||||
graphics_context_generation_ += 1;
|
graphics_context_generation_ += 1;
|
||||||
graphics_context_active_ = false;
|
graphics_context_active_ = false;
|
||||||
gl_->Flush();
|
gl_->Flush();
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
}
|
}
|
||||||
|
|
||||||
rhi::Handle<rhi::TransferContext> GlCoreRhi::begin_transfer()
|
rhi::Handle<rhi::TransferContext> GlCoreRhi::begin_transfer()
|
||||||
|
|
@ -1206,11 +1230,11 @@ void GlCoreRhi::begin_default_render_pass(Handle<GraphicsContext> ctx, bool clea
|
||||||
const Rect fb_rect = platform_->get_default_framebuffer_dimensions();
|
const Rect fb_rect = platform_->get_default_framebuffer_dimensions();
|
||||||
|
|
||||||
gl_->BindFramebuffer(GL_FRAMEBUFFER, 0);
|
gl_->BindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
gl_->Disable(GL_SCISSOR_TEST);
|
gl_->Disable(GL_SCISSOR_TEST);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
gl_->Viewport(0, 0, fb_rect.w, fb_rect.h);
|
gl_->Viewport(0, 0, fb_rect.w, fb_rect.h);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
|
|
||||||
if (clear)
|
if (clear)
|
||||||
{
|
{
|
||||||
|
|
@ -1218,7 +1242,7 @@ void GlCoreRhi::begin_default_render_pass(Handle<GraphicsContext> ctx, bool clea
|
||||||
gl_->ClearDepth(1.0f);
|
gl_->ClearDepth(1.0f);
|
||||||
gl_->ClearStencil(0);
|
gl_->ClearStencil(0);
|
||||||
gl_->Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
gl_->Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_render_pass_ = GlCoreRhi::DefaultRenderPassState {};
|
current_render_pass_ = GlCoreRhi::DefaultRenderPassState {};
|
||||||
|
|
@ -1231,65 +1255,74 @@ void GlCoreRhi::begin_render_pass(Handle<GraphicsContext> ctx, const RenderPassB
|
||||||
|
|
||||||
SRB2_ASSERT(render_pass_slab_.is_valid(info.render_pass) == true);
|
SRB2_ASSERT(render_pass_slab_.is_valid(info.render_pass) == true);
|
||||||
auto& rp = render_pass_slab_[info.render_pass];
|
auto& rp = render_pass_slab_[info.render_pass];
|
||||||
SRB2_ASSERT(rp.desc.depth_format.has_value() == info.depth_attachment.has_value());
|
SRB2_ASSERT(rp.desc.use_depth_stencil == info.depth_stencil_attachment.has_value());
|
||||||
|
|
||||||
auto fb_itr = framebuffers_.find(GlCoreFramebufferKey {info.color_attachment, info.depth_attachment});
|
auto fb_itr = framebuffers_.find(GlCoreFramebufferKey {info.color_attachment, info.depth_stencil_attachment});
|
||||||
if (fb_itr == framebuffers_.end())
|
if (fb_itr == framebuffers_.end())
|
||||||
{
|
{
|
||||||
// Create a new framebuffer for this color-depth pair
|
// Create a new framebuffer for this color-depth pair
|
||||||
GLuint fb_name;
|
GLuint fb_name;
|
||||||
gl_->GenFramebuffers(1, &fb_name);
|
gl_->GenFramebuffers(1, &fb_name);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
gl_->BindFramebuffer(GL_FRAMEBUFFER, fb_name);
|
gl_->BindFramebuffer(GL_FRAMEBUFFER, fb_name);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
fb_itr = framebuffers_
|
fb_itr = framebuffers_
|
||||||
.insert(
|
.insert(
|
||||||
{GlCoreFramebufferKey {info.color_attachment, info.depth_attachment},
|
{GlCoreFramebufferKey {info.color_attachment, info.depth_stencil_attachment},
|
||||||
static_cast<uint32_t>(fb_name)}
|
static_cast<uint32_t>(fb_name)}
|
||||||
)
|
)
|
||||||
.first;
|
.first;
|
||||||
|
|
||||||
GLuint attachment = GL_COLOR_ATTACHMENT0;
|
SRB2_ASSERT(texture_slab_.is_valid(info.color_attachment));
|
||||||
auto visitor = srb2::Overload {
|
auto& texture = texture_slab_[info.color_attachment];
|
||||||
[&, this](const Handle<Texture>& handle)
|
SRB2_ASSERT(texture.desc.format == TextureFormat::kRGBA);
|
||||||
{
|
gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.texture, 0);
|
||||||
SRB2_ASSERT(texture_slab_.is_valid(handle));
|
GL_ASSERT;
|
||||||
auto& texture = texture_slab_[handle];
|
|
||||||
gl_->FramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, texture.texture, 0);
|
if (rp.desc.use_depth_stencil && info.depth_stencil_attachment.has_value())
|
||||||
GL_ASSERT
|
|
||||||
},
|
|
||||||
[&, this](const Handle<Renderbuffer>& handle)
|
|
||||||
{
|
|
||||||
SRB2_ASSERT(renderbuffer_slab_.is_valid(handle));
|
|
||||||
auto& renderbuffer = renderbuffer_slab_[handle];
|
|
||||||
gl_->FramebufferRenderbuffer(
|
|
||||||
GL_FRAMEBUFFER,
|
|
||||||
attachment,
|
|
||||||
GL_RENDERBUFFER,
|
|
||||||
renderbuffer.renderbuffer
|
|
||||||
);
|
|
||||||
GL_ASSERT
|
|
||||||
}};
|
|
||||||
std::visit(visitor, info.color_attachment);
|
|
||||||
if (info.depth_attachment)
|
|
||||||
{
|
{
|
||||||
attachment = GL_DEPTH_ATTACHMENT;
|
SRB2_ASSERT(renderbuffer_slab_.is_valid(*info.depth_stencil_attachment));
|
||||||
std::visit(visitor, *info.depth_attachment);
|
auto& renderbuffer = renderbuffer_slab_[*info.depth_stencil_attachment];
|
||||||
|
gl_->FramebufferRenderbuffer(
|
||||||
|
GL_FRAMEBUFFER,
|
||||||
|
GL_DEPTH_ATTACHMENT,
|
||||||
|
GL_RENDERBUFFER,
|
||||||
|
renderbuffer.renderbuffer
|
||||||
|
);
|
||||||
|
GL_ASSERT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto& fb = *fb_itr;
|
auto& fb = *fb_itr;
|
||||||
gl_->BindFramebuffer(GL_FRAMEBUFFER, fb.second);
|
gl_->BindFramebuffer(GL_FRAMEBUFFER, fb.second);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
gl_->Disable(GL_SCISSOR_TEST);
|
gl_->Disable(GL_SCISSOR_TEST);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
|
|
||||||
if (rp.desc.load_op == rhi::AttachmentLoadOp::kClear)
|
GLint clear_bits = 0;
|
||||||
|
if (rp.desc.color_load_op == rhi::AttachmentLoadOp::kClear)
|
||||||
{
|
{
|
||||||
gl_->ClearColor(info.clear_color.r, info.clear_color.g, info.clear_color.b, info.clear_color.a);
|
gl_->ClearColor(info.clear_color.r, info.clear_color.g, info.clear_color.b, info.clear_color.a);
|
||||||
gl_->ClearDepth(1.f);
|
clear_bits |= GL_COLOR_BUFFER_BIT;
|
||||||
gl_->ClearStencil(0);
|
}
|
||||||
gl_->Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
|
||||||
GL_ASSERT
|
if (rp.desc.use_depth_stencil)
|
||||||
|
{
|
||||||
|
if (rp.desc.depth_load_op == rhi::AttachmentLoadOp::kClear)
|
||||||
|
{
|
||||||
|
gl_->ClearDepth(1.f);
|
||||||
|
clear_bits |= GL_DEPTH_BUFFER_BIT;
|
||||||
|
}
|
||||||
|
if (rp.desc.stencil_load_op == rhi::AttachmentLoadOp::kClear)
|
||||||
|
{
|
||||||
|
gl_->ClearStencil(0);
|
||||||
|
clear_bits |= GL_STENCIL_BUFFER_BIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clear_bits != 0)
|
||||||
|
{
|
||||||
|
gl_->Clear(clear_bits);
|
||||||
|
GL_ASSERT;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_render_pass_ = info;
|
current_render_pass_ = info;
|
||||||
|
|
@ -1314,44 +1347,98 @@ void GlCoreRhi::bind_pipeline(Handle<GraphicsContext> ctx, Handle<Pipeline> pipe
|
||||||
auto& desc = pl.desc;
|
auto& desc = pl.desc;
|
||||||
|
|
||||||
gl_->UseProgram(pl.program);
|
gl_->UseProgram(pl.program);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
|
|
||||||
gl_->Disable(GL_SCISSOR_TEST);
|
gl_->Disable(GL_SCISSOR_TEST);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
|
|
||||||
if (desc.depth_attachment)
|
if (desc.depth_stencil_state)
|
||||||
{
|
{
|
||||||
gl_->Enable(GL_DEPTH_TEST);
|
if (desc.depth_stencil_state->depth_test)
|
||||||
GL_ASSERT
|
{
|
||||||
GLenum depth_func = map_compare_func(desc.depth_attachment->func);
|
gl_->Enable(GL_DEPTH_TEST);
|
||||||
SRB2_ASSERT(depth_func != GL_ZERO);
|
GL_ASSERT;
|
||||||
gl_->DepthFunc(depth_func);
|
GLenum depth_func = map_compare_func(desc.depth_stencil_state->depth_func);
|
||||||
GL_ASSERT
|
SRB2_ASSERT(depth_func != GL_ZERO);
|
||||||
gl_->DepthMask(desc.depth_attachment->write ? GL_TRUE : GL_FALSE);
|
gl_->DepthFunc(depth_func);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
|
gl_->DepthMask(desc.depth_stencil_state->depth_write ? GL_TRUE : GL_FALSE);
|
||||||
|
GL_ASSERT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gl_->Disable(GL_DEPTH_TEST);
|
||||||
|
GL_ASSERT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desc.depth_stencil_state->depth_write)
|
||||||
|
{
|
||||||
|
gl_->DepthMask(GL_TRUE);
|
||||||
|
GL_ASSERT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gl_->DepthMask(GL_FALSE);
|
||||||
|
GL_ASSERT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desc.depth_stencil_state->stencil_test)
|
||||||
|
{
|
||||||
|
gl_->Enable(GL_STENCIL_TEST);
|
||||||
|
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
|
||||||
|
);
|
||||||
|
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
|
||||||
|
);
|
||||||
|
GL_ASSERT;
|
||||||
|
|
||||||
|
gl_->StencilMaskSeparate(GL_FRONT, desc.depth_stencil_state->front.write_mask);
|
||||||
|
GL_ASSERT;
|
||||||
|
gl_->StencilMaskSeparate(GL_BACK, desc.depth_stencil_state->back.write_mask);
|
||||||
|
GL_ASSERT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gl_->Disable(GL_STENCIL_TEST);
|
||||||
|
GL_ASSERT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gl_->Disable(GL_DEPTH_TEST);
|
gl_->Disable(GL_DEPTH_TEST);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
|
gl_->Disable(GL_STENCIL_TEST);
|
||||||
|
GL_ASSERT;
|
||||||
|
gl_->StencilMask(0);
|
||||||
|
GL_ASSERT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (desc.color_attachment.blend)
|
if (desc.color_state.blend)
|
||||||
{
|
{
|
||||||
rhi::BlendDesc& bl = *desc.color_attachment.blend;
|
rhi::BlendDesc& bl = *desc.color_state.blend;
|
||||||
gl_->Enable(GL_BLEND);
|
gl_->Enable(GL_BLEND);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
gl_->BlendFuncSeparate(
|
gl_->BlendFuncSeparate(
|
||||||
map_blend_factor(bl.source_factor_color),
|
map_blend_factor(bl.source_factor_color),
|
||||||
map_blend_factor(bl.dest_factor_color),
|
map_blend_factor(bl.dest_factor_color),
|
||||||
map_blend_factor(bl.source_factor_alpha),
|
map_blend_factor(bl.source_factor_alpha),
|
||||||
map_blend_factor(bl.dest_factor_alpha)
|
map_blend_factor(bl.dest_factor_alpha)
|
||||||
);
|
);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
gl_->BlendEquationSeparate(map_blend_function(bl.color_function), map_blend_function(bl.alpha_function));
|
gl_->BlendEquationSeparate(map_blend_function(bl.color_function), map_blend_function(bl.alpha_function));
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
gl_->BlendColor(desc.blend_color.r, desc.blend_color.g, desc.blend_color.b, desc.blend_color.a);
|
gl_->BlendColor(desc.blend_color.r, desc.blend_color.g, desc.blend_color.b, desc.blend_color.a);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -1359,28 +1446,28 @@ void GlCoreRhi::bind_pipeline(Handle<GraphicsContext> ctx, Handle<Pipeline> pipe
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_->ColorMask(
|
gl_->ColorMask(
|
||||||
desc.color_attachment.color_mask.r ? GL_TRUE : GL_FALSE,
|
desc.color_state.color_mask.r ? GL_TRUE : GL_FALSE,
|
||||||
desc.color_attachment.color_mask.g ? GL_TRUE : GL_FALSE,
|
desc.color_state.color_mask.g ? GL_TRUE : GL_FALSE,
|
||||||
desc.color_attachment.color_mask.b ? GL_TRUE : GL_FALSE,
|
desc.color_state.color_mask.b ? GL_TRUE : GL_FALSE,
|
||||||
desc.color_attachment.color_mask.a ? GL_TRUE : GL_FALSE
|
desc.color_state.color_mask.a ? GL_TRUE : GL_FALSE
|
||||||
);
|
);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
|
|
||||||
GLenum cull_face = map_cull_mode(desc.cull);
|
GLenum cull_face = map_cull_mode(desc.cull);
|
||||||
if (cull_face == GL_NONE)
|
if (cull_face == GL_NONE)
|
||||||
{
|
{
|
||||||
gl_->Disable(GL_CULL_FACE);
|
gl_->Disable(GL_CULL_FACE);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gl_->Enable(GL_CULL_FACE);
|
gl_->Enable(GL_CULL_FACE);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
gl_->CullFace(cull_face);
|
gl_->CullFace(cull_face);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
}
|
}
|
||||||
gl_->FrontFace(map_winding(desc.winding));
|
gl_->FrontFace(map_winding(desc.winding));
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
|
|
||||||
current_pipeline_ = pipeline;
|
current_pipeline_ = pipeline;
|
||||||
current_primitive_type_ = desc.primitive;
|
current_primitive_type_ = desc.primitive;
|
||||||
|
|
@ -1425,57 +1512,57 @@ void GlCoreRhi::bind_uniform_set(Handle<GraphicsContext> ctx, uint32_t slot, Han
|
||||||
[&](const float& value)
|
[&](const float& value)
|
||||||
{
|
{
|
||||||
gl_->Uniform1f(pipeline_uniform, value);
|
gl_->Uniform1f(pipeline_uniform, value);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
},
|
},
|
||||||
[&](const glm::vec2& value)
|
[&](const glm::vec2& value)
|
||||||
{
|
{
|
||||||
gl_->Uniform2f(pipeline_uniform, value.x, value.y);
|
gl_->Uniform2f(pipeline_uniform, value.x, value.y);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
},
|
},
|
||||||
[&](const glm::vec3& value)
|
[&](const glm::vec3& value)
|
||||||
{
|
{
|
||||||
gl_->Uniform3f(pipeline_uniform, value.x, value.y, value.z);
|
gl_->Uniform3f(pipeline_uniform, value.x, value.y, value.z);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
},
|
},
|
||||||
[&](const glm::vec4& value)
|
[&](const glm::vec4& value)
|
||||||
{
|
{
|
||||||
gl_->Uniform4f(pipeline_uniform, value.x, value.y, value.z, value.w);
|
gl_->Uniform4f(pipeline_uniform, value.x, value.y, value.z, value.w);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
},
|
},
|
||||||
[&](const int32_t& value)
|
[&](const int32_t& value)
|
||||||
{
|
{
|
||||||
gl_->Uniform1i(pipeline_uniform, value);
|
gl_->Uniform1i(pipeline_uniform, value);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
},
|
},
|
||||||
[&](const glm::ivec2& value)
|
[&](const glm::ivec2& value)
|
||||||
{
|
{
|
||||||
gl_->Uniform2i(pipeline_uniform, value.x, value.y);
|
gl_->Uniform2i(pipeline_uniform, value.x, value.y);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
},
|
},
|
||||||
[&](const glm::ivec3& value)
|
[&](const glm::ivec3& value)
|
||||||
{
|
{
|
||||||
gl_->Uniform3i(pipeline_uniform, value.x, value.y, value.z);
|
gl_->Uniform3i(pipeline_uniform, value.x, value.y, value.z);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
},
|
},
|
||||||
[&](const glm::ivec4& value)
|
[&](const glm::ivec4& value)
|
||||||
{
|
{
|
||||||
gl_->Uniform4i(pipeline_uniform, value.x, value.y, value.z, value.w);
|
gl_->Uniform4i(pipeline_uniform, value.x, value.y, value.z, value.w);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
},
|
},
|
||||||
[&](const glm::mat2& value)
|
[&](const glm::mat2& value)
|
||||||
{
|
{
|
||||||
gl_->UniformMatrix2fv(pipeline_uniform, 1, false, glm::value_ptr(value));
|
gl_->UniformMatrix2fv(pipeline_uniform, 1, false, glm::value_ptr(value));
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
},
|
},
|
||||||
[&](const glm::mat3& value)
|
[&](const glm::mat3& value)
|
||||||
{
|
{
|
||||||
gl_->UniformMatrix3fv(pipeline_uniform, 1, false, glm::value_ptr(value));
|
gl_->UniformMatrix3fv(pipeline_uniform, 1, false, glm::value_ptr(value));
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
},
|
},
|
||||||
[&](const glm::mat4& value)
|
[&](const glm::mat4& value)
|
||||||
{
|
{
|
||||||
gl_->UniformMatrix4fv(pipeline_uniform, 1, false, glm::value_ptr(value));
|
gl_->UniformMatrix4fv(pipeline_uniform, 1, false, glm::value_ptr(value));
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
std::visit(visitor, update_data);
|
std::visit(visitor, update_data);
|
||||||
|
|
@ -1530,11 +1617,11 @@ void GlCoreRhi::bind_binding_set(Handle<GraphicsContext> ctx, Handle<BindingSet>
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
gl_->ActiveTexture(active_texture);
|
gl_->ActiveTexture(active_texture);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
gl_->BindTexture(GL_TEXTURE_2D, texture_gl_name);
|
gl_->BindTexture(GL_TEXTURE_2D, texture_gl_name);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
gl_->Uniform1i(sampler_uniform_loc, uniform_value);
|
gl_->Uniform1i(sampler_uniform_loc, uniform_value);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1577,7 +1664,7 @@ void GlCoreRhi::draw(Handle<GraphicsContext> ctx, uint32_t vertex_count, uint32_
|
||||||
SRB2_ASSERT(current_render_pass_.has_value() == true && current_pipeline_.has_value() == true);
|
SRB2_ASSERT(current_render_pass_.has_value() == true && current_pipeline_.has_value() == true);
|
||||||
|
|
||||||
gl_->DrawArrays(map_primitive_mode(current_primitive_type_), first_vertex, vertex_count);
|
gl_->DrawArrays(map_primitive_mode(current_primitive_type_), first_vertex, vertex_count);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlCoreRhi::draw_indexed(Handle<GraphicsContext> ctx, uint32_t index_count, uint32_t first_index)
|
void GlCoreRhi::draw_indexed(Handle<GraphicsContext> ctx, uint32_t index_count, uint32_t first_index)
|
||||||
|
|
@ -1598,7 +1685,7 @@ void GlCoreRhi::draw_indexed(Handle<GraphicsContext> ctx, uint32_t index_count,
|
||||||
GL_UNSIGNED_SHORT,
|
GL_UNSIGNED_SHORT,
|
||||||
(const void*)((size_t)first_index * 2 + index_buffer_offset_)
|
(const void*)((size_t)first_index * 2 + index_buffer_offset_)
|
||||||
);
|
);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlCoreRhi::read_pixels(Handle<GraphicsContext> ctx, const Rect& rect, PixelFormat format, tcb::span<std::byte> out)
|
void GlCoreRhi::read_pixels(Handle<GraphicsContext> ctx, const Rect& rect, PixelFormat format, tcb::span<std::byte> out)
|
||||||
|
|
@ -1623,10 +1710,10 @@ void GlCoreRhi::finish()
|
||||||
for (auto it = binding_set_slab_.cbegin(); it != binding_set_slab_.cend(); it++)
|
for (auto it = binding_set_slab_.cbegin(); it != binding_set_slab_.cend(); it++)
|
||||||
{
|
{
|
||||||
gl_->BindVertexArray(0);
|
gl_->BindVertexArray(0);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
GLuint vao = reinterpret_cast<const GlCoreBindingSet&>(*it).vao;
|
GLuint vao = reinterpret_cast<const GlCoreBindingSet&>(*it).vao;
|
||||||
gl_->DeleteVertexArrays(1, &vao);
|
gl_->DeleteVertexArrays(1, &vao);
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
}
|
}
|
||||||
binding_set_slab_.clear();
|
binding_set_slab_.clear();
|
||||||
uniform_set_slab_.clear();
|
uniform_set_slab_.clear();
|
||||||
|
|
@ -1644,5 +1731,5 @@ void GlCoreRhi::finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
disposal_.clear();
|
disposal_.clear();
|
||||||
GL_ASSERT
|
GL_ASSERT;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,13 @@ namespace srb2::rhi
|
||||||
|
|
||||||
struct GlCoreFramebufferKey
|
struct GlCoreFramebufferKey
|
||||||
{
|
{
|
||||||
TextureOrRenderbuffer color;
|
Handle<Texture> color;
|
||||||
std::optional<TextureOrRenderbuffer> depth;
|
std::optional<Handle<Renderbuffer>> depth_stencil;
|
||||||
|
|
||||||
bool operator==(const GlCoreFramebufferKey& rhs) const noexcept { return color == rhs.color && depth == rhs.depth; }
|
bool operator==(const GlCoreFramebufferKey& rhs) const noexcept
|
||||||
|
{
|
||||||
|
return color == rhs.color && depth_stencil == rhs.depth_stencil;
|
||||||
|
}
|
||||||
|
|
||||||
bool operator!=(const GlCoreFramebufferKey& rhs) const noexcept { return !(*this == rhs); }
|
bool operator!=(const GlCoreFramebufferKey& rhs) const noexcept { return !(*this == rhs); }
|
||||||
};
|
};
|
||||||
|
|
@ -43,24 +46,13 @@ struct std::hash<srb2::rhi::GlCoreFramebufferKey>
|
||||||
{
|
{
|
||||||
std::size_t operator()(const srb2::rhi::GlCoreFramebufferKey& key) const
|
std::size_t operator()(const srb2::rhi::GlCoreFramebufferKey& key) const
|
||||||
{
|
{
|
||||||
struct GetHandleHashVisitor
|
std::size_t color_hash = std::hash<const srb2::rhi::Handle<srb2::rhi::Texture>>()(key.color);
|
||||||
|
std::size_t depth_stencil_hash = 0;
|
||||||
|
if (key.depth_stencil)
|
||||||
{
|
{
|
||||||
uint32_t operator()(const srb2::rhi::Handle<srb2::rhi::Texture>& handle) const noexcept
|
depth_stencil_hash = std::hash<const srb2::rhi::Handle<srb2::rhi::Renderbuffer>>()(*key.depth_stencil);
|
||||||
{
|
|
||||||
return std::hash<srb2::rhi::Handle<srb2::rhi::Texture>>()(handle);
|
|
||||||
}
|
|
||||||
uint32_t operator()(const srb2::rhi::Handle<srb2::rhi::Renderbuffer>& handle) const noexcept
|
|
||||||
{
|
|
||||||
return std::hash<srb2::rhi::Handle<srb2::rhi::Renderbuffer>>()(handle);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
std::size_t color_hash = std::visit(GetHandleHashVisitor {}, key.color);
|
|
||||||
std::size_t depth_hash = 0;
|
|
||||||
if (key.depth)
|
|
||||||
{
|
|
||||||
depth_hash = std::visit(GetHandleHashVisitor {}, *key.depth);
|
|
||||||
}
|
}
|
||||||
return color_hash ^ (depth_hash << 1);
|
return color_hash ^ (depth_stencil_hash << 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -314,7 +314,7 @@ namespace std
|
||||||
{
|
{
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct hash<srb2::rhi::Handle<T>>
|
struct hash<const srb2::rhi::Handle<T>>
|
||||||
{
|
{
|
||||||
std::size_t operator()(const srb2::rhi::Handle<T>& e) const
|
std::size_t operator()(const srb2::rhi::Handle<T>& e) const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ struct Buffer
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// @brief Sampler image source or color image attachment.
|
||||||
struct Texture
|
struct Texture
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
@ -46,12 +47,11 @@ struct RenderPass
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// @brief Depth-stencil image attachment.
|
||||||
struct Renderbuffer
|
struct Renderbuffer
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
using TextureOrRenderbuffer = std::variant<Handle<Texture>, Handle<Renderbuffer>>;
|
|
||||||
|
|
||||||
enum class VertexAttributeFormat
|
enum class VertexAttributeFormat
|
||||||
{
|
{
|
||||||
kFloat,
|
kFloat,
|
||||||
|
|
@ -90,8 +90,7 @@ enum class TextureFormat
|
||||||
kLuminance,
|
kLuminance,
|
||||||
kLuminanceAlpha,
|
kLuminanceAlpha,
|
||||||
kRGB,
|
kRGB,
|
||||||
kRGBA,
|
kRGBA
|
||||||
kDepth
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class CompareFunc
|
enum class CompareFunc
|
||||||
|
|
@ -363,16 +362,41 @@ struct BlendDesc
|
||||||
BlendFunction alpha_function;
|
BlendFunction alpha_function;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PipelineDepthAttachmentDesc
|
enum class StencilOp
|
||||||
{
|
{
|
||||||
PixelFormat format;
|
kKeep,
|
||||||
CompareFunc func;
|
kZero,
|
||||||
bool write;
|
kReplace,
|
||||||
|
kIncrementClamp,
|
||||||
|
kDecrementClamp,
|
||||||
|
kInvert,
|
||||||
|
kIncrementWrap,
|
||||||
|
kDecrementWrap
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PipelineColorAttachmentDesc
|
struct PipelineStencilOpStateDesc
|
||||||
|
{
|
||||||
|
StencilOp fail;
|
||||||
|
StencilOp pass;
|
||||||
|
StencilOp depth_fail;
|
||||||
|
CompareFunc stencil_compare;
|
||||||
|
uint32_t compare_mask;
|
||||||
|
uint32_t write_mask;
|
||||||
|
uint32_t reference;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PipelineDepthStencilStateDesc
|
||||||
|
{
|
||||||
|
bool depth_test;
|
||||||
|
bool depth_write;
|
||||||
|
CompareFunc depth_func;
|
||||||
|
bool stencil_test;
|
||||||
|
PipelineStencilOpStateDesc front;
|
||||||
|
PipelineStencilOpStateDesc back;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PipelineColorStateDesc
|
||||||
{
|
{
|
||||||
PixelFormat format;
|
|
||||||
std::optional<BlendDesc> blend;
|
std::optional<BlendDesc> blend;
|
||||||
ColorMask color_mask;
|
ColorMask color_mask;
|
||||||
};
|
};
|
||||||
|
|
@ -383,9 +407,8 @@ struct PipelineDesc
|
||||||
VertexInputDesc vertex_input;
|
VertexInputDesc vertex_input;
|
||||||
UniformInputDesc uniform_input;
|
UniformInputDesc uniform_input;
|
||||||
SamplerInputDesc sampler_input;
|
SamplerInputDesc sampler_input;
|
||||||
std::optional<PipelineDepthAttachmentDesc> depth_attachment;
|
std::optional<PipelineDepthStencilStateDesc> depth_stencil_state;
|
||||||
// std::optional<StencilAttachmentDesc> stencil_attachment;
|
PipelineColorStateDesc color_state;
|
||||||
PipelineColorAttachmentDesc color_attachment;
|
|
||||||
PrimitiveType primitive;
|
PrimitiveType primitive;
|
||||||
CullMode cull;
|
CullMode cull;
|
||||||
FaceWinding winding;
|
FaceWinding winding;
|
||||||
|
|
@ -394,24 +417,35 @@ struct PipelineDesc
|
||||||
|
|
||||||
struct RenderPassDesc
|
struct RenderPassDesc
|
||||||
{
|
{
|
||||||
std::optional<PixelFormat> depth_format;
|
bool use_depth_stencil;
|
||||||
PixelFormat color_format;
|
AttachmentLoadOp color_load_op;
|
||||||
AttachmentLoadOp load_op;
|
AttachmentStoreOp color_store_op;
|
||||||
AttachmentStoreOp store_op;
|
AttachmentLoadOp depth_load_op;
|
||||||
|
AttachmentStoreOp depth_store_op;
|
||||||
|
AttachmentLoadOp stencil_load_op;
|
||||||
|
AttachmentStoreOp stencil_store_op;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RenderbufferDesc
|
struct RenderbufferDesc
|
||||||
{
|
{
|
||||||
PixelFormat format;
|
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class TextureWrapMode
|
||||||
|
{
|
||||||
|
kRepeat,
|
||||||
|
kMirroredRepeat,
|
||||||
|
kClamp
|
||||||
|
};
|
||||||
|
|
||||||
struct TextureDesc
|
struct TextureDesc
|
||||||
{
|
{
|
||||||
TextureFormat format;
|
TextureFormat format;
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
|
TextureWrapMode u_wrap;
|
||||||
|
TextureWrapMode v_wrap;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BufferDesc
|
struct BufferDesc
|
||||||
|
|
@ -424,8 +458,8 @@ struct BufferDesc
|
||||||
struct RenderPassBeginInfo
|
struct RenderPassBeginInfo
|
||||||
{
|
{
|
||||||
Handle<RenderPass> render_pass;
|
Handle<RenderPass> render_pass;
|
||||||
TextureOrRenderbuffer color_attachment;
|
Handle<Texture> color_attachment;
|
||||||
std::optional<TextureOrRenderbuffer> depth_attachment;
|
std::optional<Handle<Renderbuffer>> depth_stencil_attachment;
|
||||||
glm::vec4 clear_color;
|
glm::vec4 clear_color;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue