Remove FFlatVertexBuffer

This commit is contained in:
Magnus Norddahl 2023-05-08 23:12:14 +02:00
commit 1fd14f1140
23 changed files with 164 additions and 290 deletions

View file

@ -1106,7 +1106,6 @@ set (PCH_SOURCES
common/rendering/hwrenderer/hw_draw2d.cpp
common/rendering/hwrenderer/data/hw_clock.cpp
common/rendering/hwrenderer/data/hw_skydome.cpp
common/rendering/hwrenderer/data/flatvertices.cpp
common/rendering/hwrenderer/data/hw_modelvertexbuffer.cpp
common/rendering/hwrenderer/data/hw_cvars.cpp
common/rendering/hwrenderer/data/hw_vrmodes.cpp

View file

@ -1,130 +0,0 @@
/*
** hw_flatvertices.cpp
** Creates flat vertex data for hardware rendering.
**
**---------------------------------------------------------------------------
** Copyright 2010-2020 Christoph Oelckers
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/
#include "c_cvars.h"
#include "flatvertices.h"
#include "v_video.h"
#include "cmdlib.h"
#include "printf.h"
#include "hwrenderer/data/buffers.h"
#include "hw_renderstate.h"
//==========================================================================
//
//
//
//==========================================================================
FFlatVertexBuffer::FFlatVertexBuffer(DFrameBuffer* fb, int width, int height, int pipelineNbr) : fb(fb), mPipelineNbr(pipelineNbr)
{
mIndexBuffer = fb->CreateIndexBuffer();
int data[4] = {};
mIndexBuffer->SetData(4, data, BufferUsageType::Static); // On Vulkan this may not be empty, so set some dummy defaults to avoid crashes.
for (int n = 0; n < mPipelineNbr; n++)
{
static const FVertexBufferAttribute format[] =
{
{ 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(FFlatVertex, x) },
{ 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(FFlatVertex, u) },
{ 0, VATTR_LIGHTMAP, VFmt_Float3, (int)myoffsetof(FFlatVertex, lu) },
};
mVertexBufferPipeline[n] = fb->CreateVertexBuffer(1, 3, sizeof(FFlatVertex), format);
mVertexBufferPipeline[n]->SetData(BUFFER_SIZE * sizeof(FFlatVertex), nullptr, BufferUsageType::Persistent);
}
mVertexBuffer = mVertexBufferPipeline[mPipelinePos];
mIndex = mCurIndex = 0;
}
//==========================================================================
//
//
//
//==========================================================================
FFlatVertexBuffer::~FFlatVertexBuffer()
{
for (int n = 0; n < mPipelineNbr; n++)
{
delete mVertexBufferPipeline[n];
}
delete mIndexBuffer;
mIndexBuffer = nullptr;
mVertexBuffer = nullptr;
}
//==========================================================================
//
//
//
//==========================================================================
std::pair<FFlatVertex *, unsigned int> FFlatVertexBuffer::AllocVertices(unsigned int count)
{
FFlatVertex *p = GetBuffer();
auto index = mCurIndex.fetch_add(count);
if (index + count >= BUFFER_SIZE_TO_USE)
{
// If a single scene needs 2'000'000 vertices there must be something very wrong.
I_FatalError("Out of vertex memory. Tried to allocate more than %u vertices for a single frame", index + count);
}
return std::make_pair(p, index);
}
//==========================================================================
//
//
//
//==========================================================================
void FFlatVertexBuffer::Copy(int start, int count)
{
IBuffer* old = mVertexBuffer;
for (int n = 0; n < mPipelineNbr; n++)
{
mVertexBuffer = mVertexBufferPipeline[n];
Map();
memcpy(GetBuffer(start), vbo_shadowdata.Data(), count * sizeof(FFlatVertex));
Unmap();
mVertexBuffer->Upload(start * sizeof(FFlatVertex), count * sizeof(FFlatVertex));
}
mVertexBuffer = old;
}

View file

@ -1,15 +1,4 @@
#ifndef _HW__VERTEXBUFFER_H
#define _HW__VERTEXBUFFER_H
#include "tarray.h"
#include "hwrenderer/data/buffers.h"
#include <atomic>
#include <mutex>
class DFrameBuffer;
class FRenderState;
struct secplane_t;
#pragma once
struct FFlatVertex
{
@ -54,84 +43,3 @@ struct FFlatVertex
}
};
class FFlatVertexBuffer
{
DFrameBuffer* fb = nullptr;
public:
TArray<FFlatVertex> vbo_shadowdata;
TArray<uint32_t> ibo_data;
int mPipelineNbr;
int mPipelinePos = 0;
IBuffer* mVertexBuffer;
IBuffer* mVertexBufferPipeline[HW_MAX_PIPELINE_BUFFERS];
IBuffer* mIndexBuffer;
unsigned int mIndex;
std::atomic<unsigned int> mCurIndex;
unsigned int mMapStart;
static const unsigned int BUFFER_SIZE = 2000000;
static const unsigned int BUFFER_SIZE_TO_USE = BUFFER_SIZE-500;
public:
FFlatVertexBuffer(DFrameBuffer* fb, int width, int height, int pipelineNbr = 1);
~FFlatVertexBuffer();
std::pair<IBuffer*, IBuffer*> GetBufferObjects() const
{
return std::make_pair(mVertexBuffer, mIndexBuffer);
}
void Copy(int start, int count);
FFlatVertex *GetBuffer(int index) const
{
FFlatVertex *ff = (FFlatVertex*)mVertexBuffer->Memory();
return &ff[index];
}
FFlatVertex *GetBuffer() const
{
return GetBuffer(mCurIndex);
}
std::pair<FFlatVertex *, unsigned int> AllocVertices(unsigned int count);
void Reset()
{
mCurIndex = mIndex;
}
void NextPipelineBuffer()
{
mPipelinePos++;
mPipelinePos %= mPipelineNbr;
mVertexBuffer = mVertexBufferPipeline[mPipelinePos];
}
void Map()
{
mMapStart = mCurIndex;
mVertexBuffer->Map();
}
void Unmap()
{
mVertexBuffer->Unmap();
mVertexBuffer->Upload(mMapStart * sizeof(FFlatVertex), (mCurIndex - mMapStart) * sizeof(FFlatVertex));
}
int GetPipelinePos()
{
return mPipelinePos;
}
};
#endif

View file

@ -71,7 +71,7 @@ void Mesh::Draw(FRenderState& renderstate)
#ifdef USE_MESH_VERTEX_BUFFER
if (mVertexBuffer)
renderstate.SetVertexBuffer(screen->mVertexData);
renderstate.SetFlatVertexBuffer();
#endif
for (const MeshDrawCommand& cmd : mIndexedDraws)

View file

@ -17,9 +17,6 @@ MeshBuilder::MeshBuilder()
ClearDepthBias();
EnableTexture(1);
EnableBrightmap(true);
// Add the vbo_shadowdata as some geometry might use it
mVertices = screen->mVertexData->vbo_shadowdata;
}
void MeshBuilder::SetShadowData(const TArray<FFlatVertex>& vertices, const TArray<uint32_t>& indexes)

View file

@ -70,7 +70,8 @@ public:
// Vertices
std::pair<FFlatVertex*, unsigned int> AllocVertices(unsigned int count) override;
void SetShadowData(const TArray<FFlatVertex>& vertices, const TArray<uint32_t>& indexes) override;
void UpdateShadowData(unsigned int index, const FFlatVertex* vertices, unsigned int count) { }
void UpdateShadowData(unsigned int index, const FFlatVertex* vertices, unsigned int count) override { }
void ResetVertices() override { }
// Buffers
int SetViewpoint(const HWViewpointUniforms& vp) override { return 0; }

View file

@ -659,9 +659,8 @@ public:
mStreamData.uClipSplit.Y = 1000000.f;
}
void SetVertexBuffer(IBuffer* vb, int offset0, int offset1)
void SetVertexBuffer(IBuffer* vb, int offset0 = 0, int offset1 = 0)
{
assert(vb);
mVertexBuffer = vb;
mVertexOffsets[0] = offset0;
mVertexOffsets[1] = offset1;
@ -672,11 +671,10 @@ public:
mIndexBuffer = ib;
}
template <class T> void SetVertexBuffer(T *buffer)
void SetFlatVertexBuffer()
{
auto ptrs = buffer->GetBufferObjects();
SetVertexBuffer(ptrs.first, 0, 0);
SetIndexBuffer(ptrs.second);
SetVertexBuffer(nullptr);
SetIndexBuffer(nullptr);
}
void SetInterpolationFactor(float fac)
@ -737,6 +735,7 @@ public:
virtual std::pair<FFlatVertex*, unsigned int> AllocVertices(unsigned int count) = 0;
virtual void SetShadowData(const TArray<FFlatVertex>& vertices, const TArray<uint32_t>& indexes) = 0;
virtual void UpdateShadowData(unsigned int index, const FFlatVertex* vertices, unsigned int count) = 0;
virtual void ResetVertices() = 0;
// Buffers
virtual int SetViewpoint(const HWViewpointUniforms& vp) = 0;

View file

@ -86,10 +86,6 @@ public:
FSkyVertexBuffer(DFrameBuffer* fb);
~FSkyVertexBuffer();
void SetupMatrices(FRenderState& state, FGameTexture *tex, float x_offset, float y_offset, bool mirror, int mode, bool tiled, float xscale = 0, float vertscale = 0);
std::pair<IBuffer*, IBuffer*> GetBufferObjects() const
{
return std::make_pair(mVertexBuffer, nullptr);
}
int FaceStart(int i)
{

View file

@ -89,7 +89,8 @@ void Draw2D(F2DDrawer* drawer, FRenderState& state, int x, int y, int width, int
}
F2DVertexBuffer vb;
vb.UploadData(&vertices[0], vertices.Size(), &indices[0], indices.Size());
state.SetVertexBuffer(&vb);
state.SetVertexBuffer(vb.GetBufferObjects().first);
state.SetIndexBuffer(vb.GetBufferObjects().second);
state.EnableFog(false);
for(auto &cmd : commands)
@ -207,9 +208,12 @@ void Draw2D(F2DDrawer* drawer, FRenderState& state, int x, int y, int width, int
if (cmd.shape2DBufInfo != nullptr)
{
state.SetVertexBuffer(&cmd.shape2DBufInfo->buffers[cmd.shape2DBufIndex]);
auto& buffers = cmd.shape2DBufInfo->buffers[cmd.shape2DBufIndex];
state.SetVertexBuffer(buffers.GetBufferObjects().first);
state.SetIndexBuffer(buffers.GetBufferObjects().second);
state.DrawIndexed(DT_Triangles, 0, cmd.shape2DIndexCount);
state.SetVertexBuffer(&vb);
state.SetVertexBuffer(vb.GetBufferObjects().first);
state.SetVertexBuffer(vb.GetBufferObjects().second);
if (cmd.shape2DCommandCounter == cmd.shape2DBufInfo->lastCommand)
{
cmd.shape2DBufInfo->lastCommand = -1;
@ -254,7 +258,7 @@ void Draw2D(F2DDrawer* drawer, FRenderState& state, int x, int y, int width, int
state.SetScissor(-1, -1, -1, -1);
state.SetRenderStyle(STYLE_Translucent);
state.SetVertexBuffer(screen->mVertexData);
state.SetFlatVertexBuffer();
state.EnableStencil(false);
state.SetStencil(0, SOP_Keep, SF_AllOn);
state.EnableTexture(true);

View file

@ -50,7 +50,6 @@
struct FPortalSceneState;
class FSkyVertexBuffer;
class IBuffer;
class FFlatVertexBuffer;
struct HWDrawInfo;
class FMaterial;
class FGameTexture;
@ -137,7 +136,6 @@ public:
unsigned int maxuniformblock = 65536;
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
ShadowMap* mShadowMap = nullptr;
int mGameScreenWidth = 0;

View file

@ -27,6 +27,7 @@
#include "vulkan/pipelines/vk_renderpass.h"
#include "vulkan/commands/vk_commandbuffer.h"
#include <zvulkan/vulkanbuilders.h>
#include "flatvertices.h"
VkBufferManager::VkBufferManager(VulkanRenderDevice* fb) : fb(fb)
{
@ -38,6 +39,32 @@ VkBufferManager::~VkBufferManager()
void VkBufferManager::Init()
{
static const FVertexBufferAttribute format[] =
{
{ 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(FFlatVertex, x) },
{ 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(FFlatVertex, u) },
{ 0, VATTR_LIGHTMAP, VFmt_Float3, (int)myoffsetof(FFlatVertex, lu) },
};
Flatbuffer.VertexFormat = fb->GetRenderPassManager()->GetVertexFormat(1, 3, sizeof(FFlatVertex), format);
Flatbuffer.VertexBuffer = BufferBuilder()
.Usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VMA_MEMORY_USAGE_UNKNOWN, VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT)
.MemoryType(
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
.Size(Flatbuffer.BUFFER_SIZE * sizeof(FFlatVertex))
.DebugName("Flatbuffer.VertexBuffer")
.Create(fb->GetDevice());
Flatbuffer.Vertices = (FFlatVertex*)Flatbuffer.VertexBuffer->Map(0, Flatbuffer.VertexBuffer->size);
Flatbuffer.IndexBuffer = BufferBuilder()
.Usage(VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VMA_MEMORY_USAGE_GPU_ONLY)
.Size(16)
.DebugName("Flatbuffer.IndexBuffer")
.Create(fb->GetDevice());
MatrixBuffer.reset(new VkStreamBuffer(this, sizeof(MatricesUBO), 50000));
StreamBuffer.reset(new VkStreamBuffer(this, sizeof(StreamUBO), 300));
@ -85,6 +112,11 @@ void VkBufferManager::Init()
void VkBufferManager::Deinit()
{
if (Flatbuffer.VertexBuffer)
Flatbuffer.VertexBuffer->Unmap();
Flatbuffer.VertexBuffer.reset();
Flatbuffer.IndexBuffer.reset();
if (Viewpoint.UBO)
Viewpoint.UBO->Unmap();
Viewpoint.UBO.reset();

View file

@ -11,6 +11,7 @@ class VkStreamBuffer;
class IBuffer;
struct FVertexBufferAttribute;
struct HWViewpointUniforms;
struct FFlatVertex;
class VkBufferManager
{
@ -27,6 +28,18 @@ public:
void AddBuffer(VkHardwareBuffer* buffer);
void RemoveBuffer(VkHardwareBuffer* buffer);
struct
{
std::unique_ptr<VulkanBuffer> VertexBuffer;
int VertexFormat = 0;
FFlatVertex* Vertices = nullptr;
unsigned int ShadowDataSize = 0;
unsigned int CurIndex = 0;
static const unsigned int BUFFER_SIZE = 2000000;
static const unsigned int BUFFER_SIZE_TO_USE = BUFFER_SIZE - 500;
std::unique_ptr<VulkanBuffer> IndexBuffer;
} Flatbuffer;
struct
{
int UploadIndex = 0;

View file

@ -129,7 +129,6 @@ VulkanRenderDevice::~VulkanRenderDevice()
{
vkDeviceWaitIdle(mDevice->device); // make sure the GPU is no longer using any objects before RAII tears them down
delete mVertexData;
delete mSkyData;
delete mShadowMap;
@ -174,7 +173,6 @@ void VulkanRenderDevice::InitializeState()
mTextureManager.reset(new VkTextureManager(this));
mFramebufferManager.reset(new VkFramebufferManager(this));
mBufferManager.reset(new VkBufferManager(this));
mBufferManager->Init();
mScreenBuffers.reset(new VkRenderBuffers(this));
mSaveBuffers.reset(new VkRenderBuffers(this));
@ -185,7 +183,8 @@ void VulkanRenderDevice::InitializeState()
mRenderPassManager.reset(new VkRenderPassManager(this));
mRaytrace.reset(new VkRaytrace(this));
mVertexData = new FFlatVertexBuffer(this, GetWidth(), GetHeight());
mBufferManager->Init();
mSkyData = new FSkyVertexBuffer(this);
mShadowMap = new ShadowMap(this);

View file

@ -224,7 +224,7 @@ void VkRenderState::ApplyRenderPass(int dt)
// Find a pipeline that matches our state
VkPipelineKey pipelineKey;
pipelineKey.DrawType = dt;
pipelineKey.VertexFormat = static_cast<VkHardwareVertexBuffer*>(mVertexBuffer)->VertexFormat;
pipelineKey.VertexFormat = mVertexBuffer ? static_cast<VkHardwareVertexBuffer*>(mVertexBuffer)->VertexFormat : fb->GetBufferManager()->Flatbuffer.VertexFormat;
pipelineKey.RenderStyle = mRenderStyle;
pipelineKey.DepthTest = mDepthTest;
pipelineKey.DepthWrite = mDepthTest && mDepthWrite;
@ -394,7 +394,7 @@ void VkRenderState::ApplyStreamData()
{
auto passManager = fb->GetRenderPassManager();
mStreamData.useVertexData = passManager->GetVertexFormat(static_cast<VkHardwareVertexBuffer*>(mVertexBuffer)->VertexFormat)->UseVertexData;
mStreamData.useVertexData = mVertexBuffer ? passManager->GetVertexFormat(static_cast<VkHardwareVertexBuffer*>(mVertexBuffer)->VertexFormat)->UseVertexData : 0;
if (mMaterial.mMaterial && mMaterial.mMaterial->Source())
mStreamData.timer = static_cast<float>((double)(screen->FrameTime - firstFrame) * (double)mMaterial.mMaterial->Source()->GetShaderSpeed() / 1000.);
@ -439,22 +439,42 @@ void VkRenderState::ApplyMatrices()
void VkRenderState::ApplyVertexBuffers()
{
if ((mVertexBuffer != mLastVertexBuffer || mVertexOffsets[0] != mLastVertexOffsets[0] || mVertexOffsets[1] != mLastVertexOffsets[1]) && mVertexBuffer)
if ((mVertexBuffer != mLastVertexBuffer || mVertexOffsets[0] != mLastVertexOffsets[0] || mVertexOffsets[1] != mLastVertexOffsets[1]))
{
auto vkbuf = static_cast<VkHardwareVertexBuffer*>(mVertexBuffer);
const VkVertexFormat *format = fb->GetRenderPassManager()->GetVertexFormat(vkbuf->VertexFormat);
VkBuffer vertexBuffers[2] = { vkbuf->mBuffer->buffer, vkbuf->mBuffer->buffer };
VkDeviceSize offsets[] = { mVertexOffsets[0] * format->Stride, mVertexOffsets[1] * format->Stride };
mCommandBuffer->bindVertexBuffers(0, 2, vertexBuffers, offsets);
if (mVertexBuffer)
{
auto vkbuf = static_cast<VkHardwareVertexBuffer*>(mVertexBuffer);
const VkVertexFormat* format = fb->GetRenderPassManager()->GetVertexFormat(vkbuf->VertexFormat);
VkBuffer vertexBuffers[2] = { vkbuf->mBuffer->buffer, vkbuf->mBuffer->buffer };
VkDeviceSize offsets[] = { mVertexOffsets[0] * format->Stride, mVertexOffsets[1] * format->Stride };
mCommandBuffer->bindVertexBuffers(0, 2, vertexBuffers, offsets);
}
else
{
auto buffers = fb->GetBufferManager();
const VkVertexFormat* format = fb->GetRenderPassManager()->GetVertexFormat(buffers->Flatbuffer.VertexFormat);
VkBuffer vertexBuffers[2] = { buffers->Flatbuffer.VertexBuffer->buffer, buffers->Flatbuffer.VertexBuffer->buffer };
VkDeviceSize offsets[] = { mVertexOffsets[0] * format->Stride, mVertexOffsets[1] * format->Stride };
mCommandBuffer->bindVertexBuffers(0, 2, vertexBuffers, offsets);
}
mLastVertexBuffer = mVertexBuffer;
mLastVertexOffsets[0] = mVertexOffsets[0];
mLastVertexOffsets[1] = mVertexOffsets[1];
}
if (mIndexBuffer != mLastIndexBuffer && mIndexBuffer)
if (mIndexBuffer != mLastIndexBuffer || mIndexBufferNeedsBind)
{
mCommandBuffer->bindIndexBuffer(static_cast<VkHardwareIndexBuffer*>(mIndexBuffer)->mBuffer->buffer, 0, VK_INDEX_TYPE_UINT32);
if (mIndexBuffer)
{
mCommandBuffer->bindIndexBuffer(static_cast<VkHardwareIndexBuffer*>(mIndexBuffer)->mBuffer->buffer, 0, VK_INDEX_TYPE_UINT32);
}
else
{
mCommandBuffer->bindIndexBuffer(fb->GetBufferManager()->Flatbuffer.IndexBuffer->buffer, 0, VK_INDEX_TYPE_UINT32);
}
mLastIndexBuffer = mIndexBuffer;
mIndexBufferNeedsBind = false;
}
}
@ -622,35 +642,77 @@ int VkRenderState::UploadBones(const TArray<VSMatrix>& bones)
std::pair<FFlatVertex*, unsigned int> VkRenderState::AllocVertices(unsigned int count)
{
return fb->mVertexData->AllocVertices(count);
auto buffers = fb->GetBufferManager();
unsigned int index = buffers->Flatbuffer.CurIndex;
if (index + count >= buffers->Flatbuffer.BUFFER_SIZE_TO_USE)
{
// If a single scene needs 2'000'000 vertices there must be something very wrong.
I_FatalError("Out of vertex memory. Tried to allocate more than %u vertices for a single frame", index + count);
}
buffers->Flatbuffer.CurIndex += count;
return std::make_pair(buffers->Flatbuffer.Vertices + index, index);
}
void VkRenderState::SetShadowData(const TArray<FFlatVertex>& vertices, const TArray<uint32_t>& indexes)
{
FFlatVertexBuffer* fvb = fb->mVertexData;
fvb->vbo_shadowdata = vertices;
fvb->ibo_data = indexes;
fvb->mCurIndex = fvb->vbo_shadowdata.Size();
fvb->mIndex = fvb->vbo_shadowdata.Size();
fvb->Copy(0, fvb->mIndex);
fvb->mIndexBuffer->SetData(fvb->ibo_data.Size() * sizeof(uint32_t), &fvb->ibo_data[0], BufferUsageType::Static);
auto buffers = fb->GetBufferManager();
auto commands = fb->GetCommands();
UpdateShadowData(0, vertices.Data(), vertices.Size());
buffers->Flatbuffer.ShadowDataSize = vertices.Size();
buffers->Flatbuffer.CurIndex = buffers->Flatbuffer.ShadowDataSize;
if (indexes.Size() > 0)
{
size_t bufsize = indexes.Size() * sizeof(uint32_t);
auto buffer = BufferBuilder()
.Usage(VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VMA_MEMORY_USAGE_GPU_ONLY)
.Size(bufsize)
.DebugName("Flatbuffer.IndexBuffer")
.Create(fb->GetDevice());
auto staging = BufferBuilder()
.Usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY)
.Size(bufsize)
.DebugName("Flatbuffer.IndexBuffer.Staging")
.Create(fb->GetDevice());
void* dst = staging->Map(0, bufsize);
memcpy(dst, indexes.Data(), bufsize);
staging->Unmap();
commands->GetTransferCommands()->copyBuffer(staging.get(), buffer.get());
commands->TransferDeleteList->Add(std::move(staging));
commands->DrawDeleteList->Add(std::move(buffers->Flatbuffer.IndexBuffer));
buffers->Flatbuffer.IndexBuffer = std::move(buffer);
mIndexBufferNeedsBind = true;
mNeedApply = true;
}
}
void VkRenderState::UpdateShadowData(unsigned int index, const FFlatVertex* vertices, unsigned int count)
{
FFlatVertexBuffer* fvb = fb->mVertexData;
FFlatVertex* mapvt = fvb->GetBuffer(index);
memcpy(mapvt, vertices, count * sizeof(FFlatVertex));
fvb->mVertexBuffer->Upload(index * sizeof(FFlatVertex), count * sizeof(FFlatVertex));
memcpy(fb->GetBufferManager()->Flatbuffer.Vertices + index, vertices, count * sizeof(FFlatVertex));
}
void VkRenderState::ResetVertices()
{
auto buffers = fb->GetBufferManager();
buffers->Flatbuffer.CurIndex = buffers->Flatbuffer.ShadowDataSize;
}
void VkRenderState::BeginFrame()
{
mMaterial.Reset();
mApplyCount = 0;
fb->GetBufferManager()->Viewpoint.UploadIndex = 0;
fb->GetBufferManager()->Lightbuffer.UploadIndex = 0;
fb->GetBufferManager()->Bonebuffer.UploadIndex = 0;
auto buffers = fb->GetBufferManager();
buffers->Viewpoint.UploadIndex = 0;
buffers->Lightbuffer.UploadIndex = 0;
buffers->Bonebuffer.UploadIndex = 0;
}
void VkRenderState::EndRenderPass()
@ -661,9 +723,10 @@ void VkRenderState::EndRenderPass()
mCommandBuffer = nullptr;
mPipelineKey = {};
// Force rebind of all buffers
mLastViewpointOffset = 0xffffffff;
mLastVertexBuffer = nullptr;
mLastIndexBuffer = nullptr;
mLastVertexOffsets[0] = 0xffffffff;
mIndexBufferNeedsBind = true;
}
}

View file

@ -59,6 +59,7 @@ public:
std::pair<FFlatVertex*, unsigned int> AllocVertices(unsigned int count) override;
void SetShadowData(const TArray<FFlatVertex>& vertices, const TArray<uint32_t>& indexes) override;
void UpdateShadowData(unsigned int index, const FFlatVertex* vertices, unsigned int count) override;
void ResetVertices() override;
protected:
void Apply(int dt);
@ -117,6 +118,7 @@ protected:
int mLastVertexOffsets[2] = { 0, 0 };
IBuffer* mLastVertexBuffer = nullptr;
IBuffer* mLastIndexBuffer = nullptr;
bool mIndexBufferNeedsBind = true;
MatricesUBO mMatrices = {};
bool mMatricesChanged = true;

View file

@ -275,8 +275,8 @@ void WriteSavePic(player_t* player, FileWriter* file, int width, int height)
hw_postprocess.SetTonemapMode(level.info ? level.info->tonemap : ETonemapMode::None);
hw_ClearFakeFlat();
screen->mVertexData->Reset();
RenderState.SetVertexBuffer(screen->mVertexData);
RenderState.ResetVertices();
RenderState.SetFlatVertexBuffer();
// This shouldn't overwrite the global viewpoint even for a short time.
FRenderViewpoint savevp;
@ -313,8 +313,8 @@ static void CheckTimer(FRenderState &state, uint64_t ShaderStartTime)
sector_t* RenderView(player_t* player)
{
auto RenderState = screen->RenderState();
RenderState->SetVertexBuffer(screen->mVertexData);
screen->mVertexData->Reset();
RenderState->SetFlatVertexBuffer();
RenderState->ResetVertices();
hw_postprocess.SetTonemapMode(level.info ? level.info->tonemap : ETonemapMode::None);
sector_t* retsec;

View file

@ -446,7 +446,6 @@ void HWDrawInfo::CreateScene(bool drawpsprites, FRenderState& state)
ProcessAll.Clock();
// clip the scene and fill the drawlists
screen->mVertexData->Map();
if (!gl_meshcache)
RenderBSP(Level->HeadNode(), drawpsprites, state);
@ -459,7 +458,6 @@ void HWDrawInfo::CreateScene(bool drawpsprites, FRenderState& state)
HandleHackedSubsectors(state); // open sector hacks for deep water
PrepareUnhandledMissingTextures(state);
DispatchRenderHacks(state);
screen->mVertexData->Unmap();
ProcessAll.Unclock();
@ -589,7 +587,7 @@ void HWDrawInfo::RenderPortal(HWPortal *p, FRenderState &state, bool usestencil)
state.SetLightIndex(-1);
gp->DrawContents(new_di, state);
new_di->EndDrawInfo();
state.SetVertexBuffer(screen->mVertexData);
state.SetFlatVertexBuffer();
state.SetViewpoint(vpIndex);
gp->RemoveStencil(this, state, usestencil);

View file

@ -32,7 +32,6 @@ struct HUDSprite;
class ACorona;
class Clipper;
class HWPortal;
class FFlatVertexBuffer;
class HWScenePortalBase;
class FRenderState;

View file

@ -939,9 +939,7 @@ void HWDrawList::DrawSorted(HWDrawInfo *di, FRenderState &state)
if (!sorted)
{
screen->mVertexData->Map();
Sort(di, state);
screen->mVertexData->Unmap();
}
state.ClearClipSplit();
DrawSorted(di, state, sorted);

View file

@ -191,7 +191,6 @@ void HWPortal::DrawPortalStencil(FRenderState &state, int pass)
if (NeedCap() && lines.Size() > 1 && planesused != 0)
{
screen->mVertexData->Map();
if (planesused & (1 << sector_t::floor))
{
auto verts = state.AllocVertices(4);
@ -212,7 +211,6 @@ void HWPortal::DrawPortalStencil(FRenderState &state, int pass)
ptr[3].Set((float)boundingBox.right, 32767.f, (float)boundingBox.bottom, 0, 0);
mTopCap = verts.second;
}
screen->mVertexData->Unmap();
}
}

View file

@ -58,7 +58,7 @@ void HWSkyPortal::DrawContents(HWDrawInfo *di, FRenderState &state)
di->SetupView(state, 0, 0, 0, !!(mState->MirrorFlag & 1), !!(mState->PlaneMirrorFlag & 1));
state.SetVertexBuffer(vertexBuffer);
state.SetVertexBuffer(vertexBuffer->mVertexBuffer);
auto skybox = origin->texture[0] ? dynamic_cast<FSkyBox*>(origin->texture[0]->GetTexture()) : nullptr;
if (skybox)
{

View file

@ -300,7 +300,7 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent)
{
FHWModelRenderer renderer(di, state, dynlightindex);
RenderModel(&renderer, x, y, z, modelframe, actor, di->Viewpoint.TicFrac);
state.SetVertexBuffer(screen->mVertexData);
state.SetFlatVertexBuffer();
state.SetLightIndex(-1);
}
}

View file

@ -89,7 +89,7 @@ void HWDrawInfo::DrawPSprite(HUDSprite *huds, FRenderState &state)
FHWModelRenderer renderer(this, state, huds->lightindex);
RenderHUDModel(&renderer, huds->weapon, huds->translation, huds->rotation + FVector3(huds->mx / 4., (huds->my - WEAPONTOP) / -4., 0), huds->pivot, huds->mframe);
state.SetVertexBuffer(screen->mVertexData);
state.SetFlatVertexBuffer();
}
else
{