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 "blit_postimg_screens.hpp"
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
#include <glm/mat3x3.hpp>
|
#include <glm/mat3x3.hpp>
|
||||||
#include <glm/mat4x4.hpp>
|
#include <glm/mat4x4.hpp>
|
||||||
#include <glm/vec3.hpp>
|
#include <glm/vec3.hpp>
|
||||||
#include <glm/vec4.hpp>
|
#include <glm/vec4.hpp>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <tcb/span.hpp>
|
||||||
|
|
||||||
#include "../p_tick.h"
|
#include "../p_tick.h"
|
||||||
#include "../i_time.h"
|
#include "../i_time.h"
|
||||||
|
|
@ -36,34 +39,6 @@ struct BlitVertex
|
||||||
};
|
};
|
||||||
} // namespace
|
} // 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[] =
|
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}};
|
{{-.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++)
|
for (uint32_t i = 0; i < screens_; i++)
|
||||||
{
|
{
|
||||||
|
BlitPostimgScreens::ScreenConfig& screen_config = screen_configs_[i];
|
||||||
BlitPostimgScreens::ScreenData& data = screen_data_[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.set_viewport(get_screen_viewport(i, screens_, target_width_, target_height_));
|
||||||
rhi.bind_uniform_set(0, data.uniform_set);
|
rhi.bind_vertex_attrib("a_position", quad_vbo_, rhi::VertexAttributeFormat::kFloat3, offsetof(BlitVertex, x), sizeof(BlitVertex));
|
||||||
rhi.bind_binding_set(data.binding_set);
|
rhi.bind_vertex_attrib("a_texcoord0", quad_vbo_, rhi::VertexAttributeFormat::kFloat2, offsetof(BlitVertex, u), sizeof(BlitVertex));
|
||||||
rhi.bind_index_buffer(quad_ibo_);
|
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);
|
rhi.draw_indexed(6, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlitPostimgScreens::prepass(Rhi& rhi)
|
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_)
|
if (!quad_vbo_)
|
||||||
|
|
@ -161,65 +190,13 @@ void BlitPostimgScreens::transfer(Rhi& rhi)
|
||||||
|
|
||||||
if (screen_config.indexed)
|
if (screen_config.indexed)
|
||||||
{
|
{
|
||||||
data.pipeline = indexed_pipeline_;
|
data.program = program_;
|
||||||
}
|
}
|
||||||
else
|
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);
|
screen_data_[i] = std::move(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,13 +46,11 @@ public:
|
||||||
private:
|
private:
|
||||||
struct ScreenData
|
struct ScreenData
|
||||||
{
|
{
|
||||||
rhi::Handle<rhi::Pipeline> pipeline;
|
rhi::Handle<rhi::Program> program;
|
||||||
rhi::Handle<rhi::BindingSet> binding_set;
|
|
||||||
rhi::Handle<rhi::UniformSet> uniform_set;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
rhi::Handle<rhi::Pipeline> pipeline_;
|
rhi::Handle<rhi::Program> program_;
|
||||||
rhi::Handle<rhi::Pipeline> indexed_pipeline_;
|
rhi::Handle<rhi::Program> indexed_program_;
|
||||||
rhi::Handle<rhi::Buffer> quad_vbo_;
|
rhi::Handle<rhi::Buffer> quad_vbo_;
|
||||||
rhi::Handle<rhi::Buffer> quad_ibo_;
|
rhi::Handle<rhi::Buffer> quad_ibo_;
|
||||||
bool upload_quad_buffer_;
|
bool upload_quad_buffer_;
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include "blit_rect.hpp"
|
#include "blit_rect.hpp"
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
#include <tcb/span.hpp>
|
#include <tcb/span.hpp>
|
||||||
|
|
@ -38,62 +39,6 @@ static const BlitVertex kVerts[] =
|
||||||
|
|
||||||
static const uint16_t kIndices[] = {0, 1, 2, 1, 3, 2};
|
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(BlitRectPass::BlitMode::kNearest) {}
|
||||||
BlitRectPass::BlitRectPass(BlitRectPass::BlitMode blit_mode) : blit_mode_(blit_mode) {}
|
BlitRectPass::BlitRectPass(BlitRectPass::BlitMode blit_mode) : blit_mode_(blit_mode) {}
|
||||||
BlitRectPass::~BlitRectPass() = default;
|
BlitRectPass::~BlitRectPass() = default;
|
||||||
|
|
@ -107,26 +52,29 @@ void BlitRectPass::draw(Rhi& rhi)
|
||||||
|
|
||||||
void BlitRectPass::prepass(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_)
|
switch (blit_mode_)
|
||||||
{
|
{
|
||||||
case BlitRectPass::BlitMode::kNearest:
|
case BlitRectPass::BlitMode::kNearest:
|
||||||
pipeline_ = rhi.create_pipeline(kUnshadedPipelineDescription);
|
desc.name = "unshaded";
|
||||||
break;
|
break;
|
||||||
case BlitRectPass::BlitMode::kSharpBilinear:
|
case BlitRectPass::BlitMode::kSharpBilinear:
|
||||||
pipeline_ = rhi.create_pipeline(kSharpBilinearPipelineDescription);
|
desc.name = "sharpbilinear";
|
||||||
break;
|
break;
|
||||||
case BlitRectPass::BlitMode::kCrt:
|
case BlitRectPass::BlitMode::kCrt:
|
||||||
pipeline_ = rhi.create_pipeline(kCrtPipelineDescription);
|
desc.name = "crt";
|
||||||
break;
|
break;
|
||||||
case BlitRectPass::BlitMode::kCrtSharp:
|
case BlitRectPass::BlitMode::kCrtSharp:
|
||||||
pipeline_ = rhi.create_pipeline(kCrtSharpPipelineDescription);
|
desc.name = "crtsharp";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
std::terminate();
|
std::terminate();
|
||||||
}
|
}
|
||||||
|
program_ = rhi.create_program(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!quad_vbo_)
|
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)));
|
rhi.update_texture(dot_pattern_, {0, 0, 12, 4}, PixelFormat::kRGBA8, tcb::as_bytes(tcb::span(kDotPattern)));
|
||||||
dot_pattern_needs_upload_ = false;
|
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 aspect = 1.0;
|
||||||
float output_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_);
|
rhi::TextureDetails texture_details = rhi.get_texture_details(texture_);
|
||||||
|
|
||||||
std::array<rhi::UniformVariant, 1> g1_uniforms = {{
|
glm::mat4 projection = glm::scale(
|
||||||
// Projection
|
glm::identity<glm::mat4>(),
|
||||||
glm::scale(
|
glm::vec3(taller ? 1.f : 1.f / output_aspect, taller ? -1.f / (1.f / output_aspect) : -1.f, 1.f)
|
||||||
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_)
|
switch (blit_mode_)
|
||||||
{
|
{
|
||||||
case BlitRectPass::BlitMode::kCrt:
|
case BlitRectPass::BlitMode::kNearest:
|
||||||
{
|
|
||||||
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;
|
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:
|
default:
|
||||||
{
|
rhi.set_uniform("u_sampler0_size", sampler0_size);
|
||||||
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});
|
|
||||||
break;
|
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.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.bind_index_buffer(quad_ibo_);
|
||||||
rhi.draw_indexed(6, 0);
|
rhi.draw_indexed(6, 0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
rhi::Handle<rhi::Pipeline> pipeline_;
|
rhi::Handle<rhi::Program> program_;
|
||||||
rhi::Handle<rhi::Texture> texture_;
|
rhi::Handle<rhi::Texture> texture_;
|
||||||
uint32_t texture_width_ = 0;
|
uint32_t texture_width_ = 0;
|
||||||
uint32_t texture_height_ = 0;
|
uint32_t texture_height_ = 0;
|
||||||
|
|
@ -42,8 +42,6 @@ private:
|
||||||
bool output_flip_ = false;
|
bool output_flip_ = false;
|
||||||
rhi::Handle<rhi::Buffer> quad_vbo_;
|
rhi::Handle<rhi::Buffer> quad_vbo_;
|
||||||
rhi::Handle<rhi::Buffer> quad_ibo_;
|
rhi::Handle<rhi::Buffer> quad_ibo_;
|
||||||
std::array<rhi::Handle<rhi::UniformSet>, 2> uniform_sets_;
|
|
||||||
rhi::Handle<rhi::BindingSet> binding_set_;
|
|
||||||
BlitMode blit_mode_;
|
BlitMode blit_mode_;
|
||||||
rhi::Handle<rhi::Texture> dot_pattern_;
|
rhi::Handle<rhi::Texture> dot_pattern_;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include "pass_imgui.hpp"
|
#include "pass_imgui.hpp"
|
||||||
|
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
|
#include <tcb/span.hpp>
|
||||||
|
|
||||||
#include "../v_video.h"
|
#include "../v_video.h"
|
||||||
|
|
||||||
|
|
@ -18,28 +19,6 @@ using namespace srb2;
|
||||||
using namespace srb2::hwr2;
|
using namespace srb2::hwr2;
|
||||||
using namespace srb2::rhi;
|
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()
|
ImguiPass::ImguiPass()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -48,9 +27,16 @@ ImguiPass::~ImguiPass() = default;
|
||||||
|
|
||||||
void ImguiPass::prepass(Rhi& rhi)
|
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();
|
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());
|
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));
|
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)
|
for (auto& draw_cmd : draw_list.cmds)
|
||||||
{
|
{
|
||||||
// Binding set
|
draw_cmd.vbo = vbo;
|
||||||
std::array<rhi::VertexAttributeBufferBinding, 1> vbos = {{{0, vbo}}};
|
draw_cmd.ibo = ibo;
|
||||||
std::array<rhi::TextureBinding, 1> tbs = {{{rhi::SamplerName::kSampler0, draw_cmd.tex}}};
|
draw_cmd.tex = draw_cmd.tex;
|
||||||
rhi::Handle<rhi::BindingSet> binding_set = rhi.create_binding_set(pipeline_, {vbos, tbs});
|
|
||||||
draw_cmd.binding_set = binding_set;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImguiPass::graphics(Rhi& rhi)
|
void ImguiPass::graphics(Rhi& rhi)
|
||||||
{
|
{
|
||||||
rhi.begin_default_render_pass(false);
|
rhi.bind_program(program_);
|
||||||
rhi.bind_pipeline(pipeline_);
|
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_)
|
for (auto& draw_list : draw_lists_)
|
||||||
{
|
{
|
||||||
rhi.bind_uniform_set(0, draw_list.us_1);
|
glm::mat4 projection = glm::mat4(
|
||||||
rhi.bind_uniform_set(1, draw_list.us_2);
|
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)
|
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.bind_index_buffer(draw_list.ibo);
|
||||||
rhi.set_scissor(cmd.clip);
|
|
||||||
rhi.draw_indexed(cmd.elems, cmd.i_offset);
|
rhi.draw_indexed(cmd.elems, cmd.i_offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rhi.end_render_pass();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImguiPass::postpass(Rhi& rhi)
|
void ImguiPass::postpass(Rhi& rhi)
|
||||||
|
|
|
||||||
|
|
@ -22,24 +22,23 @@ class ImguiPass final
|
||||||
{
|
{
|
||||||
struct DrawCmd
|
struct DrawCmd
|
||||||
{
|
{
|
||||||
rhi::Handle<rhi::Texture> tex;
|
|
||||||
uint32_t v_offset;
|
uint32_t v_offset;
|
||||||
uint32_t elems;
|
uint32_t elems;
|
||||||
uint32_t i_offset;
|
uint32_t i_offset;
|
||||||
rhi::Rect clip;
|
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
|
struct DrawList
|
||||||
{
|
{
|
||||||
void* list;
|
void* list;
|
||||||
rhi::Handle<rhi::Buffer> vbo;
|
rhi::Handle<rhi::Buffer> vbo;
|
||||||
rhi::Handle<rhi::Buffer> ibo;
|
rhi::Handle<rhi::Buffer> ibo;
|
||||||
rhi::Handle<rhi::UniformSet> us_1;
|
|
||||||
rhi::Handle<rhi::UniformSet> us_2;
|
|
||||||
std::vector<DrawCmd> cmds;
|
std::vector<DrawCmd> cmds;
|
||||||
};
|
};
|
||||||
|
|
||||||
rhi::Handle<rhi::Pipeline> pipeline_;
|
rhi::Handle<rhi::Program> program_;
|
||||||
rhi::Handle<rhi::Texture> font_atlas_;
|
rhi::Handle<rhi::Texture> font_atlas_;
|
||||||
|
|
||||||
std::vector<DrawList> draw_lists_;
|
std::vector<DrawList> draw_lists_;
|
||||||
|
|
|
||||||
|
|
@ -41,22 +41,6 @@ static const uint16_t kPostprocessIndices[] = {0, 1, 2, 1, 3, 2};
|
||||||
|
|
||||||
} // namespace
|
} // 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()
|
PostprocessWipePass::PostprocessWipePass()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -73,9 +57,12 @@ void PostprocessWipePass::draw(Rhi& rhi)
|
||||||
|
|
||||||
void PostprocessWipePass::prepass(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_)
|
if (!vbo_)
|
||||||
|
|
@ -195,20 +182,6 @@ void PostprocessWipePass::transfer(Rhi& rhi)
|
||||||
|
|
||||||
tcb::span<const std::byte> data = tcb::as_bytes(tcb::span(mask_data_));
|
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);
|
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)
|
void PostprocessWipePass::graphics(Rhi& rhi)
|
||||||
|
|
@ -218,10 +191,21 @@ void PostprocessWipePass::graphics(Rhi& rhi)
|
||||||
return;
|
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.set_viewport({0, 0, width_, height_});
|
||||||
rhi.bind_uniform_set(0, us_);
|
|
||||||
rhi.bind_binding_set(bs_);
|
|
||||||
rhi.bind_index_buffer(ibo_);
|
rhi.bind_index_buffer(ibo_);
|
||||||
rhi.draw_indexed(6, 0);
|
rhi.draw_indexed(6, 0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,11 @@ namespace srb2::hwr2
|
||||||
class PostprocessWipePass final
|
class PostprocessWipePass final
|
||||||
{
|
{
|
||||||
// Internal RHI resources
|
// Internal RHI resources
|
||||||
rhi::Handle<rhi::Pipeline> pipeline_;
|
rhi::Handle<rhi::Program> program_;
|
||||||
rhi::Handle<rhi::Buffer> vbo_;
|
rhi::Handle<rhi::Buffer> vbo_;
|
||||||
bool upload_vbo_ = false;
|
bool upload_vbo_ = false;
|
||||||
rhi::Handle<rhi::Buffer> ibo_;
|
rhi::Handle<rhi::Buffer> ibo_;
|
||||||
bool upload_ibo_ = false;
|
bool upload_ibo_ = false;
|
||||||
rhi::Handle<rhi::UniformSet> us_;
|
|
||||||
rhi::Handle<rhi::BindingSet> bs_;
|
|
||||||
rhi::Handle<rhi::Texture> wipe_tex_;
|
rhi::Handle<rhi::Texture> wipe_tex_;
|
||||||
int wipe_color_mode_ = 0;
|
int wipe_color_mode_ = 0;
|
||||||
int wipe_swizzle_ = 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)};
|
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 = {
|
switch (blend)
|
||||||
{{sizeof(TwodeeVertex)}},
|
|
||||||
{{VertexAttributeName::kPosition, 0, 0},
|
|
||||||
{VertexAttributeName::kTexCoord0, 0, 12},
|
|
||||||
{VertexAttributeName::kColor, 0, 20}}};
|
|
||||||
BlendDesc blend_desc;
|
|
||||||
switch (key.blend)
|
|
||||||
{
|
{
|
||||||
case BlendMode::kAlphaTransparent:
|
case BlendMode::kAlphaTransparent:
|
||||||
blend_desc.source_factor_color = BlendFactor::kSourceAlpha;
|
desc.blend_source_factor_color = BlendFactor::kSourceAlpha;
|
||||||
blend_desc.dest_factor_color = BlendFactor::kOneMinusSourceAlpha;
|
desc.blend_dest_factor_color = BlendFactor::kOneMinusSourceAlpha;
|
||||||
blend_desc.color_function = BlendFunction::kAdd;
|
desc.blend_color_function = BlendFunction::kAdd;
|
||||||
blend_desc.source_factor_alpha = BlendFactor::kOne;
|
desc.blend_source_factor_alpha = BlendFactor::kOne;
|
||||||
blend_desc.dest_factor_alpha = BlendFactor::kOneMinusSourceAlpha;
|
desc.blend_dest_factor_alpha = BlendFactor::kOneMinusSourceAlpha;
|
||||||
blend_desc.alpha_function = BlendFunction::kAdd;
|
desc.blend_alpha_function = BlendFunction::kAdd;
|
||||||
break;
|
break;
|
||||||
case BlendMode::kModulate:
|
case BlendMode::kModulate:
|
||||||
blend_desc.source_factor_color = BlendFactor::kDest;
|
desc.blend_source_factor_color = BlendFactor::kDest;
|
||||||
blend_desc.dest_factor_color = BlendFactor::kZero;
|
desc.blend_dest_factor_color = BlendFactor::kZero;
|
||||||
blend_desc.color_function = BlendFunction::kAdd;
|
desc.blend_color_function = BlendFunction::kAdd;
|
||||||
blend_desc.source_factor_alpha = BlendFactor::kDestAlpha;
|
desc.blend_source_factor_alpha = BlendFactor::kDestAlpha;
|
||||||
blend_desc.dest_factor_alpha = BlendFactor::kZero;
|
desc.blend_dest_factor_alpha = BlendFactor::kZero;
|
||||||
blend_desc.alpha_function = BlendFunction::kAdd;
|
desc.blend_alpha_function = BlendFunction::kAdd;
|
||||||
break;
|
break;
|
||||||
case BlendMode::kAdditive:
|
case BlendMode::kAdditive:
|
||||||
blend_desc.source_factor_color = BlendFactor::kSourceAlpha;
|
desc.blend_source_factor_color = BlendFactor::kSourceAlpha;
|
||||||
blend_desc.dest_factor_color = BlendFactor::kOne;
|
desc.blend_dest_factor_color = BlendFactor::kOne;
|
||||||
blend_desc.color_function = BlendFunction::kAdd;
|
desc.blend_color_function = BlendFunction::kAdd;
|
||||||
blend_desc.source_factor_alpha = BlendFactor::kOne;
|
desc.blend_source_factor_alpha = BlendFactor::kOne;
|
||||||
blend_desc.dest_factor_alpha = BlendFactor::kOneMinusSourceAlpha;
|
desc.blend_dest_factor_alpha = BlendFactor::kOneMinusSourceAlpha;
|
||||||
blend_desc.alpha_function = BlendFunction::kAdd;
|
desc.blend_alpha_function = BlendFunction::kAdd;
|
||||||
break;
|
break;
|
||||||
case BlendMode::kSubtractive:
|
case BlendMode::kSubtractive:
|
||||||
blend_desc.source_factor_color = BlendFactor::kSourceAlpha;
|
desc.blend_source_factor_color = BlendFactor::kSourceAlpha;
|
||||||
blend_desc.dest_factor_color = BlendFactor::kOne;
|
desc.blend_dest_factor_color = BlendFactor::kOne;
|
||||||
blend_desc.color_function = BlendFunction::kSubtract;
|
desc.blend_color_function = BlendFunction::kSubtract;
|
||||||
blend_desc.source_factor_alpha = BlendFactor::kOne;
|
desc.blend_source_factor_alpha = BlendFactor::kOne;
|
||||||
blend_desc.dest_factor_alpha = BlendFactor::kOneMinusSourceAlpha;
|
desc.blend_dest_factor_alpha = BlendFactor::kOneMinusSourceAlpha;
|
||||||
blend_desc.alpha_function = BlendFunction::kAdd;
|
desc.blend_alpha_function = BlendFunction::kAdd;
|
||||||
break;
|
break;
|
||||||
case BlendMode::kReverseSubtractive:
|
case BlendMode::kReverseSubtractive:
|
||||||
blend_desc.source_factor_color = BlendFactor::kSourceAlpha;
|
desc.blend_source_factor_color = BlendFactor::kSourceAlpha;
|
||||||
blend_desc.dest_factor_color = BlendFactor::kOne;
|
desc.blend_dest_factor_color = BlendFactor::kOne;
|
||||||
blend_desc.color_function = BlendFunction::kReverseSubtract;
|
desc.blend_color_function = BlendFunction::kReverseSubtract;
|
||||||
blend_desc.source_factor_alpha = BlendFactor::kOne;
|
desc.blend_source_factor_alpha = BlendFactor::kOne;
|
||||||
blend_desc.dest_factor_alpha = BlendFactor::kOneMinusSourceAlpha;
|
desc.blend_dest_factor_alpha = BlendFactor::kOneMinusSourceAlpha;
|
||||||
blend_desc.alpha_function = BlendFunction::kAdd;
|
desc.blend_alpha_function = BlendFunction::kAdd;
|
||||||
break;
|
break;
|
||||||
case BlendMode::kInvertDest:
|
case BlendMode::kInvertDest:
|
||||||
blend_desc.source_factor_color = BlendFactor::kOne;
|
desc.blend_source_factor_color = BlendFactor::kOne;
|
||||||
blend_desc.dest_factor_color = BlendFactor::kOne;
|
desc.blend_dest_factor_color = BlendFactor::kOne;
|
||||||
blend_desc.color_function = BlendFunction::kSubtract;
|
desc.blend_color_function = BlendFunction::kSubtract;
|
||||||
blend_desc.source_factor_alpha = BlendFactor::kZero;
|
desc.blend_source_factor_alpha = BlendFactor::kZero;
|
||||||
blend_desc.dest_factor_alpha = BlendFactor::kDestAlpha;
|
desc.blend_dest_factor_alpha = BlendFactor::kDestAlpha;
|
||||||
blend_desc.alpha_function = BlendFunction::kAdd;
|
desc.blend_alpha_function = BlendFunction::kAdd;
|
||||||
break;
|
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
|
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)
|
void TwodeeRenderer::initialize(Rhi& rhi)
|
||||||
{
|
{
|
||||||
{
|
ProgramDesc prog_desc;
|
||||||
TwodeePipelineKey alpha_transparent_tris = {BlendMode::kAlphaTransparent, false};
|
prog_desc.name = "unshadedpaletted";
|
||||||
TwodeePipelineKey modulate_tris = {BlendMode::kModulate, false};
|
const char* defines[] = {
|
||||||
TwodeePipelineKey additive_tris = {BlendMode::kAdditive, false};
|
"ENABLE_U_SAMPLER0_IS_INDEXED_ALPHA",
|
||||||
TwodeePipelineKey subtractive_tris = {BlendMode::kSubtractive, false};
|
"ENABLE_S_SAMPLER2",
|
||||||
TwodeePipelineKey revsubtractive_tris = {BlendMode::kReverseSubtractive, false};
|
"ENABLE_VA_TEXCOORD0",
|
||||||
TwodeePipelineKey invertdest_tris = {BlendMode::kInvertDest, false};
|
"ENABLE_VA_COLOR"
|
||||||
TwodeePipelineKey alpha_transparent_lines = {BlendMode::kAlphaTransparent, true};
|
};
|
||||||
TwodeePipelineKey modulate_lines = {BlendMode::kModulate, true};
|
prog_desc.defines = tcb::make_span(defines);
|
||||||
TwodeePipelineKey additive_lines = {BlendMode::kAdditive, true};
|
program_ = rhi.create_program(prog_desc);
|
||||||
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))});
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
default_tex_ = rhi.create_texture({
|
default_tex_ = rhi.create_texture({
|
||||||
|
|
@ -377,6 +342,8 @@ void TwodeeRenderer::flush(Rhi& rhi, Twodee& twodee)
|
||||||
new_cmd.colormap = nullptr;
|
new_cmd.colormap = nullptr;
|
||||||
// safety: a command list is required to have at least 1 command
|
// 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.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));
|
merged_list.cmds.push_back(std::move(new_cmd));
|
||||||
|
|
||||||
for (auto& cmd : list.cmds)
|
for (auto& cmd : list.cmds)
|
||||||
|
|
@ -458,6 +425,8 @@ void TwodeeRenderer::flush(Rhi& rhi, Twodee& twodee)
|
||||||
}};
|
}};
|
||||||
std::visit(tex_visitor_again, cmd);
|
std::visit(tex_visitor_again, cmd);
|
||||||
the_new_one.pipeline_key = pipeline_key_for_cmd(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));
|
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.vbo, 0, vertex_data);
|
||||||
rhi.update_buffer(merged_list.ibo, 0, index_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)
|
for (auto& mcmd : merged_list.cmds)
|
||||||
{
|
{
|
||||||
TextureBinding tx[3];
|
|
||||||
auto tex_visitor = srb2::Overload {
|
auto tex_visitor = srb2::Overload {
|
||||||
[&](Handle<Texture> texture)
|
[&](Handle<Texture> texture)
|
||||||
{
|
{
|
||||||
tx[0] = {SamplerName::kSampler0, texture};
|
mcmd.texture_handle = texture;
|
||||||
tx[1] = {SamplerName::kSampler1, palette_tex};
|
|
||||||
},
|
},
|
||||||
[&](const MergedTwodeeCommandFlatTexture& tex)
|
[&](const MergedTwodeeCommandFlatTexture& tex)
|
||||||
{
|
{
|
||||||
Handle<Texture> th = flat_manager_->find_or_create_indexed(rhi, tex.lump);
|
Handle<Texture> th = flat_manager_->find_or_create_indexed(rhi, tex.lump);
|
||||||
SRB2_ASSERT(th != kNullHandle);
|
SRB2_ASSERT(th != kNullHandle);
|
||||||
tx[0] = {SamplerName::kSampler0, th};
|
mcmd.texture_handle = th;
|
||||||
tx[1] = {SamplerName::kSampler1, palette_tex};
|
|
||||||
}};
|
}};
|
||||||
if (mcmd.texture)
|
if (mcmd.texture)
|
||||||
{
|
{
|
||||||
|
|
@ -519,8 +483,7 @@ void TwodeeRenderer::flush(Rhi& rhi, Twodee& twodee)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tx[0] = {SamplerName::kSampler0, default_tex_};
|
mcmd.texture_handle = default_tex_;
|
||||||
tx[1] = {SamplerName::kSampler1, palette_tex};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t* colormap = mcmd.colormap;
|
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);
|
colormap_h = palette_manager_->find_or_create_colormap(rhi, colormap);
|
||||||
SRB2_ASSERT(colormap_h != kNullHandle);
|
SRB2_ASSERT(colormap_h != kNullHandle);
|
||||||
}
|
}
|
||||||
tx[2] = {SamplerName::kSampler2, colormap_h};
|
mcmd.colormap_handle = colormap_h;
|
||||||
mcmd.binding_set =
|
|
||||||
rhi.create_binding_set(pipelines_[mcmd.pipeline_key], {tcb::span(vbos), tcb::span(tx)});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx_list_itr++;
|
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
|
// 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_)
|
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)
|
for (auto& cmd : list.cmds)
|
||||||
{
|
{
|
||||||
if (cmd.elements == 0)
|
if (cmd.elements == 0)
|
||||||
|
|
@ -570,13 +524,16 @@ void TwodeeRenderer::flush(Rhi& rhi, Twodee& twodee)
|
||||||
// This shouldn't happen, but, just in case...
|
// This shouldn't happen, but, just in case...
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
SRB2_ASSERT(pipelines_.find(cmd.pipeline_key) != pipelines_.end());
|
RasterizerStateDesc desc;
|
||||||
Handle<Pipeline> pl = pipelines_[cmd.pipeline_key];
|
desc.cull = CullMode::kNone;
|
||||||
rhi.bind_pipeline(pl);
|
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.set_viewport({0, 0, static_cast<uint32_t>(vid.width), static_cast<uint32_t>(vid.height)});
|
||||||
rhi.bind_uniform_set(0, us_1);
|
rhi.set_sampler("s_sampler0", 0, cmd.texture_handle);
|
||||||
rhi.bind_uniform_set(1, us_2);
|
rhi.set_sampler("s_sampler2", 2, cmd.colormap_handle);
|
||||||
rhi.bind_binding_set(cmd.binding_set);
|
|
||||||
rhi.bind_index_buffer(list.ibo);
|
rhi.bind_index_buffer(list.ibo);
|
||||||
rhi.draw_indexed(cmd.elements, cmd.index_offset);
|
rhi.draw_indexed(cmd.elements, cmd.index_offset);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,8 @@
|
||||||
#ifndef __SRB2_HWR2_PASS_TWODEE_HPP__
|
#ifndef __SRB2_HWR2_PASS_TWODEE_HPP__
|
||||||
#define __SRB2_HWR2_PASS_TWODEE_HPP__
|
#define __SRB2_HWR2_PASS_TWODEE_HPP__
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <unordered_map>
|
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
@ -65,10 +63,13 @@ struct MergedTwodeeCommandFlatTexture
|
||||||
struct MergedTwodeeCommand
|
struct MergedTwodeeCommand
|
||||||
{
|
{
|
||||||
using Texture = std::variant<rhi::Handle<rhi::Texture>, MergedTwodeeCommandFlatTexture>;
|
using Texture = std::variant<rhi::Handle<rhi::Texture>, MergedTwodeeCommandFlatTexture>;
|
||||||
TwodeePipelineKey pipeline_key = {};
|
rhi::PrimitiveType primitive;
|
||||||
rhi::Handle<rhi::BindingSet> binding_set = {};
|
BlendMode blend_mode;
|
||||||
std::optional<Texture> texture;
|
std::optional<Texture> texture;
|
||||||
|
TwodeePipelineKey pipeline_key;
|
||||||
|
rhi::Handle<rhi::Texture> texture_handle;
|
||||||
const uint8_t* colormap;
|
const uint8_t* colormap;
|
||||||
|
rhi::Handle<rhi::Texture> colormap_handle;
|
||||||
uint32_t index_offset = 0;
|
uint32_t index_offset = 0;
|
||||||
uint32_t elements = 0;
|
uint32_t elements = 0;
|
||||||
};
|
};
|
||||||
|
|
@ -96,7 +97,7 @@ class TwodeeRenderer final
|
||||||
std::vector<std::tuple<rhi::Handle<rhi::Buffer>, std::size_t>> ibos_;
|
std::vector<std::tuple<rhi::Handle<rhi::Buffer>, std::size_t>> ibos_;
|
||||||
rhi::Handle<rhi::Texture> output_;
|
rhi::Handle<rhi::Texture> output_;
|
||||||
rhi::Handle<rhi::Texture> default_tex_;
|
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;
|
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);
|
g_hw_state.blit_rect->draw(*rhi);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rhi->end_render_pass();
|
rhi->end_render_pass();
|
||||||
|
|
||||||
postframe_update(*rhi);
|
postframe_update(*rhi);
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -71,7 +71,7 @@ struct Gl2Platform
|
||||||
virtual ~Gl2Platform();
|
virtual ~Gl2Platform();
|
||||||
|
|
||||||
virtual void present() = 0;
|
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;
|
virtual Rect get_default_framebuffer_dimensions() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -93,26 +93,13 @@ struct Gl2Renderbuffer : public rhi::Renderbuffer
|
||||||
rhi::RenderbufferDesc desc;
|
rhi::RenderbufferDesc desc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Gl2UniformSet : public rhi::UniformSet
|
struct Gl2Program : public rhi::Program
|
||||||
{
|
|
||||||
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
|
|
||||||
{
|
{
|
||||||
uint32_t vertex_shader = 0;
|
uint32_t vertex_shader = 0;
|
||||||
uint32_t fragment_shader = 0;
|
uint32_t fragment_shader = 0;
|
||||||
uint32_t program = 0;
|
uint32_t program = 0;
|
||||||
std::unordered_map<rhi::VertexAttributeName, uint32_t> attrib_locations {2};
|
std::unordered_map<std::string, uint32_t> attrib_locations;
|
||||||
std::unordered_map<rhi::UniformName, uint32_t> uniform_locations {2};
|
std::unordered_map<std::string, uint32_t> uniform_locations;
|
||||||
std::unordered_map<rhi::SamplerName, uint32_t> sampler_locations {2};
|
|
||||||
rhi::PipelineDesc desc;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Gl2ActiveUniform
|
struct Gl2ActiveUniform
|
||||||
|
|
@ -130,9 +117,7 @@ class Gl2Rhi final : public Rhi
|
||||||
Slab<Gl2Texture> texture_slab_;
|
Slab<Gl2Texture> texture_slab_;
|
||||||
Slab<Gl2Buffer> buffer_slab_;
|
Slab<Gl2Buffer> buffer_slab_;
|
||||||
Slab<Gl2Renderbuffer> renderbuffer_slab_;
|
Slab<Gl2Renderbuffer> renderbuffer_slab_;
|
||||||
Slab<Gl2Pipeline> pipeline_slab_;
|
Slab<Gl2Program> program_slab_;
|
||||||
Slab<Gl2UniformSet> uniform_set_slab_;
|
|
||||||
Slab<Gl2BindingSet> binding_set_slab_;
|
|
||||||
|
|
||||||
Handle<Buffer> current_index_buffer_;
|
Handle<Buffer> current_index_buffer_;
|
||||||
|
|
||||||
|
|
@ -143,7 +128,7 @@ class Gl2Rhi final : public Rhi
|
||||||
};
|
};
|
||||||
using RenderPassState = std::variant<DefaultRenderPassState, RenderPassBeginInfo>;
|
using RenderPassState = std::variant<DefaultRenderPassState, RenderPassBeginInfo>;
|
||||||
std::optional<RenderPassState> current_render_pass_;
|
std::optional<RenderPassState> current_render_pass_;
|
||||||
std::optional<Handle<Pipeline>> current_pipeline_;
|
std::optional<Handle<Program>> current_program_;
|
||||||
PrimitiveType current_primitive_type_ = PrimitiveType::kPoints;
|
PrimitiveType current_primitive_type_ = PrimitiveType::kPoints;
|
||||||
uint32_t index_buffer_offset_ = 0;
|
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_reference_ = 0;
|
||||||
uint8_t stencil_back_compare_mask_ = 0xFF;
|
uint8_t stencil_back_compare_mask_ = 0xFF;
|
||||||
uint8_t stencil_back_write_mask_ = 0xFF;
|
uint8_t stencil_back_write_mask_ = 0xFF;
|
||||||
|
CompareFunc stencil_front_func_;
|
||||||
|
CompareFunc stencil_back_func_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Gl2Rhi(std::unique_ptr<Gl2Platform>&& platform, GlLoadFunc load_func);
|
Gl2Rhi(std::unique_ptr<Gl2Platform>&& platform, GlLoadFunc load_func);
|
||||||
virtual ~Gl2Rhi();
|
virtual ~Gl2Rhi();
|
||||||
|
|
||||||
virtual Handle<Pipeline> create_pipeline(const PipelineDesc& desc) override;
|
virtual Handle<Program> create_program(const ProgramDesc& desc) override;
|
||||||
virtual void destroy_pipeline(Handle<Pipeline> handle) override;
|
virtual void destroy_program(Handle<Program> handle) override;
|
||||||
|
|
||||||
virtual Handle<Texture> create_texture(const TextureDesc& desc) override;
|
virtual Handle<Texture> create_texture(const TextureDesc& desc) override;
|
||||||
virtual void destroy_texture(Handle<Texture> handle) override;
|
virtual void destroy_texture(Handle<Texture> handle) override;
|
||||||
|
|
@ -190,21 +177,33 @@ public:
|
||||||
TextureFilterMode min,
|
TextureFilterMode min,
|
||||||
TextureFilterMode mag
|
TextureFilterMode mag
|
||||||
) override;
|
) 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
|
// Graphics context functions
|
||||||
virtual void begin_default_render_pass(bool clear) override;
|
virtual void begin_default_render_pass(bool clear) override;
|
||||||
virtual void begin_render_pass(const RenderPassBeginInfo& info) override;
|
virtual void begin_render_pass(const RenderPassBeginInfo& info) override;
|
||||||
virtual void end_render_pass() override;
|
virtual void end_render_pass() override;
|
||||||
virtual void bind_pipeline(Handle<Pipeline> pipeline) override;
|
virtual void bind_program(Handle<Program> program) override;
|
||||||
virtual void bind_uniform_set(uint32_t slot, Handle<UniformSet> set) override;
|
virtual void bind_vertex_attrib(
|
||||||
virtual void bind_binding_set(Handle<BindingSet> set) override;
|
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 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 set_viewport(const Rect& rect) override;
|
||||||
virtual void draw(uint32_t vertex_count, uint32_t first_vertex) 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;
|
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 <tcb/span.hpp>
|
||||||
|
|
||||||
#include "../core/static_vec.hpp"
|
#include "../core/static_vec.hpp"
|
||||||
|
#include "glm/ext/vector_float2.hpp"
|
||||||
#include "handle.hpp"
|
#include "handle.hpp"
|
||||||
|
|
||||||
namespace srb2::rhi
|
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;
|
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
|
enum class StencilOp
|
||||||
{
|
{
|
||||||
kKeep,
|
kKeep,
|
||||||
|
|
@ -419,42 +411,41 @@ enum class StencilOp
|
||||||
kDecrementWrap
|
kDecrementWrap
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PipelineStencilOpStateDesc
|
|
||||||
|
struct ProgramDesc
|
||||||
{
|
{
|
||||||
StencilOp fail;
|
const char* name;
|
||||||
StencilOp pass;
|
tcb::span<const char*> defines;
|
||||||
StencilOp depth_fail;
|
|
||||||
CompareFunc stencil_compare;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PipelineDepthStencilStateDesc
|
struct RasterizerStateDesc
|
||||||
{
|
{
|
||||||
bool depth_test;
|
PrimitiveType primitive = PrimitiveType::kTriangles;
|
||||||
bool depth_write;
|
CullMode cull = CullMode::kBack;
|
||||||
CompareFunc depth_func;
|
FaceWinding winding = FaceWinding::kCounterClockwise;
|
||||||
bool stencil_test;
|
ColorMask color_mask = {true, true, true, true};
|
||||||
PipelineStencilOpStateDesc front;
|
bool blend_enabled = false;
|
||||||
PipelineStencilOpStateDesc back;
|
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;
|
||||||
struct PipelineColorStateDesc
|
BlendFunction blend_color_function = BlendFunction::kAdd;
|
||||||
{
|
BlendFactor blend_source_factor_alpha = BlendFactor::kOne;
|
||||||
std::optional<BlendDesc> blend;
|
BlendFactor blend_dest_factor_alpha = BlendFactor::kZero;
|
||||||
ColorMask color_mask;
|
BlendFunction blend_alpha_function = BlendFunction::kAdd;
|
||||||
};
|
bool depth_test = false;
|
||||||
|
bool depth_write = true;
|
||||||
struct PipelineDesc
|
CompareFunc depth_func = CompareFunc::kLess;
|
||||||
{
|
bool stencil_test = false;
|
||||||
PipelineProgram program;
|
StencilOp front_fail = StencilOp::kKeep;
|
||||||
VertexInputDesc vertex_input;
|
StencilOp front_pass = StencilOp::kKeep;
|
||||||
UniformInputDesc uniform_input;
|
StencilOp front_depth_fail = StencilOp::kKeep;
|
||||||
SamplerInputDesc sampler_input;
|
CompareFunc front_stencil_compare = CompareFunc::kAlways;
|
||||||
std::optional<PipelineDepthStencilStateDesc> depth_stencil_state;
|
StencilOp back_fail = StencilOp::kKeep;
|
||||||
PipelineColorStateDesc color_state;
|
StencilOp back_pass = StencilOp::kKeep;
|
||||||
PrimitiveType primitive;
|
StencilOp back_depth_fail = StencilOp::kKeep;
|
||||||
CullMode cull;
|
CompareFunc back_stencil_compare = CompareFunc::kAlways;
|
||||||
FaceWinding winding;
|
bool scissor_test = false;
|
||||||
glm::vec4 blend_color;
|
Rect scissor = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RenderbufferDesc
|
struct RenderbufferDesc
|
||||||
|
|
@ -565,13 +556,6 @@ struct CreateBindingSetInfo
|
||||||
tcb::span<TextureBinding> sampler_textures;
|
tcb::span<TextureBinding> sampler_textures;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UniformSet
|
|
||||||
{
|
|
||||||
};
|
|
||||||
struct BindingSet
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TextureDetails
|
struct TextureDetails
|
||||||
{
|
{
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
|
|
@ -588,8 +572,8 @@ struct Rhi
|
||||||
{
|
{
|
||||||
virtual ~Rhi();
|
virtual ~Rhi();
|
||||||
|
|
||||||
virtual Handle<Pipeline> create_pipeline(const PipelineDesc& desc) = 0;
|
virtual Handle<Program> create_program(const ProgramDesc& desc) = 0;
|
||||||
virtual void destroy_pipeline(Handle<Pipeline> handle) = 0;
|
virtual void destroy_program(Handle<Program> handle) = 0;
|
||||||
|
|
||||||
virtual Handle<Texture> create_texture(const TextureDesc& desc) = 0;
|
virtual Handle<Texture> create_texture(const TextureDesc& desc) = 0;
|
||||||
virtual void destroy_texture(Handle<Texture> handle) = 0;
|
virtual void destroy_texture(Handle<Texture> handle) = 0;
|
||||||
|
|
@ -620,19 +604,33 @@ struct Rhi
|
||||||
TextureFilterMode min,
|
TextureFilterMode min,
|
||||||
TextureFilterMode mag
|
TextureFilterMode mag
|
||||||
) = 0;
|
) = 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
|
// Graphics context functions
|
||||||
virtual void begin_default_render_pass(bool clear) = 0;
|
virtual void begin_default_render_pass(bool clear) = 0;
|
||||||
virtual void begin_render_pass(const RenderPassBeginInfo& info) = 0;
|
virtual void begin_render_pass(const RenderPassBeginInfo& info) = 0;
|
||||||
virtual void end_render_pass() = 0;
|
virtual void end_render_pass() = 0;
|
||||||
virtual void bind_pipeline(Handle<Pipeline> pipeline) = 0;
|
virtual void bind_program(Handle<Program> program) = 0;
|
||||||
virtual void bind_uniform_set(uint32_t slot, Handle<UniformSet> set) = 0;
|
virtual void bind_vertex_attrib(
|
||||||
virtual void bind_binding_set(Handle<BindingSet> set) = 0;
|
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 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 set_viewport(const Rect& rect) = 0;
|
||||||
virtual void draw(uint32_t vertex_count, uint32_t first_vertex) = 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;
|
virtual void draw_indexed(uint32_t index_count, uint32_t first_index) = 0;
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
/// \file
|
/// \file
|
||||||
/// \brief SRB2 graphics stuff for SDL
|
/// \brief SRB2 graphics stuff for SDL
|
||||||
|
|
||||||
|
#include <SDL_video.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
|
||||||
|
|
@ -34,35 +34,10 @@ void SdlGl2Platform::present()
|
||||||
SDL_GL_SwapWindow(window);
|
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)
|
std::string vertex_list_name = fmt::format("rhi_glsllist_{}_vertex", name);
|
||||||
{
|
std::string fragment_list_name = fmt::format("rhi_glsllist_{}_fragment", name);
|
||||||
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);
|
|
||||||
|
|
||||||
return {std::move(vertex_list_name), std::move(fragment_list_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>>
|
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> 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());
|
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 void present() override;
|
||||||
virtual std::tuple<std::vector<std::string>, std::vector<std::string>>
|
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;
|
virtual Rect get_default_framebuffer_dimensions() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue