mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
rhi: Remove Pipeline, Uniform/BindingSet, add dynamic state
The pipeline abstraction mimicked Vulkan and d3d12 explicit pipeline state objects but, like GraphicsContext, was ill-considered for the kinds of drawing behavior SRB2 uses. Rather than push this complexity into the drawing code, it will instead be the responsibility of the backend to manage explicit pipeline objects if necessary. Now, drawing code must create a Program instance, bind it, and set the rasterizer state to do the equivalent. Uniform, sampler, and vertex attribute bindings are significantly simpler to set up now.
This commit is contained in:
parent
4499979458
commit
136761cf3b
17 changed files with 795 additions and 1275 deletions
|
|
@ -10,11 +10,14 @@
|
|||
|
||||
#include "blit_postimg_screens.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <glm/mat3x3.hpp>
|
||||
#include <glm/mat4x4.hpp>
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <tcb/span.hpp>
|
||||
|
||||
#include "../p_tick.h"
|
||||
#include "../i_time.h"
|
||||
|
|
@ -36,34 +39,6 @@ struct BlitVertex
|
|||
};
|
||||
} // namespace
|
||||
|
||||
static const PipelineDesc kPostimgPipelineDesc =
|
||||
{
|
||||
PipelineProgram::kPostimg,
|
||||
{{{sizeof(BlitVertex)}}, {{VertexAttributeName::kPosition, 0, 0}, {VertexAttributeName::kTexCoord0, 0, 12}}},
|
||||
{{{{UniformName::kTime, UniformName::kProjection, UniformName::kModelView, UniformName::kTexCoord0Transform, UniformName::kTexCoord0Min, UniformName::kTexCoord0Max, UniformName::kPostimgWater, UniformName::kPostimgHeat}}}},
|
||||
{{SamplerName::kSampler0}},
|
||||
std::nullopt,
|
||||
{std::nullopt, {true, true, true, true}},
|
||||
PrimitiveType::kTriangles,
|
||||
CullMode::kNone,
|
||||
FaceWinding::kCounterClockwise,
|
||||
{0.0, 0.0, 0.0, 1.0}
|
||||
};
|
||||
|
||||
static const PipelineDesc kPostimgIndexedPipelineDesc =
|
||||
{
|
||||
PipelineProgram::kPostimg,
|
||||
{{{sizeof(BlitVertex)}}, {{VertexAttributeName::kPosition, 0, 0}, {VertexAttributeName::kTexCoord0, 0, 12}}},
|
||||
{{{{UniformName::kTime, UniformName::kProjection, UniformName::kModelView, UniformName::kTexCoord0Transform, UniformName::kTexCoord0Min, UniformName::kTexCoord0Max, UniformName::kPostimgWater, UniformName::kPostimgHeat}}}},
|
||||
{{SamplerName::kSampler0, SamplerName::kSampler1}},
|
||||
std::nullopt,
|
||||
{std::nullopt, {true, true, true, true}},
|
||||
PrimitiveType::kTriangles,
|
||||
CullMode::kNone,
|
||||
FaceWinding::kCounterClockwise,
|
||||
{0.0, 0.0, 0.0, 1.0}
|
||||
};
|
||||
|
||||
static const BlitVertex kVerts[] =
|
||||
{{-.5f, -.5f, 0.f, 0.f, 0.f}, {.5f, -.5f, 0.f, 1.f, 0.f}, {-.5f, .5f, 0.f, 0.f, 1.f}, {.5f, .5f, 0.f, 1.f, 1.f}};
|
||||
|
||||
|
|
@ -106,27 +81,81 @@ void BlitPostimgScreens::draw(Rhi& rhi)
|
|||
|
||||
for (uint32_t i = 0; i < screens_; i++)
|
||||
{
|
||||
BlitPostimgScreens::ScreenConfig& screen_config = screen_configs_[i];
|
||||
BlitPostimgScreens::ScreenData& data = screen_data_[i];
|
||||
|
||||
rhi.bind_pipeline(data.pipeline);
|
||||
glm::mat4 projection = glm::scale(glm::identity<glm::mat4>(), glm::vec3(2.f, -2.f, 1.f));
|
||||
glm::mat4 modelview = glm::identity<glm::mat4>();
|
||||
|
||||
glm::vec2 flip_mirror_uv_displace {0.0, 0.0};
|
||||
if (screen_config.post.mirror)
|
||||
{
|
||||
flip_mirror_uv_displace.x = 1 - (1 - screen_config.uv_size.x);
|
||||
}
|
||||
if (screen_config.post.flip)
|
||||
{
|
||||
flip_mirror_uv_displace.y = 1 - (1 - screen_config.uv_size.y);
|
||||
}
|
||||
|
||||
glm::mat3 texcoord_transform =
|
||||
{
|
||||
glm::vec3(screen_config.uv_size.x * (screen_config.post.mirror ? -1 : 1), 0.0, 0.0),
|
||||
glm::vec3(0.0, screen_config.uv_size.y * (screen_config.post.flip ? -1 : 1), 0.0),
|
||||
glm::vec3(screen_config.uv_offset + flip_mirror_uv_displace, 1.0)
|
||||
};
|
||||
|
||||
glm::vec2 texcoord_min = screen_config.uv_offset;
|
||||
glm::vec2 texcoord_max = screen_config.uv_offset + screen_config.uv_size;
|
||||
|
||||
RasterizerStateDesc r_state {};
|
||||
r_state.cull = CullMode::kNone;
|
||||
|
||||
rhi.bind_program(data.program);
|
||||
rhi.set_rasterizer_state(r_state);
|
||||
rhi.set_viewport(get_screen_viewport(i, screens_, target_width_, target_height_));
|
||||
rhi.bind_uniform_set(0, data.uniform_set);
|
||||
rhi.bind_binding_set(data.binding_set);
|
||||
rhi.bind_vertex_attrib("a_position", quad_vbo_, rhi::VertexAttributeFormat::kFloat3, offsetof(BlitVertex, x), sizeof(BlitVertex));
|
||||
rhi.bind_vertex_attrib("a_texcoord0", quad_vbo_, rhi::VertexAttributeFormat::kFloat2, offsetof(BlitVertex, u), sizeof(BlitVertex));
|
||||
rhi.bind_index_buffer(quad_ibo_);
|
||||
rhi.set_uniform("u_time", static_cast<float>(leveltime));
|
||||
rhi.set_uniform("u_projection", projection);
|
||||
rhi.set_uniform("u_modelview", modelview);
|
||||
rhi.set_uniform("u_texcoord0_transform", texcoord_transform);
|
||||
rhi.set_uniform("u_texcoord0_min", texcoord_min);
|
||||
rhi.set_uniform("u_texcoord0_max", texcoord_max);
|
||||
rhi.set_uniform("u_postimg_water", screen_config.post.water);
|
||||
rhi.set_uniform("u_postimg_heat", screen_config.post.heat);
|
||||
rhi.set_sampler("s_sampler0", 0, screen_config.source);
|
||||
if (screen_config.indexed)
|
||||
{
|
||||
rhi.set_sampler("s_sampler1", 1, palette_mgr_->palette());
|
||||
}
|
||||
rhi.draw_indexed(6, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void BlitPostimgScreens::prepass(Rhi& rhi)
|
||||
{
|
||||
if (!pipeline_)
|
||||
if (!program_)
|
||||
{
|
||||
pipeline_ = rhi.create_pipeline(kPostimgPipelineDesc);
|
||||
static const char* defines[1] = {
|
||||
"ENABLE_S_SAMPLER0"
|
||||
};
|
||||
ProgramDesc desc {};
|
||||
desc.name = "postimg";
|
||||
desc.defines = tcb::make_span(defines);
|
||||
program_ = rhi.create_program(desc);
|
||||
}
|
||||
|
||||
if (!indexed_pipeline_)
|
||||
if (!indexed_program_)
|
||||
{
|
||||
indexed_pipeline_ = rhi.create_pipeline(kPostimgIndexedPipelineDesc);
|
||||
static const char* defines[2] = {
|
||||
"ENABLE_S_SAMPLER0",
|
||||
"ENABLE_S_SAMPLER1"
|
||||
};
|
||||
ProgramDesc desc {};
|
||||
desc.name = "postimg";
|
||||
desc.defines = tcb::make_span(defines);
|
||||
program_ = rhi.create_program(desc);
|
||||
}
|
||||
|
||||
if (!quad_vbo_)
|
||||
|
|
@ -161,65 +190,13 @@ void BlitPostimgScreens::transfer(Rhi& rhi)
|
|||
|
||||
if (screen_config.indexed)
|
||||
{
|
||||
data.pipeline = indexed_pipeline_;
|
||||
data.program = program_;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.pipeline = pipeline_;
|
||||
data.program = indexed_program_;
|
||||
}
|
||||
|
||||
VertexAttributeBufferBinding vertex_bindings[] = {{0, quad_vbo_}};
|
||||
TextureBinding sampler_bindings[] =
|
||||
{
|
||||
{SamplerName::kSampler0, screen_config.source},
|
||||
{SamplerName::kSampler1, palette_mgr_->palette()}
|
||||
};
|
||||
|
||||
data.binding_set = rhi.create_binding_set(
|
||||
data.pipeline,
|
||||
{
|
||||
vertex_bindings,
|
||||
tcb::span(sampler_bindings, screen_config.indexed ? 2 : 1)
|
||||
}
|
||||
);
|
||||
|
||||
glm::mat4 projection = glm::scale(glm::identity<glm::mat4>(), glm::vec3(2.f, -2.f, 1.f));
|
||||
glm::mat4 modelview = glm::identity<glm::mat4>();
|
||||
|
||||
glm::vec2 flip_mirror_uv_displace {0.0, 0.0};
|
||||
if (screen_config.post.mirror)
|
||||
{
|
||||
flip_mirror_uv_displace.x = 1 - (1 - screen_config.uv_size.x);
|
||||
}
|
||||
if (screen_config.post.flip)
|
||||
{
|
||||
flip_mirror_uv_displace.y = 1 - (1 - screen_config.uv_size.y);
|
||||
}
|
||||
|
||||
glm::mat3 texcoord_transform =
|
||||
{
|
||||
glm::vec3(screen_config.uv_size.x * (screen_config.post.mirror ? -1 : 1), 0.0, 0.0),
|
||||
glm::vec3(0.0, screen_config.uv_size.y * (screen_config.post.flip ? -1 : 1), 0.0),
|
||||
glm::vec3(screen_config.uv_offset + flip_mirror_uv_displace, 1.0)
|
||||
};
|
||||
|
||||
glm::vec2 texcoord_min = screen_config.uv_offset;
|
||||
glm::vec2 texcoord_max = screen_config.uv_offset + screen_config.uv_size;
|
||||
|
||||
UniformVariant uniforms[] =
|
||||
{
|
||||
static_cast<float>(leveltime),
|
||||
projection,
|
||||
modelview,
|
||||
texcoord_transform,
|
||||
texcoord_min,
|
||||
texcoord_max,
|
||||
screen_config.post.water,
|
||||
screen_config.post.heat
|
||||
};
|
||||
|
||||
data.uniform_set = rhi.create_uniform_set({uniforms});
|
||||
|
||||
screen_data_[i] = std::move(data);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,13 +46,11 @@ public:
|
|||
private:
|
||||
struct ScreenData
|
||||
{
|
||||
rhi::Handle<rhi::Pipeline> pipeline;
|
||||
rhi::Handle<rhi::BindingSet> binding_set;
|
||||
rhi::Handle<rhi::UniformSet> uniform_set;
|
||||
rhi::Handle<rhi::Program> program;
|
||||
};
|
||||
|
||||
rhi::Handle<rhi::Pipeline> pipeline_;
|
||||
rhi::Handle<rhi::Pipeline> indexed_pipeline_;
|
||||
rhi::Handle<rhi::Program> program_;
|
||||
rhi::Handle<rhi::Program> indexed_program_;
|
||||
rhi::Handle<rhi::Buffer> quad_vbo_;
|
||||
rhi::Handle<rhi::Buffer> quad_ibo_;
|
||||
bool upload_quad_buffer_;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include "blit_rect.hpp"
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <tcb/span.hpp>
|
||||
|
|
@ -38,62 +39,6 @@ static const BlitVertex kVerts[] =
|
|||
|
||||
static const uint16_t kIndices[] = {0, 1, 2, 1, 3, 2};
|
||||
|
||||
/// @brief Pipeline used for non-paletted source textures.
|
||||
static const PipelineDesc kUnshadedPipelineDescription = {
|
||||
PipelineProgram::kUnshaded,
|
||||
{{{sizeof(BlitVertex)}}, {{VertexAttributeName::kPosition, 0, 0}, {VertexAttributeName::kTexCoord0, 0, 12}}},
|
||||
{{{UniformName::kProjection}, {{UniformName::kModelView, UniformName::kTexCoord0Transform}}}},
|
||||
{{// RGB/A texture
|
||||
SamplerName::kSampler0}},
|
||||
std::nullopt,
|
||||
{std::nullopt, {true, true, true, true}},
|
||||
PrimitiveType::kTriangles,
|
||||
CullMode::kNone,
|
||||
FaceWinding::kCounterClockwise,
|
||||
{0.f, 0.f, 0.f, 1.f}};
|
||||
|
||||
/// @brief Pipeline used for sharp bilinear special blit.
|
||||
static const PipelineDesc kSharpBilinearPipelineDescription = {
|
||||
PipelineProgram::kSharpBilinear,
|
||||
{{{sizeof(BlitVertex)}}, {{VertexAttributeName::kPosition, 0, 0}, {VertexAttributeName::kTexCoord0, 0, 12}}},
|
||||
{{{UniformName::kProjection}, {{UniformName::kModelView, UniformName::kTexCoord0Transform, UniformName::kSampler0Size}}}},
|
||||
{{// RGB/A texture
|
||||
SamplerName::kSampler0}},
|
||||
std::nullopt,
|
||||
{std::nullopt, {true, true, true, true}},
|
||||
PrimitiveType::kTriangles,
|
||||
CullMode::kNone,
|
||||
FaceWinding::kCounterClockwise,
|
||||
{0.f, 0.f, 0.f, 1.f}};
|
||||
|
||||
/// @brief Pipeline used for CRT special blit
|
||||
static const PipelineDesc kCrtPipelineDescription = {
|
||||
PipelineProgram::kCrt,
|
||||
{{{sizeof(BlitVertex)}}, {{VertexAttributeName::kPosition, 0, 0}, {VertexAttributeName::kTexCoord0, 0, 12}}},
|
||||
{{{UniformName::kProjection}, {{UniformName::kModelView, UniformName::kTexCoord0Transform, UniformName::kSampler0Size}}}},
|
||||
{{// RGB/A texture
|
||||
SamplerName::kSampler0, SamplerName::kSampler1}},
|
||||
std::nullopt,
|
||||
{std::nullopt, {true, true, true, true}},
|
||||
PrimitiveType::kTriangles,
|
||||
CullMode::kNone,
|
||||
FaceWinding::kCounterClockwise,
|
||||
{0.f, 0.f, 0.f, 1.f}};
|
||||
|
||||
/// @brief Pipeline used for CRT special blit (sharp)
|
||||
static const PipelineDesc kCrtSharpPipelineDescription = {
|
||||
PipelineProgram::kCrtSharp,
|
||||
{{{sizeof(BlitVertex)}}, {{VertexAttributeName::kPosition, 0, 0}, {VertexAttributeName::kTexCoord0, 0, 12}}},
|
||||
{{{UniformName::kProjection}, {{UniformName::kModelView, UniformName::kTexCoord0Transform, UniformName::kSampler0Size}}}},
|
||||
{{// RGB/A texture
|
||||
SamplerName::kSampler0, SamplerName::kSampler1}},
|
||||
std::nullopt,
|
||||
{std::nullopt, {true, true, true, true}},
|
||||
PrimitiveType::kTriangles,
|
||||
CullMode::kNone,
|
||||
FaceWinding::kCounterClockwise,
|
||||
{0.f, 0.f, 0.f, 1.f}};
|
||||
|
||||
BlitRectPass::BlitRectPass() : BlitRectPass(BlitRectPass::BlitMode::kNearest) {}
|
||||
BlitRectPass::BlitRectPass(BlitRectPass::BlitMode blit_mode) : blit_mode_(blit_mode) {}
|
||||
BlitRectPass::~BlitRectPass() = default;
|
||||
|
|
@ -107,26 +52,29 @@ void BlitRectPass::draw(Rhi& rhi)
|
|||
|
||||
void BlitRectPass::prepass(Rhi& rhi)
|
||||
{
|
||||
if (!pipeline_)
|
||||
if (!program_)
|
||||
{
|
||||
ProgramDesc desc {};
|
||||
const char* defines[1] = {"ENABLE_VA_TEXCOORD0"};
|
||||
desc.defines = tcb::make_span(defines);
|
||||
switch (blit_mode_)
|
||||
{
|
||||
case BlitRectPass::BlitMode::kNearest:
|
||||
pipeline_ = rhi.create_pipeline(kUnshadedPipelineDescription);
|
||||
break;
|
||||
case BlitRectPass::BlitMode::kSharpBilinear:
|
||||
pipeline_ = rhi.create_pipeline(kSharpBilinearPipelineDescription);
|
||||
break;
|
||||
case BlitRectPass::BlitMode::kCrt:
|
||||
pipeline_ = rhi.create_pipeline(kCrtPipelineDescription);
|
||||
break;
|
||||
case BlitRectPass::BlitMode::kCrtSharp:
|
||||
pipeline_ = rhi.create_pipeline(kCrtSharpPipelineDescription);
|
||||
break;
|
||||
default:
|
||||
std::terminate();
|
||||
case BlitRectPass::BlitMode::kNearest:
|
||||
desc.name = "unshaded";
|
||||
break;
|
||||
case BlitRectPass::BlitMode::kSharpBilinear:
|
||||
desc.name = "sharpbilinear";
|
||||
break;
|
||||
case BlitRectPass::BlitMode::kCrt:
|
||||
desc.name = "crt";
|
||||
break;
|
||||
case BlitRectPass::BlitMode::kCrtSharp:
|
||||
desc.name = "crtsharp";
|
||||
break;
|
||||
default:
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
program_ = rhi.create_program(desc);
|
||||
}
|
||||
|
||||
if (!quad_vbo_)
|
||||
|
|
@ -230,6 +178,18 @@ void BlitRectPass::transfer(Rhi& rhi)
|
|||
rhi.update_texture(dot_pattern_, {0, 0, 12, 4}, PixelFormat::kRGBA8, tcb::as_bytes(tcb::span(kDotPattern)));
|
||||
dot_pattern_needs_upload_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void BlitRectPass::graphics(Rhi& rhi)
|
||||
{
|
||||
rhi.bind_program(program_);
|
||||
|
||||
RasterizerStateDesc rs {};
|
||||
rs.cull = CullMode::kNone;
|
||||
|
||||
rhi.set_rasterizer_state(rs);
|
||||
rhi.bind_vertex_attrib("a_position", quad_vbo_, VertexAttributeFormat::kFloat3, offsetof(BlitVertex, x), sizeof(BlitVertex));
|
||||
rhi.bind_vertex_attrib("a_texcoord0", quad_vbo_, VertexAttributeFormat::kFloat2, offsetof(BlitVertex, u), sizeof(BlitVertex));
|
||||
|
||||
float aspect = 1.0;
|
||||
float output_aspect = 1.0;
|
||||
|
|
@ -242,122 +202,46 @@ void BlitRectPass::transfer(Rhi& rhi)
|
|||
|
||||
rhi::TextureDetails texture_details = rhi.get_texture_details(texture_);
|
||||
|
||||
std::array<rhi::UniformVariant, 1> g1_uniforms = {{
|
||||
// Projection
|
||||
glm::scale(
|
||||
glm::identity<glm::mat4>(),
|
||||
glm::vec3(taller ? 1.f : 1.f / output_aspect, taller ? -1.f / (1.f / output_aspect) : -1.f, 1.f)
|
||||
)
|
||||
}};
|
||||
glm::mat4 projection = glm::scale(
|
||||
glm::identity<glm::mat4>(),
|
||||
glm::vec3(taller ? 1.f : 1.f / output_aspect, taller ? -1.f / (1.f / output_aspect) : -1.f, 1.f)
|
||||
);
|
||||
glm::mat4 modelview = glm::scale(
|
||||
glm::identity<glm::mat4>(),
|
||||
glm::vec3(taller ? 2.f : 2.f * aspect, taller ? 2.f * (1.f / aspect) : 2.f, 1.f)
|
||||
);;
|
||||
glm::mat3 texcoord0_transform = glm::mat3(
|
||||
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 : 0.f, 1.f)
|
||||
);
|
||||
glm::vec2 sampler0_size = glm::vec2(texture_details.width, texture_details.height);
|
||||
|
||||
uniform_sets_[0] = rhi.create_uniform_set({g1_uniforms});
|
||||
rhi.set_uniform("u_projection", projection);
|
||||
rhi.set_uniform("u_modelview", modelview);
|
||||
rhi.set_uniform("u_texcoord0_transform", texcoord0_transform);
|
||||
|
||||
switch (blit_mode_)
|
||||
{
|
||||
case BlitRectPass::BlitMode::kCrt:
|
||||
{
|
||||
std::array<rhi::UniformVariant, 3> g2_uniforms = {
|
||||
// ModelView
|
||||
glm::scale(
|
||||
glm::identity<glm::mat4>(),
|
||||
glm::vec3(taller ? 2.f : 2.f * aspect, taller ? 2.f * (1.f / aspect) : 2.f, 1.f)
|
||||
),
|
||||
// Texcoord0 Transform
|
||||
glm::mat3(
|
||||
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 : 0.f, 1.f)
|
||||
),
|
||||
// Sampler 0 Size
|
||||
glm::vec2(texture_details.width, texture_details.height)
|
||||
};
|
||||
uniform_sets_[1] = rhi.create_uniform_set({g2_uniforms});
|
||||
|
||||
std::array<rhi::VertexAttributeBufferBinding, 1> vbs = {{{0, quad_vbo_}}};
|
||||
std::array<rhi::TextureBinding, 2> tbs = {{{rhi::SamplerName::kSampler0, texture_}, {rhi::SamplerName::kSampler1, dot_pattern_}}};
|
||||
binding_set_ = rhi.create_binding_set(pipeline_, {vbs, tbs});
|
||||
case BlitRectPass::BlitMode::kNearest:
|
||||
break;
|
||||
}
|
||||
case BlitRectPass::BlitMode::kCrtSharp:
|
||||
{
|
||||
std::array<rhi::UniformVariant, 3> g2_uniforms = {
|
||||
// ModelView
|
||||
glm::scale(
|
||||
glm::identity<glm::mat4>(),
|
||||
glm::vec3(taller ? 2.f : 2.f * aspect, taller ? 2.f * (1.f / aspect) : 2.f, 1.f)
|
||||
),
|
||||
// Texcoord0 Transform
|
||||
glm::mat3(
|
||||
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 : 0.f, 1.f)
|
||||
),
|
||||
// Sampler 0 Size
|
||||
glm::vec2(texture_details.width, texture_details.height)
|
||||
};
|
||||
uniform_sets_[1] = rhi.create_uniform_set({g2_uniforms});
|
||||
|
||||
std::array<rhi::VertexAttributeBufferBinding, 1> vbs = {{{0, quad_vbo_}}};
|
||||
std::array<rhi::TextureBinding, 2> tbs = {{{rhi::SamplerName::kSampler0, texture_}, {rhi::SamplerName::kSampler1, dot_pattern_}}};
|
||||
binding_set_ = rhi.create_binding_set(pipeline_, {vbs, tbs});
|
||||
break;
|
||||
}
|
||||
case BlitRectPass::BlitMode::kSharpBilinear:
|
||||
{
|
||||
std::array<rhi::UniformVariant, 3> g2_uniforms = {
|
||||
// ModelView
|
||||
glm::scale(
|
||||
glm::identity<glm::mat4>(),
|
||||
glm::vec3(taller ? 2.f : 2.f * aspect, taller ? 2.f * (1.f / aspect) : 2.f, 1.f)
|
||||
),
|
||||
// Texcoord0 Transform
|
||||
glm::mat3(
|
||||
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 : 0.f, 1.f)
|
||||
),
|
||||
// Sampler0 size
|
||||
glm::vec2(texture_details.width, texture_details.height)
|
||||
};
|
||||
uniform_sets_[1] = rhi.create_uniform_set({g2_uniforms});
|
||||
|
||||
std::array<rhi::VertexAttributeBufferBinding, 1> vbs = {{{0, quad_vbo_}}};
|
||||
std::array<rhi::TextureBinding, 1> tbs = {{{rhi::SamplerName::kSampler0, texture_}}};
|
||||
binding_set_ = rhi.create_binding_set(pipeline_, {vbs, tbs});
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
std::array<rhi::UniformVariant, 2> g2_uniforms = {
|
||||
// ModelView
|
||||
glm::scale(
|
||||
glm::identity<glm::mat4>(),
|
||||
glm::vec3(taller ? 2.f : 2.f * aspect, taller ? 2.f * (1.f / aspect) : 2.f, 1.f)
|
||||
),
|
||||
// Texcoord0 Transform
|
||||
glm::mat3(
|
||||
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 : 0.f, 1.f)
|
||||
)
|
||||
};
|
||||
uniform_sets_[1] = rhi.create_uniform_set({g2_uniforms});
|
||||
|
||||
std::array<rhi::VertexAttributeBufferBinding, 1> vbs = {{{0, quad_vbo_}}};
|
||||
std::array<rhi::TextureBinding, 1> tbs = {{{rhi::SamplerName::kSampler0, texture_}}};
|
||||
binding_set_ = rhi.create_binding_set(pipeline_, {vbs, tbs});
|
||||
rhi.set_uniform("u_sampler0_size", sampler0_size);
|
||||
break;
|
||||
}
|
||||
rhi.set_sampler("s_sampler0", 0, texture_);
|
||||
switch (blit_mode_)
|
||||
{
|
||||
case BlitRectPass::BlitMode::kCrt:
|
||||
rhi.set_sampler("s_sampler1", 1, dot_pattern_);
|
||||
break;
|
||||
case BlitRectPass::BlitMode::kCrtSharp:
|
||||
rhi.set_sampler("s_sampler1", 1, dot_pattern_);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BlitRectPass::graphics(Rhi& rhi)
|
||||
{
|
||||
rhi.bind_pipeline(pipeline_);
|
||||
rhi.set_viewport(output_position_);
|
||||
rhi.bind_uniform_set(0, uniform_sets_[0]);
|
||||
rhi.bind_uniform_set(1, uniform_sets_[1]);
|
||||
rhi.bind_binding_set(binding_set_);
|
||||
rhi.bind_index_buffer(quad_ibo_);
|
||||
rhi.draw_indexed(6, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ public:
|
|||
};
|
||||
|
||||
private:
|
||||
rhi::Handle<rhi::Pipeline> pipeline_;
|
||||
rhi::Handle<rhi::Program> program_;
|
||||
rhi::Handle<rhi::Texture> texture_;
|
||||
uint32_t texture_width_ = 0;
|
||||
uint32_t texture_height_ = 0;
|
||||
|
|
@ -42,8 +42,6 @@ private:
|
|||
bool output_flip_ = false;
|
||||
rhi::Handle<rhi::Buffer> quad_vbo_;
|
||||
rhi::Handle<rhi::Buffer> quad_ibo_;
|
||||
std::array<rhi::Handle<rhi::UniformSet>, 2> uniform_sets_;
|
||||
rhi::Handle<rhi::BindingSet> binding_set_;
|
||||
BlitMode blit_mode_;
|
||||
rhi::Handle<rhi::Texture> dot_pattern_;
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include "pass_imgui.hpp"
|
||||
|
||||
#include <imgui.h>
|
||||
#include <tcb/span.hpp>
|
||||
|
||||
#include "../v_video.h"
|
||||
|
||||
|
|
@ -18,28 +19,6 @@ using namespace srb2;
|
|||
using namespace srb2::hwr2;
|
||||
using namespace srb2::rhi;
|
||||
|
||||
static const PipelineDesc kPipelineDesc = {
|
||||
PipelineProgram::kUnshaded,
|
||||
{{{sizeof(ImDrawVert)}},
|
||||
{{VertexAttributeName::kPosition, 0, 0},
|
||||
{VertexAttributeName::kTexCoord0, 0, 12},
|
||||
{VertexAttributeName::kColor, 0, 24}}},
|
||||
{{{UniformName::kProjection}, {{UniformName::kModelView, UniformName::kTexCoord0Transform}}}},
|
||||
{{SamplerName::kSampler0}},
|
||||
PipelineDepthStencilStateDesc {true, true, CompareFunc::kAlways, false, {}, {}},
|
||||
{BlendDesc {
|
||||
BlendFactor::kSourceAlpha,
|
||||
BlendFactor::kOneMinusSourceAlpha,
|
||||
BlendFunction::kAdd,
|
||||
BlendFactor::kOne,
|
||||
BlendFactor::kOneMinusSourceAlpha,
|
||||
BlendFunction::kAdd},
|
||||
{true, true, true, true}},
|
||||
PrimitiveType::kTriangles,
|
||||
CullMode::kNone,
|
||||
FaceWinding::kCounterClockwise,
|
||||
{0.f, 0.f, 0.f, 1.f}};
|
||||
|
||||
ImguiPass::ImguiPass()
|
||||
{
|
||||
}
|
||||
|
|
@ -48,9 +27,16 @@ ImguiPass::~ImguiPass() = default;
|
|||
|
||||
void ImguiPass::prepass(Rhi& rhi)
|
||||
{
|
||||
if (!pipeline_)
|
||||
if (!program_)
|
||||
{
|
||||
pipeline_ = rhi.create_pipeline(kPipelineDesc);
|
||||
const char* defines[2] = {
|
||||
"ENABLE_VA_TEXCOORD0",
|
||||
"ENABLE_VA_COLOR"
|
||||
};
|
||||
ProgramDesc desc;
|
||||
desc.name = "unshaded";
|
||||
desc.defines = tcb::make_span(defines);
|
||||
program_ = rhi.create_program(desc);
|
||||
}
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
|
@ -166,65 +152,67 @@ void ImguiPass::transfer(Rhi& rhi)
|
|||
tcb::span<ImDrawIdx> index_span = tcb::span(im_list->IdxBuffer.Data, im_list->IdxBuffer.size());
|
||||
rhi.update_buffer(ibo, 0, tcb::as_bytes(index_span));
|
||||
|
||||
// Uniform sets
|
||||
std::array<UniformVariant, 1> g1_uniforms = {
|
||||
// Projection
|
||||
glm::mat4(
|
||||
glm::vec4(2.f / vid.realwidth, 0.f, 0.f, 0.f),
|
||||
glm::vec4(0.f, 2.f / vid.realheight, 0.f, 0.f),
|
||||
glm::vec4(0.f, 0.f, 1.f, 0.f),
|
||||
glm::vec4(-1.f, 1.f, 0.f, 1.f)
|
||||
)
|
||||
};
|
||||
std::array<UniformVariant, 2> g2_uniforms = {
|
||||
// ModelView
|
||||
glm::mat4(
|
||||
glm::vec4(1.f, 0.f, 0.f, 0.f),
|
||||
glm::vec4(0.f, -1.f, 0.f, 0.f),
|
||||
glm::vec4(0.f, 0.f, 1.f, 0.f),
|
||||
glm::vec4(0.f, 0, 0.f, 1.f)
|
||||
),
|
||||
// Texcoord0 Transform
|
||||
glm::mat3(
|
||||
glm::vec3(1.f, 0.f, 0.f),
|
||||
glm::vec3(0.f, 1.f, 0.f),
|
||||
glm::vec3(0.f, 0.f, 1.f)
|
||||
)
|
||||
};
|
||||
Handle<UniformSet> us_1 = rhi.create_uniform_set({g1_uniforms});
|
||||
Handle<UniformSet> us_2 = rhi.create_uniform_set({g2_uniforms});
|
||||
|
||||
draw_list.us_1 = us_1;
|
||||
draw_list.us_2 = us_2;
|
||||
|
||||
for (auto& draw_cmd : draw_list.cmds)
|
||||
{
|
||||
// Binding set
|
||||
std::array<rhi::VertexAttributeBufferBinding, 1> vbos = {{{0, vbo}}};
|
||||
std::array<rhi::TextureBinding, 1> tbs = {{{rhi::SamplerName::kSampler0, draw_cmd.tex}}};
|
||||
rhi::Handle<rhi::BindingSet> binding_set = rhi.create_binding_set(pipeline_, {vbos, tbs});
|
||||
draw_cmd.binding_set = binding_set;
|
||||
draw_cmd.vbo = vbo;
|
||||
draw_cmd.ibo = ibo;
|
||||
draw_cmd.tex = draw_cmd.tex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ImguiPass::graphics(Rhi& rhi)
|
||||
{
|
||||
rhi.begin_default_render_pass(false);
|
||||
rhi.bind_pipeline(pipeline_);
|
||||
rhi.bind_program(program_);
|
||||
RasterizerStateDesc rs;
|
||||
|
||||
rs.cull = CullMode::kNone;
|
||||
rs.winding = FaceWinding::kCounterClockwise;
|
||||
rs.depth_test = true;
|
||||
rs.depth_func = CompareFunc::kAlways;
|
||||
rs.blend_enabled = true;
|
||||
rs.blend_source_factor_color = BlendFactor::kSourceAlpha;
|
||||
rs.blend_dest_factor_color = BlendFactor::kOneMinusSourceAlpha;
|
||||
rs.blend_color_function = BlendFunction::kAdd;
|
||||
rs.blend_source_factor_alpha = BlendFactor::kOne;
|
||||
rs.blend_dest_factor_alpha = BlendFactor::kOneMinusSourceAlpha;
|
||||
rs.blend_alpha_function = BlendFunction::kAdd;
|
||||
|
||||
for (auto& draw_list : draw_lists_)
|
||||
{
|
||||
rhi.bind_uniform_set(0, draw_list.us_1);
|
||||
rhi.bind_uniform_set(1, draw_list.us_2);
|
||||
glm::mat4 projection = glm::mat4(
|
||||
glm::vec4(2.f / vid.realwidth, 0.f, 0.f, 0.f),
|
||||
glm::vec4(0.f, 2.f / vid.realheight, 0.f, 0.f),
|
||||
glm::vec4(0.f, 0.f, 1.f, 0.f),
|
||||
glm::vec4(-1.f, 1.f, 0.f, 1.f)
|
||||
);
|
||||
glm::mat4 modelview = glm::mat4(
|
||||
glm::vec4(1.f, 0.f, 0.f, 0.f),
|
||||
glm::vec4(0.f, -1.f, 0.f, 0.f),
|
||||
glm::vec4(0.f, 0.f, 1.f, 0.f),
|
||||
glm::vec4(0.f, 0, 0.f, 1.f)
|
||||
);
|
||||
glm::mat3 texcoord0_transform = glm::mat3(
|
||||
glm::vec3(1.f, 0.f, 0.f),
|
||||
glm::vec3(0.f, 1.f, 0.f),
|
||||
glm::vec3(0.f, 0.f, 1.f)
|
||||
);
|
||||
rhi.set_uniform("u_projection", projection);
|
||||
rhi.set_uniform("u_modelview", modelview);
|
||||
rhi.set_uniform("u_texcoord0_transform", texcoord0_transform);
|
||||
for (auto& cmd : draw_list.cmds)
|
||||
{
|
||||
rhi.bind_binding_set(cmd.binding_set);
|
||||
rs.scissor_test = true;
|
||||
rs.scissor = cmd.clip;
|
||||
rhi.set_rasterizer_state(rs);
|
||||
rhi.bind_vertex_attrib("a_position", cmd.vbo, VertexAttributeFormat::kFloat3, offsetof(ImDrawVert, pos), sizeof(ImDrawVert));
|
||||
rhi.bind_vertex_attrib("a_texcoord0", cmd.vbo, VertexAttributeFormat::kFloat2, offsetof(ImDrawVert, uv), sizeof(ImDrawVert));
|
||||
rhi.bind_vertex_attrib("a_color", cmd.vbo, VertexAttributeFormat::kFloat4, offsetof(ImDrawVert, colf), sizeof(ImDrawVert));
|
||||
rhi.set_sampler("s_sampler0", 0, cmd.tex);
|
||||
rhi.bind_index_buffer(draw_list.ibo);
|
||||
rhi.set_scissor(cmd.clip);
|
||||
rhi.draw_indexed(cmd.elems, cmd.i_offset);
|
||||
}
|
||||
}
|
||||
rhi.end_render_pass();
|
||||
}
|
||||
|
||||
void ImguiPass::postpass(Rhi& rhi)
|
||||
|
|
|
|||
|
|
@ -22,24 +22,23 @@ class ImguiPass final
|
|||
{
|
||||
struct DrawCmd
|
||||
{
|
||||
rhi::Handle<rhi::Texture> tex;
|
||||
uint32_t v_offset;
|
||||
uint32_t elems;
|
||||
uint32_t i_offset;
|
||||
rhi::Rect clip;
|
||||
rhi::Handle<rhi::BindingSet> binding_set;
|
||||
rhi::Handle<rhi::Buffer> vbo;
|
||||
rhi::Handle<rhi::Buffer> ibo;
|
||||
rhi::Handle<rhi::Texture> tex;
|
||||
};
|
||||
struct DrawList
|
||||
{
|
||||
void* list;
|
||||
rhi::Handle<rhi::Buffer> vbo;
|
||||
rhi::Handle<rhi::Buffer> ibo;
|
||||
rhi::Handle<rhi::UniformSet> us_1;
|
||||
rhi::Handle<rhi::UniformSet> us_2;
|
||||
std::vector<DrawCmd> cmds;
|
||||
};
|
||||
|
||||
rhi::Handle<rhi::Pipeline> pipeline_;
|
||||
rhi::Handle<rhi::Program> program_;
|
||||
rhi::Handle<rhi::Texture> font_atlas_;
|
||||
|
||||
std::vector<DrawList> draw_lists_;
|
||||
|
|
|
|||
|
|
@ -41,22 +41,6 @@ static const uint16_t kPostprocessIndices[] = {0, 1, 2, 1, 3, 2};
|
|||
|
||||
} // namespace
|
||||
|
||||
static const PipelineDesc kWipePipelineDesc = {
|
||||
PipelineProgram::kPostprocessWipe,
|
||||
{{{sizeof(PostprocessVertex)}},
|
||||
{
|
||||
{VertexAttributeName::kPosition, 0, 0},
|
||||
{VertexAttributeName::kTexCoord0, 0, 12},
|
||||
}},
|
||||
{{{{UniformName::kProjection, UniformName::kWipeColorizeMode, UniformName::kWipeEncoreSwizzle}}}},
|
||||
{{SamplerName::kSampler0, SamplerName::kSampler1, SamplerName::kSampler2}},
|
||||
std::nullopt,
|
||||
{std::nullopt, {true, true, true, true}},
|
||||
PrimitiveType::kTriangles,
|
||||
CullMode::kNone,
|
||||
FaceWinding::kCounterClockwise,
|
||||
{0.f, 0.f, 0.f, 1.f}};
|
||||
|
||||
PostprocessWipePass::PostprocessWipePass()
|
||||
{
|
||||
}
|
||||
|
|
@ -73,9 +57,12 @@ void PostprocessWipePass::draw(Rhi& rhi)
|
|||
|
||||
void PostprocessWipePass::prepass(Rhi& rhi)
|
||||
{
|
||||
if (!pipeline_)
|
||||
if (!program_)
|
||||
{
|
||||
pipeline_ = rhi.create_pipeline(kWipePipelineDesc);
|
||||
ProgramDesc desc;
|
||||
desc.name = "postprocesswipe";
|
||||
desc.defines = tcb::span<const char*>();
|
||||
program_ = rhi.create_program(desc);
|
||||
}
|
||||
|
||||
if (!vbo_)
|
||||
|
|
@ -195,20 +182,6 @@ void PostprocessWipePass::transfer(Rhi& rhi)
|
|||
|
||||
tcb::span<const std::byte> data = tcb::as_bytes(tcb::span(mask_data_));
|
||||
rhi.update_texture(wipe_tex_, {0, 0, mask_w_, mask_h_}, PixelFormat::kR8, data);
|
||||
|
||||
UniformVariant uniforms[] = {
|
||||
glm::scale(glm::identity<glm::mat4>(), glm::vec3(2.f, 2.f, 1.f)),
|
||||
static_cast<int32_t>(wipe_color_mode_),
|
||||
static_cast<int32_t>(wipe_swizzle_)
|
||||
};
|
||||
us_ = rhi.create_uniform_set({tcb::span(uniforms)});
|
||||
|
||||
VertexAttributeBufferBinding vbos[] = {{0, vbo_}};
|
||||
TextureBinding tx[] = {
|
||||
{SamplerName::kSampler0, start_},
|
||||
{SamplerName::kSampler1, end_},
|
||||
{SamplerName::kSampler2, wipe_tex_}};
|
||||
bs_ = rhi.create_binding_set(pipeline_, {vbos, tx});
|
||||
}
|
||||
|
||||
void PostprocessWipePass::graphics(Rhi& rhi)
|
||||
|
|
@ -218,10 +191,21 @@ void PostprocessWipePass::graphics(Rhi& rhi)
|
|||
return;
|
||||
}
|
||||
|
||||
rhi.bind_pipeline(pipeline_);
|
||||
rhi.bind_program(program_);
|
||||
|
||||
RasterizerStateDesc desc {};
|
||||
desc.cull = CullMode::kNone;
|
||||
|
||||
rhi.set_rasterizer_state(desc);
|
||||
rhi.set_uniform("u_projection", glm::scale(glm::identity<glm::mat4>(), glm::vec3(2.f, 2.f, 1.f)));
|
||||
rhi.set_uniform("u_wipe_colorize_mode", static_cast<int32_t>(wipe_color_mode_));
|
||||
rhi.set_uniform("u_wipe_encore_swizzle", static_cast<int32_t>(wipe_swizzle_));
|
||||
rhi.set_sampler("s_sampler0", 0, start_);
|
||||
rhi.set_sampler("s_sampler1", 1, end_);
|
||||
rhi.set_sampler("s_sampler2", 2, wipe_tex_);
|
||||
rhi.bind_vertex_attrib("a_position", vbo_, VertexAttributeFormat::kFloat3, offsetof(PostprocessVertex, x), sizeof(PostprocessVertex));
|
||||
rhi.bind_vertex_attrib("a_texcoord0", vbo_, VertexAttributeFormat::kFloat2, offsetof(PostprocessVertex, u), sizeof(PostprocessVertex));
|
||||
rhi.set_viewport({0, 0, width_, height_});
|
||||
rhi.bind_uniform_set(0, us_);
|
||||
rhi.bind_binding_set(bs_);
|
||||
rhi.bind_index_buffer(ibo_);
|
||||
rhi.draw_indexed(6, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,13 +21,11 @@ namespace srb2::hwr2
|
|||
class PostprocessWipePass final
|
||||
{
|
||||
// Internal RHI resources
|
||||
rhi::Handle<rhi::Pipeline> pipeline_;
|
||||
rhi::Handle<rhi::Program> program_;
|
||||
rhi::Handle<rhi::Buffer> vbo_;
|
||||
bool upload_vbo_ = false;
|
||||
rhi::Handle<rhi::Buffer> ibo_;
|
||||
bool upload_ibo_ = false;
|
||||
rhi::Handle<rhi::UniformSet> us_;
|
||||
rhi::Handle<rhi::BindingSet> bs_;
|
||||
rhi::Handle<rhi::Texture> wipe_tex_;
|
||||
int wipe_color_mode_ = 0;
|
||||
int wipe_swizzle_ = 0;
|
||||
|
|
|
|||
|
|
@ -43,78 +43,59 @@ static TwodeePipelineKey pipeline_key_for_cmd(const Draw2dCmd& cmd)
|
|||
return {hwr2::get_blend_mode(cmd), hwr2::is_draw_lines(cmd)};
|
||||
}
|
||||
|
||||
static PipelineDesc make_pipeline_desc(TwodeePipelineKey key)
|
||||
static void set_blend_state(RasterizerStateDesc& desc, BlendMode blend)
|
||||
{
|
||||
constexpr const VertexInputDesc kTwodeeVertexInput = {
|
||||
{{sizeof(TwodeeVertex)}},
|
||||
{{VertexAttributeName::kPosition, 0, 0},
|
||||
{VertexAttributeName::kTexCoord0, 0, 12},
|
||||
{VertexAttributeName::kColor, 0, 20}}};
|
||||
BlendDesc blend_desc;
|
||||
switch (key.blend)
|
||||
switch (blend)
|
||||
{
|
||||
case BlendMode::kAlphaTransparent:
|
||||
blend_desc.source_factor_color = BlendFactor::kSourceAlpha;
|
||||
blend_desc.dest_factor_color = BlendFactor::kOneMinusSourceAlpha;
|
||||
blend_desc.color_function = BlendFunction::kAdd;
|
||||
blend_desc.source_factor_alpha = BlendFactor::kOne;
|
||||
blend_desc.dest_factor_alpha = BlendFactor::kOneMinusSourceAlpha;
|
||||
blend_desc.alpha_function = BlendFunction::kAdd;
|
||||
desc.blend_source_factor_color = BlendFactor::kSourceAlpha;
|
||||
desc.blend_dest_factor_color = BlendFactor::kOneMinusSourceAlpha;
|
||||
desc.blend_color_function = BlendFunction::kAdd;
|
||||
desc.blend_source_factor_alpha = BlendFactor::kOne;
|
||||
desc.blend_dest_factor_alpha = BlendFactor::kOneMinusSourceAlpha;
|
||||
desc.blend_alpha_function = BlendFunction::kAdd;
|
||||
break;
|
||||
case BlendMode::kModulate:
|
||||
blend_desc.source_factor_color = BlendFactor::kDest;
|
||||
blend_desc.dest_factor_color = BlendFactor::kZero;
|
||||
blend_desc.color_function = BlendFunction::kAdd;
|
||||
blend_desc.source_factor_alpha = BlendFactor::kDestAlpha;
|
||||
blend_desc.dest_factor_alpha = BlendFactor::kZero;
|
||||
blend_desc.alpha_function = BlendFunction::kAdd;
|
||||
desc.blend_source_factor_color = BlendFactor::kDest;
|
||||
desc.blend_dest_factor_color = BlendFactor::kZero;
|
||||
desc.blend_color_function = BlendFunction::kAdd;
|
||||
desc.blend_source_factor_alpha = BlendFactor::kDestAlpha;
|
||||
desc.blend_dest_factor_alpha = BlendFactor::kZero;
|
||||
desc.blend_alpha_function = BlendFunction::kAdd;
|
||||
break;
|
||||
case BlendMode::kAdditive:
|
||||
blend_desc.source_factor_color = BlendFactor::kSourceAlpha;
|
||||
blend_desc.dest_factor_color = BlendFactor::kOne;
|
||||
blend_desc.color_function = BlendFunction::kAdd;
|
||||
blend_desc.source_factor_alpha = BlendFactor::kOne;
|
||||
blend_desc.dest_factor_alpha = BlendFactor::kOneMinusSourceAlpha;
|
||||
blend_desc.alpha_function = BlendFunction::kAdd;
|
||||
desc.blend_source_factor_color = BlendFactor::kSourceAlpha;
|
||||
desc.blend_dest_factor_color = BlendFactor::kOne;
|
||||
desc.blend_color_function = BlendFunction::kAdd;
|
||||
desc.blend_source_factor_alpha = BlendFactor::kOne;
|
||||
desc.blend_dest_factor_alpha = BlendFactor::kOneMinusSourceAlpha;
|
||||
desc.blend_alpha_function = BlendFunction::kAdd;
|
||||
break;
|
||||
case BlendMode::kSubtractive:
|
||||
blend_desc.source_factor_color = BlendFactor::kSourceAlpha;
|
||||
blend_desc.dest_factor_color = BlendFactor::kOne;
|
||||
blend_desc.color_function = BlendFunction::kSubtract;
|
||||
blend_desc.source_factor_alpha = BlendFactor::kOne;
|
||||
blend_desc.dest_factor_alpha = BlendFactor::kOneMinusSourceAlpha;
|
||||
blend_desc.alpha_function = BlendFunction::kAdd;
|
||||
desc.blend_source_factor_color = BlendFactor::kSourceAlpha;
|
||||
desc.blend_dest_factor_color = BlendFactor::kOne;
|
||||
desc.blend_color_function = BlendFunction::kSubtract;
|
||||
desc.blend_source_factor_alpha = BlendFactor::kOne;
|
||||
desc.blend_dest_factor_alpha = BlendFactor::kOneMinusSourceAlpha;
|
||||
desc.blend_alpha_function = BlendFunction::kAdd;
|
||||
break;
|
||||
case BlendMode::kReverseSubtractive:
|
||||
blend_desc.source_factor_color = BlendFactor::kSourceAlpha;
|
||||
blend_desc.dest_factor_color = BlendFactor::kOne;
|
||||
blend_desc.color_function = BlendFunction::kReverseSubtract;
|
||||
blend_desc.source_factor_alpha = BlendFactor::kOne;
|
||||
blend_desc.dest_factor_alpha = BlendFactor::kOneMinusSourceAlpha;
|
||||
blend_desc.alpha_function = BlendFunction::kAdd;
|
||||
desc.blend_source_factor_color = BlendFactor::kSourceAlpha;
|
||||
desc.blend_dest_factor_color = BlendFactor::kOne;
|
||||
desc.blend_color_function = BlendFunction::kReverseSubtract;
|
||||
desc.blend_source_factor_alpha = BlendFactor::kOne;
|
||||
desc.blend_dest_factor_alpha = BlendFactor::kOneMinusSourceAlpha;
|
||||
desc.blend_alpha_function = BlendFunction::kAdd;
|
||||
break;
|
||||
case BlendMode::kInvertDest:
|
||||
blend_desc.source_factor_color = BlendFactor::kOne;
|
||||
blend_desc.dest_factor_color = BlendFactor::kOne;
|
||||
blend_desc.color_function = BlendFunction::kSubtract;
|
||||
blend_desc.source_factor_alpha = BlendFactor::kZero;
|
||||
blend_desc.dest_factor_alpha = BlendFactor::kDestAlpha;
|
||||
blend_desc.alpha_function = BlendFunction::kAdd;
|
||||
desc.blend_source_factor_color = BlendFactor::kOne;
|
||||
desc.blend_dest_factor_color = BlendFactor::kOne;
|
||||
desc.blend_color_function = BlendFunction::kSubtract;
|
||||
desc.blend_source_factor_alpha = BlendFactor::kZero;
|
||||
desc.blend_dest_factor_alpha = BlendFactor::kDestAlpha;
|
||||
desc.blend_alpha_function = BlendFunction::kAdd;
|
||||
break;
|
||||
}
|
||||
|
||||
return {
|
||||
PipelineProgram::kUnshadedPaletted,
|
||||
kTwodeeVertexInput,
|
||||
{{{UniformName::kProjection},
|
||||
{{UniformName::kModelView, UniformName::kTexCoord0Transform, UniformName::kSampler0IsIndexedAlpha}}}},
|
||||
{{SamplerName::kSampler0, SamplerName::kSampler1, SamplerName::kSampler2}},
|
||||
std::nullopt,
|
||||
{blend_desc, {true, true, true, true}},
|
||||
key.lines ? PrimitiveType::kLines : PrimitiveType::kTriangles,
|
||||
CullMode::kNone,
|
||||
FaceWinding::kCounterClockwise,
|
||||
{0.f, 0.f, 0.f, 1.f}};
|
||||
}
|
||||
|
||||
void TwodeeRenderer::rewrite_patch_quad_vertices(Draw2dList& list, const Draw2dPatchQuad& cmd) const
|
||||
|
|
@ -233,32 +214,16 @@ void TwodeeRenderer::rewrite_patch_quad_vertices(Draw2dList& list, const Draw2dP
|
|||
|
||||
void TwodeeRenderer::initialize(Rhi& rhi)
|
||||
{
|
||||
{
|
||||
TwodeePipelineKey alpha_transparent_tris = {BlendMode::kAlphaTransparent, false};
|
||||
TwodeePipelineKey modulate_tris = {BlendMode::kModulate, false};
|
||||
TwodeePipelineKey additive_tris = {BlendMode::kAdditive, false};
|
||||
TwodeePipelineKey subtractive_tris = {BlendMode::kSubtractive, false};
|
||||
TwodeePipelineKey revsubtractive_tris = {BlendMode::kReverseSubtractive, false};
|
||||
TwodeePipelineKey invertdest_tris = {BlendMode::kInvertDest, false};
|
||||
TwodeePipelineKey alpha_transparent_lines = {BlendMode::kAlphaTransparent, true};
|
||||
TwodeePipelineKey modulate_lines = {BlendMode::kModulate, true};
|
||||
TwodeePipelineKey additive_lines = {BlendMode::kAdditive, true};
|
||||
TwodeePipelineKey subtractive_lines = {BlendMode::kSubtractive, true};
|
||||
TwodeePipelineKey revsubtractive_lines = {BlendMode::kReverseSubtractive, true};
|
||||
TwodeePipelineKey invertdest_lines = {BlendMode::kInvertDest, true};
|
||||
pipelines_.insert({alpha_transparent_tris, rhi.create_pipeline(make_pipeline_desc(alpha_transparent_tris))});
|
||||
pipelines_.insert({modulate_tris, rhi.create_pipeline(make_pipeline_desc(modulate_tris))});
|
||||
pipelines_.insert({additive_tris, rhi.create_pipeline(make_pipeline_desc(additive_tris))});
|
||||
pipelines_.insert({subtractive_tris, rhi.create_pipeline(make_pipeline_desc(subtractive_tris))});
|
||||
pipelines_.insert({revsubtractive_tris, rhi.create_pipeline(make_pipeline_desc(revsubtractive_tris))});
|
||||
pipelines_.insert({invertdest_tris, rhi.create_pipeline(make_pipeline_desc(invertdest_tris))});
|
||||
pipelines_.insert({alpha_transparent_lines, rhi.create_pipeline(make_pipeline_desc(alpha_transparent_lines))});
|
||||
pipelines_.insert({modulate_lines, rhi.create_pipeline(make_pipeline_desc(modulate_lines))});
|
||||
pipelines_.insert({additive_lines, rhi.create_pipeline(make_pipeline_desc(additive_lines))});
|
||||
pipelines_.insert({subtractive_lines, rhi.create_pipeline(make_pipeline_desc(subtractive_lines))});
|
||||
pipelines_.insert({revsubtractive_lines, rhi.create_pipeline(make_pipeline_desc(revsubtractive_lines))});
|
||||
pipelines_.insert({invertdest_lines, rhi.create_pipeline(make_pipeline_desc(revsubtractive_lines))});
|
||||
}
|
||||
ProgramDesc prog_desc;
|
||||
prog_desc.name = "unshadedpaletted";
|
||||
const char* defines[] = {
|
||||
"ENABLE_U_SAMPLER0_IS_INDEXED_ALPHA",
|
||||
"ENABLE_S_SAMPLER2",
|
||||
"ENABLE_VA_TEXCOORD0",
|
||||
"ENABLE_VA_COLOR"
|
||||
};
|
||||
prog_desc.defines = tcb::make_span(defines);
|
||||
program_ = rhi.create_program(prog_desc);
|
||||
|
||||
{
|
||||
default_tex_ = rhi.create_texture({
|
||||
|
|
@ -377,6 +342,8 @@ void TwodeeRenderer::flush(Rhi& rhi, Twodee& twodee)
|
|||
new_cmd.colormap = nullptr;
|
||||
// safety: a command list is required to have at least 1 command
|
||||
new_cmd.pipeline_key = pipeline_key_for_cmd(list.cmds[0]);
|
||||
new_cmd.primitive = new_cmd.pipeline_key.lines ? PrimitiveType::kLines : PrimitiveType::kTriangles;
|
||||
new_cmd.blend_mode = new_cmd.pipeline_key.blend;
|
||||
merged_list.cmds.push_back(std::move(new_cmd));
|
||||
|
||||
for (auto& cmd : list.cmds)
|
||||
|
|
@ -458,6 +425,8 @@ void TwodeeRenderer::flush(Rhi& rhi, Twodee& twodee)
|
|||
}};
|
||||
std::visit(tex_visitor_again, cmd);
|
||||
the_new_one.pipeline_key = pipeline_key_for_cmd(cmd);
|
||||
the_new_one.primitive = the_new_one.pipeline_key.lines ? PrimitiveType::kLines : PrimitiveType::kTriangles;
|
||||
the_new_one.blend_mode = the_new_one.pipeline_key.blend;
|
||||
merged_list.cmds.push_back(std::move(the_new_one));
|
||||
}
|
||||
|
||||
|
|
@ -495,23 +464,18 @@ void TwodeeRenderer::flush(Rhi& rhi, Twodee& twodee)
|
|||
rhi.update_buffer(merged_list.vbo, 0, vertex_data);
|
||||
rhi.update_buffer(merged_list.ibo, 0, index_data);
|
||||
|
||||
// Update the binding sets for each individual merged command
|
||||
VertexAttributeBufferBinding vbos[] = {{0, merged_list.vbo}};
|
||||
for (auto& mcmd : merged_list.cmds)
|
||||
{
|
||||
TextureBinding tx[3];
|
||||
auto tex_visitor = srb2::Overload {
|
||||
[&](Handle<Texture> texture)
|
||||
{
|
||||
tx[0] = {SamplerName::kSampler0, texture};
|
||||
tx[1] = {SamplerName::kSampler1, palette_tex};
|
||||
mcmd.texture_handle = texture;
|
||||
},
|
||||
[&](const MergedTwodeeCommandFlatTexture& tex)
|
||||
{
|
||||
Handle<Texture> th = flat_manager_->find_or_create_indexed(rhi, tex.lump);
|
||||
SRB2_ASSERT(th != kNullHandle);
|
||||
tx[0] = {SamplerName::kSampler0, th};
|
||||
tx[1] = {SamplerName::kSampler1, palette_tex};
|
||||
mcmd.texture_handle = th;
|
||||
}};
|
||||
if (mcmd.texture)
|
||||
{
|
||||
|
|
@ -519,8 +483,7 @@ void TwodeeRenderer::flush(Rhi& rhi, Twodee& twodee)
|
|||
}
|
||||
else
|
||||
{
|
||||
tx[0] = {SamplerName::kSampler0, default_tex_};
|
||||
tx[1] = {SamplerName::kSampler1, palette_tex};
|
||||
mcmd.texture_handle = default_tex_;
|
||||
}
|
||||
|
||||
const uint8_t* colormap = mcmd.colormap;
|
||||
|
|
@ -530,38 +493,29 @@ void TwodeeRenderer::flush(Rhi& rhi, Twodee& twodee)
|
|||
colormap_h = palette_manager_->find_or_create_colormap(rhi, colormap);
|
||||
SRB2_ASSERT(colormap_h != kNullHandle);
|
||||
}
|
||||
tx[2] = {SamplerName::kSampler2, colormap_h};
|
||||
mcmd.binding_set =
|
||||
rhi.create_binding_set(pipelines_[mcmd.pipeline_key], {tcb::span(vbos), tcb::span(tx)});
|
||||
mcmd.colormap_handle = colormap_h;
|
||||
}
|
||||
|
||||
ctx_list_itr++;
|
||||
}
|
||||
|
||||
// Uniform sets
|
||||
std::array<UniformVariant, 1> g1_uniforms = {
|
||||
// Projection
|
||||
glm::mat4(
|
||||
glm::vec4(2.f / vid.width, 0.f, 0.f, 0.f),
|
||||
glm::vec4(0.f, -2.f / vid.height, 0.f, 0.f),
|
||||
glm::vec4(0.f, 0.f, 1.f, 0.f),
|
||||
glm::vec4(-1.f, 1.f, 0.f, 1.f)
|
||||
),
|
||||
};
|
||||
std::array<UniformVariant, 3> g2_uniforms = {
|
||||
// ModelView
|
||||
glm::identity<glm::mat4>(),
|
||||
// Texcoord0 Transform
|
||||
glm::identity<glm::mat3>(),
|
||||
// Sampler 0 Is Indexed Alpha (yes, it always is)
|
||||
static_cast<int32_t>(1)
|
||||
};
|
||||
Handle<UniformSet> us_1 = rhi.create_uniform_set({tcb::span(g1_uniforms)});
|
||||
Handle<UniformSet> us_2 = rhi.create_uniform_set({tcb::span(g2_uniforms)});
|
||||
|
||||
// Presumably, we're already in a renderpass when flush is called
|
||||
rhi.bind_program(program_);
|
||||
rhi.set_uniform("u_projection", glm::mat4(
|
||||
glm::vec4(2.f / vid.width, 0.f, 0.f, 0.f),
|
||||
glm::vec4(0.f, -2.f / vid.height, 0.f, 0.f),
|
||||
glm::vec4(0.f, 0.f, 1.f, 0.f),
|
||||
glm::vec4(-1.f, 1.f, 0.f, 1.f)
|
||||
));
|
||||
rhi.set_uniform("u_modelview", glm::identity<glm::mat4>());
|
||||
rhi.set_uniform("u_texcoord0_transform", glm::identity<glm::mat3>());
|
||||
rhi.set_uniform("u_sampler0_is_indexed_alpha", static_cast<int32_t>(1));
|
||||
rhi.set_sampler("s_sampler1", 1, palette_tex);
|
||||
for (auto& list : cmd_lists_)
|
||||
{
|
||||
rhi.bind_vertex_attrib("a_position", list.vbo, VertexAttributeFormat::kFloat3, offsetof(TwodeeVertex, x), sizeof(TwodeeVertex));
|
||||
rhi.bind_vertex_attrib("a_texcoord0", list.vbo, VertexAttributeFormat::kFloat2, offsetof(TwodeeVertex, u), sizeof(TwodeeVertex));
|
||||
rhi.bind_vertex_attrib("a_color", list.vbo, VertexAttributeFormat::kFloat4, offsetof(TwodeeVertex, r), sizeof(TwodeeVertex));
|
||||
for (auto& cmd : list.cmds)
|
||||
{
|
||||
if (cmd.elements == 0)
|
||||
|
|
@ -570,13 +524,16 @@ void TwodeeRenderer::flush(Rhi& rhi, Twodee& twodee)
|
|||
// This shouldn't happen, but, just in case...
|
||||
continue;
|
||||
}
|
||||
SRB2_ASSERT(pipelines_.find(cmd.pipeline_key) != pipelines_.end());
|
||||
Handle<Pipeline> pl = pipelines_[cmd.pipeline_key];
|
||||
rhi.bind_pipeline(pl);
|
||||
RasterizerStateDesc desc;
|
||||
desc.cull = CullMode::kNone;
|
||||
desc.primitive = cmd.primitive;
|
||||
desc.blend_enabled = true;
|
||||
set_blend_state(desc, cmd.blend_mode);
|
||||
// Set blend and primitives
|
||||
rhi.set_rasterizer_state(desc);
|
||||
rhi.set_viewport({0, 0, static_cast<uint32_t>(vid.width), static_cast<uint32_t>(vid.height)});
|
||||
rhi.bind_uniform_set(0, us_1);
|
||||
rhi.bind_uniform_set(1, us_2);
|
||||
rhi.bind_binding_set(cmd.binding_set);
|
||||
rhi.set_sampler("s_sampler0", 0, cmd.texture_handle);
|
||||
rhi.set_sampler("s_sampler2", 2, cmd.colormap_handle);
|
||||
rhi.bind_index_buffer(list.ibo);
|
||||
rhi.draw_indexed(cmd.elements, cmd.index_offset);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,10 +11,8 @@
|
|||
#ifndef __SRB2_HWR2_PASS_TWODEE_HPP__
|
||||
#define __SRB2_HWR2_PASS_TWODEE_HPP__
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
|
|
@ -65,10 +63,13 @@ struct MergedTwodeeCommandFlatTexture
|
|||
struct MergedTwodeeCommand
|
||||
{
|
||||
using Texture = std::variant<rhi::Handle<rhi::Texture>, MergedTwodeeCommandFlatTexture>;
|
||||
TwodeePipelineKey pipeline_key = {};
|
||||
rhi::Handle<rhi::BindingSet> binding_set = {};
|
||||
rhi::PrimitiveType primitive;
|
||||
BlendMode blend_mode;
|
||||
std::optional<Texture> texture;
|
||||
TwodeePipelineKey pipeline_key;
|
||||
rhi::Handle<rhi::Texture> texture_handle;
|
||||
const uint8_t* colormap;
|
||||
rhi::Handle<rhi::Texture> colormap_handle;
|
||||
uint32_t index_offset = 0;
|
||||
uint32_t elements = 0;
|
||||
};
|
||||
|
|
@ -96,7 +97,7 @@ class TwodeeRenderer final
|
|||
std::vector<std::tuple<rhi::Handle<rhi::Buffer>, std::size_t>> ibos_;
|
||||
rhi::Handle<rhi::Texture> output_;
|
||||
rhi::Handle<rhi::Texture> default_tex_;
|
||||
std::unordered_map<TwodeePipelineKey, rhi::Handle<rhi::Pipeline>> pipelines_;
|
||||
rhi::Handle<rhi::Program> program_;
|
||||
|
||||
void rewrite_patch_quad_vertices(Draw2dList& list, const Draw2dPatchQuad& cmd) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -322,6 +322,7 @@ void I_FinishUpdate(void)
|
|||
g_hw_state.blit_rect->draw(*rhi);
|
||||
break;
|
||||
}
|
||||
|
||||
rhi->end_render_pass();
|
||||
|
||||
postframe_update(*rhi);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -71,7 +71,7 @@ struct Gl2Platform
|
|||
virtual ~Gl2Platform();
|
||||
|
||||
virtual void present() = 0;
|
||||
virtual std::tuple<std::vector<std::string>, std::vector<std::string>> find_shader_sources(PipelineProgram program) = 0;
|
||||
virtual std::tuple<std::vector<std::string>, std::vector<std::string>> find_shader_sources(const char* name) = 0;
|
||||
virtual Rect get_default_framebuffer_dimensions() = 0;
|
||||
};
|
||||
|
||||
|
|
@ -93,26 +93,13 @@ struct Gl2Renderbuffer : public rhi::Renderbuffer
|
|||
rhi::RenderbufferDesc desc;
|
||||
};
|
||||
|
||||
struct Gl2UniformSet : public rhi::UniformSet
|
||||
{
|
||||
std::vector<rhi::UniformVariant> uniforms;
|
||||
};
|
||||
|
||||
struct Gl2BindingSet : public rhi::BindingSet
|
||||
{
|
||||
std::vector<rhi::VertexAttributeBufferBinding> vertex_buffer_bindings;
|
||||
std::unordered_map<rhi::SamplerName, uint32_t> textures {4};
|
||||
};
|
||||
|
||||
struct Gl2Pipeline : public rhi::Pipeline
|
||||
struct Gl2Program : public rhi::Program
|
||||
{
|
||||
uint32_t vertex_shader = 0;
|
||||
uint32_t fragment_shader = 0;
|
||||
uint32_t program = 0;
|
||||
std::unordered_map<rhi::VertexAttributeName, uint32_t> attrib_locations {2};
|
||||
std::unordered_map<rhi::UniformName, uint32_t> uniform_locations {2};
|
||||
std::unordered_map<rhi::SamplerName, uint32_t> sampler_locations {2};
|
||||
rhi::PipelineDesc desc;
|
||||
std::unordered_map<std::string, uint32_t> attrib_locations;
|
||||
std::unordered_map<std::string, uint32_t> uniform_locations;
|
||||
};
|
||||
|
||||
struct Gl2ActiveUniform
|
||||
|
|
@ -130,9 +117,7 @@ class Gl2Rhi final : public Rhi
|
|||
Slab<Gl2Texture> texture_slab_;
|
||||
Slab<Gl2Buffer> buffer_slab_;
|
||||
Slab<Gl2Renderbuffer> renderbuffer_slab_;
|
||||
Slab<Gl2Pipeline> pipeline_slab_;
|
||||
Slab<Gl2UniformSet> uniform_set_slab_;
|
||||
Slab<Gl2BindingSet> binding_set_slab_;
|
||||
Slab<Gl2Program> program_slab_;
|
||||
|
||||
Handle<Buffer> current_index_buffer_;
|
||||
|
||||
|
|
@ -143,7 +128,7 @@ class Gl2Rhi final : public Rhi
|
|||
};
|
||||
using RenderPassState = std::variant<DefaultRenderPassState, RenderPassBeginInfo>;
|
||||
std::optional<RenderPassState> current_render_pass_;
|
||||
std::optional<Handle<Pipeline>> current_pipeline_;
|
||||
std::optional<Handle<Program>> current_program_;
|
||||
PrimitiveType current_primitive_type_ = PrimitiveType::kPoints;
|
||||
uint32_t index_buffer_offset_ = 0;
|
||||
|
||||
|
|
@ -153,13 +138,15 @@ class Gl2Rhi final : public Rhi
|
|||
uint8_t stencil_back_reference_ = 0;
|
||||
uint8_t stencil_back_compare_mask_ = 0xFF;
|
||||
uint8_t stencil_back_write_mask_ = 0xFF;
|
||||
CompareFunc stencil_front_func_;
|
||||
CompareFunc stencil_back_func_;
|
||||
|
||||
public:
|
||||
Gl2Rhi(std::unique_ptr<Gl2Platform>&& platform, GlLoadFunc load_func);
|
||||
virtual ~Gl2Rhi();
|
||||
|
||||
virtual Handle<Pipeline> create_pipeline(const PipelineDesc& desc) override;
|
||||
virtual void destroy_pipeline(Handle<Pipeline> handle) override;
|
||||
virtual Handle<Program> create_program(const ProgramDesc& desc) override;
|
||||
virtual void destroy_program(Handle<Program> handle) override;
|
||||
|
||||
virtual Handle<Texture> create_texture(const TextureDesc& desc) override;
|
||||
virtual void destroy_texture(Handle<Texture> handle) override;
|
||||
|
|
@ -190,21 +177,33 @@ public:
|
|||
TextureFilterMode min,
|
||||
TextureFilterMode mag
|
||||
) override;
|
||||
virtual Handle<UniformSet>
|
||||
create_uniform_set(const CreateUniformSetInfo& info) override;
|
||||
virtual Handle<BindingSet>
|
||||
create_binding_set(Handle<Pipeline> pipeline, const CreateBindingSetInfo& info)
|
||||
override;
|
||||
|
||||
// Graphics context functions
|
||||
virtual void begin_default_render_pass(bool clear) override;
|
||||
virtual void begin_render_pass(const RenderPassBeginInfo& info) override;
|
||||
virtual void end_render_pass() override;
|
||||
virtual void bind_pipeline(Handle<Pipeline> pipeline) override;
|
||||
virtual void bind_uniform_set(uint32_t slot, Handle<UniformSet> set) override;
|
||||
virtual void bind_binding_set(Handle<BindingSet> set) override;
|
||||
virtual void bind_program(Handle<Program> program) override;
|
||||
virtual void bind_vertex_attrib(
|
||||
const char* name,
|
||||
Handle<Buffer> buffer,
|
||||
VertexAttributeFormat format,
|
||||
uint32_t offset,
|
||||
uint32_t stride
|
||||
) override;
|
||||
virtual void bind_index_buffer(Handle<Buffer> buffer) override;
|
||||
virtual void set_scissor(const Rect& rect) override;
|
||||
virtual void set_uniform(const char* name, float value) override;
|
||||
virtual void set_uniform(const char* name, int value) override;
|
||||
virtual void set_uniform(const char* name, glm::vec2 value) override;
|
||||
virtual void set_uniform(const char* name, glm::vec3 value) override;
|
||||
virtual void set_uniform(const char* name, glm::vec4 value) override;
|
||||
virtual void set_uniform(const char* name, glm::ivec2 value) override;
|
||||
virtual void set_uniform(const char* name, glm::ivec3 value) override;
|
||||
virtual void set_uniform(const char* name, glm::ivec4 value) override;
|
||||
virtual void set_uniform(const char* name, glm::mat2 value) override;
|
||||
virtual void set_uniform(const char* name, glm::mat3 value) override;
|
||||
virtual void set_uniform(const char* name, glm::mat4 value) override;
|
||||
virtual void set_sampler(const char* name, uint32_t slot, Handle<Texture> texture) override;
|
||||
virtual void set_rasterizer_state(const RasterizerStateDesc& desc) override;
|
||||
virtual void set_viewport(const Rect& rect) override;
|
||||
virtual void draw(uint32_t vertex_count, uint32_t first_vertex) override;
|
||||
virtual void draw_indexed(uint32_t index_count, uint32_t first_index) override;
|
||||
|
|
|
|||
116
src/rhi/rhi.hpp
116
src/rhi/rhi.hpp
|
|
@ -24,6 +24,7 @@
|
|||
#include <tcb/span.hpp>
|
||||
|
||||
#include "../core/static_vec.hpp"
|
||||
#include "glm/ext/vector_float2.hpp"
|
||||
#include "handle.hpp"
|
||||
|
||||
namespace srb2::rhi
|
||||
|
|
@ -38,7 +39,8 @@ struct Texture
|
|||
{
|
||||
};
|
||||
|
||||
struct Pipeline
|
||||
/// @brief A linked rendering pipeline program combining a vertex shader and fragment shader.
|
||||
struct Program
|
||||
{
|
||||
};
|
||||
|
||||
|
|
@ -397,16 +399,6 @@ struct ColorMask
|
|||
bool a;
|
||||
};
|
||||
|
||||
struct BlendDesc
|
||||
{
|
||||
BlendFactor source_factor_color;
|
||||
BlendFactor dest_factor_color;
|
||||
BlendFunction color_function;
|
||||
BlendFactor source_factor_alpha;
|
||||
BlendFactor dest_factor_alpha;
|
||||
BlendFunction alpha_function;
|
||||
};
|
||||
|
||||
enum class StencilOp
|
||||
{
|
||||
kKeep,
|
||||
|
|
@ -419,42 +411,41 @@ enum class StencilOp
|
|||
kDecrementWrap
|
||||
};
|
||||
|
||||
struct PipelineStencilOpStateDesc
|
||||
|
||||
struct ProgramDesc
|
||||
{
|
||||
StencilOp fail;
|
||||
StencilOp pass;
|
||||
StencilOp depth_fail;
|
||||
CompareFunc stencil_compare;
|
||||
const char* name;
|
||||
tcb::span<const char*> defines;
|
||||
};
|
||||
|
||||
struct PipelineDepthStencilStateDesc
|
||||
struct RasterizerStateDesc
|
||||
{
|
||||
bool depth_test;
|
||||
bool depth_write;
|
||||
CompareFunc depth_func;
|
||||
bool stencil_test;
|
||||
PipelineStencilOpStateDesc front;
|
||||
PipelineStencilOpStateDesc back;
|
||||
};
|
||||
|
||||
struct PipelineColorStateDesc
|
||||
{
|
||||
std::optional<BlendDesc> blend;
|
||||
ColorMask color_mask;
|
||||
};
|
||||
|
||||
struct PipelineDesc
|
||||
{
|
||||
PipelineProgram program;
|
||||
VertexInputDesc vertex_input;
|
||||
UniformInputDesc uniform_input;
|
||||
SamplerInputDesc sampler_input;
|
||||
std::optional<PipelineDepthStencilStateDesc> depth_stencil_state;
|
||||
PipelineColorStateDesc color_state;
|
||||
PrimitiveType primitive;
|
||||
CullMode cull;
|
||||
FaceWinding winding;
|
||||
glm::vec4 blend_color;
|
||||
PrimitiveType primitive = PrimitiveType::kTriangles;
|
||||
CullMode cull = CullMode::kBack;
|
||||
FaceWinding winding = FaceWinding::kCounterClockwise;
|
||||
ColorMask color_mask = {true, true, true, true};
|
||||
bool blend_enabled = false;
|
||||
glm::vec4 blend_color = {0.0, 0.0, 0.0, 0.0};
|
||||
BlendFactor blend_source_factor_color = BlendFactor::kOne;
|
||||
BlendFactor blend_dest_factor_color = BlendFactor::kZero;
|
||||
BlendFunction blend_color_function = BlendFunction::kAdd;
|
||||
BlendFactor blend_source_factor_alpha = BlendFactor::kOne;
|
||||
BlendFactor blend_dest_factor_alpha = BlendFactor::kZero;
|
||||
BlendFunction blend_alpha_function = BlendFunction::kAdd;
|
||||
bool depth_test = false;
|
||||
bool depth_write = true;
|
||||
CompareFunc depth_func = CompareFunc::kLess;
|
||||
bool stencil_test = false;
|
||||
StencilOp front_fail = StencilOp::kKeep;
|
||||
StencilOp front_pass = StencilOp::kKeep;
|
||||
StencilOp front_depth_fail = StencilOp::kKeep;
|
||||
CompareFunc front_stencil_compare = CompareFunc::kAlways;
|
||||
StencilOp back_fail = StencilOp::kKeep;
|
||||
StencilOp back_pass = StencilOp::kKeep;
|
||||
StencilOp back_depth_fail = StencilOp::kKeep;
|
||||
CompareFunc back_stencil_compare = CompareFunc::kAlways;
|
||||
bool scissor_test = false;
|
||||
Rect scissor = {};
|
||||
};
|
||||
|
||||
struct RenderbufferDesc
|
||||
|
|
@ -565,13 +556,6 @@ struct CreateBindingSetInfo
|
|||
tcb::span<TextureBinding> sampler_textures;
|
||||
};
|
||||
|
||||
struct UniformSet
|
||||
{
|
||||
};
|
||||
struct BindingSet
|
||||
{
|
||||
};
|
||||
|
||||
struct TextureDetails
|
||||
{
|
||||
uint32_t width;
|
||||
|
|
@ -588,8 +572,8 @@ struct Rhi
|
|||
{
|
||||
virtual ~Rhi();
|
||||
|
||||
virtual Handle<Pipeline> create_pipeline(const PipelineDesc& desc) = 0;
|
||||
virtual void destroy_pipeline(Handle<Pipeline> handle) = 0;
|
||||
virtual Handle<Program> create_program(const ProgramDesc& desc) = 0;
|
||||
virtual void destroy_program(Handle<Program> handle) = 0;
|
||||
|
||||
virtual Handle<Texture> create_texture(const TextureDesc& desc) = 0;
|
||||
virtual void destroy_texture(Handle<Texture> handle) = 0;
|
||||
|
|
@ -620,19 +604,33 @@ struct Rhi
|
|||
TextureFilterMode min,
|
||||
TextureFilterMode mag
|
||||
) = 0;
|
||||
virtual Handle<UniformSet> create_uniform_set(const CreateUniformSetInfo& info) = 0;
|
||||
virtual Handle<BindingSet>
|
||||
create_binding_set(Handle<Pipeline> pipeline, const CreateBindingSetInfo& info) = 0;
|
||||
|
||||
// Graphics context functions
|
||||
virtual void begin_default_render_pass(bool clear) = 0;
|
||||
virtual void begin_render_pass(const RenderPassBeginInfo& info) = 0;
|
||||
virtual void end_render_pass() = 0;
|
||||
virtual void bind_pipeline(Handle<Pipeline> pipeline) = 0;
|
||||
virtual void bind_uniform_set(uint32_t slot, Handle<UniformSet> set) = 0;
|
||||
virtual void bind_binding_set(Handle<BindingSet> set) = 0;
|
||||
virtual void bind_program(Handle<Program> program) = 0;
|
||||
virtual void bind_vertex_attrib(
|
||||
const char* name,
|
||||
Handle<Buffer> buffer,
|
||||
VertexAttributeFormat format,
|
||||
uint32_t offset,
|
||||
uint32_t stride
|
||||
) = 0;
|
||||
virtual void bind_index_buffer(Handle<Buffer> buffer) = 0;
|
||||
virtual void set_scissor(const Rect& rect) = 0;
|
||||
virtual void set_uniform(const char* name, float value) = 0;
|
||||
virtual void set_uniform(const char* name, int value) = 0;
|
||||
virtual void set_uniform(const char* name, glm::vec2 value) = 0;
|
||||
virtual void set_uniform(const char* name, glm::vec3 value) = 0;
|
||||
virtual void set_uniform(const char* name, glm::vec4 value) = 0;
|
||||
virtual void set_uniform(const char* name, glm::ivec2 value) = 0;
|
||||
virtual void set_uniform(const char* name, glm::ivec3 value) = 0;
|
||||
virtual void set_uniform(const char* name, glm::ivec4 value) = 0;
|
||||
virtual void set_uniform(const char* name, glm::mat2 value) = 0;
|
||||
virtual void set_uniform(const char* name, glm::mat3 value) = 0;
|
||||
virtual void set_uniform(const char* name, glm::mat4 value) = 0;
|
||||
virtual void set_sampler(const char* name, uint32_t slot, Handle<Texture> texture) = 0;
|
||||
virtual void set_rasterizer_state(const RasterizerStateDesc& desc) = 0;
|
||||
virtual void set_viewport(const Rect& rect) = 0;
|
||||
virtual void draw(uint32_t vertex_count, uint32_t first_vertex) = 0;
|
||||
virtual void draw_indexed(uint32_t index_count, uint32_t first_index) = 0;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
/// \file
|
||||
/// \brief SRB2 graphics stuff for SDL
|
||||
|
||||
#include <SDL_video.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <memory>
|
||||
|
|
|
|||
|
|
@ -34,35 +34,10 @@ void SdlGl2Platform::present()
|
|||
SDL_GL_SwapWindow(window);
|
||||
}
|
||||
|
||||
static constexpr const char* pipeline_lump_slug(rhi::PipelineProgram program)
|
||||
static std::array<std::string, 2> glsllist_lump_names(const char* name)
|
||||
{
|
||||
switch (program)
|
||||
{
|
||||
case rhi::PipelineProgram::kUnshaded:
|
||||
return "unshaded";
|
||||
case rhi::PipelineProgram::kUnshadedPaletted:
|
||||
return "unshadedpaletted";
|
||||
case rhi::PipelineProgram::kPostprocessWipe:
|
||||
return "postprocesswipe";
|
||||
case rhi::PipelineProgram::kPostimg:
|
||||
return "postimg";
|
||||
case rhi::PipelineProgram::kSharpBilinear:
|
||||
return "sharpbilinear";
|
||||
case rhi::PipelineProgram::kCrt:
|
||||
return "crt";
|
||||
case rhi::PipelineProgram::kCrtSharp:
|
||||
return "crtsharp";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
static std::array<std::string, 2> glsllist_lump_names(rhi::PipelineProgram program)
|
||||
{
|
||||
const char* pipeline_slug = pipeline_lump_slug(program);
|
||||
|
||||
std::string vertex_list_name = fmt::format("rhi_glsllist_{}_vertex", pipeline_slug);
|
||||
std::string fragment_list_name = fmt::format("rhi_glsllist_{}_fragment", pipeline_slug);
|
||||
std::string vertex_list_name = fmt::format("rhi_glsllist_{}_vertex", name);
|
||||
std::string fragment_list_name = fmt::format("rhi_glsllist_{}_fragment", name);
|
||||
|
||||
return {std::move(vertex_list_name), std::move(fragment_list_name)};
|
||||
}
|
||||
|
|
@ -132,9 +107,9 @@ static std::vector<std::string> get_sources_from_glsllist_lump(const char* lumpn
|
|||
}
|
||||
|
||||
std::tuple<std::vector<std::string>, std::vector<std::string>>
|
||||
SdlGl2Platform::find_shader_sources(rhi::PipelineProgram program)
|
||||
SdlGl2Platform::find_shader_sources(const char* name)
|
||||
{
|
||||
std::array<std::string, 2> glsllist_names = glsllist_lump_names(program);
|
||||
std::array<std::string, 2> glsllist_names = glsllist_lump_names(name);
|
||||
|
||||
std::vector<std::string> vertex_sources = get_sources_from_glsllist_lump(glsllist_names[0].c_str());
|
||||
std::vector<std::string> fragment_sources = get_sources_from_glsllist_lump(glsllist_names[1].c_str());
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ struct SdlGl2Platform final : public Gl2Platform
|
|||
|
||||
virtual void present() override;
|
||||
virtual std::tuple<std::vector<std::string>, std::vector<std::string>>
|
||||
find_shader_sources(PipelineProgram program) override;
|
||||
find_shader_sources(const char* name) override;
|
||||
virtual Rect get_default_framebuffer_dimensions() override;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue