vk: make default render target independent of call order (#9065)

This commit is contained in:
Powei Feng
2025-08-11 13:27:53 -07:00
committed by GitHub
parent c21f211a13
commit bc83ffdcd1
2 changed files with 27 additions and 3 deletions

View File

@@ -206,6 +206,11 @@ VulkanDriver::VulkanDriver(VulkanPlatform* platform, VulkanContext& context,
: mPlatform(platform),
mResourceManager(driverConfig.handleArenaSize, driverConfig.disableHandleUseAfterFreeCheck,
driverConfig.disableHeapHandleTags),
// Note that we always create the default rendertarget before createDefaultRenderTarget(). We
// swap the content later when createDefaultRenderTarget() is called. This frees
// createDefaultRenderTarget() from being ordered with makeCurrent().
mDefaultRenderTarget(
fvkmemory::resource_ptr<VulkanRenderTarget>::construct(&mResourceManager)),
mAllocator(createAllocator(mPlatform->getInstance(), mPlatform->getPhysicalDevice(),
mPlatform->getDevice())),
mContext(context),
@@ -698,8 +703,11 @@ void VulkanDriver::destroyProgram(Handle<HwProgram> ph) {
}
void VulkanDriver::createDefaultRenderTargetR(Handle<HwRenderTarget> rth, int) {
assert_invariant(!mDefaultRenderTarget);
auto renderTarget = resource_ptr<VulkanRenderTarget>::make(&mResourceManager, rth);
assert_invariant(mDefaultRenderTarget); // Default render target should already exist.
auto renderTarget = resource_ptr<VulkanRenderTarget>::make(&mResourceManager, rth,
std::move(std::move(*mDefaultRenderTarget.get())));
mDefaultRenderTarget = renderTarget;
}
@@ -775,6 +783,7 @@ void VulkanDriver::destroyRenderTarget(Handle<HwRenderTarget> rth) {
auto rt = resource_ptr<VulkanRenderTarget>::cast(&mResourceManager, rth);
if (UTILS_UNLIKELY(rt == mDefaultRenderTarget)) {
// Note that this should only happen on driver shutdown.
mDefaultRenderTarget = {};
} else {
rt.dec();

View File

@@ -308,6 +308,15 @@ struct VulkanRenderTarget : private HwRenderTarget, fvkmemory::Resource {
// Creates a special "default" render target (i.e. associated with the swap chain)
explicit VulkanRenderTarget();
VulkanRenderTarget(VulkanRenderTarget&& target) {
swap(std::move(target));
}
VulkanRenderTarget& operator=(VulkanRenderTarget&& target) {
swap(std::move(target));
return *this;
}
void transformClientRectToPlatform(VkRect2D* bounds) const;
void transformViewportToPlatform(VkViewport* bounds) const;
@@ -355,6 +364,12 @@ struct VulkanRenderTarget : private HwRenderTarget, fvkmemory::Resource {
void emitBarriersEndRenderPass(VulkanCommandBuffer& commands);
private:
void swap(VulkanRenderTarget&& target) {
std::swap(mOffscreen, target.mOffscreen);
std::swap(mProtected, target.mProtected);
std::swap(mInfo, target.mInfo);
}
struct Auxiliary {
static constexpr int8_t UNDEFINED_INDEX = -1;
@@ -368,7 +383,7 @@ private:
int8_t msaaDepthIndex = UNDEFINED_INDEX;
int8_t msaaIndex = UNDEFINED_INDEX;
};
bool const mOffscreen;
bool mOffscreen;
bool mProtected;
std::unique_ptr<Auxiliary> mInfo;