Path SDL3 GPU amb PostFX passthrough; Screen amb init/shutdown explicit (v0.4.0)
This commit is contained in:
1 parent
0348acb0eb
commit
6c8ef9ff44
18 files changed
+14213
-38
No files matched your search
@@ -0,0 +1,102 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_gpu.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "core/rendering/shader_backend.hpp"
|
||||
|
||||
// Uniforms enviats al fragment stage cada frame.
|
||||
// Han de coincidir amb l'estructura MSL/GLSL (48 bytes, alineats a 16).
|
||||
struct PostFXUniforms {
|
||||
float vignette_strength;
|
||||
float chroma_strength;
|
||||
float scanline_strength;
|
||||
float screen_height;
|
||||
float mask_strength;
|
||||
float gamma_strength;
|
||||
float curvature;
|
||||
float bleeding;
|
||||
float pixel_scale;
|
||||
float time;
|
||||
float oversample;
|
||||
float flicker;
|
||||
};
|
||||
|
||||
namespace Rendering {
|
||||
|
||||
// Backend GPU basat en SDL3 GPU API (Vulkan/SPIR-V a Linux i Windows,
|
||||
// Metal/MSL a macOS). Pipeline únic: CPU framebuffer → transfer buffer →
|
||||
// scene texture → PostFX pass → swapchain. Sense supersampling, sense
|
||||
// CrtPi i sense Lanczos (reservats per a fases següents).
|
||||
//
|
||||
// Marcat `final` perquè el destructor crida cleanup() (que és virtual);
|
||||
// sense final, clang-tidy avisa de dispatch virtual durant destrucció.
|
||||
class SDL3GPUShader final : public ShaderBackend {
|
||||
public:
|
||||
SDL3GPUShader() = default;
|
||||
~SDL3GPUShader() override;
|
||||
|
||||
SDL3GPUShader(const SDL3GPUShader&) = delete;
|
||||
SDL3GPUShader(SDL3GPUShader&&) = delete;
|
||||
auto operator=(const SDL3GPUShader&) -> SDL3GPUShader& = delete;
|
||||
auto operator=(SDL3GPUShader&&) -> SDL3GPUShader& = delete;
|
||||
|
||||
auto init(SDL_Window* window, int game_width, int game_height) -> bool override;
|
||||
void uploadPixels(const std::uint32_t* pixels, int width, int height) override;
|
||||
void render() override;
|
||||
void setPostFXParams(const PostFXParams& params) override;
|
||||
void setVSync(bool vsync) override;
|
||||
void setPreferredDriver(const std::string& driver) override { preferred_driver_ = driver; }
|
||||
void cleanup() override;
|
||||
|
||||
// Allibera la finestra del device sense destruir el device. Cal cridar-ho
|
||||
// abans de SDL_DestroyWindow perquè el VkSurface tancat no sobrevisca la
|
||||
// finestra de Wayland (vkDestroyInstance cridaria Wayland amb surface invàlida).
|
||||
void releaseWindow();
|
||||
|
||||
[[nodiscard]] auto isReady() const -> bool override { return is_ready_; }
|
||||
[[nodiscard]] auto getDriverName() const -> std::string override { return driver_name_; }
|
||||
|
||||
private:
|
||||
auto createDevice() -> bool;
|
||||
auto createShaders() -> bool;
|
||||
auto createPipeline() -> bool;
|
||||
auto createResources() -> bool;
|
||||
[[nodiscard]] auto bestPresentMode(bool vsync) const -> SDL_GPUPresentMode;
|
||||
|
||||
SDL_Window* window_{nullptr};
|
||||
SDL_GPUDevice* device_{nullptr};
|
||||
SDL_GPUShader* vertex_shader_{nullptr};
|
||||
SDL_GPUShader* fragment_shader_{nullptr};
|
||||
SDL_GPUGraphicsPipeline* pipeline_{nullptr};
|
||||
SDL_GPUTexture* scene_texture_{nullptr};
|
||||
SDL_GPUTransferBuffer* upload_buffer_{nullptr};
|
||||
SDL_GPUSampler* sampler_{nullptr};
|
||||
|
||||
PostFXUniforms uniforms_{
|
||||
.vignette_strength = 0.0F,
|
||||
.chroma_strength = 0.0F,
|
||||
.scanline_strength = 0.0F,
|
||||
.screen_height = 0.0F,
|
||||
.mask_strength = 0.0F,
|
||||
.gamma_strength = 0.0F,
|
||||
.curvature = 0.0F,
|
||||
.bleeding = 0.0F,
|
||||
.pixel_scale = 1.0F,
|
||||
.time = 0.0F,
|
||||
.oversample = 1.0F,
|
||||
.flicker = 0.0F,
|
||||
};
|
||||
|
||||
int game_width_{0};
|
||||
int game_height_{0};
|
||||
std::string preferred_driver_;
|
||||
std::string driver_name_;
|
||||
bool vsync_{true};
|
||||
bool is_ready_{false};
|
||||
};
|
||||
|
||||
} // namespace Rendering
|
||||
Reference in new issue
Block a user