mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-01-31 13:50:48 +00:00
- move streaming uniform buffers out of VkRenderState
This commit is contained in:
parent
05cae50612
commit
4adac3fe59
8 changed files with 227 additions and 88 deletions
|
@ -920,6 +920,7 @@ set (VULKAN_SOURCES
|
|||
rendering/vulkan/system/vk_buffers.cpp
|
||||
rendering/vulkan/renderer/vk_renderstate.cpp
|
||||
rendering/vulkan/renderer/vk_renderpass.cpp
|
||||
rendering/vulkan/renderer/vk_streambuffer.cpp
|
||||
rendering/vulkan/renderer/vk_postprocess.cpp
|
||||
rendering/vulkan/renderer/vk_renderbuffers.cpp
|
||||
rendering/vulkan/shaders/vk_shader.cpp
|
||||
|
|
|
@ -173,8 +173,8 @@ void VkRenderPassManager::UpdateDynamicSet()
|
|||
WriteDescriptors update;
|
||||
update.addBuffer(DynamicSet.get(), 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->ViewpointUBO->mBuffer.get(), 0, sizeof(HWViewpointUniforms));
|
||||
update.addBuffer(DynamicSet.get(), 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->LightBufferSSO->mBuffer.get());
|
||||
update.addBuffer(DynamicSet.get(), 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->MatricesUBO->mBuffer.get(), 0, sizeof(MatricesUBO));
|
||||
update.addBuffer(DynamicSet.get(), 3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->StreamUBO->mBuffer.get(), 0, sizeof(StreamUBO));
|
||||
update.addBuffer(DynamicSet.get(), 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->MatrixBuffer->UniformBuffer->mBuffer.get(), 0, sizeof(MatricesUBO));
|
||||
update.addBuffer(DynamicSet.get(), 3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->StreamBuffer->UniformBuffer->mBuffer.get(), 0, sizeof(StreamUBO));
|
||||
update.addCombinedImageSampler(DynamicSet.get(), 4, fb->GetBuffers()->Shadowmap.View.get(), fb->GetBuffers()->ShadowmapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
update.updateSets(fb->device);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ CVAR(Int, vk_submit_size, 1000, 0);
|
|||
|
||||
VkRenderState::VkRenderState()
|
||||
{
|
||||
mIdentityMatrix.loadIdentity();
|
||||
Reset();
|
||||
}
|
||||
|
||||
|
@ -322,17 +321,11 @@ void VkRenderState::ApplyStreamData()
|
|||
else
|
||||
mStreamData.timer = 0.0f;
|
||||
|
||||
mDataIndex++;
|
||||
if (mDataIndex == MAX_STREAM_DATA)
|
||||
if (!mStreamBufferWriter.Write(mStreamData))
|
||||
{
|
||||
mDataIndex = 0;
|
||||
mStreamDataOffset += sizeof(StreamUBO);
|
||||
|
||||
if (mStreamDataOffset + sizeof(StreamUBO) >= fb->StreamUBO->Size())
|
||||
WaitForStreamBuffers();
|
||||
WaitForStreamBuffers();
|
||||
mStreamBufferWriter.Write(mStreamData);
|
||||
}
|
||||
uint8_t *ptr = (uint8_t*)fb->StreamUBO->Memory();
|
||||
memcpy(ptr + mStreamDataOffset + sizeof(StreamData) * mDataIndex, &mStreamData, sizeof(StreamData));
|
||||
}
|
||||
|
||||
void VkRenderState::ApplyPushConstants()
|
||||
|
@ -371,63 +364,20 @@ void VkRenderState::ApplyPushConstants()
|
|||
mPushConstants.uSpecularMaterial = { mMaterial.mMaterial->tex->Glossiness, mMaterial.mMaterial->tex->SpecularLevel };
|
||||
|
||||
mPushConstants.uLightIndex = mLightIndex;
|
||||
mPushConstants.uDataIndex = mDataIndex;
|
||||
mPushConstants.uDataIndex = mStreamBufferWriter.DataIndex();
|
||||
|
||||
auto fb = GetVulkanFrameBuffer();
|
||||
auto passManager = fb->GetRenderPassManager();
|
||||
mCommandBuffer->pushConstants(passManager->GetPipelineLayout(mPipelineKey.NumTextureLayers), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, (uint32_t)sizeof(PushConstants), &mPushConstants);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void BufferedSet(bool &modified, T &dst, const T &src)
|
||||
{
|
||||
if (dst == src)
|
||||
return;
|
||||
dst = src;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
static void BufferedSet(bool &modified, VSMatrix &dst, const VSMatrix &src)
|
||||
{
|
||||
if (memcmp(dst.get(), src.get(), sizeof(FLOATTYPE) * 16) == 0)
|
||||
return;
|
||||
dst = src;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
void VkRenderState::ApplyMatrices()
|
||||
{
|
||||
bool modified = (mMatricesOffset == 0); // always modified first call
|
||||
if (mTextureMatrixEnabled)
|
||||
auto fb = GetVulkanFrameBuffer();
|
||||
if (!fb->MatrixBuffer->Write(mModelMatrix, mModelMatrixEnabled, mTextureMatrix, mTextureMatrixEnabled))
|
||||
{
|
||||
BufferedSet(modified, mMatrices.TextureMatrix, mTextureMatrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferedSet(modified, mMatrices.TextureMatrix, mIdentityMatrix);
|
||||
}
|
||||
|
||||
if (mModelMatrixEnabled)
|
||||
{
|
||||
BufferedSet(modified, mMatrices.ModelMatrix, mModelMatrix);
|
||||
if (modified)
|
||||
mMatrices.NormalModelMatrix.computeNormalMatrix(mModelMatrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferedSet(modified, mMatrices.ModelMatrix, mIdentityMatrix);
|
||||
BufferedSet(modified, mMatrices.NormalModelMatrix, mIdentityMatrix);
|
||||
}
|
||||
|
||||
if (modified)
|
||||
{
|
||||
auto fb = GetVulkanFrameBuffer();
|
||||
|
||||
if (mMatricesOffset + (fb->UniformBufferAlignedSize<MatricesUBO>() << 1) >= fb->MatricesUBO->Size())
|
||||
WaitForStreamBuffers();
|
||||
|
||||
mMatricesOffset += fb->UniformBufferAlignedSize<MatricesUBO>();
|
||||
memcpy(static_cast<uint8_t*>(fb->MatricesUBO->Memory()) + mMatricesOffset, &mMatrices, sizeof(MatricesUBO));
|
||||
WaitForStreamBuffers();
|
||||
fb->MatrixBuffer->Write(mModelMatrix, mModelMatrixEnabled, mTextureMatrix, mTextureMatrixEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -470,17 +420,19 @@ void VkRenderState::ApplyMaterial()
|
|||
|
||||
void VkRenderState::ApplyDynamicSet()
|
||||
{
|
||||
if (mViewpointOffset != mLastViewpointOffset || mMatricesOffset != mLastMatricesOffset || mStreamDataOffset != mLastStreamDataOffset)
|
||||
auto fb = GetVulkanFrameBuffer();
|
||||
uint32_t matrixOffset = fb->MatrixBuffer->Offset();
|
||||
uint32_t streamDataOffset = mStreamBufferWriter.StreamDataOffset();
|
||||
if (mViewpointOffset != mLastViewpointOffset || matrixOffset != mLastMatricesOffset || streamDataOffset != mLastStreamDataOffset)
|
||||
{
|
||||
auto fb = GetVulkanFrameBuffer();
|
||||
auto passManager = fb->GetRenderPassManager();
|
||||
|
||||
uint32_t offsets[3] = { mViewpointOffset, mMatricesOffset, mStreamDataOffset };
|
||||
uint32_t offsets[3] = { mViewpointOffset, matrixOffset, streamDataOffset };
|
||||
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, passManager->GetPipelineLayout(mPipelineKey.NumTextureLayers), 0, passManager->DynamicSet.get(), 3, offsets);
|
||||
|
||||
mLastViewpointOffset = mViewpointOffset;
|
||||
mLastMatricesOffset = mMatricesOffset;
|
||||
mLastStreamDataOffset = mStreamDataOffset;
|
||||
mLastMatricesOffset = matrixOffset;
|
||||
mLastStreamDataOffset = streamDataOffset;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -489,9 +441,8 @@ void VkRenderState::WaitForStreamBuffers()
|
|||
EndRenderPass();
|
||||
GetVulkanFrameBuffer()->WaitForCommands(false);
|
||||
mApplyCount = 0;
|
||||
mStreamDataOffset = 0;
|
||||
mDataIndex = 0;
|
||||
mMatricesOffset = 0;
|
||||
mStreamBufferWriter.Reset();
|
||||
GetVulkanFrameBuffer()->MatrixBuffer->Reset();
|
||||
}
|
||||
|
||||
void VkRenderState::Bind(int bindingpoint, uint32_t offset)
|
||||
|
@ -527,9 +478,8 @@ void VkRenderState::EndRenderPass()
|
|||
|
||||
void VkRenderState::EndFrame()
|
||||
{
|
||||
mMatricesOffset = 0;
|
||||
mStreamDataOffset = 0;
|
||||
mDataIndex = -1;
|
||||
GetVulkanFrameBuffer()->MatrixBuffer->Reset();
|
||||
mStreamBufferWriter.Reset();
|
||||
}
|
||||
|
||||
void VkRenderState::EnableDrawBuffers(int count)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "vulkan/system/vk_buffers.h"
|
||||
#include "vulkan/shaders/vk_shader.h"
|
||||
#include "vulkan/renderer/vk_renderpass.h"
|
||||
#include "vulkan/renderer/vk_streambuffer.h"
|
||||
|
||||
#include "name.h"
|
||||
|
||||
|
@ -63,8 +64,8 @@ protected:
|
|||
void ApplyVertexBuffers();
|
||||
void ApplyMaterial();
|
||||
|
||||
void WaitForStreamBuffers();
|
||||
void BeginRenderPass(VulkanCommandBuffer *cmdbuffer);
|
||||
void WaitForStreamBuffers();
|
||||
|
||||
bool mDepthClamp = true;
|
||||
VulkanCommandBuffer *mCommandBuffer = nullptr;
|
||||
|
@ -90,18 +91,14 @@ protected:
|
|||
int mColorMask = 15;
|
||||
int mCullMode = 0;
|
||||
|
||||
MatricesUBO mMatrices = {};
|
||||
PushConstants mPushConstants = {};
|
||||
|
||||
uint32_t mLastViewpointOffset = 0xffffffff;
|
||||
uint32_t mLastMatricesOffset = 0xffffffff;
|
||||
uint32_t mLastStreamDataOffset = 0xffffffff;
|
||||
uint32_t mViewpointOffset = 0;
|
||||
uint32_t mMatricesOffset = 0;
|
||||
uint32_t mDataIndex = -1;
|
||||
uint32_t mStreamDataOffset = 0;
|
||||
|
||||
VSMatrix mIdentityMatrix;
|
||||
VkStreamBufferWriter mStreamBufferWriter;
|
||||
|
||||
int mLastVertexOffsets[2] = { 0, 0 };
|
||||
IVertexBuffer *mLastVertexBuffer = nullptr;
|
||||
|
|
135
src/rendering/vulkan/renderer/vk_streambuffer.cpp
Normal file
135
src/rendering/vulkan/renderer/vk_streambuffer.cpp
Normal file
|
@ -0,0 +1,135 @@
|
|||
|
||||
#include "vk_renderstate.h"
|
||||
#include "vulkan/system/vk_framebuffer.h"
|
||||
#include "vulkan/system/vk_builders.h"
|
||||
#include "vulkan/renderer/vk_streambuffer.h"
|
||||
|
||||
template<typename T>
|
||||
int UniformBufferAlignedSize(int count) { return ((sizeof(T) + screen->uniformblockalignment - 1) / screen->uniformblockalignment * screen->uniformblockalignment) * count; }
|
||||
|
||||
VkStreamBuffer::VkStreamBuffer()
|
||||
{
|
||||
auto fb = GetVulkanFrameBuffer();
|
||||
UniformBuffer = (VKDataBuffer*)fb->CreateDataBuffer(-1, false, false);
|
||||
UniformBuffer->SetData(UniformBufferAlignedSize<StreamUBO>(200), nullptr, false);
|
||||
}
|
||||
|
||||
VkStreamBuffer::~VkStreamBuffer()
|
||||
{
|
||||
delete UniformBuffer;
|
||||
}
|
||||
|
||||
uint32_t VkStreamBuffer::NextStreamDataBlock()
|
||||
{
|
||||
mStreamDataOffset += sizeof(StreamUBO);
|
||||
if (mStreamDataOffset + sizeof(StreamUBO) >= UniformBuffer->Size())
|
||||
{
|
||||
mStreamDataOffset = 0;
|
||||
return 0xffffffff;
|
||||
}
|
||||
return mStreamDataOffset;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
VkStreamBufferWriter::VkStreamBufferWriter()
|
||||
{
|
||||
mBuffer = GetVulkanFrameBuffer()->StreamBuffer;
|
||||
}
|
||||
|
||||
bool VkStreamBufferWriter::Write(const StreamData& data)
|
||||
{
|
||||
mDataIndex++;
|
||||
if (mDataIndex == MAX_STREAM_DATA)
|
||||
{
|
||||
mDataIndex = 0;
|
||||
mStreamDataOffset = mBuffer->NextStreamDataBlock();
|
||||
if (mStreamDataOffset == 0xffffffff)
|
||||
return false;
|
||||
}
|
||||
uint8_t* ptr = (uint8_t*)mBuffer->UniformBuffer->Memory();
|
||||
memcpy(ptr + mStreamDataOffset + sizeof(StreamData) * mDataIndex, &data, sizeof(StreamData));
|
||||
return true;
|
||||
}
|
||||
|
||||
void VkStreamBufferWriter::Reset()
|
||||
{
|
||||
mDataIndex = MAX_STREAM_DATA - 1;
|
||||
mStreamDataOffset = 0;
|
||||
mBuffer->Reset();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
VkMatrixBuffer::VkMatrixBuffer()
|
||||
{
|
||||
mIdentityMatrix.loadIdentity();
|
||||
|
||||
auto fb = GetVulkanFrameBuffer();
|
||||
UniformBuffer = (VKDataBuffer*)fb->CreateDataBuffer(-1, false, false);
|
||||
UniformBuffer->SetData(UniformBufferAlignedSize<MatricesUBO>(50000), nullptr, false);
|
||||
}
|
||||
|
||||
VkMatrixBuffer::~VkMatrixBuffer()
|
||||
{
|
||||
delete UniformBuffer;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void BufferedSet(bool& modified, T& dst, const T& src)
|
||||
{
|
||||
if (dst == src)
|
||||
return;
|
||||
dst = src;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
static void BufferedSet(bool& modified, VSMatrix& dst, const VSMatrix& src)
|
||||
{
|
||||
if (memcmp(dst.get(), src.get(), sizeof(FLOATTYPE) * 16) == 0)
|
||||
return;
|
||||
dst = src;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
bool VkMatrixBuffer::Write(const VSMatrix& modelMatrix, bool modelMatrixEnabled, const VSMatrix& textureMatrix, bool textureMatrixEnabled)
|
||||
{
|
||||
bool modified = (mOffset == 0); // always modified first call
|
||||
|
||||
if (modelMatrixEnabled)
|
||||
{
|
||||
BufferedSet(modified, mMatrices.ModelMatrix, modelMatrix);
|
||||
if (modified)
|
||||
mMatrices.NormalModelMatrix.computeNormalMatrix(modelMatrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferedSet(modified, mMatrices.ModelMatrix, mIdentityMatrix);
|
||||
BufferedSet(modified, mMatrices.NormalModelMatrix, mIdentityMatrix);
|
||||
}
|
||||
|
||||
if (textureMatrixEnabled)
|
||||
{
|
||||
BufferedSet(modified, mMatrices.TextureMatrix, textureMatrixEnabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferedSet(modified, mMatrices.TextureMatrix, mIdentityMatrix);
|
||||
}
|
||||
|
||||
if (modified)
|
||||
{
|
||||
if (mOffset + (size_t)UniformBufferAlignedSize<MatricesUBO>(2) >= UniformBuffer->Size())
|
||||
return false;
|
||||
|
||||
mOffset += UniformBufferAlignedSize<MatricesUBO>(1);
|
||||
memcpy(static_cast<uint8_t*>(UniformBuffer->Memory()) + mOffset, &mMatrices, sizeof(MatricesUBO));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VkMatrixBuffer::Reset()
|
||||
{
|
||||
mOffset = 0;
|
||||
}
|
58
src/rendering/vulkan/renderer/vk_streambuffer.h
Normal file
58
src/rendering/vulkan/renderer/vk_streambuffer.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "vulkan/system/vk_buffers.h"
|
||||
#include "vulkan/shaders/vk_shader.h"
|
||||
|
||||
class VkStreamBuffer;
|
||||
|
||||
class VkStreamBufferWriter
|
||||
{
|
||||
public:
|
||||
VkStreamBufferWriter();
|
||||
|
||||
bool Write(const StreamData& data);
|
||||
void Reset();
|
||||
|
||||
uint32_t DataIndex() const { return mDataIndex; }
|
||||
uint32_t StreamDataOffset() const { return mStreamDataOffset; }
|
||||
|
||||
private:
|
||||
VkStreamBuffer* mBuffer;
|
||||
uint32_t mDataIndex = MAX_STREAM_DATA - 1;
|
||||
uint32_t mStreamDataOffset = 0;
|
||||
};
|
||||
|
||||
class VkStreamBuffer
|
||||
{
|
||||
public:
|
||||
VkStreamBuffer();
|
||||
~VkStreamBuffer();
|
||||
|
||||
uint32_t NextStreamDataBlock();
|
||||
void Reset() { mStreamDataOffset = 0; }
|
||||
|
||||
VKDataBuffer* UniformBuffer = nullptr;
|
||||
|
||||
private:
|
||||
uint32_t mStreamDataOffset = 0;
|
||||
};
|
||||
|
||||
class VkMatrixBuffer
|
||||
{
|
||||
public:
|
||||
VkMatrixBuffer();
|
||||
~VkMatrixBuffer();
|
||||
|
||||
bool Write(const VSMatrix &modelMatrix, bool modelMatrixEnabled, const VSMatrix& textureMatrix, bool textureMatrixEnabled);
|
||||
void Reset();
|
||||
|
||||
uint32_t Offset() const { return mOffset; }
|
||||
|
||||
VKDataBuffer* UniformBuffer = nullptr;
|
||||
|
||||
private:
|
||||
MatricesUBO mMatrices = {};
|
||||
VSMatrix mIdentityMatrix;
|
||||
uint32_t mOffset = 0;
|
||||
};
|
|
@ -50,6 +50,7 @@
|
|||
#include "vk_buffers.h"
|
||||
#include "vulkan/renderer/vk_renderstate.h"
|
||||
#include "vulkan/renderer/vk_renderpass.h"
|
||||
#include "vulkan/renderer/vk_streambuffer.h"
|
||||
#include "vulkan/renderer/vk_postprocess.h"
|
||||
#include "vulkan/renderer/vk_renderbuffers.h"
|
||||
#include "vulkan/shaders/vk_shader.h"
|
||||
|
@ -106,8 +107,8 @@ VulkanFrameBuffer::~VulkanFrameBuffer()
|
|||
VKBuffer::ResetAll();
|
||||
PPResource::ResetAll();
|
||||
|
||||
delete MatricesUBO;
|
||||
delete StreamUBO;
|
||||
delete MatrixBuffer;
|
||||
delete StreamBuffer;
|
||||
delete mVertexData;
|
||||
delete mSkyData;
|
||||
delete mViewpoints;
|
||||
|
@ -158,10 +159,8 @@ void VulkanFrameBuffer::InitializeState()
|
|||
CreateFanToTrisIndexBuffer();
|
||||
|
||||
// To do: move this to HW renderer interface maybe?
|
||||
MatricesUBO = (VKDataBuffer*)CreateDataBuffer(-1, false, false);
|
||||
StreamUBO = (VKDataBuffer*)CreateDataBuffer(-1, false, false);
|
||||
MatricesUBO->SetData(UniformBufferAlignedSize<::MatricesUBO>() * 50000, nullptr, false);
|
||||
StreamUBO->SetData(UniformBufferAlignedSize<::StreamUBO>() * 200, nullptr, false);
|
||||
MatrixBuffer = new VkMatrixBuffer();
|
||||
StreamBuffer = new VkStreamBuffer();
|
||||
|
||||
mShaderManager.reset(new VkShaderManager(device));
|
||||
mSamplerManager.reset(new VkSamplerManager(device));
|
||||
|
|
|
@ -9,6 +9,8 @@ class VkSamplerManager;
|
|||
class VkShaderManager;
|
||||
class VkRenderPassManager;
|
||||
class VkRenderState;
|
||||
class VkStreamBuffer;
|
||||
class VkMatrixBuffer;
|
||||
class VKDataBuffer;
|
||||
class VkHardwareTexture;
|
||||
class VkRenderBuffers;
|
||||
|
@ -38,13 +40,10 @@ public:
|
|||
|
||||
unsigned int GetLightBufferBlockSize() const;
|
||||
|
||||
template<typename T>
|
||||
int UniformBufferAlignedSize() const { return (sizeof(T) + uniformblockalignment - 1) / uniformblockalignment * uniformblockalignment; }
|
||||
|
||||
VKDataBuffer *ViewpointUBO = nullptr;
|
||||
VKDataBuffer *LightBufferSSO = nullptr;
|
||||
VKDataBuffer *MatricesUBO = nullptr;
|
||||
VKDataBuffer *StreamUBO = nullptr;
|
||||
VkMatrixBuffer *MatrixBuffer = nullptr;
|
||||
VkStreamBuffer *StreamBuffer = nullptr;
|
||||
|
||||
VKDataBuffer *LightNodes = nullptr;
|
||||
VKDataBuffer *LightLines = nullptr;
|
||||
|
|
Loading…
Reference in a new issue