diff --git a/src/common/rendering/v_video.h b/src/common/rendering/v_video.h index b4361c517..98176ed8d 100644 --- a/src/common/rendering/v_video.h +++ b/src/common/rendering/v_video.h @@ -73,6 +73,7 @@ enum FTextureFormat : uint32_t; class FModelRenderer; struct SamplerUniform; struct FVertexBufferAttribute; +struct HWViewpointUniforms; // // VIDEO @@ -225,7 +226,7 @@ public: virtual void PostProcessScene(bool swscene, int fixedcm, float flash, const std::function &afterBloomDrawEndScene2D) { if (afterBloomDrawEndScene2D) afterBloomDrawEndScene2D(); } - virtual void DrawLevelMesh(const FVector3& pos, const VSMatrix& proj) { } + virtual void DrawLevelMesh(const HWViewpointUniforms& viewpoint) { } void ScaleCoordsFromWindow(int16_t &x, int16_t &y); diff --git a/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp b/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp index 0eb633485..52913618e 100644 --- a/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp +++ b/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp @@ -89,6 +89,11 @@ void VkRaytrace::BeginFrame() } } +int VkRaytrace::GetIndexCount() +{ + return Mesh->StaticMesh->MeshElements.Size(); +} + void VkRaytrace::UploadMeshes(bool dynamicOnly) { TArray locations(2); @@ -202,7 +207,7 @@ void VkRaytrace::UploadMeshes(bool dynamicOnly) SurfaceVertex* vertices = (SurfaceVertex*)(data + datapos); for (int j = 0, count = submesh->MeshVertices.Size(); j < count; ++j) - *(vertices++) = { { submesh->MeshVertices[j], 1.0f }, submesh->MeshVertexUVs[j], float(j), j + 10000.0f }; + *(vertices++) = { { submesh->MeshVertices[j], 1.0f }, submesh->MeshVertexUVs[j], float(j), j + 10000.0f, FVector3(0.0f, 0.0f, -1.0f), 0.0f}; size_t copysize = submesh->MeshVertices.Size() * sizeof(SurfaceVertex); if (copysize > 0) diff --git a/src/common/rendering/vulkan/accelstructs/vk_raytrace.h b/src/common/rendering/vulkan/accelstructs/vk_raytrace.h index 6ce73b434..64c644497 100644 --- a/src/common/rendering/vulkan/accelstructs/vk_raytrace.h +++ b/src/common/rendering/vulkan/accelstructs/vk_raytrace.h @@ -42,6 +42,8 @@ struct SurfaceVertex FVector4 pos; FVector2 uv; float Padding1, Padding2; + FVector3 lightmap; + float Padding3; }; struct PortalInfo @@ -80,6 +82,8 @@ public: VulkanBuffer* GetSurfaceBuffer() { return SurfaceBuffer.get(); } VulkanBuffer* GetPortalBuffer() { return PortalBuffer.get(); } + int GetIndexCount(); + private: struct BLAS { diff --git a/src/common/rendering/vulkan/buffers/vk_rsbuffers.cpp b/src/common/rendering/vulkan/buffers/vk_rsbuffers.cpp index 0d13983a2..d2f5fafd4 100644 --- a/src/common/rendering/vulkan/buffers/vk_rsbuffers.cpp +++ b/src/common/rendering/vulkan/buffers/vk_rsbuffers.cpp @@ -56,8 +56,8 @@ VkRSBuffers::VkRSBuffers(VulkanRenderDevice* fb) .DebugName("Flatbuffer.IndexBuffer") .Create(fb->GetDevice()); - MatrixBuffer = std::make_unique(fb, sizeof(MatricesUBO), 50000); - StreamBuffer = std::make_unique(fb, sizeof(StreamUBO), 300); + MatrixBuffer = std::make_unique(fb); + StreamBuffer = std::make_unique(fb); Viewpoint.BlockAlign = (sizeof(HWViewpointUniforms) + fb->uniformblockalignment - 1) / fb->uniformblockalignment * fb->uniformblockalignment; @@ -149,9 +149,11 @@ uint32_t VkStreamBuffer::NextStreamDataBlock() return mStreamDataOffset; } -VkStreamBufferWriter::VkStreamBufferWriter(VkRSBuffers* rsbuffers) +///////////////////////////////////////////////////////////////////////////// + +VkStreamBufferWriter::VkStreamBufferWriter(VulkanRenderDevice* fb) { - mBuffer = rsbuffers->StreamBuffer.get(); + mBuffer = std::make_unique(fb, sizeof(StreamUBO), 300); } bool VkStreamBufferWriter::Write(const StreamData& data) @@ -178,9 +180,9 @@ void VkStreamBufferWriter::Reset() ///////////////////////////////////////////////////////////////////////////// -VkMatrixBufferWriter::VkMatrixBufferWriter(VkRSBuffers* rsbuffers) +VkMatrixBufferWriter::VkMatrixBufferWriter(VulkanRenderDevice* fb) { - mBuffer = rsbuffers->MatrixBuffer.get(); + mBuffer = std::make_unique(fb, sizeof(MatricesUBO), 50000); } bool VkMatrixBufferWriter::Write(const MatricesUBO& matrices) diff --git a/src/common/rendering/vulkan/buffers/vk_rsbuffers.h b/src/common/rendering/vulkan/buffers/vk_rsbuffers.h index 3df215a58..df06cac0c 100644 --- a/src/common/rendering/vulkan/buffers/vk_rsbuffers.h +++ b/src/common/rendering/vulkan/buffers/vk_rsbuffers.h @@ -4,7 +4,8 @@ #include "vulkan/buffers/vk_hwbuffer.h" #include "vulkan/shaders/vk_shader.h" -class VkStreamBuffer; +class VkMatrixBufferWriter; +class VkStreamBufferWriter; struct FFlatVertex; class VkRSBuffers @@ -50,8 +51,8 @@ public: void* Data = nullptr; } Bonebuffer; - std::unique_ptr MatrixBuffer; - std::unique_ptr StreamBuffer; + std::unique_ptr MatrixBuffer; + std::unique_ptr StreamBuffer; }; class VkStreamBuffer @@ -74,16 +75,18 @@ private: class VkStreamBufferWriter { public: - VkStreamBufferWriter(VkRSBuffers* rsbuffers); + VkStreamBufferWriter(VulkanRenderDevice* fb); bool Write(const StreamData& data); void Reset(); uint32_t DataIndex() const { return mDataIndex; } - uint32_t StreamDataOffset() const { return mStreamDataOffset; } + uint32_t Offset() const { return mStreamDataOffset; } + + VulkanBuffer* UBO() const { return mBuffer->UBO.get(); } private: - VkStreamBuffer* mBuffer; + std::unique_ptr mBuffer; uint32_t mDataIndex = MAX_STREAM_DATA - 1; uint32_t mStreamDataOffset = 0; }; @@ -91,14 +94,16 @@ private: class VkMatrixBufferWriter { public: - VkMatrixBufferWriter(VkRSBuffers* rsbuffers); + VkMatrixBufferWriter(VulkanRenderDevice* fb); bool Write(const MatricesUBO& matrices); void Reset(); uint32_t Offset() const { return mOffset; } + VulkanBuffer* UBO() const { return mBuffer->UBO.get(); } + private: - VkStreamBuffer* mBuffer; + std::unique_ptr mBuffer; uint32_t mOffset = 0; }; diff --git a/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp b/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp index 28941c35d..d71411aac 100644 --- a/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp +++ b/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp @@ -62,8 +62,8 @@ void VkDescriptorSetManager::Init() WriteDescriptors() .AddBuffer(rsbufferset.get(), 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->Viewpoint.UBO.get(), 0, sizeof(HWViewpointUniforms)) - .AddBuffer(rsbufferset.get(), 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->MatrixBuffer->UBO.get(), 0, sizeof(MatricesUBO)) - .AddBuffer(rsbufferset.get(), 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->StreamBuffer->UBO.get(), 0, sizeof(StreamUBO)) + .AddBuffer(rsbufferset.get(), 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->MatrixBuffer->UBO(), 0, sizeof(MatricesUBO)) + .AddBuffer(rsbufferset.get(), 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->StreamBuffer->UBO(), 0, sizeof(StreamUBO)) .AddBuffer(rsbufferset.get(), 3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->Lightbuffer.UBO.get(), 0, sizeof(LightBufferUBO)) .AddBuffer(rsbufferset.get(), 4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, rsbuffers->Bonebuffer.SSO.get()) .Execute(fb->GetDevice()); diff --git a/src/common/rendering/vulkan/shaders/vk_shader.cpp b/src/common/rendering/vulkan/shaders/vk_shader.cpp index 17c5a68ce..d1953591f 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.cpp +++ b/src/common/rendering/vulkan/shaders/vk_shader.cpp @@ -183,6 +183,7 @@ std::unique_ptr VkShaderManager::LoadFragShader(FString shadername if (key.UseRaytrace) definesBlock << "#define USE_RAYTRACE\n"; if (key.UseShadowmap) definesBlock << "#define USE_SHADOWMAP\n"; + if (key.UseLevelMesh) definesBlock << "#define USE_LEVELMESH\n"; switch (key.TextureMode) { diff --git a/src/common/rendering/vulkan/shaders/vk_shader.h b/src/common/rendering/vulkan/shaders/vk_shader.h index 84b52e053..ef5a37f4e 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.h +++ b/src/common/rendering/vulkan/shaders/vk_shader.h @@ -63,7 +63,7 @@ public: uint64_t Detailmap : 1; // uTextureMode & TEXF_Detailmap uint64_t Glowmap : 1; // uTextureMode & TEXF_Glowmap uint64_t GBufferPass : 1; // GBUFFER_PASS - uint64_t UseShadowmap : 1; // USE_SHADOWMAPS + uint64_t UseShadowmap : 1; // USE_SHADOWMAP uint64_t UseRaytrace : 1; // USE_RAYTRACE uint64_t FogBeforeLights : 1; // FOG_BEFORE_LIGHTS uint64_t FogAfterLights : 1; // FOG_AFTER_LIGHTS @@ -71,7 +71,8 @@ public: uint64_t SWLightRadial : 1; // SWLIGHT_RADIAL uint64_t SWLightBanded : 1; // SWLIGHT_BANDED uint64_t LightMode : 2; // LIGHTMODE_DEFAULT, LIGHTMODE_SOFTWARE, LIGHTMODE_VANILLA, LIGHTMODE_BUILD - uint64_t Unused : 45; + uint64_t UseLevelMesh : 1; // USE_LEVELMESH + uint64_t Unused : 44; }; uint64_t AsQWORD = 0; }; diff --git a/src/common/rendering/vulkan/textures/vk_renderbuffers.cpp b/src/common/rendering/vulkan/textures/vk_renderbuffers.cpp index 145a2ed8e..979422850 100644 --- a/src/common/rendering/vulkan/textures/vk_renderbuffers.cpp +++ b/src/common/rendering/vulkan/textures/vk_renderbuffers.cpp @@ -85,6 +85,27 @@ void VkRenderBuffers::BeginFrame(int width, int height, int sceneWidth, int scen mSceneHeight = sceneHeight; } +VulkanFramebuffer* VkRenderBuffers::GetFramebuffer(const VkRenderPassKey& key) +{ + auto& framebuffer = SceneColor.RSFramebuffers[key]; + if (framebuffer) + return framebuffer.get(); + + FramebufferBuilder builder; + builder.RenderPass(fb->GetRenderPassManager()->GetRenderPass(key)->GetRenderPass(0)); + builder.Size(GetWidth(), GetHeight()); + builder.AddAttachment(SceneColor.View.get()); + if (key.DrawBuffers > 1) + builder.AddAttachment(SceneFog.View.get()); + if (key.DrawBuffers > 2) + builder.AddAttachment(SceneNormal.View.get()); + if (key.DepthStencil) + builder.AddAttachment(SceneDepthStencil.View.get()); + builder.DebugName("VkRenderPassSetup.Framebuffer"); + framebuffer = builder.Create(fb->GetDevice()); + return framebuffer.get(); +} + void VkRenderBuffers::CreatePipelineDepthStencil(int width, int height) { ImageBuilder builder; diff --git a/src/common/rendering/vulkan/textures/vk_renderbuffers.h b/src/common/rendering/vulkan/textures/vk_renderbuffers.h index 360b366ab..4e9cab4da 100644 --- a/src/common/rendering/vulkan/textures/vk_renderbuffers.h +++ b/src/common/rendering/vulkan/textures/vk_renderbuffers.h @@ -28,6 +28,8 @@ public: int GetSceneHeight() const { return mSceneHeight; } VkSampleCountFlagBits GetSceneSamples() const { return mSamples; } + VulkanFramebuffer* GetFramebuffer(const VkRenderPassKey& key); + VkTextureImage SceneColor; VkTextureImage SceneDepthStencil; VkTextureImage SceneNormal; diff --git a/src/common/rendering/vulkan/vk_renderdevice.cpp b/src/common/rendering/vulkan/vk_renderdevice.cpp index 51509f815..17efd5f3f 100644 --- a/src/common/rendering/vulkan/vk_renderdevice.cpp +++ b/src/common/rendering/vulkan/vk_renderdevice.cpp @@ -607,6 +607,150 @@ int VulkanRenderDevice::GetBindlessTextureIndex(FMaterial* material, int clampmo return static_cast(material)->GetBindlessIndex(materialState); } -void VulkanRenderDevice::DrawLevelMesh(const FVector3& pos, const VSMatrix& proj) +void VulkanRenderDevice::DrawLevelMesh(const HWViewpointUniforms& viewpoint) { + auto cmdbuffer = GetCommands()->GetDrawCommands(); + auto buffers = GetBuffers(); + auto descriptors = GetDescriptorSetManager(); + + 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_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); + + static const FVertexBufferAttribute format[] = + { + { 0, VATTR_VERTEX, VFmt_Float4, (int)myoffsetof(SurfaceVertex, pos.X) }, + { 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(SurfaceVertex, uv.X) }, + { 0, VATTR_LIGHTMAP, VFmt_Float3, (int)myoffsetof(SurfaceVertex, lightmap.X) }, + }; + int vertexFormatIndex = GetRenderPassManager()->GetVertexFormat(1, 3, sizeof(SurfaceVertex), format); + VkBuffer vertexBuffers[2] = { GetRaytrace()->GetVertexBuffer()->buffer, GetRaytrace()->GetVertexBuffer()->buffer }; + VkDeviceSize vertexBufferOffsets[] = { 0, 0 }; + cmdbuffer->bindVertexBuffers(0, 2, vertexBuffers, vertexBufferOffsets); + cmdbuffer->bindIndexBuffer(GetRaytrace()->GetIndexBuffer()->buffer, 0, VK_INDEX_TYPE_UINT32); + + VkPipelineKey pipelineKey; + pipelineKey.DrawType = DT_Triangles; + pipelineKey.VertexFormat = vertexFormatIndex; + pipelineKey.RenderStyle = DefaultRenderStyle(); + pipelineKey.DepthTest = false; + pipelineKey.DepthWrite = false; + pipelineKey.DepthFunc = 0; + pipelineKey.DepthClamp = false; + pipelineKey.DepthBias = false; + pipelineKey.StencilTest = false; + pipelineKey.StencilPassOp = 0; + pipelineKey.ColorMask = 15; + pipelineKey.CullMode = 0; + pipelineKey.NumTextureLayers = 0; + pipelineKey.NumTextureLayers = max(pipelineKey.NumTextureLayers, SHADER_MIN_REQUIRED_TEXTURE_LAYERS);// Always force minimum 8 textures as the shader requires it + pipelineKey.ShaderKey.SpecialEffect = EFF_NONE; + pipelineKey.ShaderKey.EffectState = SHADER_NoTexture; + pipelineKey.ShaderKey.AlphaTest = false; + pipelineKey.ShaderKey.SWLightRadial = true; + pipelineKey.ShaderKey.LightMode = 1; // Software + pipelineKey.ShaderKey.UseShadowmap = gl_light_shadowmap; + pipelineKey.ShaderKey.UseRaytrace = gl_light_raytrace; + pipelineKey.ShaderKey.GBufferPass = key.DrawBuffers > 1; + pipelineKey.ShaderKey.UseLevelMesh = true; + + VulkanPipelineLayout* layout = GetRenderPassManager()->GetPipelineLayout(pipelineKey.NumTextureLayers); + + cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, passSetup->GetPipeline(pipelineKey)); + + auto rsbuffers = GetBufferManager()->GetRSBuffers(); + memcpy(((char*)rsbuffers->Viewpoint.Data) + rsbuffers->Viewpoint.UploadIndex * rsbuffers->Viewpoint.BlockAlign, &viewpoint, sizeof(HWViewpointUniforms)); + int viewpointIndex = rsbuffers->Viewpoint.UploadIndex++; + + StreamData streamdata = {}; + streamdata.uFogColor = 0xffffffff; + streamdata.uDesaturationFactor = 0.0f; + streamdata.uAlphaThreshold = 0.5f; + streamdata.uAddColor = 0; + streamdata.uObjectColor = 0xffffffff; + streamdata.uObjectColor2 = 0; + streamdata.uTextureBlendColor = 0; + streamdata.uTextureAddColor = 0; + streamdata.uTextureModulateColor = 0; + streamdata.uLightDist = 0.0f; + streamdata.uLightFactor = 0.0f; + streamdata.uFogDensity = 0.0f; + streamdata.uLightLevel = 255.0f;// -1.0f; + streamdata.uInterpolationFactor = 0; + streamdata.uVertexColor = { 1.0f, 1.0f, 1.0f, 1.0f }; + streamdata.uGlowTopColor = { 0.0f, 0.0f, 0.0f, 0.0f }; + streamdata.uGlowBottomColor = { 0.0f, 0.0f, 0.0f, 0.0f }; + streamdata.uGlowTopPlane = { 0.0f, 0.0f, 0.0f, 0.0f }; + streamdata.uGlowBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f }; + streamdata.uGradientTopPlane = { 0.0f, 0.0f, 0.0f, 0.0f }; + streamdata.uGradientBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f }; + streamdata.uSplitTopPlane = { 0.0f, 0.0f, 0.0f, 0.0f }; + streamdata.uSplitBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f }; + streamdata.uDynLightColor = { 0.0f, 0.0f, 0.0f, 1.0f }; + streamdata.uDetailParms = { 0.0f, 0.0f, 0.0f, 0.0f }; +#ifdef NPOT_EMULATION + streamdata.uNpotEmulation = { 0,0,0,0 }; +#endif + + rsbuffers->StreamBuffer->Write(streamdata); + + MatricesUBO matrices = {}; + matrices.ModelMatrix.loadIdentity(); + matrices.NormalModelMatrix.loadIdentity(); + matrices.TextureMatrix.loadIdentity(); + rsbuffers->MatrixBuffer->Write(matrices); + + uint32_t viewpointOffset = viewpointIndex * rsbuffers->Viewpoint.BlockAlign; + uint32_t matrixOffset = rsbuffers->MatrixBuffer->Offset(); + uint32_t streamDataOffset = rsbuffers->StreamBuffer->Offset(); + uint32_t lightsOffset = 0; + uint32_t offsets[4] = { viewpointOffset, matrixOffset, streamDataOffset, lightsOffset }; + cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptors->GetFixedDescriptorSet()); + cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 1, descriptors->GetRSBufferDescriptorSet(), 4, offsets); + cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 2, descriptors->GetNullTextureDescriptorSet()); + + PushConstants pushConstants = {}; + pushConstants.uDataIndex = rsbuffers->StreamBuffer->DataIndex(); + pushConstants.uLightIndex = -1; + pushConstants.uBoneIndexBase = -1; + cmdbuffer->pushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, (uint32_t)sizeof(PushConstants), &pushConstants); + + cmdbuffer->drawIndexed(GetRaytrace()->GetIndexCount(), 1, 0, 0, 0); + + cmdbuffer->endRenderPass(); } diff --git a/src/common/rendering/vulkan/vk_renderdevice.h b/src/common/rendering/vulkan/vk_renderdevice.h index 3bea6fdd3..ee8db667b 100644 --- a/src/common/rendering/vulkan/vk_renderdevice.h +++ b/src/common/rendering/vulkan/vk_renderdevice.h @@ -89,7 +89,7 @@ public: int GetBindlessTextureIndex(FMaterial* material, int clampmode, int translation) override; - void DrawLevelMesh(const FVector3& pos, const VSMatrix& proj) override; + void DrawLevelMesh(const HWViewpointUniforms& viewpoint) override; private: void RenderTextureView(FCanvasTexture* tex, std::function renderFunc) override; diff --git a/src/common/rendering/vulkan/vk_renderstate.cpp b/src/common/rendering/vulkan/vk_renderstate.cpp index 43c3fb86e..20502a39d 100644 --- a/src/common/rendering/vulkan/vk_renderstate.cpp +++ b/src/common/rendering/vulkan/vk_renderstate.cpp @@ -40,7 +40,7 @@ CVAR(Int, vk_submit_size, 1000, 0); EXTERN_CVAR(Bool, r_skipmats) -VkRenderState::VkRenderState(VulkanRenderDevice* fb) : fb(fb), mRSBuffers(fb->GetBufferManager()->GetRSBuffers()), mStreamBufferWriter(mRSBuffers), mMatrixBufferWriter(mRSBuffers) +VkRenderState::VkRenderState(VulkanRenderDevice* fb) : fb(fb), mRSBuffers(fb->GetBufferManager()->GetRSBuffers()) { mMatrices.ModelMatrix.loadIdentity(); mMatrices.NormalModelMatrix.loadIdentity(); @@ -408,16 +408,16 @@ void VkRenderState::ApplyStreamData() mStreamData.uSpecularMaterial = { source->GetGlossiness(), source->GetSpecularLevel() }; } - if (!mStreamBufferWriter.Write(mStreamData)) + if (!mRSBuffers->StreamBuffer->Write(mStreamData)) { WaitForStreamBuffers(); - mStreamBufferWriter.Write(mStreamData); + mRSBuffers->StreamBuffer->Write(mStreamData); } } void VkRenderState::ApplyPushConstants() { - mPushConstants.uDataIndex = mStreamBufferWriter.DataIndex(); + mPushConstants.uDataIndex = mRSBuffers->StreamBuffer->DataIndex(); mPushConstants.uLightIndex = mLightIndex >= 0 ? (mLightIndex % MAX_LIGHT_DATA) : -1; mPushConstants.uBoneIndexBase = mBoneIndexBase; @@ -428,10 +428,10 @@ void VkRenderState::ApplyMatrices() { if (mMatricesChanged) { - if (!mMatrixBufferWriter.Write(mMatrices)) + if (!mRSBuffers->MatrixBuffer->Write(mMatrices)) { WaitForStreamBuffers(); - mMatrixBufferWriter.Write(mMatrices); + mRSBuffers->MatrixBuffer->Write(mMatrices); } mMatricesChanged = false; } @@ -497,8 +497,8 @@ void VkRenderState::ApplyMaterial() void VkRenderState::ApplyBufferSets() { - uint32_t matrixOffset = mMatrixBufferWriter.Offset(); - uint32_t streamDataOffset = mStreamBufferWriter.StreamDataOffset(); + uint32_t matrixOffset = mRSBuffers->MatrixBuffer->Offset(); + uint32_t streamDataOffset = mRSBuffers->StreamBuffer->Offset(); uint32_t lightsOffset = mLightIndex >= 0 ? (uint32_t)(mLightIndex / MAX_LIGHT_DATA) * sizeof(LightBufferUBO) : mLastLightsOffset; if (mViewpointOffset != mLastViewpointOffset || matrixOffset != mLastMatricesOffset || streamDataOffset != mLastStreamDataOffset || lightsOffset != mLastLightsOffset) { @@ -520,8 +520,8 @@ void VkRenderState::WaitForStreamBuffers() { fb->WaitForCommands(false); mApplyCount = 0; - mStreamBufferWriter.Reset(); - mMatrixBufferWriter.Reset(); + mRSBuffers->StreamBuffer->Reset(); + mRSBuffers->MatrixBuffer->Reset(); } int VkRenderState::SetViewpoint(const HWViewpointUniforms& vp) @@ -723,8 +723,8 @@ void VkRenderState::EndRenderPass() void VkRenderState::EndFrame() { - mMatrixBufferWriter.Reset(); - mStreamBufferWriter.Reset(); + mRSBuffers->MatrixBuffer->Reset(); + mRSBuffers->StreamBuffer->Reset(); } void VkRenderState::EnableDrawBuffers(int count, bool apply) diff --git a/src/common/rendering/vulkan/vk_renderstate.h b/src/common/rendering/vulkan/vk_renderstate.h index 8f21e5297..1ae2896ee 100644 --- a/src/common/rendering/vulkan/vk_renderstate.h +++ b/src/common/rendering/vulkan/vk_renderstate.h @@ -116,9 +116,6 @@ protected: uint32_t mLastLightsOffset = 0; uint32_t mViewpointOffset = 0; - VkStreamBufferWriter mStreamBufferWriter; - VkMatrixBufferWriter mMatrixBufferWriter; - int mLastVertexOffsets[2] = { 0, 0 }; IBuffer* mLastVertexBuffer = nullptr; IBuffer* mLastIndexBuffer = nullptr; diff --git a/src/rendering/hwrenderer/hw_entrypoint.cpp b/src/rendering/hwrenderer/hw_entrypoint.cpp index 367945b57..c635b6cb0 100644 --- a/src/rendering/hwrenderer/hw_entrypoint.cpp +++ b/src/rendering/hwrenderer/hw_entrypoint.cpp @@ -52,6 +52,9 @@ #include "hw_vrmodes.h" EXTERN_CVAR(Bool, cl_capfps) +EXTERN_CVAR(Float, r_visibility) +EXTERN_CVAR(Bool, gl_bandedswlight) + extern bool NoInterpolateView; CVAR(Bool, gl_levelmesh, true, 0/*CVAR_ARCHIVE | CVAR_GLOBALCONFIG*/) @@ -141,7 +144,34 @@ sector_t* RenderViewpoint(FRenderViewpoint& mainvp, AActor* camera, IntRect* bou const auto& eye = vrmode->mEyes[0]; vp.Pos += eye.GetViewShift(vp.HWAngles.Yaw.Degrees()); - screen->DrawLevelMesh(FVector3((float)vp.Pos.X, (float)vp.Pos.Y, (float)vp.Pos.Z), eye.GetProjection(fov, ratio, fovratio)); + vp.SetViewAngle(r_viewwindow); + + 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.mNormalViewMatrix.loadIdentity(); + 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.mShadowmapFilter = static_cast(gl_shadowmap_filter); + VPUniforms.mLightBlendMode = (level.info ? (int)level.info->lightblendmode : 0); + VPUniforms.mCameraPos = FVector4(vp.Pos.X, vp.Pos.Z, vp.Pos.Y, 0.0f); + + screen->DrawLevelMesh(VPUniforms); PostProcess.Clock(); //if (toscreen) di->EndDrawScene(mainvp.sector, RenderState); // do not call this for camera textures. diff --git a/wadsrc/static/shaders/scene/binding_fixed.glsl b/wadsrc/static/shaders/scene/binding_fixed.glsl new file mode 100644 index 000000000..f72df3bf9 --- /dev/null +++ b/wadsrc/static/shaders/scene/binding_fixed.glsl @@ -0,0 +1,31 @@ + +layout(set = 0, binding = 0) uniform sampler2D ShadowMap; +layout(set = 0, binding = 1) uniform sampler2DArray LightMap; + +#if defined(USE_RAYTRACE) +#if defined(SUPPORTS_RAYQUERY) +layout(set = 0, binding = 2) uniform accelerationStructureEXT TopLevelAS; +#else +struct CollisionNode +{ + vec3 center; + float padding1; + vec3 extents; + float padding2; + int left; + int right; + int element_index; + int padding3; +}; +layout(std430, set = 0, binding = 2) buffer NodeBuffer +{ + int nodesRoot; + int nodebufferPadding1; + int nodebufferPadding2; + int nodebufferPadding3; + CollisionNode nodes[]; +}; +layout(std430, set = 0, binding = 3) buffer VertexBuffer { vec4 vertices[]; }; +layout(std430, set = 0, binding = 4) buffer ElementBuffer { int elements[]; }; +#endif +#endif diff --git a/wadsrc/static/shaders/scene/binding_rsbuffers.glsl b/wadsrc/static/shaders/scene/binding_rsbuffers.glsl new file mode 100644 index 000000000..a9fa50506 --- /dev/null +++ b/wadsrc/static/shaders/scene/binding_rsbuffers.glsl @@ -0,0 +1,90 @@ + +// This must match the HWViewpointUniforms struct +layout(set = 1, binding = 0, std140) uniform ViewpointUBO +{ + mat4 ProjectionMatrix; + mat4 ViewMatrix; + mat4 NormalViewMatrix; + + vec4 uCameraPos; + vec4 uClipLine; + + float uGlobVis; // uGlobVis = R_GetGlobVis(r_visibility) / 32.0 + int uPalLightLevels; + int uViewHeight; // Software fuzz scaling + float uClipHeight; + float uClipHeightDirection; + int uShadowmapFilter; + + int uLightBlendMode; +}; + +layout(set = 1, binding = 1, std140) uniform MatricesUBO +{ + mat4 ModelMatrix; + mat4 NormalModelMatrix; + mat4 TextureMatrix; +}; + +// This must match the StreamData struct +struct StreamData +{ + vec4 uObjectColor; + vec4 uObjectColor2; + vec4 uDynLightColor; + vec4 uAddColor; + vec4 uTextureAddColor; + vec4 uTextureModulateColor; + vec4 uTextureBlendColor; + vec4 uFogColor; + float uDesaturationFactor; + float uInterpolationFactor; + float timer; // timer data for material shaders + int useVertexData; + vec4 uVertexColor; + vec4 uVertexNormal; + + vec4 uGlowTopPlane; + vec4 uGlowTopColor; + vec4 uGlowBottomPlane; + vec4 uGlowBottomColor; + + vec4 uGradientTopPlane; + vec4 uGradientBottomPlane; + + vec4 uSplitTopPlane; + vec4 uSplitBottomPlane; + + vec4 uDetailParms; + vec4 uNpotEmulation; + + vec2 uClipSplit; + vec2 uSpecularMaterial; + + float uLightLevel; + float uFogDensity; + float uLightFactor; + float uLightDist; + + float uAlphaThreshold; + float padding1; + float padding2; + float padding3; +}; + +layout(set = 1, binding = 2, std140) uniform StreamUBO +{ + StreamData data[MAX_STREAM_DATA]; +}; + +// light buffers +layout(set = 1, binding = 3, std140) uniform LightBufferUBO +{ + vec4 lights[MAX_LIGHT_DATA]; +}; + +// bone matrix buffers +layout(set = 1, binding = 4, std430) buffer BoneBufferSSO +{ + mat4 bones[]; +}; diff --git a/wadsrc/static/shaders/scene/binding_textures.glsl b/wadsrc/static/shaders/scene/binding_textures.glsl new file mode 100644 index 000000000..a38cd5933 --- /dev/null +++ b/wadsrc/static/shaders/scene/binding_textures.glsl @@ -0,0 +1,13 @@ + +// textures +layout(set = 2, binding = 0) uniform sampler2D tex; +layout(set = 2, binding = 1) uniform sampler2D texture2; +layout(set = 2, binding = 2) uniform sampler2D texture3; +layout(set = 2, binding = 3) uniform sampler2D texture4; +layout(set = 2, binding = 4) uniform sampler2D texture5; +layout(set = 2, binding = 5) uniform sampler2D texture6; +layout(set = 2, binding = 6) uniform sampler2D texture7; +layout(set = 2, binding = 7) uniform sampler2D texture8; +layout(set = 2, binding = 8) uniform sampler2D texture9; +layout(set = 2, binding = 9) uniform sampler2D texture10; +layout(set = 2, binding = 10) uniform sampler2D texture11; diff --git a/wadsrc/static/shaders/scene/frag_main.glsl b/wadsrc/static/shaders/scene/frag_main.glsl index ba3987517..ccfa6a51b 100644 --- a/wadsrc/static/shaders/scene/frag_main.glsl +++ b/wadsrc/static/shaders/scene/frag_main.glsl @@ -1,6 +1,10 @@ void main() { +#ifdef USE_LEVELMESH + FragColor = vec4(fract(gl_FragCoord.x / 500), fract(gl_FragCoord.x / 500), 1.0, 1.0); +#else + #ifdef NO_CLIPDISTANCE_SUPPORT if (ClipDistanceA.x < 0 || ClipDistanceA.y < 0 || ClipDistanceA.z < 0 || ClipDistanceA.w < 0 || ClipDistanceB.x < 0) discard; #endif @@ -17,4 +21,6 @@ void main() FragFog = vec4(AmbientOcclusionColor(), 1.0); FragNormal = vec4(vEyeNormal.xyz * 0.5 + 0.5, 1.0); #endif + +#endif } diff --git a/wadsrc/static/shaders/scene/layout_shared.glsl b/wadsrc/static/shaders/scene/layout_shared.glsl index 7f30d3ae2..741fb6247 100644 --- a/wadsrc/static/shaders/scene/layout_shared.glsl +++ b/wadsrc/static/shaders/scene/layout_shared.glsl @@ -1,136 +1,7 @@ -layout(set = 0, binding = 0) uniform sampler2D ShadowMap; -layout(set = 0, binding = 1) uniform sampler2DArray LightMap; -#if defined(USE_RAYTRACE) -#if defined(SUPPORTS_RAYQUERY) -layout(set = 0, binding = 2) uniform accelerationStructureEXT TopLevelAS; -#else -struct CollisionNode -{ - vec3 center; - float padding1; - vec3 extents; - float padding2; - int left; - int right; - int element_index; - int padding3; -}; -layout(std430, set = 0, binding = 2) buffer NodeBuffer -{ - int nodesRoot; - int nodebufferPadding1; - int nodebufferPadding2; - int nodebufferPadding3; - CollisionNode nodes[]; -}; -layout(std430, set = 0, binding = 3) buffer VertexBuffer { vec4 vertices[]; }; -layout(std430, set = 0, binding = 4) buffer ElementBuffer { int elements[]; }; -#endif -#endif - -// This must match the HWViewpointUniforms struct -layout(set = 1, binding = 0, std140) uniform ViewpointUBO -{ - mat4 ProjectionMatrix; - mat4 ViewMatrix; - mat4 NormalViewMatrix; - - vec4 uCameraPos; - vec4 uClipLine; - - float uGlobVis; // uGlobVis = R_GetGlobVis(r_visibility) / 32.0 - int uPalLightLevels; - int uViewHeight; // Software fuzz scaling - float uClipHeight; - float uClipHeightDirection; - int uShadowmapFilter; - - int uLightBlendMode; -}; - -layout(set = 1, binding = 1, std140) uniform MatricesUBO -{ - mat4 ModelMatrix; - mat4 NormalModelMatrix; - mat4 TextureMatrix; -}; - -// This must match the StreamData struct -struct StreamData -{ - vec4 uObjectColor; - vec4 uObjectColor2; - vec4 uDynLightColor; - vec4 uAddColor; - vec4 uTextureAddColor; - vec4 uTextureModulateColor; - vec4 uTextureBlendColor; - vec4 uFogColor; - float uDesaturationFactor; - float uInterpolationFactor; - float timer; // timer data for material shaders - int useVertexData; - vec4 uVertexColor; - vec4 uVertexNormal; - - vec4 uGlowTopPlane; - vec4 uGlowTopColor; - vec4 uGlowBottomPlane; - vec4 uGlowBottomColor; - - vec4 uGradientTopPlane; - vec4 uGradientBottomPlane; - - vec4 uSplitTopPlane; - vec4 uSplitBottomPlane; - - vec4 uDetailParms; - vec4 uNpotEmulation; - - vec2 uClipSplit; - vec2 uSpecularMaterial; - - float uLightLevel; - float uFogDensity; - float uLightFactor; - float uLightDist; - - float uAlphaThreshold; - float padding1; - float padding2; - float padding3; -}; - -layout(set = 1, binding = 2, std140) uniform StreamUBO -{ - StreamData data[MAX_STREAM_DATA]; -}; - -// light buffers -layout(set = 1, binding = 3, std140) uniform LightBufferUBO -{ - vec4 lights[MAX_LIGHT_DATA]; -}; - -// bone matrix buffers -layout(set = 1, binding = 4, std430) buffer BoneBufferSSO -{ - mat4 bones[]; -}; - -// textures -layout(set = 2, binding = 0) uniform sampler2D tex; -layout(set = 2, binding = 1) uniform sampler2D texture2; -layout(set = 2, binding = 2) uniform sampler2D texture3; -layout(set = 2, binding = 3) uniform sampler2D texture4; -layout(set = 2, binding = 4) uniform sampler2D texture5; -layout(set = 2, binding = 5) uniform sampler2D texture6; -layout(set = 2, binding = 6) uniform sampler2D texture7; -layout(set = 2, binding = 7) uniform sampler2D texture8; -layout(set = 2, binding = 8) uniform sampler2D texture9; -layout(set = 2, binding = 9) uniform sampler2D texture10; -layout(set = 2, binding = 10) uniform sampler2D texture11; +#include "shaders/scene/binding_fixed.glsl" +#include "shaders/scene/binding_rsbuffers.glsl" +#include "shaders/scene/binding_textures.glsl" // This must match the PushConstants struct layout(push_constant) uniform PushConstants