Files
coffee-crisis-ae/source/core/rendering/sdl3gpu/sdl3gpu_shader.hpp
T

166 lines
5.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include <SDL3/SDL.h>
#include <SDL3/SDL_gpu.h>
#include <string>
#include "core/rendering/shader_backend.hpp"
// PostFX uniforms pushed to fragment stage each frame.
// 16 floats = 64 bytes (4 × vec4) — std140/scalar layout for Vulkan + Metal.
struct PostFXUniforms {
// vec4 #0
float vignette_strength;
float chroma_min;
float scanline_strength;
float screen_height;
// vec4 #1
float mask_strength;
float gamma_strength;
float curvature;
float bleeding;
// vec4 #2
float pixel_scale;
float time;
float flicker;
float chroma_max;
// vec4 #3 — paràmetres de scanlines exposats al preset YAML
float scan_dark_ratio;
float scan_dark_floor;
float scan_edge_soft;
float pad3;
};
// CrtPi uniforms pushed to fragment stage each frame.
// 16 fields = 64 bytes — 4 × 16-byte alignment.
struct CrtPiUniforms {
float scanline_weight;
float scanline_gap_brightness;
float bloom_factor;
float input_gamma;
float output_gamma;
float mask_brightness;
float curvature_x;
float curvature_y;
int mask_type;
int enable_scanlines;
int enable_multisample;
int enable_gamma;
int enable_curvature;
int enable_sharper;
float texture_width;
float texture_height;
};
namespace Rendering {
/**
* @brief Backend de shaders usando SDL3 GPU API (Metal en macOS, Vulkan/SPIR-V en Win/Linux)
*
* Pipeline: Surface pixels (CPU) → SDL_GPUTransferBuffer → SDL_GPUTexture (scene)
* → PostFX/CrtPi render pass → swapchain → present
*/
class SDL3GPUShader : public ShaderBackend {
public:
SDL3GPUShader() = default;
~SDL3GPUShader() override;
auto init(SDL_Window* window,
SDL_Texture* texture,
const std::string& vertex_source,
const std::string& fragment_source) -> bool override;
void render() override;
void setTextureSize(float /*width*/, float /*height*/) override {}
void cleanup() final;
void destroy();
[[nodiscard]] auto isHardwareAccelerated() const -> bool override { return is_initialized_; }
[[nodiscard]] auto getDriverName() const -> std::string override { return driver_name_; }
void setPreferredDriver(const std::string& driver) override { preferred_driver_ = driver; }
void uploadPixels(const Uint32* pixels, int width, int height) override;
void setPostFXParams(const PostFXParams& p) override;
void setVSync(bool vsync) override;
void setScaleMode(bool integer_scale) override;
void setActiveShader(ShaderType type) override;
void setCrtPiParams(const CrtPiParams& p) override;
[[nodiscard]] auto getActiveShader() const -> ShaderType override { return active_shader_; }
private:
static auto createShaderMSL(SDL_GPUDevice* device,
const char* msl_source,
const char* entrypoint,
SDL_GPUShaderStage stage,
Uint32 num_samplers,
Uint32 num_uniform_buffers) -> SDL_GPUShader*;
static auto createShaderSPIRV(SDL_GPUDevice* device,
const uint8_t* spv_code,
size_t spv_size,
const char* entrypoint,
SDL_GPUShaderStage stage,
Uint32 num_samplers,
Uint32 num_uniform_buffers) -> SDL_GPUShader*;
auto createPipeline() -> bool;
auto createCrtPiPipeline() -> bool;
auto reinitTexturesAndBuffer() -> bool;
[[nodiscard]] auto bestPresentMode(bool vsync) const -> SDL_GPUPresentMode;
SDL_Window* window_ = nullptr;
SDL_GPUDevice* device_ = nullptr;
SDL_GPUGraphicsPipeline* pipeline_ = nullptr;
SDL_GPUGraphicsPipeline* crtpi_pipeline_ = nullptr;
SDL_GPUTexture* scene_texture_ = nullptr;
SDL_GPUTransferBuffer* upload_buffer_ = nullptr;
SDL_GPUSampler* sampler_ = nullptr;
PostFXUniforms uniforms_{
.vignette_strength = 0.6F,
.chroma_min = 0.15F,
.scanline_strength = 0.7F,
.screen_height = 192.0F,
.mask_strength = 0.0F,
.gamma_strength = 0.0F,
.curvature = 0.0F,
.bleeding = 0.0F,
.pixel_scale = 1.0F,
.time = 0.0F,
.flicker = 0.0F,
.chroma_max = 0.15F,
.scan_dark_ratio = 0.333F,
.scan_dark_floor = 0.42F,
.scan_edge_soft = 1.0F,
.pad3 = 0.0F};
CrtPiUniforms crtpi_uniforms_{
.scanline_weight = 6.0F,
.scanline_gap_brightness = 0.12F,
.bloom_factor = 3.5F,
.input_gamma = 2.4F,
.output_gamma = 2.2F,
.mask_brightness = 0.80F,
.curvature_x = 0.05F,
.curvature_y = 0.10F,
.mask_type = 2,
.enable_scanlines = 1,
.enable_multisample = 1,
.enable_gamma = 1,
.enable_curvature = 0,
.enable_sharper = 0,
.texture_width = 0.0F,
.texture_height = 0.0F};
ShaderType active_shader_ = ShaderType::POSTFX;
int game_width_ = 0;
int game_height_ = 0;
std::string driver_name_;
std::string preferred_driver_;
bool is_initialized_ = false;
bool vsync_ = true;
bool integer_scale_ = false;
};
} // namespace Rendering