mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-22 12:01:13 +00:00
Create a RenderState object for each thread
This commit is contained in:
parent
6739b079d0
commit
0adb152913
10 changed files with 62 additions and 31 deletions
|
@ -214,7 +214,7 @@ public:
|
|||
virtual void BeginFrame() {}
|
||||
virtual void SetWindowSize(int w, int h) {}
|
||||
virtual void StartPrecaching() {}
|
||||
virtual FRenderState* RenderState() { return nullptr; }
|
||||
virtual FRenderState* RenderState(int threadIndex) { return nullptr; }
|
||||
|
||||
virtual int GetClientWidth() = 0;
|
||||
virtual int GetClientHeight() = 0;
|
||||
|
@ -277,6 +277,8 @@ 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;
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ void VkCommandBufferManager::FlushCommands(VulkanCommandBuffer** commands, size_
|
|||
void VkCommandBufferManager::FlushCommands(bool finish, bool lastsubmit, bool uploadOnly)
|
||||
{
|
||||
if (!uploadOnly)
|
||||
fb->GetRenderState()->EndRenderPass();
|
||||
fb->GetRenderState(0)->EndRenderPass();
|
||||
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
|
||||
|
|
|
@ -61,11 +61,16 @@ void VkPostprocess::SetActiveRenderTarget()
|
|||
.AddImage(&buffers->PipelineDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false)
|
||||
.Execute(fb->GetCommands()->GetDrawCommands());
|
||||
|
||||
fb->GetRenderState()->SetRenderTarget(&buffers->PipelineImage[mCurrentPipelineImage], buffers->PipelineDepthStencil.View.get(), buffers->GetWidth(), buffers->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, VK_SAMPLE_COUNT_1_BIT);
|
||||
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);
|
||||
}
|
||||
|
||||
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->GetCommands()->FlushCommands(false);
|
||||
|
||||
int sceneWidth = fb->GetBuffers()->GetSceneWidth();
|
||||
int sceneHeight = fb->GetBuffers()->GetSceneHeight();
|
||||
|
||||
|
@ -79,7 +84,8 @@ void VkPostprocess::PostProcessScene(int fixedcm, float flash, const std::functi
|
|||
|
||||
void VkPostprocess::BlitSceneToPostprocess()
|
||||
{
|
||||
fb->GetRenderState()->EndRenderPass();
|
||||
for (int i = 0; i < fb->MaxThreads; i++)
|
||||
fb->GetRenderState(i)->EndRenderPass();
|
||||
|
||||
auto buffers = fb->GetBuffers();
|
||||
auto cmdbuffer = fb->GetCommands()->GetDrawCommands();
|
||||
|
@ -148,7 +154,8 @@ void VkPostprocess::ImageTransitionScene(bool undefinedSrcLayout)
|
|||
|
||||
void VkPostprocess::BlitCurrentToImage(VkTextureImage *dstimage, VkImageLayout finallayout)
|
||||
{
|
||||
fb->GetRenderState()->EndRenderPass();
|
||||
for (int i = 0; i < fb->MaxThreads; i++)
|
||||
fb->GetRenderState(i)->EndRenderPass();
|
||||
|
||||
auto srcimage = &fb->GetBuffers()->PipelineImage[mCurrentPipelineImage];
|
||||
auto cmdbuffer = fb->GetCommands()->GetDrawCommands();
|
||||
|
|
|
@ -53,7 +53,7 @@ void VkPPRenderState::PopGroup()
|
|||
|
||||
void VkPPRenderState::Draw()
|
||||
{
|
||||
fb->GetRenderState()->EndRenderPass();
|
||||
fb->GetRenderState(0)->EndRenderPass();
|
||||
|
||||
VkPPRenderPassKey key;
|
||||
key.BlendMode = BlendMode;
|
||||
|
|
|
@ -190,11 +190,15 @@ void VulkanRenderDevice::InitializeState()
|
|||
|
||||
mShaderManager.reset(new VkShaderManager(this));
|
||||
mDescriptorSetManager->Init();
|
||||
|
||||
for (int threadIndex = 0; threadIndex < MaxThreads; threadIndex++)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
mRenderState.reset(new VkRenderStateMolten(this));
|
||||
mRenderState.push_back(std::make_unique<VkRenderStateMolten>(this));
|
||||
#else
|
||||
mRenderState.reset(new VkRenderState(this, 0));
|
||||
mRenderState.push_back(std::make_unique<VkRenderState>(this, 0));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanRenderDevice::Update()
|
||||
|
@ -209,8 +213,11 @@ void VulkanRenderDevice::Update()
|
|||
Draw2D();
|
||||
twod->Clear();
|
||||
|
||||
mRenderState->EndRenderPass();
|
||||
mRenderState->EndFrame();
|
||||
for (auto& renderstate : mRenderState)
|
||||
{
|
||||
renderstate->EndRenderPass();
|
||||
renderstate->EndFrame();
|
||||
}
|
||||
|
||||
Flush3D.Unclock();
|
||||
|
||||
|
@ -232,13 +239,19 @@ void VulkanRenderDevice::RenderTextureView(FCanvasTexture* tex, std::function<vo
|
|||
VkTextureImage *image = BaseLayer->GetImage(tex, 0, 0);
|
||||
VkTextureImage *depthStencil = BaseLayer->GetDepthStencil(tex);
|
||||
|
||||
mRenderState->EndRenderPass();
|
||||
for (auto& renderstate : mRenderState)
|
||||
{
|
||||
renderstate->EndRenderPass();
|
||||
}
|
||||
|
||||
VkImageTransition()
|
||||
.AddImage(image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false)
|
||||
.Execute(mCommands->GetDrawCommands());
|
||||
|
||||
mRenderState->SetRenderTarget(image, depthStencil->View.get(), image->Image->width, image->Image->height, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT);
|
||||
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);
|
||||
}
|
||||
|
||||
IntRect bounds;
|
||||
bounds.left = bounds.top = 0;
|
||||
|
@ -247,13 +260,19 @@ void VulkanRenderDevice::RenderTextureView(FCanvasTexture* tex, std::function<vo
|
|||
|
||||
renderFunc(bounds);
|
||||
|
||||
mRenderState->EndRenderPass();
|
||||
for (auto& renderstate : mRenderState)
|
||||
{
|
||||
renderstate->EndRenderPass();
|
||||
}
|
||||
|
||||
VkImageTransition()
|
||||
.AddImage(image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false)
|
||||
.Execute(mCommands->GetDrawCommands());
|
||||
|
||||
mRenderState->SetRenderTarget(&GetBuffers()->SceneColor, GetBuffers()->SceneDepthStencil.View.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
|
||||
for (auto& renderstate : mRenderState)
|
||||
{
|
||||
renderstate->SetRenderTarget(&GetBuffers()->SceneColor, GetBuffers()->SceneDepthStencil.View.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
|
||||
}
|
||||
|
||||
tex->SetUpdated(true);
|
||||
}
|
||||
|
@ -450,7 +469,8 @@ 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);
|
||||
mRenderState->BeginFrame();
|
||||
for (auto& renderstate : mRenderState)
|
||||
renderstate->BeginFrame();
|
||||
mDescriptorSetManager->BeginFrame();
|
||||
}
|
||||
|
||||
|
@ -465,7 +485,7 @@ void VulkanRenderDevice::InitLightmap(int LMTextureSize, int LMTextureCount, TAr
|
|||
|
||||
void VulkanRenderDevice::Draw2D()
|
||||
{
|
||||
::Draw2D(twod, *mRenderState);
|
||||
::Draw2D(twod, *RenderState(0));
|
||||
}
|
||||
|
||||
void VulkanRenderDevice::WaitForCommands(bool finish)
|
||||
|
@ -546,9 +566,9 @@ void VulkanRenderDevice::ImageTransitionScene(bool unknown)
|
|||
mPostprocess->ImageTransitionScene(unknown);
|
||||
}
|
||||
|
||||
FRenderState* VulkanRenderDevice::RenderState()
|
||||
FRenderState* VulkanRenderDevice::RenderState(int threadIndex)
|
||||
{
|
||||
return mRenderState.get();
|
||||
return mRenderState[threadIndex].get();
|
||||
}
|
||||
|
||||
void VulkanRenderDevice::AmbientOccludeScene(float m5)
|
||||
|
@ -558,5 +578,8 @@ void VulkanRenderDevice::AmbientOccludeScene(float m5)
|
|||
|
||||
void VulkanRenderDevice::SetSceneRenderTarget(bool useSSAO)
|
||||
{
|
||||
mRenderState->SetRenderTarget(&GetBuffers()->SceneColor, GetBuffers()->SceneDepthStencil.View.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
|
||||
for (auto& renderstate : mRenderState)
|
||||
{
|
||||
renderstate->SetRenderTarget(&GetBuffers()->SceneColor, GetBuffers()->SceneDepthStencil.View.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,10 +38,10 @@ public:
|
|||
VkDescriptorSetManager* GetDescriptorSetManager() { return mDescriptorSetManager.get(); }
|
||||
VkRenderPassManager *GetRenderPassManager() { return mRenderPassManager.get(); }
|
||||
VkRaytrace* GetRaytrace() { return mRaytrace.get(); }
|
||||
VkRenderState *GetRenderState() { return mRenderState.get(); }
|
||||
VkRenderState *GetRenderState(int threadIndex) { return mRenderState[threadIndex].get(); }
|
||||
VkPostprocess *GetPostprocess() { return mPostprocess.get(); }
|
||||
VkRenderBuffers *GetBuffers() { return mActiveRenderBuffers; }
|
||||
FRenderState* RenderState() override;
|
||||
FRenderState* RenderState(int threadIndex) override;
|
||||
|
||||
bool IsVulkan() override { return true; }
|
||||
|
||||
|
@ -85,7 +85,6 @@ public:
|
|||
|
||||
void WaitForCommands(bool finish) override;
|
||||
|
||||
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)
|
||||
std::mutex ThreadMutex;
|
||||
|
||||
private:
|
||||
|
@ -106,7 +105,7 @@ private:
|
|||
std::unique_ptr<VkDescriptorSetManager> mDescriptorSetManager;
|
||||
std::unique_ptr<VkRenderPassManager> mRenderPassManager;
|
||||
std::unique_ptr<VkRaytrace> mRaytrace;
|
||||
std::unique_ptr<VkRenderState> mRenderState;
|
||||
std::vector<std::unique_ptr<VkRenderState>> mRenderState;
|
||||
|
||||
VkRenderBuffers *mActiveRenderBuffers = nullptr;
|
||||
|
||||
|
|
|
@ -3243,7 +3243,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(), Level->sectors);
|
||||
CreateVBO(*screen->RenderState(0), Level->sectors);
|
||||
meshcache.Clear();
|
||||
|
||||
screen->InitLightmap(Level->LMTextureSize, Level->LMTextureCount, Level->LMTextureData);
|
||||
|
|
|
@ -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();
|
||||
auto& RenderState = *screen->RenderState(0);
|
||||
|
||||
R_SetupFrame(mainvp, r_viewwindow, camera);
|
||||
|
||||
|
@ -168,7 +168,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());
|
||||
di->ProcessScene(toscreen, *screen->RenderState(0));
|
||||
|
||||
if (mainview)
|
||||
{
|
||||
|
@ -264,7 +264,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();
|
||||
auto& RenderState = *screen->RenderState(0);
|
||||
|
||||
// we must be sure the GPU finished reading from the buffer before we fill it with new data.
|
||||
screen->WaitForCommands(false);
|
||||
|
@ -312,7 +312,7 @@ static void CheckTimer(FRenderState &state, uint64_t ShaderStartTime)
|
|||
|
||||
sector_t* RenderView(player_t* player)
|
||||
{
|
||||
auto RenderState = screen->RenderState();
|
||||
auto RenderState = screen->RenderState(0);
|
||||
RenderState->SetFlatVertexBuffer();
|
||||
RenderState->ResetVertices();
|
||||
hw_postprocess.SetTonemapMode(level.info ? level.info->tonemap : ETonemapMode::None);
|
||||
|
@ -356,7 +356,7 @@ sector_t* RenderView(player_t* player)
|
|||
screen->RenderTextureView(canvas->Tex, [=](IntRect& bounds)
|
||||
{
|
||||
screen->SetViewportRects(&bounds);
|
||||
Draw2D(&canvas->Drawer, *screen->RenderState(), 0, 0, canvas->Tex->GetWidth(), canvas->Tex->GetHeight());
|
||||
Draw2D(&canvas->Drawer, *screen->RenderState(0), 0, 0, canvas->Tex->GetWidth(), canvas->Tex->GetHeight());
|
||||
canvas->Drawer.Clear();
|
||||
});
|
||||
canvas->Tex->SetUpdated(true);
|
||||
|
|
|
@ -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(), -1);
|
||||
FModelRenderer* renderer = new FHWModelRenderer(nullptr, *screen->RenderState(0), -1);
|
||||
for (unsigned i = 0; i < Models.Size(); i++)
|
||||
{
|
||||
if (modellist[i])
|
||||
|
|
|
@ -106,7 +106,7 @@ void HWDrawInfo::WorkerThread()
|
|||
{
|
||||
sector_t *front, *back;
|
||||
|
||||
FRenderState& state = *screen->RenderState();
|
||||
FRenderState& state = *screen->RenderState(0);
|
||||
|
||||
WTTotal.Clock();
|
||||
isWorkerThread = true; // for adding asserts in GL API code. The worker thread may never call any GL API.
|
||||
|
|
Loading…
Reference in a new issue