diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 54bacc34c6..596eae5e5c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1101,7 +1101,6 @@ set (PCH_SOURCES common/rendering/hwrenderer/data/hw_modelvertexbuffer.cpp common/rendering/hwrenderer/data/hw_cvars.cpp common/rendering/hwrenderer/data/hw_vrmodes.cpp - common/rendering/hwrenderer/data/hw_bonebuffer.cpp common/rendering/hwrenderer/data/hw_aabbtree.cpp common/rendering/hwrenderer/data/hw_shadowmap.cpp common/rendering/hwrenderer/data/hw_shaderpatcher.cpp diff --git a/src/common/rendering/hwrenderer/data/hw_bonebuffer.cpp b/src/common/rendering/hwrenderer/data/hw_bonebuffer.cpp deleted file mode 100644 index 4074964c5d..0000000000 --- a/src/common/rendering/hwrenderer/data/hw_bonebuffer.cpp +++ /dev/null @@ -1,109 +0,0 @@ -// -//--------------------------------------------------------------------------- -// -// Copyright(C) 2014-2016 Christoph Oelckers -// All rights reserved. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 2 of the License, or -// (at your option) any later version. -// -// This program 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 Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see http://www.gnu.org/licenses/ -// -//-------------------------------------------------------------------------- -// - -#include "hw_bonebuffer.h" -#include "hw_dynlightdata.h" -#include "v_video.h" - -static const int BONE_SIZE = (16*sizeof(float)); - -BoneBuffer::BoneBuffer(DFrameBuffer* fb, int pipelineNbr) : fb(fb), mPipelineNbr(pipelineNbr) -{ - int maxNumberOfBones = 80000; - - mBufferSize = maxNumberOfBones; - mByteSize = mBufferSize * BONE_SIZE; - - //if (fb->useSSBO()) - { - mBufferType = true; - mBlockAlign = 0; - mBlockSize = mBufferSize; - mMaxUploadSize = mBlockSize; - } - /*else - { - mBufferType = false; - mBlockSize = fb->maxuniformblock / BONE_SIZE; - mBlockAlign = fb->uniformblockalignment < 64 ? 1 : fb->uniformblockalignment / BONE_SIZE; - mMaxUploadSize = (mBlockSize - mBlockAlign); - }*/ - - for (int n = 0; n < mPipelineNbr; n++) - { - mBufferPipeline[n] = fb->CreateBoneBuffer(); - mBufferPipeline[n]->SetData(mByteSize, nullptr, BufferUsageType::Persistent); - } - - Clear(); -} - -BoneBuffer::~BoneBuffer() -{ - delete mBuffer; -} - -void BoneBuffer::Clear() -{ - mIndex = 0; - - mPipelinePos++; - mPipelinePos %= mPipelineNbr; - - mBuffer = mBufferPipeline[mPipelinePos]; -} - -int BoneBuffer::UploadBones(const TArray& bones) -{ - int totalsize = bones.Size(); - if (totalsize > (int)mMaxUploadSize) - { - totalsize = mMaxUploadSize; - } - - uint8_t *mBufferPointer = (uint8_t*)mBuffer->Memory(); - assert(mBufferPointer != nullptr); - if (mBufferPointer == nullptr) return -1; - if (totalsize <= 0) return -1; // there are no bones - - unsigned int thisindex = mIndex.fetch_add(totalsize); - - if (thisindex + totalsize <= mBufferSize) - { - memcpy(mBufferPointer + thisindex * BONE_SIZE, bones.Data(), totalsize * BONE_SIZE); - return thisindex; - } - else - { - return -1; // Buffer is full. Since it is being used live at the point of the upload we cannot do much here but to abort. - } -} - -int BoneBuffer::GetBinding(unsigned int index, size_t* pOffset, size_t* pSize) -{ - // this function will only get called if a uniform buffer is used. For a shader storage buffer we only need to bind the buffer once at the start. - unsigned int offset = (index / mBlockAlign) * mBlockAlign; - - *pOffset = offset * BONE_SIZE; - *pSize = mBlockSize * BONE_SIZE; - return (index - offset); -} diff --git a/src/common/rendering/hwrenderer/data/hw_bonebuffer.h b/src/common/rendering/hwrenderer/data/hw_bonebuffer.h deleted file mode 100644 index 367529416a..0000000000 --- a/src/common/rendering/hwrenderer/data/hw_bonebuffer.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include "tarray.h" -#include "hwrenderer/data/buffers.h" -#include "common/utility/matrix.h" -#include -#include - -class DFrameBuffer; -class FRenderState; - -class BoneBuffer -{ - DFrameBuffer* fb = nullptr; - IBuffer *mBuffer; - IBuffer* mBufferPipeline[HW_MAX_PIPELINE_BUFFERS]; - int mPipelineNbr; - int mPipelinePos = 0; - - bool mBufferType; - std::atomic mIndex; - unsigned int mBlockAlign; - unsigned int mBlockSize; - unsigned int mBufferSize; - unsigned int mByteSize; - unsigned int mMaxUploadSize; - -public: - BoneBuffer(DFrameBuffer* fb, int pipelineNbr = 1); - ~BoneBuffer(); - - void Clear(); - int UploadBones(const TArray &bones); - void Map() { mBuffer->Map(); } - void Unmap() { mBuffer->Unmap(); } - unsigned int GetBlockSize() const { return mBlockSize; } - bool GetBufferType() const { return mBufferType; } - int GetBinding(unsigned int index, size_t* pOffset, size_t* pSize); - - // Only for GLES to determin how much data is in the buffer - int GetCurrentIndex() { return mIndex; }; - - // OpenGL needs the buffer to mess around with the binding. - IBuffer* GetBuffer() const - { - return mBuffer; - } -}; diff --git a/src/common/rendering/hwrenderer/data/hw_meshbuilder.h b/src/common/rendering/hwrenderer/data/hw_meshbuilder.h index 8c6e92e675..f91bd7880e 100644 --- a/src/common/rendering/hwrenderer/data/hw_meshbuilder.h +++ b/src/common/rendering/hwrenderer/data/hw_meshbuilder.h @@ -69,6 +69,7 @@ public: int SetViewpoint(const HWViewpointUniforms& vp) override { return 0; } void SetViewpoint(int index) override { } int UploadLights(const FDynLightData& lightdata) override { return -1; } + int UploadBones(const TArray& bones) override { return -1; } // Draw commands void Draw(int dt, int index, int count, bool apply = true) override; diff --git a/src/common/rendering/hwrenderer/data/hw_renderstate.h b/src/common/rendering/hwrenderer/data/hw_renderstate.h index ef072b4ec3..83d0e6dc7f 100644 --- a/src/common/rendering/hwrenderer/data/hw_renderstate.h +++ b/src/common/rendering/hwrenderer/data/hw_renderstate.h @@ -760,6 +760,7 @@ public: virtual int SetViewpoint(const HWViewpointUniforms& vp) = 0; virtual void SetViewpoint(int index) = 0; virtual int UploadLights(const FDynLightData& lightdata) = 0; + virtual int UploadBones(const TArray& bones) = 0; // Draw commands virtual void ClearScreen() = 0; diff --git a/src/common/rendering/v_video.h b/src/common/rendering/v_video.h index 4ad5da709d..ce4b810059 100644 --- a/src/common/rendering/v_video.h +++ b/src/common/rendering/v_video.h @@ -56,7 +56,6 @@ struct HWDrawInfo; class FMaterial; class FGameTexture; class FRenderState; -class BoneBuffer; enum EHWCaps { @@ -139,7 +138,6 @@ public: const char *vendorstring; // We have to account for some issues with particular vendors. FSkyVertexBuffer *mSkyData = nullptr; // the sky vertex buffer FFlatVertexBuffer *mVertexData = nullptr; // Global vertex data - BoneBuffer* mBones = nullptr; // Model bones ShadowMap* mShadowMap = nullptr; int mGameScreenWidth = 0; @@ -236,7 +234,6 @@ public: bool BuffersArePersistent() { return !!(hwcaps & RFL_BUFFER_STORAGE); } // To do: these buffers shouldn't be created by the hwrenderer layer - it will be simpler if the backend manages them completely - virtual IBuffer* CreateBoneBuffer() { return nullptr; } virtual IBuffer* CreateShadowmapNodesBuffer() { return nullptr; } virtual IBuffer* CreateShadowmapLinesBuffer() { return nullptr; } virtual IBuffer* CreateShadowmapLightsBuffer() { return nullptr; } diff --git a/src/common/rendering/vulkan/buffers/vk_buffer.cpp b/src/common/rendering/vulkan/buffers/vk_buffer.cpp index 0a2baca15b..c34d3bfe9d 100644 --- a/src/common/rendering/vulkan/buffers/vk_buffer.cpp +++ b/src/common/rendering/vulkan/buffers/vk_buffer.cpp @@ -46,6 +46,9 @@ void VkBufferManager::Init() Lightbuffer.SSO.reset(new VkHardwareDataBuffer(fb, true, false)); Lightbuffer.SSO->SetData(Lightbuffer.Count * 4 * sizeof(FVector4), nullptr, BufferUsageType::Persistent); + Bonebuffer.SSO.reset(new VkHardwareDataBuffer(fb, true, false)); + Bonebuffer.SSO->SetData(Bonebuffer.Count * sizeof(VSMatrix), nullptr, BufferUsageType::Persistent); + CreateFanToTrisIndexBuffer(); } @@ -53,6 +56,7 @@ void VkBufferManager::Deinit() { Viewpoint.UBO.reset(); Lightbuffer.SSO.reset(); + Bonebuffer.SSO.reset(); while (!Buffers.empty()) RemoveBuffer(Buffers.back()); @@ -69,7 +73,7 @@ void VkBufferManager::RemoveBuffer(VkHardwareBuffer* buffer) buffer->fb = nullptr; Buffers.erase(buffer->it); - for (VkHardwareDataBuffer** knownbuf : { &LightNodes, &LightLines, &LightList, &BoneBufferSSO}) + for (VkHardwareDataBuffer** knownbuf : { &LightNodes, &LightLines, &LightList}) { if (buffer == *knownbuf) *knownbuf = nullptr; } @@ -85,12 +89,6 @@ IBuffer* VkBufferManager::CreateIndexBuffer() return new VkHardwareIndexBuffer(fb); } -IBuffer* VkBufferManager::CreateBoneBuffer() -{ - BoneBufferSSO = new VkHardwareDataBuffer(fb, true, false); - return BoneBufferSSO; -} - IBuffer* VkBufferManager::CreateShadowmapNodesBuffer() { LightNodes = new VkHardwareDataBuffer(fb, true, false); diff --git a/src/common/rendering/vulkan/buffers/vk_buffer.h b/src/common/rendering/vulkan/buffers/vk_buffer.h index 61792ca750..57ffd3439b 100644 --- a/src/common/rendering/vulkan/buffers/vk_buffer.h +++ b/src/common/rendering/vulkan/buffers/vk_buffer.h @@ -24,7 +24,6 @@ public: IBuffer* CreateVertexBuffer(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute* attrs); IBuffer* CreateIndexBuffer(); - IBuffer* CreateBoneBuffer(); IBuffer* CreateShadowmapNodesBuffer(); IBuffer* CreateShadowmapLinesBuffer(); IBuffer* CreateShadowmapLightsBuffer(); @@ -47,10 +46,16 @@ public: std::unique_ptr SSO; } Lightbuffer; + struct + { + int UploadIndex = 0; + int Count = 80000; + std::unique_ptr SSO; + } Bonebuffer; + VkHardwareDataBuffer* LightNodes = nullptr; VkHardwareDataBuffer* LightLines = nullptr; VkHardwareDataBuffer* LightList = nullptr; - VkHardwareDataBuffer* BoneBufferSSO = nullptr; std::unique_ptr MatrixBuffer; std::unique_ptr StreamBuffer; diff --git a/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp b/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp index daee216edf..ca83a60920 100644 --- a/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp +++ b/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp @@ -85,7 +85,7 @@ void VkDescriptorSetManager::UpdateHWBufferSet() .AddBuffer(HWBufferSet.get(), 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->GetBufferManager()->MatrixBuffer->UniformBuffer->mBuffer.get(), 0, sizeof(MatricesUBO)) .AddBuffer(HWBufferSet.get(), 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->GetBufferManager()->StreamBuffer->UniformBuffer->mBuffer.get(), 0, sizeof(StreamUBO)) .AddBuffer(HWBufferSet.get(), 3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->Lightbuffer.SSO->mBuffer.get()) - .AddBuffer(HWBufferSet.get(), 4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->BoneBufferSSO->mBuffer.get()) + .AddBuffer(HWBufferSet.get(), 4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->Bonebuffer.SSO->mBuffer.get()) .Execute(fb->GetDevice()); } diff --git a/src/common/rendering/vulkan/vk_renderdevice.cpp b/src/common/rendering/vulkan/vk_renderdevice.cpp index 2bb0bb0e3e..06bc3aa02a 100644 --- a/src/common/rendering/vulkan/vk_renderdevice.cpp +++ b/src/common/rendering/vulkan/vk_renderdevice.cpp @@ -38,7 +38,6 @@ #include "hw_cvars.h" #include "hw_skydome.h" #include "flatvertices.h" -#include "hw_bonebuffer.h" #include "vk_renderdevice.h" #include "vulkan/vk_renderstate.h" @@ -132,7 +131,6 @@ VulkanRenderDevice::~VulkanRenderDevice() delete mVertexData; delete mSkyData; - delete mBones; delete mShadowMap; if (mDescriptorSetManager) @@ -189,7 +187,6 @@ void VulkanRenderDevice::InitializeState() mVertexData = new FFlatVertexBuffer(this, GetWidth(), GetHeight()); mSkyData = new FSkyVertexBuffer(this); - mBones = new BoneBuffer(this); mShadowMap = new ShadowMap(this); mShaderManager.reset(new VkShaderManager(this)); @@ -316,11 +313,6 @@ IBuffer*VulkanRenderDevice::CreateIndexBuffer() return GetBufferManager()->CreateIndexBuffer(); } -IBuffer* VulkanRenderDevice::CreateBoneBuffer() -{ - return GetBufferManager()->CreateBoneBuffer(); -} - IBuffer* VulkanRenderDevice::CreateShadowmapNodesBuffer() { return GetBufferManager()->CreateShadowmapNodesBuffer(); diff --git a/src/common/rendering/vulkan/vk_renderdevice.h b/src/common/rendering/vulkan/vk_renderdevice.h index c1c9a66715..f569f18c6c 100644 --- a/src/common/rendering/vulkan/vk_renderdevice.h +++ b/src/common/rendering/vulkan/vk_renderdevice.h @@ -74,7 +74,6 @@ public: IBuffer* CreateVertexBuffer(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute* attrs) override; IBuffer* CreateIndexBuffer() override; - IBuffer* CreateBoneBuffer() override; IBuffer* CreateShadowmapNodesBuffer() override; IBuffer* CreateShadowmapLinesBuffer() override; IBuffer* CreateShadowmapLightsBuffer() override; diff --git a/src/common/rendering/vulkan/vk_renderstate.cpp b/src/common/rendering/vulkan/vk_renderstate.cpp index edda69d8fb..fa394040d7 100644 --- a/src/common/rendering/vulkan/vk_renderstate.cpp +++ b/src/common/rendering/vulkan/vk_renderstate.cpp @@ -554,12 +554,37 @@ int VkRenderState::UploadLights(const FDynLightData& data) } } +int VkRenderState::UploadBones(const TArray& bones) +{ + auto buffers = fb->GetBufferManager(); + + int totalsize = bones.Size(); + if (bones.Size() == 0) + { + return -1; + } + + int thisindex = buffers->Bonebuffer.UploadIndex; + buffers->Bonebuffer.UploadIndex += totalsize; + + if (thisindex + totalsize <= buffers->Bonebuffer.Count) + { + memcpy((VSMatrix*)buffers->Bonebuffer.SSO->Memory() + thisindex, bones.Data(), bones.Size() * sizeof(VSMatrix)); + return thisindex; + } + else + { + return -1; // Buffer is full. Since it is being used live at the point of the upload we cannot do much here but to abort. + } +} + void VkRenderState::BeginFrame() { mMaterial.Reset(); mApplyCount = 0; fb->GetBufferManager()->Viewpoint.UploadIndex = 0; fb->GetBufferManager()->Lightbuffer.UploadIndex = 0; + fb->GetBufferManager()->Bonebuffer.UploadIndex = 0; } void VkRenderState::EndRenderPass() diff --git a/src/common/rendering/vulkan/vk_renderstate.h b/src/common/rendering/vulkan/vk_renderstate.h index ee282f9442..4168d5f601 100644 --- a/src/common/rendering/vulkan/vk_renderstate.h +++ b/src/common/rendering/vulkan/vk_renderstate.h @@ -51,6 +51,7 @@ public: int SetViewpoint(const HWViewpointUniforms& vp) override; void SetViewpoint(int index) override; int UploadLights(const FDynLightData& lightdata) override; + int UploadBones(const TArray& bones) override; protected: void Apply(int dt); diff --git a/src/rendering/hwrenderer/hw_entrypoint.cpp b/src/rendering/hwrenderer/hw_entrypoint.cpp index 3358f0ff0c..704e446c60 100644 --- a/src/rendering/hwrenderer/hw_entrypoint.cpp +++ b/src/rendering/hwrenderer/hw_entrypoint.cpp @@ -43,7 +43,6 @@ #include "g_cvars.h" #include "v_draw.h" -#include "hw_bonebuffer.h" #include "hw_cvars.h" #include "hwrenderer/scene/hw_fakeflat.h" #include "hwrenderer/scene/hw_clipper.h" @@ -278,7 +277,6 @@ void WriteSavePic(player_t* player, FileWriter* file, int width, int height) hw_ClearFakeFlat(); screen->mVertexData->Reset(); RenderState.SetVertexBuffer(screen->mVertexData); - screen->mBones->Clear(); // This shouldn't overwrite the global viewpoint even for a short time. FRenderViewpoint savevp; @@ -342,8 +340,6 @@ sector_t* RenderView(player_t* player) if (cl_capfps || r_NoInterpolate) r_viewpoint.TicFrac = 1.; else r_viewpoint.TicFrac = I_GetTimeFrac(); - screen->mBones->Clear(); - // NoInterpolateView should have no bearing on camera textures, but needs to be preserved for the main view below. bool saved_niv = NoInterpolateView; NoInterpolateView = false; diff --git a/src/rendering/hwrenderer/hw_models.cpp b/src/rendering/hwrenderer/hw_models.cpp index 7feefb9a27..23517b7867 100644 --- a/src/rendering/hwrenderer/hw_models.cpp +++ b/src/rendering/hwrenderer/hw_models.cpp @@ -41,7 +41,6 @@ #include "hwrenderer/scene/hw_drawinfo.h" #include "hw_renderstate.h" #include "hwrenderer/scene/hw_portal.h" -#include "hw_bonebuffer.h" #include "hw_models.h" CVAR(Bool, gl_light_models, true, CVAR_ARCHIVE) @@ -157,9 +156,7 @@ void FHWModelRenderer::DrawElements(int numIndices, size_t offset) int FHWModelRenderer::SetupFrame(FModel *model, unsigned int frame1, unsigned int frame2, unsigned int size, const TArray& bones, int boneStartIndex) { auto mdbuff = static_cast(model->GetVertexBuffer(GetType())); - screen->mBones->Map(); - boneIndexBase = boneStartIndex >= 0 ? boneStartIndex : screen->mBones->UploadBones(bones); - screen->mBones->Unmap(); + boneIndexBase = boneStartIndex >= 0 ? boneStartIndex : state.UploadBones(bones); state.SetBoneIndexBase(boneIndexBase); if (mdbuff) { diff --git a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp index 40ddfd2ecb..067febb6c0 100644 --- a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp +++ b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp @@ -39,7 +39,6 @@ #include "hw_clock.h" #include "hw_cvars.h" #include "flatvertices.h" -#include "hw_bonebuffer.h" #include "hw_vrmodes.h" #include "hw_clipper.h" #include "hw_meshcache.h" @@ -449,7 +448,6 @@ void HWDrawInfo::CreateScene(bool drawpsprites, FRenderState& state) // clip the scene and fill the drawlists screen->mVertexData->Map(); - screen->mBones->Map(); if (!gl_meshcache) RenderBSP(Level->HeadNode(), drawpsprites, state); @@ -462,7 +460,6 @@ void HWDrawInfo::CreateScene(bool drawpsprites, FRenderState& state) HandleHackedSubsectors(state); // open sector hacks for deep water PrepareUnhandledMissingTextures(state); DispatchRenderHacks(state); - screen->mBones->Unmap(); screen->mVertexData->Unmap(); ProcessAll.Unclock();