Revert "Font: make atlas uploads queue-aware on Vulkan"

This reverts commit 256dff7fd4.
This commit is contained in:
Vladislav Belov 2025-09-17 12:32:08 +02:00
parent 5be2d7d9ed
commit e2d9450d0d
No known key found for this signature in database
GPG key ID: 353545E45DB9CCB3
16 changed files with 34 additions and 90 deletions

View file

@ -289,7 +289,7 @@ bool CFont::ConstructTextureAtlas()
Renderer::Backend::ITexture::Usage::TRANSFER_DST |
Renderer::Backend::ITexture::Usage::SAMPLED,
m_TextureFormat,
textureSize, textureSize, defaultSamplerDesc, 1, 1, true
textureSize, textureSize, defaultSamplerDesc
));
if (!m_Texture)
@ -298,6 +298,8 @@ bool CFont::ConstructTextureAtlas()
return false;
}
m_IsLoadingTextureToGPU = true;
// Initialise texture with transparency, for the areas we don't
// overwrite with uploading later.
m_TexData = std::make_unique<u8[]>(m_AtlasSize);
@ -492,7 +494,10 @@ std::optional<CVector2D> CFont::GenerateGlyphBitmap(FT_Glyph& glyph, u16 codepoi
void CFont::UploadTextureAtlasToGPU()
{
if (m_Texture->GetBackendTexture()->IsPendingQueueSubmit() || !m_IsDirty)
if (std::exchange(m_IsLoadingTextureToGPU, false))
return;
if (!m_IsDirty)
return;
Renderer::Backend::IDeviceCommandContext* deviceCommandContext = g_Renderer.GetDeviceCommandContext();

View file

@ -162,6 +162,7 @@ private:
int m_AtlasPadding;
bool m_IsDirty{false};
bool m_IsLoadingTextureToGPU{false};
float m_StrokeWidth{0.0f};
float m_Scale{1.0f};

View file

@ -114,12 +114,12 @@ public:
virtual std::unique_ptr<ITexture> CreateTexture(
const char* name, const ITexture::Type type, const uint32_t usage,
const Format format, const uint32_t width, const uint32_t height,
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount, const uint32_t sampleCount, const bool queueSubmitAware = false) = 0;
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount, const uint32_t sampleCount) = 0;
virtual std::unique_ptr<ITexture> CreateTexture2D(
const char* name, const uint32_t usage,
const Format format, const uint32_t width, const uint32_t height,
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount = 1, const uint32_t sampleCount = 1, const bool queueSubmitAware = false) = 0;
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount = 1, const uint32_t sampleCount = 1) = 0;
/**
* @see IFramebuffer

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games.
/* Copyright (C) 2024 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -58,8 +58,6 @@ public:
virtual uint32_t GetWidth() const = 0;
virtual uint32_t GetHeight() const = 0;
virtual uint32_t GetMIPLevelCount() const = 0;
virtual bool IsPendingQueueSubmit() const = 0;
};
} // namespace Backend

View file

@ -98,7 +98,7 @@ std::unique_ptr<ITexture> CDevice::CreateTexture(
const char* /*name*/, const CTexture::Type type, const uint32_t usage,
const Format format, const uint32_t width, const uint32_t height,
const Sampler::Desc& /*defaultSamplerDesc*/, const uint32_t MIPLevelCount,
const uint32_t /*sampleCount*/, const bool /*queueSubmitAware*/)
const uint32_t /*sampleCount*/)
{
return CTexture::Create(this, type, usage, format, width, height, MIPLevelCount);
}
@ -106,10 +106,10 @@ std::unique_ptr<ITexture> CDevice::CreateTexture(
std::unique_ptr<ITexture> CDevice::CreateTexture2D(
const char* name, const uint32_t usage,
const Format format, const uint32_t width, const uint32_t height,
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount, const uint32_t sampleCount, const bool queueSubmitAware)
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount, const uint32_t sampleCount)
{
return CreateTexture(name, ITexture::Type::TEXTURE_2D, usage,
format, width, height, defaultSamplerDesc, MIPLevelCount, sampleCount, queueSubmitAware);
format, width, height, defaultSamplerDesc, MIPLevelCount, sampleCount);
}
std::unique_ptr<IFramebuffer> CDevice::CreateFramebuffer(

View file

@ -71,12 +71,12 @@ public:
std::unique_ptr<ITexture> CreateTexture(
const char* name, const ITexture::Type type, const uint32_t usage,
const Format format, const uint32_t width, const uint32_t height,
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount, const uint32_t sampleCount, const bool queueSubmitAware = false) override;
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount, const uint32_t sampleCount) override;
std::unique_ptr<ITexture> CreateTexture2D(
const char* name, const uint32_t usage,
const Format format, const uint32_t width, const uint32_t height,
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount = 1, const uint32_t sampleCount = 1, const bool queueSubmitAware = false) override;
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount = 1, const uint32_t sampleCount = 1) override;
std::unique_ptr<IFramebuffer> CreateFramebuffer(
const char* name, SColorAttachment* colorAttachment,

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games.
/* Copyright (C) 2022 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -51,9 +51,6 @@ public:
uint32_t GetHeight() const override { return m_Height; }
uint32_t GetMIPLevelCount() const override { return m_MIPLevelCount; }
// Dummy backend does not support queue submission.
bool IsPendingQueueSubmit() const override { return false; }
private:
friend class CDevice;

View file

@ -926,7 +926,7 @@ std::unique_ptr<IVertexInputLayout> CDevice::CreateVertexInputLayout(
std::unique_ptr<ITexture> CDevice::CreateTexture(
const char* name, const ITexture::Type type, const uint32_t usage,
const Format format, const uint32_t width, const uint32_t height,
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount, const uint32_t sampleCount, const bool /*queueSubmitAware*/)
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount, const uint32_t sampleCount)
{
return CTexture::Create(this, name, type, usage,
format, width, height, defaultSamplerDesc, MIPLevelCount, sampleCount);
@ -935,10 +935,10 @@ std::unique_ptr<ITexture> CDevice::CreateTexture(
std::unique_ptr<ITexture> CDevice::CreateTexture2D(
const char* name, const uint32_t usage,
const Format format, const uint32_t width, const uint32_t height,
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount, const uint32_t sampleCount, const bool queueSubmitAware)
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount, const uint32_t sampleCount)
{
return CreateTexture(name, CTexture::Type::TEXTURE_2D, usage,
format, width, height, defaultSamplerDesc, MIPLevelCount, sampleCount, queueSubmitAware);
format, width, height, defaultSamplerDesc, MIPLevelCount, sampleCount);
}
std::unique_ptr<IFramebuffer> CDevice::CreateFramebuffer(

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games.
/* Copyright (C) 2024 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -87,12 +87,12 @@ public:
std::unique_ptr<ITexture> CreateTexture(
const char* name, const ITexture::Type type, const uint32_t usage,
const Format format, const uint32_t width, const uint32_t height,
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount, const uint32_t sampleCount, const bool queueSubmitAware) override;
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount, const uint32_t sampleCount) override;
std::unique_ptr<ITexture> CreateTexture2D(
const char* name, const uint32_t usage,
const Format format, const uint32_t width, const uint32_t height,
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount = 1, const uint32_t sampleCount = 1, const bool queueSubmitAware = false) override;
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount = 1, const uint32_t sampleCount = 1) override;
std::unique_ptr<IFramebuffer> CreateFramebuffer(
const char* name, SColorAttachment* colorAttachment,

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games.
/* Copyright (C) 2022 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -58,8 +58,6 @@ public:
GLuint GetHandle() const { return m_Handle; }
// GL doesn's support queue submmit, so we don't need to track pending.
bool IsPendingQueueSubmit() const override { return false; }
private:
friend class CDevice;

View file

@ -681,7 +681,6 @@ CDevice::~CDevice()
if (m_QueryPool)
vkDestroyQueryPool(GetVkDevice(), m_QueryPool, nullptr);
ProcessTextureUploadWatchQueue(true);
ProcessDeviceObjectToDestroyQueue(true);
m_RenderPassManager.reset();
@ -754,21 +753,21 @@ std::unique_ptr<IVertexInputLayout> CDevice::CreateVertexInputLayout(
std::unique_ptr<ITexture> CDevice::CreateTexture(
const char* name, const ITexture::Type type, const uint32_t usage,
const Format format, const uint32_t width, const uint32_t height,
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount, const uint32_t sampleCount, const bool queueSubmitAware)
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount, const uint32_t sampleCount)
{
return CTexture::Create(
this, name, type, usage, format, width, height,
defaultSamplerDesc, MIPLevelCount, sampleCount, queueSubmitAware);
defaultSamplerDesc, MIPLevelCount, sampleCount);
}
std::unique_ptr<ITexture> CDevice::CreateTexture2D(
const char* name, const uint32_t usage,
const Format format, const uint32_t width, const uint32_t height,
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount, const uint32_t sampleCount, const bool queueSubmitAware)
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount, const uint32_t sampleCount)
{
return CreateTexture(
name, ITexture::Type::TEXTURE_2D, usage, format,
width, height, defaultSamplerDesc, MIPLevelCount, sampleCount, queueSubmitAware);
width, height, defaultSamplerDesc, MIPLevelCount, sampleCount);
}
std::unique_ptr<IFramebuffer> CDevice::CreateFramebuffer(
@ -837,7 +836,6 @@ void CDevice::Present()
m_SubmitScheduler->Present(*m_SwapChain);
ProcessTextureUploadWatchQueue();
ProcessObjectToDestroyQueue();
ProcessDeviceObjectToDestroyQueue();
@ -1018,10 +1016,6 @@ void CDevice::ScheduleBufferToDestroy(const DeviceObjectUID uid)
{
m_BufferToDestroyQueue.push({m_FrameID, uid});
}
void CDevice::ScheduleTextureUploadWatch(CTexture* texture)
{
m_TextureUploadWatcherQueue.push({ m_FrameID, texture });
}
void CDevice::SetObjectName(VkObjectType type, const uint64_t handle, const char* name)
{
@ -1125,18 +1119,6 @@ void CDevice::ProcessDeviceObjectToDestroyQueue(const bool ignoreFrameID)
}
}
void CDevice::ProcessTextureUploadWatchQueue(const bool ignoreFrameID)
{
while (!m_TextureUploadWatcherQueue.empty() &&
(ignoreFrameID || m_TextureUploadWatcherQueue.front().first + NUMBER_OF_FRAMES_IN_FLIGHT < m_FrameID))
{
CTexture* texture = m_TextureUploadWatcherQueue.front().second;
if (texture)
texture->SetPendingQueueSubmit(false);
m_TextureUploadWatcherQueue.pop();
}
}
CTexture* CDevice::GetCurrentBackbufferTexture()
{
return IsSwapChainValid() ? m_SwapChain->GetCurrentBackbufferTexture() : nullptr;
@ -1169,11 +1151,6 @@ std::unique_ptr<IDevice> CreateDevice(SDL_Window* window)
return Vulkan::CDevice::Create(window);
}
uint32_t CDevice::GetCurrentSchedulerHandle() const
{
return m_SubmitScheduler ? m_SubmitScheduler->GetCurrentHandle() : CSubmitScheduler::INVALID_SUBMIT_HANDLE;
}
} // namespace Vulkan
} // namespace Backend

View file

@ -96,12 +96,12 @@ public:
std::unique_ptr<ITexture> CreateTexture(
const char* name, const ITexture::Type type, const uint32_t usage,
const Format format, const uint32_t width, const uint32_t height,
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount, const uint32_t sampleCount, const bool queueSubmitAware = false) override;
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount, const uint32_t sampleCount) override;
std::unique_ptr<ITexture> CreateTexture2D(
const char* name, const uint32_t usage,
const Format format, const uint32_t width, const uint32_t height,
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount = 1, const uint32_t sampleCount = 1, const bool queueSubmitAware = false) override;
const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount = 1, const uint32_t sampleCount = 1) override;
std::unique_ptr<IFramebuffer> CreateFramebuffer(
const char* name, SColorAttachment* colorAttachment,
@ -165,8 +165,6 @@ public:
void ScheduleBufferToDestroy(const DeviceObjectUID uid);
void ScheduleTextureUploadWatch(CTexture* texture);
void SetObjectName(VkObjectType type, const void* handle, const char* name)
{
SetObjectName(type, reinterpret_cast<uint64_t>(handle), name);
@ -190,8 +188,6 @@ public:
DeviceObjectUID GenerateNextDeviceObjectUID();
uint32_t GetCurrentSchedulerHandle() const;
private:
CDevice();
@ -199,7 +195,6 @@ private:
bool IsSwapChainValid();
void ProcessObjectToDestroyQueue(const bool ignoreFrameID = false);
void ProcessDeviceObjectToDestroyQueue(const bool ignoreFrameID = false);
void ProcessTextureUploadWatchQueue(const bool ignoreFrameID = false);
bool IsFormatSupportedForUsage(const Format format, const uint32_t usage) const;
@ -250,7 +245,6 @@ private:
};
std::queue<ObjectToDestroy> m_ObjectToDestroyQueue;
std::queue<std::pair<uint32_t, DeviceObjectUID>> m_TextureToDestroyQueue;
std::queue<std::pair<uint32_t, CTexture*>> m_TextureUploadWatcherQueue;
std::queue<std::pair<uint32_t, DeviceObjectUID>> m_BufferToDestroyQueue;
std::unique_ptr<CRenderPassManager> m_RenderPassManager;

View file

@ -172,7 +172,6 @@ void CRingCommandContext::ScheduleUpload(
const uint32_t level, const uint32_t layer)
{
ENSURE(texture->GetType() != ITexture::Type::TEXTURE_2D_MULTISAMPLE);
const Format format = texture->GetFormat();
if (texture->GetType() != ITexture::Type::TEXTURE_CUBE)
ENSURE(layer == 0);
@ -232,7 +231,6 @@ void CRingCommandContext::ScheduleUpload(
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_PIPELINE_STAGE_TRANSFER_BIT, dstStageMask);
texture->SetInitialized();
texture->SetPendingQueueSubmit(true);
}
void CRingCommandContext::ScheduleUpload(

View file

@ -65,7 +65,6 @@ public:
void Flush();
SubmitHandle GetCurrentHandle() const { return m_CurrentHandle; };
private:
CSubmitScheduler(CDevice* device, VkQueue queue);

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games.
/* Copyright (C) 2024 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -28,8 +28,6 @@
#include "renderer/backend/vulkan/SamplerManager.h"
#include "renderer/backend/vulkan/Utilities.h"
#include <utility>
namespace Renderer
{
@ -44,7 +42,7 @@ std::unique_ptr<CTexture> CTexture::Create(
CDevice* device, const char* name, const Type type, const uint32_t usage,
const Format format, const uint32_t width, const uint32_t height,
const Sampler::Desc& defaultSamplerDesc,
const uint32_t MIPLevelCount, const uint32_t sampleCount, const bool queueSubmitAware)
const uint32_t MIPLevelCount, const uint32_t sampleCount)
{
std::unique_ptr<CTexture> texture(new CTexture(device));
@ -56,7 +54,6 @@ std::unique_ptr<CTexture> CTexture::Create(
texture->m_MIPLevelCount = MIPLevelCount;
texture->m_SampleCount = sampleCount;
texture->m_LayerCount = type == ITexture::Type::TEXTURE_CUBE ? 6 : 1;
texture->m_QueueSubmitAware = queueSubmitAware;
if (type == Type::TEXTURE_2D_MULTISAMPLE)
ENSURE(sampleCount > 1);
@ -383,15 +380,6 @@ CTexture::~CTexture()
m_Device->ScheduleTextureToDestroy(m_UID);
}
void CTexture::SetPendingQueueSubmit(bool pending)
{
if (!m_QueueSubmitAware)
return;
if (!std::exchange(m_PendingQueueSubmit, pending) && pending)
m_Device->ScheduleTextureUploadWatch(this);
}
IDevice* CTexture::GetDevice()
{
return m_Device;

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games.
/* Copyright (C) 2023 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -56,9 +56,6 @@ public:
uint32_t GetSampleCount() const { return m_SampleCount; }
uint32_t GetLayerCount() const { return m_LayerCount; }
bool IsPendingQueueSubmit() const override { return m_PendingQueueSubmit; }
void SetPendingQueueSubmit(bool pending);
VkImage GetImage() { return m_Image; }
VkImageView GetAttachmentImageView() { return m_AttachmentImageView; }
VkImageView GetSamplerImageView() { return m_SamplerImageView; }
@ -91,7 +88,7 @@ private:
CDevice* device, const char* name, const Type type, const uint32_t usage,
const Format format, const uint32_t width, const uint32_t height,
const Sampler::Desc& defaultSamplerDesc,
const uint32_t MIPLevelCount, const uint32_t sampleCount, const bool queueSubmitAware = false);
const uint32_t MIPLevelCount, const uint32_t sampleCount);
static std::unique_ptr<CTexture> WrapBackbufferImage(
CDevice* device, const char* name, const VkImage image, const VkFormat format,
@ -133,14 +130,6 @@ private:
// It's safe to store the current state while we use a single device command
// context.
bool m_Initialized = false;
// We store a flag to indicate that the texture is in Queue submit.
bool m_PendingQueueSubmit = false;
// If true, the texture is aware of queue submission useful for
// for dynamic textures that are updated frequently and needs to wait for
// the queue submission to finish before overwriting the texture data.
bool m_QueueSubmitAware = false;
};
} // namespace Vulkan