mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 20:21:26 +00:00
Move bone buffer to backend
This commit is contained in:
parent
d24ffc021b
commit
930107636e
16 changed files with 42 additions and 191 deletions
|
@ -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
|
||||
|
|
|
@ -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<VSMatrix>& 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);
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "tarray.h"
|
||||
#include "hwrenderer/data/buffers.h"
|
||||
#include "common/utility/matrix.h"
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
|
||||
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<unsigned int> 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<VSMatrix> &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;
|
||||
}
|
||||
};
|
|
@ -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<VSMatrix>& bones) override { return -1; }
|
||||
|
||||
// Draw commands
|
||||
void Draw(int dt, int index, int count, bool apply = true) override;
|
||||
|
|
|
@ -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<VSMatrix>& bones) = 0;
|
||||
|
||||
// Draw commands
|
||||
virtual void ClearScreen() = 0;
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<VkHardwareDataBuffer> SSO;
|
||||
} Lightbuffer;
|
||||
|
||||
struct
|
||||
{
|
||||
int UploadIndex = 0;
|
||||
int Count = 80000;
|
||||
std::unique_ptr<VkHardwareDataBuffer> SSO;
|
||||
} Bonebuffer;
|
||||
|
||||
VkHardwareDataBuffer* LightNodes = nullptr;
|
||||
VkHardwareDataBuffer* LightLines = nullptr;
|
||||
VkHardwareDataBuffer* LightList = nullptr;
|
||||
VkHardwareDataBuffer* BoneBufferSSO = nullptr;
|
||||
|
||||
std::unique_ptr<VkStreamBuffer> MatrixBuffer;
|
||||
std::unique_ptr<VkStreamBuffer> StreamBuffer;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -554,12 +554,37 @@ int VkRenderState::UploadLights(const FDynLightData& data)
|
|||
}
|
||||
}
|
||||
|
||||
int VkRenderState::UploadBones(const TArray<VSMatrix>& 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()
|
||||
|
|
|
@ -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<VSMatrix>& bones) override;
|
||||
|
||||
protected:
|
||||
void Apply(int dt);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<VSMatrix>& bones, int boneStartIndex)
|
||||
{
|
||||
auto mdbuff = static_cast<FModelVertexBuffer*>(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)
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue