Remove multithreading RenderState as that seemed to be a poor approach

This commit is contained in:
dpjudas 2023-10-09 03:20:19 +02:00
commit 411b281e7c
19 changed files with 64 additions and 237 deletions

View file

@ -215,7 +215,7 @@ public:
virtual void BeginFrame() {}
virtual void SetWindowSize(int w, int h) {}
virtual void StartPrecaching() {}
virtual FRenderState* RenderState(int threadIndex) { return nullptr; }
virtual FRenderState* RenderState() { return nullptr; }
virtual int GetClientWidth() = 0;
virtual int GetClientHeight() = 0;
@ -279,8 +279,6 @@ public:
uint64_t FrameTime = 0;
uint64_t FrameTimeNS = 0;
int MaxThreads = 8; // To do: this may need to be limited by how much memory is available for dedicated buffer mapping (i.e. is resizeable bar available or not)
private:
uint64_t fpsLimitTime = 0;

View file

@ -38,10 +38,7 @@ VkBufferManager::~VkBufferManager()
void VkBufferManager::Init()
{
for (int threadIndex = 0; threadIndex < fb->MaxThreads; threadIndex++)
{
RSBuffers.push_back(std::make_unique<VkRSBuffers>(fb));
}
RSBuffers = std::make_unique<VkRSBuffers>(fb);
Shadowmap.Nodes.reset(new VkHardwareDataBuffer(fb, true, false));
Shadowmap.Lines.reset(new VkHardwareDataBuffer(fb, true, false));
@ -52,7 +49,7 @@ void VkBufferManager::Init()
void VkBufferManager::Deinit()
{
RSBuffers.clear();
RSBuffers.reset();
Shadowmap.Nodes.reset();
Shadowmap.Lines.reset();

View file

@ -26,7 +26,7 @@ public:
void AddBuffer(VkHardwareBuffer* buffer);
void RemoveBuffer(VkHardwareBuffer* buffer);
VkRSBuffers* GetRSBuffers(int threadIndex) { return RSBuffers[threadIndex].get(); }
VkRSBuffers* GetRSBuffers() { return RSBuffers.get(); }
struct
{
@ -43,5 +43,5 @@ private:
VulkanRenderDevice* fb = nullptr;
std::list<VkHardwareBuffer*> Buffers;
std::vector<std::unique_ptr<VkRSBuffers>> RSBuffers;
std::unique_ptr<VkRSBuffers> RSBuffers;
};

View file

@ -154,7 +154,7 @@ void VkCommandBufferManager::FlushCommands(bool finish, bool lastsubmit, bool up
fb->GetDescriptorSetManager()->UpdateBindlessDescriptorSet();
if (!uploadOnly)
fb->GetRenderState(0)->EndRenderPass();
fb->GetRenderState()->EndRenderPass();
std::unique_lock<std::mutex> lock(mMutex);

View file

@ -57,21 +57,18 @@ void VkDescriptorSetManager::Init()
{
UpdateFixedSet();
for (int threadIndex = 0; threadIndex < fb->MaxThreads; threadIndex++)
{
auto rsbuffers = fb->GetBufferManager()->GetRSBuffers(threadIndex);
auto rsbufferset = RSBufferDescriptorPool->allocate(RSBufferSetLayout.get());
auto rsbuffers = fb->GetBufferManager()->GetRSBuffers();
auto rsbufferset = RSBufferDescriptorPool->allocate(RSBufferSetLayout.get());
WriteDescriptors()
.AddBuffer(rsbufferset.get(), 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->Viewpoint.UBO.get(), 0, sizeof(HWViewpointUniforms))
.AddBuffer(rsbufferset.get(), 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->MatrixBuffer->UBO.get(), 0, sizeof(MatricesUBO))
.AddBuffer(rsbufferset.get(), 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->StreamBuffer->UBO.get(), 0, sizeof(StreamUBO))
.AddBuffer(rsbufferset.get(), 3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->Lightbuffer.UBO.get(), 0, sizeof(LightBufferUBO))
.AddBuffer(rsbufferset.get(), 4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, rsbuffers->Bonebuffer.SSO.get())
.Execute(fb->GetDevice());
WriteDescriptors()
.AddBuffer(rsbufferset.get(), 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->Viewpoint.UBO.get(), 0, sizeof(HWViewpointUniforms))
.AddBuffer(rsbufferset.get(), 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->MatrixBuffer->UBO.get(), 0, sizeof(MatricesUBO))
.AddBuffer(rsbufferset.get(), 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->StreamBuffer->UBO.get(), 0, sizeof(StreamUBO))
.AddBuffer(rsbufferset.get(), 3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->Lightbuffer.UBO.get(), 0, sizeof(LightBufferUBO))
.AddBuffer(rsbufferset.get(), 4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, rsbuffers->Bonebuffer.SSO.get())
.Execute(fb->GetDevice());
RSBufferSets.push_back(std::move(rsbufferset));
}
RSBufferSet = std::move(rsbufferset);
}
void VkDescriptorSetManager::Deinit()
@ -287,9 +284,9 @@ void VkDescriptorSetManager::CreateFixedSetLayout()
void VkDescriptorSetManager::CreateRSBufferPool()
{
RSBufferDescriptorPool = DescriptorPoolBuilder()
.AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 4 * fb->MaxThreads)
.AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1 * fb->MaxThreads)
.MaxSets(fb->MaxThreads)
.AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 4)
.AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1)
.MaxSets(1)
.DebugName("VkDescriptorSetManager.RSBufferDescriptorPool")
.Create(fb->GetDevice());
}

