/* =========================================================================== Copyright (C) 2023-2024 Gian 'myT' Schellenbaum This file is part of Challenge Quake 3 (CNQ3). Challenge Quake 3 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Challenge Quake 3 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Challenge Quake 3. If not, see . =========================================================================== */ // Cinematic Rendering Pipeline - private declarations #pragma once #include "srp_local.h" extern cvar_t* crp_dof; extern cvar_t* crp_dof_overlay; extern cvar_t* crp_dof_blades; extern cvar_t* crp_dof_angle; extern cvar_t* crp_gatherDof_focusNearDist; extern cvar_t* crp_gatherDof_focusNearRange; extern cvar_t* crp_gatherDof_focusFarDist; extern cvar_t* crp_gatherDof_focusFarRange; extern cvar_t* crp_gatherDof_brightness; extern cvar_t* crp_accumDof_focusDist; extern cvar_t* crp_accumDof_radius; extern cvar_t* crp_accumDof_samples; extern cvar_t* crp_accumDof_preview; struct DOFMethod { enum Id { None, Gather, Accumulation, Count }; }; struct Tessellator { enum Id { None, Prepass, Opaque, Transp, Count }; }; using namespace RHI; struct WorldVertexRC { float modelViewMatrix[16]; float projectionMatrix[16]; float clipPlane[4]; }; struct PSOCache { struct Entry { GraphicsPipelineDesc desc; HPipeline handle; }; void Init(Entry* entries, uint32_t maxEntryCount); int AddPipeline(const GraphicsPipelineDesc& desc, const char* name); Entry* entries = NULL; uint32_t maxEntryCount = 0; uint32_t entryCount = 1; // we treat index 0 as invalid }; struct Prepass { void Init(); void Draw(const drawSceneViewCommand_t& cmd); void ProcessShader(shader_t& shader); void TessellationOverflow(); private: void BeginBatch(const shader_t* shader); void EndBatch(); PSOCache::Entry psoCacheEntries[128]; PSOCache psoCache; float clipPlane[4]; bool batchOldDepthHack; bool batchDepthHack; }; struct WorldOpaque { void Init(); void Draw(const drawSceneViewCommand_t& cmd); void ProcessShader(shader_t& shader); void TessellationOverflow(); void DrawSkyBox(); void DrawClouds(); private: void BeginBatch(const shader_t* shader); void EndBatch(); void EndSkyBatch(); PSOCache::Entry psoCacheEntries[128]; PSOCache psoCache; float clipPlane[4]; bool batchOldDepthHack; bool batchDepthHack; }; struct WorldTransp { void Init(); void Draw(const drawSceneViewCommand_t& cmd); void ProcessShader(shader_t& shader); void TessellationOverflow(); private: void BeginBatch(const shader_t* shader); void EndBatch(); PSOCache::Entry psoCacheEntries[32]; PSOCache psoCache; float clipPlane[4]; bool batchOldDepthHack; bool batchDepthHack; }; struct Fog { void Init(); void Draw(); private: HBuffer boxIndexBuffer; HBuffer boxVertexBuffer; HPipeline fogInsidePipeline; HPipeline fogOutsidePipeline; }; struct TranspResolve { void Init(); void Draw(const drawSceneViewCommand_t& cmd); private: HPipeline pipeline; }; struct ToneMap { void Init(); void DrawToneMap(); void DrawInverseToneMap(); private: HPipeline pipeline; HPipeline inversePipeline; }; struct AccumDepthOfField { void Init(); void Begin(const drawSceneViewCommand_t& cmd); uint32_t GetSampleCount(); void FixCommand(drawSceneViewCommand_t& newCmd, const drawSceneViewCommand_t& cmd, uint32_t x, uint32_t y); void Accumulate(); void Normalize(); void DrawDebug(); private: HPipeline accumPipeline; HPipeline normPipeline; HPipeline debugPipeline; HTexture accumTexture; float maxNearCocCS; float maxFarCocCS; float modelViewMatrix[16]; float projMatrix[16]; }; struct GatherDepthOfField { void Init(); void Draw(); private: void DrawDebug(); void DrawSplit(); void DrawNearCocTileGen(); void DrawNearCocTileMax(); void DrawBlur(); void DrawFill(); void DrawCombine(); HPipeline debugPipeline; HPipeline splitPipeline; HPipeline nearCocTileGenPipeline; HPipeline nearCocTileMaxPipeline; HPipeline blurPipeline; HPipeline fillPipeline; HPipeline combinePipeline; HTexture nearColorTexture; HTexture farColorTexture; HTexture nearBlurTexture; HTexture farBlurTexture; HTexture nearCocTexture; HTexture nearCocTexture2; HTexture nearCocTileTexture; HTexture nearCocTileTexture2; HTexture farCocTexture; uint32_t tileWidth; uint32_t tileHeight; }; struct Magnifier { void Init(); void Draw(); void DrawGUI(); private: HPipeline pipeline; }; struct BaseBufferId { enum Id { Position, Normal, Count }; }; struct StageBufferId { enum Id { TexCoords, Color, Count }; }; struct GeoBuffers { void Create(const char* name, uint32_t vertexCount, uint32_t indexCount); void Rewind(); void BeginUpload(); void EndUpload(); void UploadBase(); void UploadStage(uint32_t svarsIndex); void EndBaseBatch(uint32_t vertexCount); bool CanAdd(uint32_t vertexCount, uint32_t indexCount, uint32_t stageCount); void DrawStage(uint32_t vertexCount, uint32_t indexCount); GeometryBuffer baseVertexBuffers[BaseBufferId::Count]; GeometryBuffer stageVertexBuffers[StageBufferId::Count]; IndexBuffer indexBuffer; HBuffer vertexBuffers[BaseBufferId::Count + StageBufferId::Count]; uint32_t vertexBufferStrides[BaseBufferId::Count + StageBufferId::Count]; }; struct CRP : IRenderPipeline { void Init() override; void ShutDown(bool fullShutDown) override; void ProcessWorld(world_t& world) override; void ProcessModel(model_t& model) override; void ProcessShader(shader_t& shader) override; void CreateTexture(image_t* image, int mipCount, int width, int height) override; void UpoadTextureAndGenerateMipMaps(image_t* image, const byte* data) override; void BeginTextureUpload(MappedTexture& mappedTexture, image_t* image) override; void EndTextureUpload() override; void ExecuteRenderCommands(const byte* data, bool readbackRequested) override; void TessellationOverflow() override; void DrawSkyBox() override { opaque.DrawSkyBox(); } void DrawClouds() override { opaque.DrawClouds(); } void ReadPixels(int w, int h, int alignment, colorSpace_t colorSpace, void* out) override; uint32_t GetSamplerDescriptorIndexFromBaseIndex(uint32_t baseIndex) override; void BeginFrame(); void EndFrame(); void Blit(HTexture destination, HTexture source, const char* passName, bool hdr, const vec2_t tcScale, const vec2_t tcBias); void BlitRenderTarget(HTexture destination, const char* passName); void DrawSceneView(const drawSceneViewCommand_t& cmd); HTexture GetReadRenderTarget(); HTexture GetWriteRenderTarget(); void SwapRenderTargets(); // general float frameSeed; HTexture readbackRenderTarget; HTexture depthTexture; HTexture normalTexture; HTexture motionVectorTexture; HTexture renderTarget; TextureFormat::Id renderTargetFormat; HTexture renderTargets[2]; uint32_t renderTargetIndex; // the one to write to HSampler samplers[BASE_SAMPLER_COUNT]; // all base samplers uint32_t samplerIndices[BASE_SAMPLER_COUNT]; // descriptor heap indices // blit HPipeline blitPipelineLDR; HPipeline blitPipelineHDR; // world geometry GeoBuffers dynBuffers[FrameCount]; // for rendering world surfaces // for rendering transparent world surfaces HTexture oitIndexTexture; HBuffer oitFragmentBuffer; HBuffer oitCounterBuffer; HBuffer oitCounterStagingBuffer; UI ui; MipMapGenerator mipMapGen; ImGUI imgui; Nuklear nuklear; Prepass prepass; WorldOpaque opaque; WorldTransp transp; TranspResolve transpResolve; ToneMap toneMap; GatherDepthOfField gatherDof; AccumDepthOfField accumDof; Fog fog; Magnifier magnifier; }; extern CRP crp;