Make sure the renderpass cache hashmap is never accessed from the main thread at runtime. Should help #10811

This commit is contained in:
Henrik Rydgård 2018-03-27 14:44:51 +02:00
parent 29de4b5a18
commit d125fa00e1
5 changed files with 23 additions and 10 deletions

View File

@ -304,6 +304,7 @@ private:
state.clear();
int oldCount = count_;
int oldCapacity = capacity_;
capacity_ *= factor;
map.resize(capacity_);
state.resize(capacity_);
@ -314,6 +315,7 @@ private:
Insert(old[i].hash, old[i].value);
}
}
ILOG("Grew hashmap capacity from %d to %d", oldCapacity, capacity_);
_assert_msg_(SYSTEM, oldCount == count_, "PrehashMap: count should not change in Grow()");
}
struct Pair {

View File

@ -8,6 +8,9 @@ void VulkanQueueRunner::CreateDeviceObjects() {
ILOG("VulkanQueueRunner::CreateDeviceObjects");
InitBackbufferRenderPass();
framebufferRenderPass_ = GetRenderPass(VKRRenderPassAction::CLEAR, VKRRenderPassAction::CLEAR, VKRRenderPassAction::CLEAR,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
#if 0
// Just to check whether it makes sense to split some of these. drawidx is way bigger than the others...
// We should probably just move to variable-size data in a raw buffer anyway...
@ -340,6 +343,7 @@ VkRenderPass VulkanQueueRunner::GetRenderPass(VKRRenderPassAction colorLoadActio
VkResult res = vkCreateRenderPass(vulkan_->GetDevice(), &rp, nullptr, &pass);
_assert_(res == VK_SUCCESS);
_assert_(pass != VK_NULL_HANDLE);
renderPasses_.Insert(key, pass);
return pass;
}

View File

@ -161,8 +161,12 @@ public:
VkRenderPass GetBackbufferRenderPass() const {
return backbufferRenderPass_;
}
VkRenderPass GetRenderPass(VKRRenderPassAction colorLoadAction, VKRRenderPassAction depthLoadAction, VKRRenderPassAction stencilLoadAction,
VkImageLayout prevColorLayout, VkImageLayout prevDepthLayout, VkImageLayout finalColorLayout);
// Get a render pass that's compatible with all our framebuffers.
// Note that it's precached, cannot look up in the map as this might be on another thread.
VkRenderPass GetFramebufferRenderPass() const {
return framebufferRenderPass_;
}
inline int RPIndex(VKRRenderPassAction color, VKRRenderPassAction depth) {
return (int)depth * 3 + (int)color;
@ -171,6 +175,10 @@ public:
void CopyReadbackBuffer(int width, int height, Draw::DataFormat srcFormat, Draw::DataFormat destFormat, int pixelStride, uint8_t *pixels);
private:
// Only call this from the render thread!
VkRenderPass GetRenderPass(VKRRenderPassAction colorLoadAction, VKRRenderPassAction depthLoadAction, VKRRenderPassAction stencilLoadAction,
VkImageLayout prevColorLayout, VkImageLayout prevDepthLayout, VkImageLayout finalColorLayout);
void InitBackbufferRenderPass();
void PerformBindFramebufferAsRenderTarget(const VKRStep &pass, VkCommandBuffer cmd);
@ -198,6 +206,7 @@ private:
VkFramebuffer curFramebuffer_ = VK_NULL_HANDLE;
VkRenderPass backbufferRenderPass_ = VK_NULL_HANDLE;
VkRenderPass framebufferRenderPass_ = VK_NULL_HANDLE;
struct RPKey {
VKRRenderPassAction colorAction;

View File

@ -205,17 +205,15 @@ public:
VkCommandBuffer GetInitCmd();
VkRenderPass GetRenderPass(VKRRenderPassAction colorLoadAction, VKRRenderPassAction depthLoadAction, VKRRenderPassAction stencilLoadAction) {
return queueRunner_.GetRenderPass(colorLoadAction, depthLoadAction, stencilLoadAction,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
}
VkRenderPass GetBackbufferRenderPass() {
return queueRunner_.GetBackbufferRenderPass();
}
VkRenderPass GetFramebufferRenderPass() {
return queueRunner_.GetFramebufferRenderPass();
}
VkRenderPass GetCompatibleRenderPass() {
if (curRenderStep_ && curRenderStep_->render.framebuffer != nullptr) {
return queueRunner_.GetRenderPass(VKRRenderPassAction::CLEAR, VKRRenderPassAction::CLEAR, VKRRenderPassAction::CLEAR,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
return queueRunner_.GetFramebufferRenderPass();
} else {
return queueRunner_.GetBackbufferRenderPass();
}

View File

@ -460,7 +460,7 @@ public:
switch (obj) {
case NativeObject::FRAMEBUFFER_RENDERPASS:
// Return a representative renderpass.
return (uintptr_t)renderManager_.GetRenderPass(VKRRenderPassAction::CLEAR, VKRRenderPassAction::CLEAR, VKRRenderPassAction::CLEAR);
return (uintptr_t)renderManager_.GetFramebufferRenderPass();
case NativeObject::BACKBUFFER_RENDERPASS:
return (uintptr_t)renderManager_.GetBackbufferRenderPass();
case NativeObject::COMPATIBLE_RENDERPASS:
@ -1316,7 +1316,7 @@ private:
Framebuffer *VKContext::CreateFramebuffer(const FramebufferDesc &desc) {
VkCommandBuffer cmd = renderManager_.GetInitCmd();
VKRFramebuffer *vkrfb = new VKRFramebuffer(vulkan_, cmd, renderManager_.GetRenderPass(VKRRenderPassAction::CLEAR, VKRRenderPassAction::CLEAR, VKRRenderPassAction::CLEAR), desc.width, desc.height);
VKRFramebuffer *vkrfb = new VKRFramebuffer(vulkan_, cmd, renderManager_.GetFramebufferRenderPass(), desc.width, desc.height);
return new VKFramebuffer(vkrfb);
}