View file

@ -27,7 +27,7 @@ public:
VulkanDescriptorSetLayout* GetTextureSetLayout(int numLayers);
VulkanDescriptorSetLayout* GetBindlessSetLayout() { return BindlessDescriptorSetLayout.get(); }
VulkanDescriptorSet* GetRSBufferDescriptorSet(int threadIndex) { return RSBufferSets[threadIndex].get(); }
VulkanDescriptorSet* GetRSBufferDescriptorSet() { return RSBufferSet.get(); }
VulkanDescriptorSet* GetFixedDescriptorSet() { return FixedSet.get(); }
VulkanDescriptorSet* GetNullTextureDescriptorSet();
VulkanDescriptorSet* GetBindlessDescriptorSet() { return BindlessDescriptorSet.get(); }
@ -67,7 +67,7 @@ private:
int TextureDescriptorsLeft = 0;
std::vector<std::unique_ptr<VulkanDescriptorPool>> TextureDescriptorPools;
std::vector<std::unique_ptr<VulkanDescriptorSet>> RSBufferSets;
std::unique_ptr<VulkanDescriptorSet> RSBufferSet;
std::unique_ptr<VulkanDescriptorSet> FixedSet;
std::unique_ptr<VulkanDescriptorSet> NullTextureDescriptorSet;

View file

@ -304,7 +304,6 @@ void VkHardwareTexture::CreateWipeTexture(int w, int h, const char *name)
VkMaterial::VkMaterial(VulkanRenderDevice* fb, FGameTexture* tex, int scaleflags) : FMaterial(tex, scaleflags), fb(fb)
{
mThreadDescriptorSets.resize(fb->MaxThreads);
fb->GetDescriptorSetManager()->AddMaterial(this);
}
@ -324,9 +323,6 @@ void VkMaterial::DeleteDescriptors()
deleteList->Add(std::move(it.descriptor));
}
mDescriptorSets.clear();
for (auto& list : mThreadDescriptorSets)
list.clear();
}
}
@ -405,20 +401,3 @@ VkMaterial::DescriptorEntry& VkMaterial::GetDescriptorEntry(const FMaterialState
mDescriptorSets.emplace_back(clampmode, translationp, std::move(descriptor), bindlessIndex);
return mDescriptorSets.back();
}
VulkanDescriptorSet* VkMaterial::GetDescriptorSet(int threadIndex, const FMaterialState& state)
{
int clampmode = Source()->GetClampMode(state.mClampMode);
int translation = state.mTranslation;
auto translationp = IsLuminosityTranslation(translation) ? translation : intptr_t(GPalette.GetTranslation(GetTranslationType(translation), GetTranslationIndex(translation)));
for (auto& set : mThreadDescriptorSets[threadIndex])
{
if (set.descriptor && set.clampmode == clampmode && set.remap == translationp)
return set.descriptor;
}
std::unique_lock<std::mutex> lock(fb->ThreadMutex);
VulkanDescriptorSet* descriptorset = GetDescriptorSet(state);
mThreadDescriptorSets[threadIndex].push_back(ThreadDescriptorEntry(clampmode, translationp, descriptorset));
return descriptorset;
}

