From 202558e48bf0774596b90fb86e9c30d0c7d8aed0 Mon Sep 17 00:00:00 2001 From: Matt Haynie Date: Mon, 17 Jun 2019 09:42:05 -0700 Subject: [PATCH] =?UTF-8?q?lightmapping:=20=E2=9C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/TF2Vulkan/IStateManagerVulkan.h | 7 +- .../src/TF2Vulkan/StateManagerVulkan.cpp | 118 ++++++++++-------- .../src/TF2Vulkan/meshes/VulkanMesh.cpp | 36 +++++- .../src/TF2Vulkan/meshes/VulkanMesh.h | 44 +++++-- .../src/interface/internal/IMeshInternal.h | 29 ++++- stdshader_vulkan/src/shaders/XLitGeneric.cpp | 2 + 6 files changed, 164 insertions(+), 72 deletions(-) diff --git a/shaderapivulkan/src/TF2Vulkan/IStateManagerVulkan.h b/shaderapivulkan/src/TF2Vulkan/IStateManagerVulkan.h index 4185656..804b5a7 100644 --- a/shaderapivulkan/src/TF2Vulkan/IStateManagerVulkan.h +++ b/shaderapivulkan/src/TF2Vulkan/IStateManagerVulkan.h @@ -2,6 +2,7 @@ namespace TF2Vulkan { + class IMeshInternal; struct LogicalShadowState; struct LogicalDynamicState; @@ -19,13 +20,13 @@ namespace TF2Vulkan virtual VulkanStateID FindOrCreateState( const LogicalShadowState& staticState, const LogicalDynamicState& dynamicState, - const IMesh& mesh) = 0; + const IMeshInternal& mesh) = 0; virtual void ApplyState(VulkanStateID stateID, const LogicalShadowState& staticState, - const LogicalDynamicState& dynamicState, const IMesh& mesh, IVulkanCommandBuffer& buf) = 0; + const LogicalDynamicState& dynamicState, const IMeshInternal& mesh, IVulkanCommandBuffer& buf) = 0; VulkanStateID ApplyState(const LogicalShadowState& staticState, - const LogicalDynamicState& dynamicState, const IMesh& mesh, + const LogicalDynamicState& dynamicState, const IMeshInternal& mesh, IVulkanCommandBuffer& buf) { const auto& stateID = FindOrCreateState(staticState, dynamicState, mesh); diff --git a/shaderapivulkan/src/TF2Vulkan/StateManagerVulkan.cpp b/shaderapivulkan/src/TF2Vulkan/StateManagerVulkan.cpp index 13a23c8..c3eb2ff 100644 --- a/shaderapivulkan/src/TF2Vulkan/StateManagerVulkan.cpp +++ b/shaderapivulkan/src/TF2Vulkan/StateManagerVulkan.cpp @@ -22,7 +22,7 @@ #include -#include +#include "interface/internal/IMeshInternal.h" #undef min #undef max @@ -93,12 +93,12 @@ namespace struct PipelineLayoutKey : DescriptorSetLayoutKey { PipelineLayoutKey(const LogicalShadowState& staticState, const LogicalDynamicState& dynamicState, - const IMesh& mesh); + const IMeshInternal& mesh); DEFAULT_STRONG_ORDERING_OPERATOR(PipelineLayoutKey); // TODO: Pipeline layout only needs to know shader groups, not specific instances const IShaderInstanceInternal* m_VSShaderInstance; - VertexFormat m_VSVertexFormat; + std::array m_VSVertexFormats; const IShaderInstanceInternal* m_PSShaderInstance; }; @@ -106,7 +106,7 @@ namespace STD_HASH_DEFINITION(PipelineLayoutKey, v.m_VSShaderInstance, - v.m_VSVertexFormat, + v.m_VSVertexFormats, v.m_PSShaderInstance ); @@ -116,7 +116,7 @@ namespace struct PipelineKey final : RenderPassKey, PipelineLayoutKey { PipelineKey(const LogicalShadowState& staticState, const LogicalDynamicState& dynamicState, - const IMesh& mesh); + const IMeshInternal& mesh); DEFAULT_STRONG_ORDERING_OPERATOR(PipelineKey); ShaderDepthFunc_t m_DepthCompareFunc; @@ -402,10 +402,10 @@ namespace TF2Vulkan public: void ApplyState(VulkanStateID stateID, const LogicalShadowState& staticState, const LogicalDynamicState& dynamicState, - const IMesh& mesh, IVulkanCommandBuffer& buf) override; + const IMeshInternal& mesh, IVulkanCommandBuffer& buf) override; VulkanStateID FindOrCreateState(const LogicalShadowState& staticState, - const LogicalDynamicState& dynamicState, const IMesh& mesh) override; + const LogicalDynamicState& dynamicState, const IMeshInternal& mesh) override; const DescriptorSet& FindOrCreateDescriptorSet(const DescriptorSetKey& key); const DescriptorPool& FindOrCreateDescriptorPool(const DescriptorPoolKey& key); @@ -705,28 +705,27 @@ static vk::Format ConvertVertexFormat(const ShaderReflection::VertexAttribute& v return FormatInfo::ConvertDataFormat(componentType, var.m_ComponentCount, componentSize); } -Pipeline::Pipeline(const PipelineKey& key, const PipelineLayout& layout, - const RenderPass& renderPass) : - m_Layout(&layout), - m_RenderPass(&renderPass) +static void InitVertexInputState( + std::vector& attrDescs, + std::vector& bindDescs, + vk::PipelineVertexInputStateCreateInfo& ci, + const ShaderReflection::ReflectionData& vertexShaderRefl, + const std::array& vertexFormats) { - // Shader stage create info(s) + using VIAD = vk::VertexInputAttributeDescription; + for (size_t streamIndex = 0; streamIndex < vertexFormats.size(); streamIndex++) { - auto& cis = m_ShaderStageCIs; - cis.emplace_back(*key.m_VSShaderInstance, vk::ShaderStageFlagBits::eVertex); - cis.emplace_back(*key.m_PSShaderInstance, vk::ShaderStageFlagBits::eFragment); - } - - // Vertex input state create info - { - auto& attrs = m_VertexInputAttributeDescriptions; - - const auto& vertexShaderRefl = key.m_VSShaderInstance->GetGroup().GetVulkanShader().GetReflectionData(); + const VertexFormat& stream = vertexFormats[streamIndex]; VertexFormat::Element vertexElements[VERTEX_ELEMENT_NUMELEMENTS]; size_t totalVertexSize; - const auto vertexElementCount = key.m_VSVertexFormat.GetVertexElements(vertexElements, std::size(vertexElements), &totalVertexSize); - using VIAD = vk::VertexInputAttributeDescription; + const auto vertexElementCount = stream.GetVertexElements(vertexElements, std::size(vertexElements), &totalVertexSize); + if (vertexElementCount <= 0) + continue; + + if (streamIndex > 0) + DebuggerBreakIfDebugging(); + for (uint_fast8_t i = 0; i < vertexElementCount; i++) { const auto& vertexElement = vertexElements[i]; @@ -734,7 +733,7 @@ Pipeline::Pipeline(const PipelineKey& key, const PipelineLayout& layout, VIAD attr; attr.offset = vertexElement.m_Offset; attr.format = vertexElement.m_Type->GetVKFormat(); - attr.binding = 0; + attr.binding = streamIndex + 1; static constexpr auto INVALID_LOCATION = std::numeric_limits::max(); attr.location = INVALID_LOCATION; @@ -753,40 +752,55 @@ Pipeline::Pipeline(const PipelineKey& key, const PipelineLayout& layout, continue; } - attrs.emplace_back(attr); + attrDescs.emplace_back(attr); } - for (const auto& input : vertexShaderRefl.m_VertexInputs) + bindDescs.emplace_back(vk::VertexInputBindingDescription(streamIndex + 1, totalVertexSize)); + } + + // Bind missing vertex input attributes to binding 0 (the fake binding) + for (const auto& input : vertexShaderRefl.m_VertexInputs) + { + bool found = false; + for (auto& attr : attrDescs) { - bool found = false; - for (auto& attr : attrs) + if (attr.location == input.m_Location) { - if (attr.location == input.m_Location) - { - found = true; - break; - } + found = true; + break; } + } - if (found) - continue; + if (found) + continue; - // Otherwise, insert an empty one - //attrs.emplace_back(VIAD(input.m_Location, 1, vk::Format::eR32G32B32A32Sfloat)); - attrs.emplace_back(VIAD(input.m_Location, 1, ConvertVertexFormat(input))); - } + // Insert a reference to the fake binding (index 0) + attrDescs.emplace_back(VIAD(input.m_Location, 0, ConvertVertexFormat(input))); + } - auto & binds = m_VertexInputBindingDescriptions; - binds.emplace_back(vk::VertexInputBindingDescription(0, totalVertexSize)); + // "Fake" binding with no real data + bindDescs.emplace_back(vk::VertexInputBindingDescription(0, /*0*/sizeof(float) * 4, vk::VertexInputRate::eInstance)); - // "Fake" binding with no real data - binds.emplace_back(vk::VertexInputBindingDescription(1, sizeof(float) * 4, vk::VertexInputRate::eInstance)); + AttachVector(ci.pVertexAttributeDescriptions, ci.vertexAttributeDescriptionCount, attrDescs); + AttachVector(ci.pVertexBindingDescriptions, ci.vertexBindingDescriptionCount, bindDescs); +} - auto& ci = m_VertexInputStateCI; - AttachVector(ci.pVertexAttributeDescriptions, ci.vertexAttributeDescriptionCount, attrs); - AttachVector(ci.pVertexBindingDescriptions, ci.vertexBindingDescriptionCount, binds); +Pipeline::Pipeline(const PipelineKey& key, const PipelineLayout& layout, + const RenderPass& renderPass) : + m_Layout(&layout), + m_RenderPass(&renderPass) +{ + // Shader stage create info(s) + { + auto& cis = m_ShaderStageCIs; + cis.emplace_back(*key.m_VSShaderInstance, vk::ShaderStageFlagBits::eVertex); + cis.emplace_back(*key.m_PSShaderInstance, vk::ShaderStageFlagBits::eFragment); } + // Vertex input state create info + InitVertexInputState(m_VertexInputAttributeDescriptions, m_VertexInputBindingDescriptions, m_VertexInputStateCI, + key.m_VSShaderInstance->GetGroup().GetVulkanShader().GetReflectionData(), key.m_VSVertexFormats); + // Vertex input assembly state create info { auto& ci = m_InputAssemblyStateCI; @@ -1258,7 +1272,7 @@ void StateManagerVulkan::ApplyDescriptorSets(const Pipeline& pipeline, } void StateManagerVulkan::ApplyState(VulkanStateID id, const LogicalShadowState& staticState, - const LogicalDynamicState& dynamicState, const IMesh& mesh, IVulkanCommandBuffer& buf) + const LogicalDynamicState& dynamicState, const IMeshInternal& mesh, IVulkanCommandBuffer& buf) { LOG_FUNC(); std::lock_guard lock(m_Mutex); @@ -1327,7 +1341,7 @@ const PipelineLayout& StateManagerVulkan::FindOrCreatePipelineLayout(const Pipel VulkanStateID StateManagerVulkan::FindOrCreateState( const LogicalShadowState& staticState, const LogicalDynamicState& dynamicState, - const IMesh& mesh) + const IMeshInternal& mesh) { LOG_FUNC(); std::lock_guard lock(m_Mutex); @@ -1348,7 +1362,7 @@ VulkanStateID StateManagerVulkan::FindOrCreateState( } PipelineKey::PipelineKey(const LogicalShadowState& staticState, - const LogicalDynamicState& dynamicState, const IMesh& mesh) : + const LogicalDynamicState& dynamicState, const IMeshInternal& mesh) : RenderPassKey(staticState, dynamicState), PipelineLayoutKey(staticState, dynamicState, mesh), @@ -1388,11 +1402,11 @@ PipelineKey::PipelineKey(const LogicalShadowState& staticState, } PipelineLayoutKey::PipelineLayoutKey(const LogicalShadowState& staticState, - const LogicalDynamicState& dynamicState, const IMesh& mesh) : + const LogicalDynamicState& dynamicState, const IMeshInternal& mesh) : DescriptorSetLayoutKey(staticState, dynamicState), m_VSShaderInstance(dynamicState.m_VSShader), - m_VSVertexFormat(mesh.GetVertexFormat()), + m_VSVertexFormats{ VertexFormat(mesh.GetVertexFormat()), mesh.GetColorMeshFormat() }, m_PSShaderInstance(dynamicState.m_PSShader) { diff --git a/shaderapivulkan/src/TF2Vulkan/meshes/VulkanMesh.cpp b/shaderapivulkan/src/TF2Vulkan/meshes/VulkanMesh.cpp index 0667060..474f455 100644 --- a/shaderapivulkan/src/TF2Vulkan/meshes/VulkanMesh.cpp +++ b/shaderapivulkan/src/TF2Vulkan/meshes/VulkanMesh.cpp @@ -60,6 +60,12 @@ int VulkanMesh::GetRoomRemaining() const return Util::algorithm::min(vtxRoom, idxRoom); } +VertexFormat VulkanMesh::GetColorMeshFormat() const +{ + LOG_FUNC_ANYTHREAD(); + return m_ColorMesh ? VertexFormat(m_ColorMesh->GetVertexFormat()) : VertexFormat{}; +} + void VulkanMesh::OverrideVertexBuffer(IMesh* src) { auto lock = ScopeThreadLock(); @@ -264,26 +270,40 @@ void VulkanMesh::DrawInternal(IVulkanCommandBuffer& cmdBuf, int firstIndex, int return; } - vk::Buffer indexBuffer, vertexBuffer; - size_t indexBufferOffset, vertexBufferOffset; + vk::Buffer indexBuffer, vertexBuffer, vertexBufferColor; + size_t indexBufferOffset, vertexBufferOffset, vertexBufferColorOffset = 0; // intentionally only last one assigned + m_IndexBuffer->GetGPUBuffer(indexBuffer, indexBufferOffset); - m_VertexBuffer->GetGPUBuffer(vertexBuffer, vertexBufferOffset); cmdBuf.bindIndexBuffer(indexBuffer, indexBufferOffset, vk::IndexType::eUint16); + m_VertexBuffer->GetGPUBuffer(vertexBuffer, vertexBufferOffset); + if (m_ColorMesh) + { + auto colorMeshInternal = assert_cast(m_ColorMesh); + auto& colorVB = colorMeshInternal->GetVertexBuffer(); + colorVB.GetGPUBuffer(vertexBufferColor, vertexBufferColorOffset); + vertexBufferColorOffset += m_ColorMeshVertexOffset; + } + // Bind vertex buffers { const vk::Buffer vtxBufs[] = { - vertexBuffer, g_ShaderDevice.GetDummyVertexBuffer(), + vertexBuffer, + vertexBufferColor, }; const vk::DeviceSize offsets[] = { - vertexBufferOffset, 0, + vertexBufferOffset, + Util::SafeConvert(vertexBufferColorOffset) }; + + const uint32_t vbCount = m_ColorMesh ? 3 : 2; + static_assert(std::size(vtxBufs) == std::size(offsets)); - cmdBuf.bindVertexBuffers(0, TF2Vulkan::to_array_proxy(vtxBufs), TF2Vulkan::to_array_proxy(offsets)); + cmdBuf.bindVertexBuffers(0, vk::ArrayProxy(vbCount, vtxBufs), vk::ArrayProxy(vbCount, offsets)); } cmdBuf.drawIndexed(Util::SafeConvert(indexCount), 1, Util::SafeConvert(firstIndex)); @@ -295,6 +315,7 @@ void VulkanMesh::SetColorMesh(IMesh* colorMesh, int vertexOffset) { auto lock = ScopeThreadLock(); LOG_FUNC_ANYTHREAD(); + m_ColorMesh = colorMesh; m_ColorMeshVertexOffset = vertexOffset; } @@ -305,6 +326,7 @@ void VulkanMesh::Draw(CPrimList* lists, int listCount) LOG_FUNC(); // TODO: Indirect rendering? + //assert(listCount == 1); for (int i = 0; i < listCount; i++) Draw(lists[i].m_FirstIndex, lists[i].m_NumIndices); } @@ -405,6 +427,8 @@ VulkanGPUBuffer::VulkanGPUBuffer(bool isDynamic, vk::BufferUsageFlags usage) : void VulkanGPUBuffer::GetGPUBuffer(vk::Buffer& buffer, size_t& offset) { + auto lock = ScopeThreadLock(); + if (IsDynamic()) UpdateDynamicBuffer(); diff --git a/shaderapivulkan/src/TF2Vulkan/meshes/VulkanMesh.h b/shaderapivulkan/src/TF2Vulkan/meshes/VulkanMesh.h index b2ef96c..eb74065 100644 --- a/shaderapivulkan/src/TF2Vulkan/meshes/VulkanMesh.h +++ b/shaderapivulkan/src/TF2Vulkan/meshes/VulkanMesh.h @@ -83,6 +83,8 @@ namespace TF2Vulkan size_t ComputeMemoryUsed() const { NOT_IMPLEMENTED_FUNC(); } + void GetGPUBuffer(vk::Buffer& buffer, size_t& offset) override final; + private: struct ModifyData @@ -128,6 +130,8 @@ namespace TF2Vulkan size_t ComputeMemoryUsed() const { NOT_IMPLEMENTED_FUNC(); } + void GetGPUBuffer(vk::Buffer& buffer, size_t& offset) override final; + private: void ValidateData(uint32_t indexCount, uint32_t firstIndex, const IndexDesc_t& desc); @@ -207,12 +211,18 @@ namespace TF2Vulkan void EndCastBuffer() override final; int GetRoomRemaining() const override final; + // IMeshInternal + VertexFormat GetColorMeshFormat() const override final; + void OverrideVertexBuffer(IMesh* src); void OverrideIndexBuffer(IMesh* src); bool HasVertexBufferOverride() const { return !!m_OriginalVertexBuffer; } bool HasIndexBufferOverride() const { return !!m_OriginalIndexBuffer; } + const IIndexBufferInternal& GetIndexBuffer() const override final; + const IVertexBufferInternal& GetVertexBuffer() const override final; + private: std::shared_ptr m_VertexBuffer; std::shared_ptr m_IndexBuffer; @@ -221,7 +231,7 @@ namespace TF2Vulkan std::shared_ptr m_OriginalIndexBuffer; IMesh* m_ColorMesh = nullptr; - int m_ColorMeshVertexOffset = 0; + uint32_t m_ColorMeshVertexOffset = 0; MaterialPrimitiveType_t m_PrimitiveType = MATERIAL_TRIANGLES; }; @@ -251,6 +261,30 @@ namespace TF2Vulkan bool m_HasDrawn = false; }; + inline const IIndexBufferInternal& VulkanMesh::GetIndexBuffer() const + { + LOG_FUNC_ANYTHREAD(); + return *m_IndexBuffer; + } + + inline const IVertexBufferInternal& VulkanMesh::GetVertexBuffer() const + { + LOG_FUNC_ANYTHREAD(); + return *m_VertexBuffer; + } + + inline void VulkanVertexBuffer::GetGPUBuffer(vk::Buffer& buffer, size_t& offset) + { + LOG_FUNC_ANYTHREAD(); + return VulkanGPUBuffer::GetGPUBuffer(buffer, offset); + } + + inline void VulkanIndexBuffer::GetGPUBuffer(vk::Buffer& buffer, size_t& offset) + { + LOG_FUNC_ANYTHREAD(); + return VulkanGPUBuffer::GetGPUBuffer(buffer, offset); + } + inline int VulkanMesh::IndexCount() const { LOG_FUNC_ANYTHREAD(); @@ -266,35 +300,30 @@ namespace TF2Vulkan inline void VulkanMesh::BeginCastBuffer(MaterialIndexFormat_t format) { LOG_FUNC_ANYTHREAD(); - //assert(!HasIndexBufferOverride()); return m_IndexBuffer->BeginCastBuffer(format); } inline bool VulkanMesh::Lock(int maxIndexCount, bool append, IndexDesc_t& desc) { LOG_FUNC_ANYTHREAD(); - //assert(!HasIndexBufferOverride()); return m_IndexBuffer->Lock(maxIndexCount, append, desc); } inline void VulkanMesh::Unlock(int writtenIndexCount, IndexDesc_t& desc) { LOG_FUNC_ANYTHREAD(); - //assert(!HasIndexBufferOverride()); return m_IndexBuffer->Unlock(writtenIndexCount, desc); } inline void VulkanMesh::ModifyBegin(bool readOnly, int firstIndex, int indexCount, IndexDesc_t& desc) { LOG_FUNC_ANYTHREAD(); - //assert(!HasIndexBufferOverride()); return m_IndexBuffer->ModifyBegin(readOnly, firstIndex, indexCount, desc); } inline void VulkanMesh::ModifyEnd(IndexDesc_t& desc) { LOG_FUNC_ANYTHREAD(); - //assert(!HasIndexBufferOverride()); m_IndexBuffer->ModifyEnd(desc); } @@ -325,21 +354,18 @@ namespace TF2Vulkan inline void VulkanMesh::BeginCastBuffer(VertexFormat_t format) { LOG_FUNC_ANYTHREAD(); - //assert(!HasVertexBufferOverride()); return m_VertexBuffer->BeginCastBuffer(format); } inline bool VulkanMesh::Lock(int vertexCount, bool append, VertexDesc_t& desc) { LOG_FUNC_ANYTHREAD(); - //assert(!HasVertexBufferOverride()); return m_VertexBuffer->Lock(vertexCount, append, desc); } inline void VulkanMesh::Unlock(int vertexCount, VertexDesc_t& desc) { LOG_FUNC_ANYTHREAD(); - //assert(!HasVertexBufferOverride()); return m_VertexBuffer->Unlock(vertexCount, desc); } diff --git a/shaderapivulkan/src/interface/internal/IMeshInternal.h b/shaderapivulkan/src/interface/internal/IMeshInternal.h index 694422c..f0a91c3 100644 --- a/shaderapivulkan/src/interface/internal/IMeshInternal.h +++ b/shaderapivulkan/src/interface/internal/IMeshInternal.h @@ -4,7 +4,15 @@ namespace TF2Vulkan { - class IVertexBufferInternal : public IVertexBuffer + class IBufferCommonInternal + { + public: + virtual ~IBufferCommonInternal() = default; + + virtual void GetGPUBuffer(vk::Buffer& buffer, size_t& offset) = 0; + }; + + class IVertexBufferInternal : public IVertexBuffer, public IBufferCommonInternal { private: // These are here to catch any potentially missing virtual functions @@ -22,7 +30,7 @@ namespace TF2Vulkan public: }; - class IIndexBufferInternal : public IIndexBuffer + class IIndexBufferInternal : public IIndexBuffer, public IBufferCommonInternal { private: // These are here to catch any potentially missing virtual functions @@ -56,5 +64,22 @@ namespace TF2Vulkan virtual void DummyFunc9() const final { NOT_IMPLEMENTED_FUNC(); } public: + virtual VertexFormat GetColorMeshFormat() const = 0; + + virtual const IIndexBufferInternal& GetIndexBuffer() const = 0; + virtual const IVertexBufferInternal& GetVertexBuffer() const = 0; + + IIndexBufferInternal& GetIndexBuffer(); + IVertexBufferInternal& GetVertexBuffer(); }; + + inline IIndexBufferInternal& IMeshInternal::GetIndexBuffer() + { + return const_cast(Util::as_const(this)->GetIndexBuffer()); + } + + inline IVertexBufferInternal& IMeshInternal::GetVertexBuffer() + { + return const_cast(Util::as_const(this)->GetVertexBuffer()); + } } diff --git a/stdshader_vulkan/src/shaders/XLitGeneric.cpp b/stdshader_vulkan/src/shaders/XLitGeneric.cpp index 7938b28..53d4a8e 100644 --- a/stdshader_vulkan/src/shaders/XLitGeneric.cpp +++ b/stdshader_vulkan/src/shaders/XLitGeneric.cpp @@ -501,6 +501,8 @@ void Shader::OnDrawElements(const OnDrawElementsParams& params) if (params[BASETEXTURE]->IsTexture()) drawParams.m_Format.AddTexCoord(); + if (derivedType == DerivedShaderType::LightmappedGeneric) + drawParams.m_Format.AddTexCoord(); { int texCoordSizes[8];