From 47f17b1c03e018e1ffb25411d9b1312443a7c3e6 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 2 Dec 2023 16:26:51 +0100 Subject: [PATCH] Move DrawLevelMesh to RenderState --- .../hwrenderer/data/hw_renderstate.h | 7 + src/common/rendering/v_video.h | 2 - .../descriptorsets/vk_descriptorset.cpp | 1 + .../rendering/vulkan/vk_renderdevice.cpp | 189 +----------------- src/common/rendering/vulkan/vk_renderdevice.h | 4 +- .../rendering/vulkan/vk_renderstate.cpp | 88 ++++++++ src/common/rendering/vulkan/vk_renderstate.h | 12 ++ src/rendering/hwrenderer/hw_entrypoint.cpp | 63 ------ .../hwrenderer/scene/hw_drawinfo.cpp | 25 ++- src/rendering/hwrenderer/scene/hw_drawinfo.h | 1 + 10 files changed, 136 insertions(+), 256 deletions(-) diff --git a/src/common/rendering/hwrenderer/data/hw_renderstate.h b/src/common/rendering/hwrenderer/data/hw_renderstate.h index e21f40c93..016b85dd3 100644 --- a/src/common/rendering/hwrenderer/data/hw_renderstate.h +++ b/src/common/rendering/hwrenderer/data/hw_renderstate.h @@ -688,6 +688,13 @@ public: SetColorMask(on, on, on, on); } + // Draw level mesh + virtual void DrawLevelMeshDepthPass() { } + virtual void DrawLevelMeshOpaquePass() { } + virtual void BeginQuery() { } + virtual void EndQuery() { } + virtual void GetQueryResults(TArray& results) { } + friend class Mesh; }; diff --git a/src/common/rendering/v_video.h b/src/common/rendering/v_video.h index 04c8e941e..2e0739993 100644 --- a/src/common/rendering/v_video.h +++ b/src/common/rendering/v_video.h @@ -73,7 +73,6 @@ enum FTextureFormat : uint32_t; class FModelRenderer; struct SamplerUniform; struct FVertexBufferAttribute; -struct HWViewpointUniforms; struct MeshApplyData; // @@ -228,7 +227,6 @@ public: virtual void PostProcessScene(bool swscene, int fixedcm, float flash, const std::function &afterBloomDrawEndScene2D) { if (afterBloomDrawEndScene2D) afterBloomDrawEndScene2D(); } virtual int GetLevelMeshPipelineID(const MeshApplyData& applyData, const SurfaceUniforms& surfaceUniforms, const FMaterialState& material) { return 0; } - virtual void DrawLevelMesh(const HWViewpointUniforms& viewpoint) { } void ScaleCoordsFromWindow(int16_t &x, int16_t &y); diff --git a/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp b/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp index 6cc4ae7eb..174e72f09 100644 --- a/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp +++ b/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp @@ -82,6 +82,7 @@ void VkDescriptorSetManager::Deinit() void VkDescriptorSetManager::BeginFrame() { UpdateFixedSet(); + UpdateLevelMeshSet(); } void VkDescriptorSetManager::UpdateLevelMeshSet() diff --git a/src/common/rendering/vulkan/vk_renderdevice.cpp b/src/common/rendering/vulkan/vk_renderdevice.cpp index c5ac4fbbd..a90d80319 100644 --- a/src/common/rendering/vulkan/vk_renderdevice.cpp +++ b/src/common/rendering/vulkan/vk_renderdevice.cpp @@ -727,192 +727,7 @@ int VulkanRenderDevice::GetLevelMeshPipelineID(const MeshApplyData& applyData, c return levelMeshPipelineKeys.Size() - 1; } -void VulkanRenderDevice::DrawLevelMesh(const HWViewpointUniforms& viewpoint) +const VkPipelineKey& VulkanRenderDevice::GetLevelMeshPipelineKey(int id) const { - auto cmdbuffer = GetCommands()->GetDrawCommands(); - auto buffers = GetBuffers(); - auto descriptors = GetDescriptorSetManager(); - - descriptors->UpdateLevelMeshSet(); - - VkRenderPassKey key = {}; - key.DrawBufferFormat = VK_FORMAT_R16G16B16A16_SFLOAT; - key.Samples = buffers->GetSceneSamples(); - key.DrawBuffers = 1; // 3 if ssao is enabled - key.DepthStencil = true; - - auto passSetup = GetRenderPassManager()->GetRenderPass(key); - - RenderPassBegin beginInfo; - beginInfo.RenderPass(passSetup->GetRenderPass(CT_Color | CT_Depth | CT_Stencil)); - beginInfo.RenderArea(0, 0, buffers->GetWidth(), buffers->GetHeight()); - beginInfo.Framebuffer(buffers->GetFramebuffer(key)); - beginInfo.AddClearColor(screen->mSceneClearColor[0], screen->mSceneClearColor[1], screen->mSceneClearColor[2], screen->mSceneClearColor[3]); - if (key.DrawBuffers > 1) - beginInfo.AddClearColor(0.0f, 0.0f, 0.0f, 0.0f); - if (key.DrawBuffers > 2) - beginInfo.AddClearColor(0.0f, 0.0f, 0.0f, 0.0f); - beginInfo.AddClearDepthStencil(1.0f, 0); - beginInfo.Execute(cmdbuffer); - - VkViewport viewport = {}; - viewport.x = (float)mSceneViewport.left; - viewport.y = (float)mSceneViewport.top; - viewport.width = (float)mSceneViewport.width; - viewport.height = (float)mSceneViewport.height; - viewport.minDepth = 0.0f; - viewport.maxDepth = 1.0f; - cmdbuffer->setViewport(0, 1, &viewport); - - VkRect2D scissor = {}; - scissor.offset.x = 0; - scissor.offset.y = 0; - scissor.extent.width = mSceneViewport.width; - scissor.extent.height = mSceneViewport.height; - cmdbuffer->setScissor(0, 1, &scissor); - - cmdbuffer->setStencilReference(VK_STENCIL_FRONT_AND_BACK, 0); - cmdbuffer->setDepthBias(0.0f, 0.0f, 0.0f); - - VkBuffer vertexBuffers[2] = { GetRaytrace()->GetVertexBuffer()->buffer, GetRaytrace()->GetUniformIndexBuffer()->buffer }; - VkDeviceSize vertexBufferOffsets[] = { 0, 0 }; - cmdbuffer->bindVertexBuffers(0, 2, vertexBuffers, vertexBufferOffsets); - cmdbuffer->bindIndexBuffer(GetRaytrace()->GetIndexBuffer()->buffer, 0, VK_INDEX_TYPE_UINT32); - - auto rsbuffers = GetBufferManager()->GetRSBuffers(); - memcpy(((char*)rsbuffers->Viewpoint.Data) + rsbuffers->Viewpoint.UploadIndex * rsbuffers->Viewpoint.BlockAlign, &viewpoint, sizeof(HWViewpointUniforms)); - int viewpointIndex = rsbuffers->Viewpoint.UploadIndex++; - - MatricesUBO matrices = {}; - matrices.ModelMatrix.loadIdentity(); - matrices.NormalModelMatrix.loadIdentity(); - matrices.TextureMatrix.loadIdentity(); - rsbuffers->MatrixBuffer->Write(matrices); - - auto submesh = GetRaytrace()->GetMesh()->StaticMesh.get(); - - // Draw opaque scene into the depth buffer - for (LevelSubmeshDrawRange& range : submesh->DrawList) - { - VkPipelineKey pipelineKey = levelMeshPipelineKeys[range.PipelineID]; - if (pipelineKey.ShaderKey.AlphaTest) continue; - pipelineKey.ShaderKey.NoFragmentShader = true; - DrawLevelMeshRange(cmdbuffer, passSetup, pipelineKey, viewpointIndex, range.Start, range.Count, 0); - } - for (LevelSubmeshDrawRange& range : submesh->PortalList) - { - VkPipelineKey pipelineKey = levelMeshPipelineKeys[range.PipelineID]; - pipelineKey.ShaderKey.NoFragmentShader = true; - DrawLevelMeshRange(cmdbuffer, passSetup, pipelineKey, viewpointIndex, range.Start, range.Count, 0); - } - - // Draw portal surface occlusion queries - - //int portalIndex = 0; - //cmdbuffer->beginQuery(queryPool, portalIndex, 0); - for (LevelSubmeshDrawRange& range : submesh->PortalList) - { - VkPipelineKey pipelineKey = levelMeshPipelineKeys[range.PipelineID]; - pipelineKey.ShaderKey.NoFragmentShader = true; - DrawLevelMeshRange(cmdbuffer, passSetup, pipelineKey, viewpointIndex, range.Start, range.Count, 0); - } - //cmdbuffer->endQuery(queryPool, portalIndex); - //portalIndex++; - - // Draw opaque scene - for (LevelSubmeshDrawRange& range : submesh->DrawList) - { - DrawLevelMeshRange(cmdbuffer, passSetup, levelMeshPipelineKeys[range.PipelineID], viewpointIndex, range.Start, range.Count, 0); - } - - cmdbuffer->endRenderPass(); - - GetCommands()->FlushCommands(false); - //VkResult result = vkGetQueryPoolResults(GetDevice()->device, queryPool->pool, 0, portalIndex, ...); - cmdbuffer = GetCommands()->GetDrawCommands(); - - // Create stencil - for (LevelSubmeshDrawRange& range : submesh->PortalList) - { - VkPipelineKey pipelineKey = levelMeshPipelineKeys[range.PipelineID]; - pipelineKey.ShaderKey.NoFragmentShader = true; - pipelineKey.StencilTest = true; - pipelineKey.StencilPassOp = SOP_Increment; - DrawLevelMeshRange(cmdbuffer, passSetup, pipelineKey, viewpointIndex, range.Start, range.Count, 0); - } - - // Clear zbuffer - viewport.minDepth = 1.0f; - viewport.maxDepth = 1.0f; - cmdbuffer->setViewport(0, 1, &viewport); - for (LevelSubmeshDrawRange& range : submesh->PortalList) - { - VkPipelineKey pipelineKey = levelMeshPipelineKeys[range.PipelineID]; - pipelineKey.ShaderKey.NoFragmentShader = true; - pipelineKey.StencilTest = true; - pipelineKey.StencilPassOp = SOP_Keep; - pipelineKey.DepthFunc = DF_Always; - DrawLevelMeshRange(cmdbuffer, passSetup, pipelineKey, viewpointIndex, range.Start, range.Count, 1); - } - - // Portal scene - viewport.minDepth = 0.0f; - viewport.maxDepth = 1.0f; - cmdbuffer->setViewport(0, 1, &viewport); - - /* - auto& state = *mRenderState.get(); - state.SetTextureMode(TM_OPAQUE); - mSkyData->RenderDome(state, origin->texture[0], origin->x_offset[0], origin->y_offset, origin->mirrored, FSkyVertexBuffer::SKYMODE_MAINLAYER, !!(di->Level->flags & LEVEL_FORCETILEDSKY)); - state.SetTextureMode(TM_NORMAL); - */ - - // Clear zbuffer - viewport.minDepth = 1.0f; - viewport.maxDepth = 1.0f; - cmdbuffer->setViewport(0, 1, &viewport); - for (LevelSubmeshDrawRange& range : submesh->PortalList) - { - VkPipelineKey pipelineKey = levelMeshPipelineKeys[range.PipelineID]; - pipelineKey.ShaderKey.NoFragmentShader = true; - pipelineKey.StencilTest = true; - pipelineKey.StencilPassOp = SOP_Keep; - pipelineKey.DepthFunc = DF_Always; - DrawLevelMeshRange(cmdbuffer, passSetup, pipelineKey, viewpointIndex, range.Start, range.Count, 1); - } - - // Restore zbuffer - for (LevelSubmeshDrawRange& range : submesh->PortalList) - { - VkPipelineKey pipelineKey = levelMeshPipelineKeys[range.PipelineID]; - pipelineKey.ShaderKey.NoFragmentShader = true; - pipelineKey.StencilTest = true; - pipelineKey.StencilPassOp = SOP_Decrement; - DrawLevelMeshRange(cmdbuffer, passSetup, pipelineKey, viewpointIndex, range.Start, range.Count, 1); - } -} - -void VulkanRenderDevice::DrawLevelMeshRange(VulkanCommandBuffer* cmdbuffer, VkRenderPassSetup* passSetup, const VkPipelineKey& pipelineKey, int viewpointIndex, int start, int count, int stencilRef) -{ - auto rsbuffers = GetBufferManager()->GetRSBuffers(); - auto descriptors = GetDescriptorSetManager(); - - PushConstants pushConstants = {}; - pushConstants.uDataIndex = 0; - pushConstants.uLightIndex = -1; - pushConstants.uBoneIndexBase = -1; - - VulkanPipelineLayout* layout = GetRenderPassManager()->GetPipelineLayout(pipelineKey.NumTextureLayers, pipelineKey.ShaderKey.UseLevelMesh); - uint32_t viewpointOffset = viewpointIndex * rsbuffers->Viewpoint.BlockAlign; - uint32_t matrixOffset = rsbuffers->MatrixBuffer->Offset(); - uint32_t lightsOffset = 0; - uint32_t offsets[] = { viewpointOffset, matrixOffset, lightsOffset }; - - cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, passSetup->GetPipeline(pipelineKey)); - cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptors->GetFixedSet()); - cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 1, descriptors->GetLevelMeshSet(), 3, offsets); - cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 2, descriptors->GetBindlessSet()); - cmdbuffer->pushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, (uint32_t)sizeof(PushConstants), &pushConstants); - cmdbuffer->setStencilReference(VK_STENCIL_FACE_FRONT_AND_BACK, stencilRef); - cmdbuffer->drawIndexed(count, 1, start, 0, 0); + return levelMeshPipelineKeys[id]; } diff --git a/src/common/rendering/vulkan/vk_renderdevice.h b/src/common/rendering/vulkan/vk_renderdevice.h index 9c4ae0fb0..25ab31997 100644 --- a/src/common/rendering/vulkan/vk_renderdevice.h +++ b/src/common/rendering/vulkan/vk_renderdevice.h @@ -92,13 +92,13 @@ public: int GetBindlessTextureIndex(FMaterial* material, int clampmode, int translation) override; int GetLevelMeshPipelineID(const MeshApplyData& applyData, const SurfaceUniforms& surfaceUniforms, const FMaterialState& material) override; - void DrawLevelMesh(const HWViewpointUniforms& viewpoint) override; + + const VkPipelineKey& GetLevelMeshPipelineKey(int id) const; private: void RenderTextureView(FCanvasTexture* tex, std::function renderFunc) override; void PrintStartupLog(); void CopyScreenToBuffer(int w, int h, uint8_t *data) override; - void DrawLevelMeshRange(VulkanCommandBuffer* cmdbuffer, VkRenderPassSetup* passSetup, const VkPipelineKey& pipelineKey, int viewpointIndex, int start, int count, int stencilRef); std::shared_ptr mDevice; std::unique_ptr mCommands; diff --git a/src/common/rendering/vulkan/vk_renderstate.cpp b/src/common/rendering/vulkan/vk_renderstate.cpp index 294879a01..f360a15ac 100644 --- a/src/common/rendering/vulkan/vk_renderstate.cpp +++ b/src/common/rendering/vulkan/vk_renderstate.cpp @@ -28,6 +28,7 @@ #include "vulkan/descriptorsets/vk_descriptorset.h" #include "vulkan/textures/vk_renderbuffers.h" #include "vulkan/textures/vk_hwtexture.h" +#include "vulkan/accelstructs/vk_raytrace.h" #include #include "hw_skydome.h" @@ -739,6 +740,8 @@ void VkRenderState::BeginFrame() mRSBuffers->Lightbuffer.UploadIndex = 0; mRSBuffers->Bonebuffer.UploadIndex = 0; mRSBuffers->Fogballbuffer.UploadIndex = 0; + + mNextOcclusionQueryIndex = 0; } void VkRenderState::EndRenderPass() @@ -831,6 +834,91 @@ void VkRenderState::BeginRenderPass(VulkanCommandBuffer *cmdbuffer) mClearTargets = 0; } +void VkRenderState::ApplyLevelMesh() +{ + ApplyMatrices(); + ApplyRenderPass(DT_Triangles); + ApplyScissor(); + ApplyViewport(); + ApplyStencilRef(); + ApplyDepthBias(); + mNeedApply = true; + + VkBuffer vertexBuffers[2] = { fb->GetRaytrace()->GetVertexBuffer()->buffer, fb->GetRaytrace()->GetUniformIndexBuffer()->buffer }; + VkDeviceSize vertexBufferOffsets[] = { 0, 0 }; + mCommandBuffer->bindVertexBuffers(0, 2, vertexBuffers, vertexBufferOffsets); + mCommandBuffer->bindIndexBuffer(fb->GetRaytrace()->GetIndexBuffer()->buffer, 0, VK_INDEX_TYPE_UINT32); +} + +void VkRenderState::DrawLevelMeshDepthPass() +{ + ApplyLevelMesh(); + + auto submesh = fb->GetRaytrace()->GetMesh()->StaticMesh.get(); + for (LevelSubmeshDrawRange& range : submesh->DrawList) + { + VkPipelineKey pipelineKey = fb->GetLevelMeshPipelineKey(range.PipelineID); + if (pipelineKey.ShaderKey.AlphaTest) continue; + pipelineKey.ShaderKey.NoFragmentShader = true; + DrawLevelMeshRange(mCommandBuffer, pipelineKey, range.Start, range.Count); + } + for (LevelSubmeshDrawRange& range : submesh->PortalList) + { + VkPipelineKey pipelineKey = fb->GetLevelMeshPipelineKey(range.PipelineID); + pipelineKey.ShaderKey.NoFragmentShader = true; + DrawLevelMeshRange(mCommandBuffer, pipelineKey, range.Start, range.Count); + } +} + +void VkRenderState::DrawLevelMeshOpaquePass() +{ + ApplyLevelMesh(); + + auto submesh = fb->GetRaytrace()->GetMesh()->StaticMesh.get(); + for (LevelSubmeshDrawRange& range : submesh->DrawList) + { + DrawLevelMeshRange(mCommandBuffer, fb->GetLevelMeshPipelineKey(range.PipelineID), range.Start, range.Count); + } +} + +void VkRenderState::BeginQuery() +{ + // mCommandBuffer->beginQuery(mNextOcclusionQueryIndex++); +} + +void VkRenderState::EndQuery() +{ + // mCommandBuffer->endQuery(mNextOcclusionQueryIndex - 1); +} + +void VkRenderState::GetQueryResults(TArray& results) +{ + //vkGetQueryPoolResults(fb->GetDevice()->device, ...) + results.Clear(); +} + +void VkRenderState::DrawLevelMeshRange(VulkanCommandBuffer* cmdbuffer, const VkPipelineKey& pipelineKey, int start, int count) +{ + PushConstants pushConstants = {}; + pushConstants.uDataIndex = 0; + pushConstants.uLightIndex = -1; + pushConstants.uBoneIndexBase = -1; + + VulkanPipelineLayout* layout = fb->GetRenderPassManager()->GetPipelineLayout(pipelineKey.NumTextureLayers, pipelineKey.ShaderKey.UseLevelMesh); + uint32_t viewpointOffset = mViewpointOffset; + uint32_t matrixOffset = mRSBuffers->MatrixBuffer->Offset(); + uint32_t lightsOffset = 0; + uint32_t offsets[] = { viewpointOffset, matrixOffset, lightsOffset }; + + auto descriptors = fb->GetDescriptorSetManager(); + cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, mPassSetup->GetPipeline(pipelineKey)); + cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptors->GetFixedSet()); + cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 1, descriptors->GetLevelMeshSet(), 3, offsets); + cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 2, descriptors->GetBindlessSet()); + cmdbuffer->pushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, (uint32_t)sizeof(PushConstants), &pushConstants); + cmdbuffer->drawIndexed(count, 1, start, 0, 0); +} + ///////////////////////////////////////////////////////////////////////////// void VkRenderStateMolten::Draw(int dt, int index, int count, bool apply) diff --git a/src/common/rendering/vulkan/vk_renderstate.h b/src/common/rendering/vulkan/vk_renderstate.h index 8bb3bf243..9ca947870 100644 --- a/src/common/rendering/vulkan/vk_renderstate.h +++ b/src/common/rendering/vulkan/vk_renderstate.h @@ -56,6 +56,13 @@ public: void UpdateShadowData(unsigned int index, const FFlatVertex* vertices, unsigned int count) override; void ResetVertices() override; + // Draw level mesh + void DrawLevelMeshDepthPass() override; + void DrawLevelMeshOpaquePass() override; + void BeginQuery() override; + void EndQuery() override; + void GetQueryResults(TArray& results) override; + // Worker threads void FlushCommands() override { EndRenderPass(); } @@ -81,6 +88,9 @@ protected: void BeginRenderPass(VulkanCommandBuffer *cmdbuffer); void WaitForStreamBuffers(); + void ApplyLevelMesh(); + void DrawLevelMeshRange(VulkanCommandBuffer* cmdbuffer, const VkPipelineKey& pipelineKey, int start, int count); + VulkanRenderDevice* fb = nullptr; VkRSBuffers* mRSBuffers = nullptr; @@ -109,6 +119,8 @@ protected: int mColorMask = 15; int mCullMode = 0; + int mNextOcclusionQueryIndex = 0; + PushConstants mPushConstants = {}; uint32_t mLastViewpointOffset = 0xffffffff; diff --git a/src/rendering/hwrenderer/hw_entrypoint.cpp b/src/rendering/hwrenderer/hw_entrypoint.cpp index af30a1f53..a7e42ab93 100644 --- a/src/rendering/hwrenderer/hw_entrypoint.cpp +++ b/src/rendering/hwrenderer/hw_entrypoint.cpp @@ -57,8 +57,6 @@ EXTERN_CVAR(Bool, gl_bandedswlight) extern bool NoInterpolateView; -CVAR(Bool, gl_levelmesh, false, 0/*CVAR_ARCHIVE | CVAR_GLOBALCONFIG*/) - static SWSceneDrawer *swdrawer; void CleanSWDrawer() @@ -132,67 +130,6 @@ sector_t* RenderViewpoint(FRenderViewpoint& mainvp, AActor* camera, IntRect* bou // This function will only do something if the setting differs. FLightDefaults::SetAttenuationForLevel(!!(camera->Level->flags3 & LEVEL3_ATTENUATE)); - if (gl_levelmesh) - { - screen->SetViewportRects(bounds); - - auto vrmode = VRMode::GetVRMode(mainview && toscreen); - const int eyeCount = vrmode->mEyeCount; - screen->FirstEye(); - - FRenderViewpoint vp = mainvp; - const auto& eye = vrmode->mEyes[0]; - vp.Pos += eye.GetViewShift(vp.HWAngles.Yaw.Degrees()); - - vp.SetViewAngle(r_viewwindow); - - vp.FieldOfView = DAngle::fromDeg(fov); // Set the real FOV for the current scene (it's not necessarily the same as the global setting in r_viewpoint) - - auto lightmode = camera->Level->info->lightmode; - if (lightmode == ELightMode::NotSet) - lightmode = ELightMode::ZDoomSoftware; - - bool mirror = false; - bool planemirror = false; - float mult = mirror ? -1.f : 1.f; - float planemult = planemirror ? -camera->Level->info->pixelstretch : camera->Level->info->pixelstretch; - HWViewpointUniforms VPUniforms = {}; - VPUniforms.mProjectionMatrix = eye.GetProjection(fov, ratio, fovratio); - VPUniforms.mViewMatrix.loadIdentity(); - VPUniforms.mViewMatrix.rotate(vp.HWAngles.Roll.Degrees(), 0.0f, 0.0f, 1.0f); - VPUniforms.mViewMatrix.rotate(vp.HWAngles.Pitch.Degrees(), 1.0f, 0.0f, 0.0f); - VPUniforms.mViewMatrix.rotate(vp.HWAngles.Yaw.Degrees(), 0.0f, mult, 0.0f); - VPUniforms.mViewMatrix.translate(vp.Pos.X * mult, -vp.Pos.Z * planemult, -vp.Pos.Y); - VPUniforms.mViewMatrix.scale(-mult, planemult, 1); - VPUniforms.mViewHeight = viewheight; - VPUniforms.mGlobVis = (float)R_GetGlobVis(r_viewwindow, r_visibility) / 32.f; - VPUniforms.mPalLightLevels = static_cast(gl_bandedswlight) | (static_cast(gl_fogmode) << 8) | ((int)lightmode << 16); - VPUniforms.mClipLine.X = -10000000.0f; - VPUniforms.mShadowFilter = static_cast(gl_light_shadow_filter); - VPUniforms.mLightBlendMode = (level.info ? (int)level.info->lightblendmode : 0); - VPUniforms.mCameraPos = FVector4(vp.Pos.X, vp.Pos.Z, vp.Pos.Y, 0.0f); - VPUniforms.CalcDependencies(); - - screen->DrawLevelMesh(VPUniforms); - - PostProcess.Clock(); - //if (toscreen) di->EndDrawScene(mainvp.sector, RenderState); // do not call this for camera textures. - - /*if (RenderState.GetPassType() == GBUFFER_PASS) // Turn off ssao draw buffers - { - RenderState.SetPassType(NORMAL_PASS); - RenderState.EnableDrawBuffers(1); - }*/ - - auto cm = CM_DEFAULT; // di->SetFullbrightFlags(mainview ? vp.camera->player : nullptr); - float flash = 1.f; - - screen->PostProcessScene(false, cm, flash, [&]() { /* di->DrawEndScene2D(mainvp.sector, RenderState); */ }); - PostProcess.Unclock(); - - return mainvp.sector; - } - static HWDrawContext mainthread_drawctx; hw_ClearFakeFlat(&mainthread_drawctx); diff --git a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp index dee9d418f..bcd4f1d87 100644 --- a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp +++ b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp @@ -65,6 +65,7 @@ CVAR(Float, gl_mask_sprite_threshold, 0.5f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, gl_coronas, true, CVAR_ARCHIVE); CVAR(Bool, gl_meshcache, false, 0/*CVAR_ARCHIVE | CVAR_GLOBALCONFIG*/) +CVAR(Bool, gl_levelmesh, false, 0/*CVAR_ARCHIVE | CVAR_GLOBALCONFIG*/) sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool back); @@ -400,7 +401,28 @@ void HWDrawInfo::CreateScene(bool drawpsprites, FRenderState& state) // clip the scene and fill the drawlists - RenderBSP(Level->HeadNode(), drawpsprites, state); + if (gl_levelmesh) + { + // To do: + // 1) draw level into depth buffer + // 2) use occlusion queries on all portals in level to decide which are visible + // 3) draw opaque level so the GPU has something to do while we examine the query results + // 4) retrieve the query results and use them to fill the portal manager with portals + // + state.DrawLevelMeshDepthPass(); + // for (HWWall& wall : PortalWalls) { state.BeginQuery(); wall.Draw(state); state.EndQuery(); } + // for (HWFlat& flat : PortalFlats) { state.BeginQuery(); flat.Draw(state); state.EndQuery(); } + state.DrawLevelMeshOpaquePass(); + state.GetQueryResults(QueryResultsBuffer); + for (unsigned int i = 0, count = QueryResultsBuffer.Size(); i < count; i++) + { + bool portalVisible = QueryResultsBuffer[i]; + } + } + else + { + RenderBSP(Level->HeadNode(), drawpsprites, state); + } // And now the crappy hacks that have to be done to avoid rendering anomalies. // These cannot be multithreaded when the time comes because all these depend @@ -852,7 +874,6 @@ void HWDrawInfo::DrawScene(int drawmode, FRenderState& state) } } - //----------------------------------------------------------------------------- // // R_RenderView - renders one view - either the screen or a camera texture diff --git a/src/rendering/hwrenderer/scene/hw_drawinfo.h b/src/rendering/hwrenderer/scene/hw_drawinfo.h index a2d32d4dc..acaed30dd 100644 --- a/src/rendering/hwrenderer/scene/hw_drawinfo.h +++ b/src/rendering/hwrenderer/scene/hw_drawinfo.h @@ -183,6 +183,7 @@ struct HWDrawInfo bool MeshBSP = false; bool MeshBuilding = false; + TArray QueryResultsBuffer; HWDrawInfo(HWDrawContext* drawctx) : drawctx(drawctx) { for (HWDrawList& list : drawlists) list.drawctx = drawctx; }