View file

@ -70,7 +70,7 @@ public:
VulkanRenderDevice* fb = nullptr;
std::list<VkMaterial*>::iterator it;
VulkanDescriptorSet* GetDescriptorSet(int threadIndex, const FMaterialState& state);
VulkanDescriptorSet* GetDescriptorSet(const FMaterialState& state);
int GetBindlessIndex(const FMaterialState& state);
private:
@ -90,18 +90,7 @@ private:
}
};
struct ThreadDescriptorEntry
{
int clampmode;
intptr_t remap;
VulkanDescriptorSet* descriptor;
ThreadDescriptorEntry(int cm, intptr_t f, VulkanDescriptorSet* d) : clampmode(cm), remap(f), descriptor(d) { }
};
VulkanDescriptorSet* GetDescriptorSet(const FMaterialState& state);
DescriptorEntry& GetDescriptorEntry(const FMaterialState& state);
std::vector<DescriptorEntry> mDescriptorSets;
std::vector<std::vector<ThreadDescriptorEntry>> mThreadDescriptorSets;
};

View file

@ -70,7 +70,6 @@ void VkRenderBuffers::BeginFrame(int width, int height, int sceneWidth, int scen
{
fb->GetCommands()->WaitForCommands(false);
fb->GetRenderPassManager()->RenderBuffersReset();
fb->ResetRenderStateCache();
}
if (width != mWidth || height != mHeight)

View file

@ -61,14 +61,12 @@ void VkPostprocess::SetActiveRenderTarget()
.AddImage(&buffers->PipelineDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false)
.Execute(fb->GetCommands()->GetDrawCommands());
for (int i = 0; i < fb->MaxThreads; i++)
fb->GetRenderState(i)->SetRenderTarget(&buffers->PipelineImage[mCurrentPipelineImage], buffers->PipelineDepthStencil.View.get(), buffers->GetWidth(), buffers->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, VK_SAMPLE_COUNT_1_BIT);
fb->GetRenderState()->SetRenderTarget(&buffers->PipelineImage[mCurrentPipelineImage], buffers->PipelineDepthStencil.View.get(), buffers->GetWidth(), buffers->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, VK_SAMPLE_COUNT_1_BIT);
}
void VkPostprocess::PostProcessScene(int fixedcm, float flash, const std::function<void()> &afterBloomDrawEndScene2D)
{
for (int i = 0; i < fb->MaxThreads; i++)
fb->GetRenderState(i)->EndRenderPass();
fb->GetRenderState()->EndRenderPass();
fb->GetCommands()->FlushCommands(false);
int sceneWidth = fb->GetBuffers()->GetSceneWidth();
@ -84,8 +82,7 @@ void VkPostprocess::PostProcessScene(int fixedcm, float flash, const std::functi
void VkPostprocess::BlitSceneToPostprocess()
{
for (int i = 0; i < fb->MaxThreads; i++)
fb->GetRenderState(i)->EndRenderPass();
fb->GetRenderState()->EndRenderPass();
auto buffers = fb->GetBuffers();
auto cmdbuffer = fb->GetCommands()->GetDrawCommands();
@ -154,8 +151,7 @@ void VkPostprocess::ImageTransitionScene(bool undefinedSrcLayout)
void VkPostprocess::BlitCurrentToImage(VkTextureImage *dstimage, VkImageLayout finallayout)
{
for (int i = 0; i < fb->MaxThreads; i++)
fb->GetRenderState(i)->EndRenderPass();
fb->GetRenderState()->EndRenderPass();
auto srcimage = &fb->GetBuffers()->PipelineImage[mCurrentPipelineImage];
auto cmdbuffer = fb->GetCommands()->GetDrawCommands();

View file

@ -53,7 +53,7 @@ void VkPPRenderState::PopGroup()
void VkPPRenderState::Draw()
{
fb->GetRenderState(0)->EndRenderPass();
fb->GetRenderState()->EndRenderPass();
VkPPRenderPassKey key;
key.BlendMode = BlendMode;

View file

@ -208,14 +208,11 @@ void VulkanRenderDevice::InitializeState()
mShaderManager.reset(new VkShaderManager(this));
mDescriptorSetManager->Init();
for (int threadIndex = 0; threadIndex < MaxThreads; threadIndex++)
{
#ifdef __APPLE__
mRenderState.push_back(std::make_unique<VkRenderStateMolten>(this, 0));
mRenderState = std::make_unique<VkRenderStateMolten>(this);
#else
mRenderState.push_back(std::make_unique<VkRenderState>(this, 0));
mRenderState = std::make_unique<VkRenderState>(this);
#endif
}
}
void VulkanRenderDevice::Update()
@ -230,11 +227,8 @@ void VulkanRenderDevice::Update()
Draw2D();
twod->Clear();
for (auto& renderstate : mRenderState)
{
renderstate->EndRenderPass();
renderstate->EndFrame();
}
mRenderState->EndRenderPass();
mRenderState->EndFrame();
Flush3D.Unclock();
@ -256,19 +250,13 @@ void VulkanRenderDevice::RenderTextureView(FCanvasTexture* tex, std::function<vo
VkTextureImage *image = BaseLayer->GetImage(tex, 0, 0);
VkTextureImage *depthStencil = BaseLayer->GetDepthStencil(tex);
for (auto& renderstate : mRenderState)
{
renderstate->EndRenderPass();
}
mRenderState->EndRenderPass();
VkImageTransition()
.AddImage(image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false)
.Execute(mCommands->GetDrawCommands());
for (auto& renderstate : mRenderState)
{
renderstate->SetRenderTarget(image, depthStencil->View.get(), image->Image->width, image->Image->height, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT);
}
mRenderState->SetRenderTarget(image, depthStencil->View.get(), image->Image->width, image->Image->height, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT);
IntRect bounds;
bounds.left = bounds.top = 0;
@ -277,19 +265,13 @@ void VulkanRenderDevice::RenderTextureView(FCanvasTexture* tex, std::function<vo
renderFunc(bounds);
for (auto& renderstate : mRenderState)
{
renderstate->EndRenderPass();
}
mRenderState->EndRenderPass();
VkImageTransition()
.AddImage(image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false)
.Execute(mCommands->GetDrawCommands());
for (auto& renderstate : mRenderState)
{
renderstate->SetRenderTarget(&GetBuffers()->SceneColor, GetBuffers()->SceneDepthStencil.View.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
}
mRenderState->SetRenderTarget(&GetBuffers()->SceneColor, GetBuffers()->SceneDepthStencil.View.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
tex->SetUpdated(true);
}
@ -498,8 +480,7 @@ void VulkanRenderDevice::BeginFrame()
mTextureManager->BeginFrame();
mScreenBuffers->BeginFrame(screen->mScreenViewport.width, screen->mScreenViewport.height, screen->mSceneViewport.width, screen->mSceneViewport.height);
mSaveBuffers->BeginFrame(SAVEPICWIDTH, SAVEPICHEIGHT, SAVEPICWIDTH, SAVEPICHEIGHT);
for (auto& renderstate : mRenderState)
renderstate->BeginFrame();
mRenderState->BeginFrame();
mDescriptorSetManager->BeginFrame();
mRaytrace->BeginFrame();
mLightmap->BeginFrame();
@ -507,7 +488,7 @@ void VulkanRenderDevice::BeginFrame()
void VulkanRenderDevice::Draw2D()
{
::Draw2D(twod, *RenderState(0));
::Draw2D(twod, *RenderState());
}
void VulkanRenderDevice::WaitForCommands(bool finish)
@ -515,14 +496,6 @@ void VulkanRenderDevice::WaitForCommands(bool finish)
mCommands->WaitForCommands(finish);
}
void VulkanRenderDevice::ResetRenderStateCache()
{
for (auto& renderstate : mRenderState)
{
renderstate->ResetCache();
}
}
void VulkanRenderDevice::PrintStartupLog()
{
const auto &props = mDevice->PhysicalDevice.Properties.Properties;
@ -604,9 +577,9 @@ void VulkanRenderDevice::ImageTransitionScene(bool unknown)
mPostprocess->ImageTransitionScene(unknown);
}
FRenderState* VulkanRenderDevice::RenderState(int threadIndex)
FRenderState* VulkanRenderDevice::RenderState()
{
return mRenderState[threadIndex].get();
return mRenderState.get();
}
void VulkanRenderDevice::AmbientOccludeScene(float m5)
@ -616,10 +589,7 @@ void VulkanRenderDevice::AmbientOccludeScene(float m5)
void VulkanRenderDevice::SetSceneRenderTarget(bool useSSAO)
{
for (auto& renderstate : mRenderState)
{
renderstate->SetRenderTarget(&GetBuffers()->SceneColor, GetBuffers()->SceneDepthStencil.View.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
}
mRenderState->SetRenderTarget(&GetBuffers()->SceneColor, GetBuffers()->SceneDepthStencil.View.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
}
int VulkanRenderDevice::GetBindlessTextureIndex(FMaterial* material, int clampmode, int translation)

View file

@ -40,10 +40,10 @@ public:
VkRenderPassManager *GetRenderPassManager() { return mRenderPassManager.get(); }
VkRaytrace* GetRaytrace() { return mRaytrace.get(); }
VkLightmap* GetLightmap() { return mLightmap.get(); }
VkRenderState *GetRenderState(int threadIndex) { return mRenderState[threadIndex].get(); }
VkRenderState *GetRenderState() { return mRenderState.get(); }
VkPostprocess *GetPostprocess() { return mPostprocess.get(); }
VkRenderBuffers *GetBuffers() { return mActiveRenderBuffers; }
FRenderState* RenderState(int threadIndex) override;
FRenderState* RenderState() override;
bool IsVulkan() override { return true; }
@ -89,10 +89,6 @@ public:
int GetBindlessTextureIndex(FMaterial* material, int clampmode, int translation) override;
void ResetRenderStateCache();
std::mutex ThreadMutex;
private:
void RenderTextureView(FCanvasTexture* tex, std::function<void(IntRect &)> renderFunc) override;
void PrintStartupLog();
@ -112,7 +108,7 @@ private:
std::unique_ptr<VkRenderPassManager> mRenderPassManager;
std::unique_ptr<VkRaytrace> mRaytrace;
std::unique_ptr<VkLightmap> mLightmap;
std::vector<std::unique_ptr<VkRenderState>> mRenderState;
std::unique_ptr<VkRenderState> mRenderState;
VkRenderBuffers *mActiveRenderBuffers = nullptr;

View file

@ -40,7 +40,7 @@
CVAR(Int, vk_submit_size, 1000, 0);
EXTERN_CVAR(Bool, r_skipmats)
VkRenderState::VkRenderState(VulkanRenderDevice* fb, int threadIndex) : fb(fb), threadIndex(threadIndex), mRSBuffers(fb->GetBufferManager()->GetRSBuffers(threadIndex)), mStreamBufferWriter(mRSBuffers), mMatrixBufferWriter(mRSBuffers)
VkRenderState::VkRenderState(VulkanRenderDevice* fb) : fb(fb), mRSBuffers(fb->GetBufferManager()->GetRSBuffers()), mStreamBufferWriter(mRSBuffers), mMatrixBufferWriter(mRSBuffers)
{
mMatrices.ModelMatrix.loadIdentity();
mMatrices.NormalModelMatrix.loadIdentity();
@ -188,7 +188,7 @@ void VkRenderState::Apply(int dt)
drawcalls.Clock();
mApplyCount++;
if (threadIndex == 0 && mApplyCount >= vk_submit_size)
if (mApplyCount >= vk_submit_size)
{
fb->GetCommands()->FlushCommands(false);
mApplyCount = 0;
@ -310,15 +310,7 @@ void VkRenderState::ApplyRenderPass(int dt)
if (!inRenderPass)
{
if (threadIndex == 0)
{
mCommandBuffer = fb->GetCommands()->GetDrawCommands();
}
else
{
mThreadCommandBuffer = fb->GetCommands()->BeginThreadCommands();
mCommandBuffer = mThreadCommandBuffer.get();
}
mCommandBuffer = fb->GetCommands()->GetDrawCommands();
mScissorChanged = true;
mViewportChanged = true;
@ -429,7 +421,7 @@ void VkRenderState::ApplyPushConstants()
mPushConstants.uLightIndex = mLightIndex >= 0 ? (mLightIndex % MAX_LIGHT_DATA) : -1;
mPushConstants.uBoneIndexBase = mBoneIndexBase;
mCommandBuffer->pushConstants(GetPipelineLayout(mPipelineKey.NumTextureLayers), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, (uint32_t)sizeof(PushConstants), &mPushConstants);
mCommandBuffer->pushConstants(fb->GetRenderPassManager()->GetPipelineLayout(mPipelineKey.NumTextureLayers), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, (uint32_t)sizeof(PushConstants), &mPushConstants);
}
void VkRenderState::ApplyMatrices()
@ -490,12 +482,12 @@ void VkRenderState::ApplyMaterial()
if (mMaterial.mChanged)
{
auto descriptors = fb->GetDescriptorSetManager();
VulkanPipelineLayout* layout = GetPipelineLayout(mPipelineKey.NumTextureLayers);
VulkanPipelineLayout* layout = fb->GetRenderPassManager()->GetPipelineLayout(mPipelineKey.NumTextureLayers);
if (mMaterial.mMaterial && mMaterial.mMaterial->Source()->isHardwareCanvas())
static_cast<FCanvasTexture*>(mMaterial.mMaterial->Source()->GetTexture())->NeedUpdate();
VulkanDescriptorSet* descriptorset = mMaterial.mMaterial ? static_cast<VkMaterial*>(mMaterial.mMaterial)->GetDescriptorSet(threadIndex, mMaterial) : descriptors->GetNullTextureDescriptorSet();
VulkanDescriptorSet* descriptorset = mMaterial.mMaterial ? static_cast<VkMaterial*>(mMaterial.mMaterial)->GetDescriptorSet(mMaterial) : descriptors->GetNullTextureDescriptorSet();
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptors->GetFixedDescriptorSet());
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 2, descriptorset);
@ -511,11 +503,11 @@ void VkRenderState::ApplyBufferSets()
if (mViewpointOffset != mLastViewpointOffset || matrixOffset != mLastMatricesOffset || streamDataOffset != mLastStreamDataOffset || lightsOffset != mLastLightsOffset)
{
auto descriptors = fb->GetDescriptorSetManager();
VulkanPipelineLayout* layout = GetPipelineLayout(mPipelineKey.NumTextureLayers);
VulkanPipelineLayout* layout = fb->GetRenderPassManager()->GetPipelineLayout(mPipelineKey.NumTextureLayers);
uint32_t offsets[4] = { mViewpointOffset, matrixOffset, streamDataOffset, lightsOffset };
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptors->GetFixedDescriptorSet());
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 1, descriptors->GetRSBufferDescriptorSet(threadIndex), 4, offsets);
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 1, descriptors->GetRSBufferDescriptorSet(), 4, offsets);
mLastViewpointOffset = mViewpointOffset;
mLastMatricesOffset = matrixOffset;
@ -722,11 +714,6 @@ void VkRenderState::EndRenderPass()
mCommandBuffer = nullptr;
}
if (mThreadCommandBuffer)
{
fb->GetCommands()->EndThreadCommands(std::move(mThreadCommandBuffer));
}
// Force rebind of everything on next draw
mPipelineKey = {};
mLastViewpointOffset = 0xffffffff;
@ -740,12 +727,6 @@ void VkRenderState::EndFrame()
mStreamBufferWriter.Reset();
}
void VkRenderState::ResetCache()
{
mRenderPassSetups.clear();
mPipelineLayouts.clear();
}
void VkRenderState::EnableDrawBuffers(int count, bool apply)
{
if (mRenderTarget.DrawBuffers != count)
@ -775,7 +756,7 @@ void VkRenderState::BeginRenderPass(VulkanCommandBuffer *cmdbuffer)
key.DrawBuffers = mRenderTarget.DrawBuffers;
key.DepthStencil = !!mRenderTarget.DepthStencil;
mPassSetup = GetRenderPass(key);
mPassSetup = fb->GetRenderPassManager()->GetRenderPass(key);
auto &framebuffer = mRenderTarget.Image->RSFramebuffers[key];
if (!framebuffer)
@ -815,55 +796,6 @@ void VkRenderState::BeginRenderPass(VulkanCommandBuffer *cmdbuffer)
mClearTargets = 0;
}
VkThreadRenderPassSetup* VkRenderState::GetRenderPass(const VkRenderPassKey& key)
{
auto& item = mRenderPassSetups[key];
if (!item)
item.reset(new VkThreadRenderPassSetup(fb, key));
return item.get();
}
VulkanPipelineLayout* VkRenderState::GetPipelineLayout(int numLayers)
{
if (mPipelineLayouts.size() <= (size_t)numLayers)
mPipelineLayouts.resize(numLayers + 1);
auto& layout = mPipelineLayouts[numLayers];
if (layout)
return layout;
std::unique_lock<std::mutex> lock(fb->ThreadMutex);
layout = fb->GetRenderPassManager()->GetPipelineLayout(numLayers);
return layout;
}
/////////////////////////////////////////////////////////////////////////////
VkThreadRenderPassSetup::VkThreadRenderPassSetup(VulkanRenderDevice* fb, const VkRenderPassKey& key) : PassKey(key), fb(fb)
{
}
VulkanRenderPass* VkThreadRenderPassSetup::GetRenderPass(int clearTargets)
{
if (RenderPasses[clearTargets])
return RenderPasses[clearTargets];
std::unique_lock<std::mutex> lock(fb->ThreadMutex);
RenderPasses[clearTargets] = fb->GetRenderPassManager()->GetRenderPass(PassKey)->GetRenderPass(clearTargets);
return RenderPasses[clearTargets];
}
VulkanPipeline* VkThreadRenderPassSetup::GetPipeline(const VkPipelineKey& key)
{
auto& item = Pipelines[key];
if (item)
return item;
std::unique_lock<std::mutex> lock(fb->ThreadMutex);
item = fb->GetRenderPassManager()->GetRenderPass(PassKey)->GetPipeline(key);
return item;
}
/////////////////////////////////////////////////////////////////////////////
void VkRenderStateMolten::Draw(int dt, int index, int count, bool apply)

View file

@ -12,13 +12,12 @@
#include "hw_material.h"
class VulkanRenderDevice;
class VkThreadRenderPassSetup;
class VkTextureImage;
class VkRenderState : public FRenderState
{
public:
VkRenderState(VulkanRenderDevice* fb, int threadIndex);
VkRenderState(VulkanRenderDevice* fb);
virtual ~VkRenderState() = default;
// Draw commands
@ -64,8 +63,6 @@ public:
void EndRenderPass();
void EndFrame();
void ResetCache();
protected:
void Apply(int dt);
void ApplyRenderPass(int dt);
@ -83,18 +80,14 @@ protected:
void BeginRenderPass(VulkanCommandBuffer *cmdbuffer);
void WaitForStreamBuffers();
VkThreadRenderPassSetup* GetRenderPass(const VkRenderPassKey& key);
VulkanPipelineLayout* GetPipelineLayout(int numLayers);
VulkanRenderDevice* fb = nullptr;
int threadIndex = 0;
VkRSBuffers* mRSBuffers = nullptr;
bool mDepthClamp = true;
VulkanCommandBuffer *mCommandBuffer = nullptr;
VkPipelineKey mPipelineKey = {};
VkThreadRenderPassSetup* mPassSetup = nullptr;
VkRenderPassSetup* mPassSetup = nullptr;
int mClearTargets = 0;
bool mNeedApply = true;
@ -146,25 +139,6 @@ protected:
VkSampleCountFlagBits Samples = VK_SAMPLE_COUNT_1_BIT;
int DrawBuffers = 1;
} mRenderTarget;
std::map<VkRenderPassKey, std::unique_ptr<VkThreadRenderPassSetup>> mRenderPassSetups;
std::vector<VulkanPipelineLayout*> mPipelineLayouts;
std::unique_ptr<VulkanCommandBuffer> mThreadCommandBuffer;
};
class VkThreadRenderPassSetup
{
public:
VkThreadRenderPassSetup(VulkanRenderDevice* fb, const VkRenderPassKey& key);
VulkanRenderPass* GetRenderPass(int clearTargets);
VulkanPipeline* GetPipeline(const VkPipelineKey& key);
private:
VkRenderPassKey PassKey;
VulkanRenderDevice* fb;
VulkanRenderPass* RenderPasses[8] = {};
std::map<VkPipelineKey, VulkanPipeline*> Pipelines;
};
class VkRenderStateMolten : public VkRenderState

View file

@ -3722,7 +3722,7 @@ void MapLoader::LoadLevel(MapData *map, const char *lumpname, int position)
InitRenderInfo(); // create hardware independent renderer resources for the level. This must be done BEFORE the PolyObj Spawn!!!
Level->ClearDynamic3DFloorData(); // CreateVBO must be run on the plain 3D floor data.
CreateVBO(*screen->RenderState(0), Level->sectors);
CreateVBO(*screen->RenderState(), Level->sectors);
meshcache.Clear();
for (auto &sec : Level->sectors)

View file

@ -104,7 +104,7 @@ void CollectLights(FLevelLocals* Level)
sector_t* RenderViewpoint(FRenderViewpoint& mainvp, AActor* camera, IntRect* bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen)
{
auto& RenderState = *screen->RenderState(0);
auto& RenderState = *screen->RenderState();
R_SetupFrame(mainvp, r_viewwindow, camera);
@ -170,7 +170,7 @@ sector_t* RenderViewpoint(FRenderViewpoint& mainvp, AActor* camera, IntRect* bou
vp.Pos += eye.GetViewShift(vp.HWAngles.Yaw.Degrees());
di->SetupView(RenderState, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, false, false);
di->ProcessScene(toscreen, *screen->RenderState(0));
di->ProcessScene(toscreen, *screen->RenderState());
if (mainview)
{
@ -266,7 +266,7 @@ void WriteSavePic(player_t* player, FileWriter* file, int width, int height)
bounds.top = 0;
bounds.width = width;
bounds.height = height;
auto& RenderState = *screen->RenderState(0);
auto& RenderState = *screen->RenderState();
// we must be sure the GPU finished reading from the buffer before we fill it with new data.
screen->WaitForCommands(false);
@ -313,7 +313,7 @@ static void CheckTimer(FRenderState &state, uint64_t ShaderStartTime)
sector_t* RenderView(player_t* player)
{
auto RenderState = screen->RenderState(0);
auto RenderState = screen->RenderState();
RenderState->SetFlatVertexBuffer();
RenderState->ResetVertices();
hw_postprocess.SetTonemapMode(level.info ? level.info->tonemap : ETonemapMode::None);
@ -355,7 +355,7 @@ sector_t* RenderView(player_t* player)
screen->RenderTextureView(canvas->Tex, [=](IntRect& bounds)
{
screen->SetViewportRects(&bounds);
Draw2D(&canvas->Drawer, *screen->RenderState(0), 0, 0, canvas->Tex->GetWidth(), canvas->Tex->GetHeight());
Draw2D(&canvas->Drawer, *screen->RenderState(), 0, 0, canvas->Tex->GetWidth(), canvas->Tex->GetHeight());
canvas->Drawer.Clear();
});
canvas->Tex->SetUpdated(true);

View file

@ -316,7 +316,7 @@ void hw_PrecacheTexture(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitl
FImageSource::EndPrecaching();
// cache all used models
FModelRenderer* renderer = new FHWModelRenderer(nullptr, *screen->RenderState(0), -1);
FModelRenderer* renderer = new FHWModelRenderer(nullptr, *screen->RenderState(), -1);
for (unsigned i = 0; i < Models.Size(); i++)
{
if (modellist[i])

View file

@ -108,7 +108,7 @@ void HWDrawInfo::WorkerThread()
{
sector_t *front, *back;
FRenderState& state = *screen->RenderState(0);
FRenderState& state = *screen->RenderState();
WTTotal.Clock();
isWorkerThread = true; // for adding asserts in GL API code. The worker thread may never call any GL API.