GPUDevice: Move empty/null texture to base class

This commit is contained in:
Stenzek 2025-01-18 15:02:56 +10:00
parent 609fa5c7d7
commit 338d29d271
No known key found for this signature in database
4 changed files with 33 additions and 21 deletions

View File

@ -650,6 +650,16 @@ bool GPUDevice::GetPipelineCacheData(DynamicHeapArray<u8>* data, Error* error)
bool GPUDevice::CreateResources(Error* error)
{
// Backend may initialize null texture itself if it needs it.
if (!m_empty_texture &&
!(m_empty_texture = CreateTexture(1, 1, 1, 1, 1, GPUTexture::Type::Texture, GPUTexture::Format::RGBA8,
GPUTexture::Flags::None, nullptr, 0, error)))
{
Error::AddPrefix(error, "Failed to create null texture: ");
return false;
}
GL_OBJECT_NAME(m_empty_texture, "Null Texture");
if (!(m_nearest_sampler = GetSampler(GPUSampler::GetNearestConfig(), error)) ||
!(m_linear_sampler = GetSampler(GPUSampler::GetLinearConfig(), error)))
{
@ -714,6 +724,8 @@ bool GPUDevice::CreateResources(Error* error)
void GPUDevice::DestroyResources()
{
m_empty_texture.reset();
m_imgui_font_texture.reset();
m_imgui_pipeline.reset();

View File

@ -716,6 +716,7 @@ public:
ALWAYS_INLINE GPUSwapChain* GetMainSwapChain() const { return m_main_swap_chain.get(); }
ALWAYS_INLINE bool HasMainSwapChain() const { return static_cast<bool>(m_main_swap_chain); }
ALWAYS_INLINE GPUTexture* GetEmptyTexture() const { return m_empty_texture.get(); }
ALWAYS_INLINE GPUSampler* GetLinearSampler() const { return m_linear_sampler; }
ALWAYS_INLINE GPUSampler* GetNearestSampler() const { return m_nearest_sampler; }
@ -920,12 +921,12 @@ protected:
u32 m_max_multisamples = 0;
std::unique_ptr<GPUSwapChain> m_main_swap_chain;
std::unique_ptr<GPUTexture> m_empty_texture;
GPUSampler* m_nearest_sampler = nullptr;
GPUSampler* m_linear_sampler = nullptr;
GPUShaderCache m_shader_cache;
private:
static constexpr u32 MAX_TEXTURE_POOL_SIZE = 125;
static constexpr u32 MAX_TARGET_POOL_SIZE = 50;
@ -986,7 +987,6 @@ private:
size_t m_pool_vram_usage = 0;
u32 m_texture_pool_counter = 0;
protected:
static Statistics s_stats;

View File

@ -2060,11 +2060,6 @@ void VulkanDevice::DestroyDevice()
m_main_swap_chain.reset();
}
if (m_null_texture)
{
m_null_texture->Destroy(false);
m_null_texture.reset();
}
for (auto& it : m_cleanup_objects)
it.second();
m_cleanup_objects.clear();
@ -2777,9 +2772,10 @@ void VulkanDevice::UnmapUniformBuffer(u32 size)
bool VulkanDevice::CreateNullTexture(Error* error)
{
m_null_texture = VulkanTexture::Create(1, 1, 1, 1, 1, GPUTexture::Type::Texture, GPUTexture::Format::RGBA8,
GPUTexture::Flags::AllowBindAsImage, VK_FORMAT_R8G8B8A8_UNORM, error);
if (!m_null_texture)
std::unique_ptr<VulkanTexture> null_texture =
VulkanTexture::Create(1, 1, 1, 1, 1, GPUTexture::Type::Texture, GPUTexture::Format::RGBA8,
GPUTexture::Flags::AllowBindAsImage, VK_FORMAT_R8G8B8A8_UNORM, error);
if (!null_texture)
{
Error::AddPrefix(error, "Failed to create null texture: ");
return false;
@ -2788,11 +2784,12 @@ bool VulkanDevice::CreateNullTexture(Error* error)
const VkCommandBuffer cmdbuf = GetCurrentCommandBuffer();
const VkImageSubresourceRange srr{VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u};
const VkClearColorValue ccv{};
m_null_texture->TransitionToLayout(cmdbuf, VulkanTexture::Layout::ClearDst);
vkCmdClearColorImage(cmdbuf, m_null_texture->GetImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &ccv, 1, &srr);
m_null_texture->TransitionToLayout(cmdbuf, VulkanTexture::Layout::General);
Vulkan::SetObjectName(m_device, m_null_texture->GetImage(), "Null texture");
Vulkan::SetObjectName(m_device, m_null_texture->GetView(), "Null texture view");
null_texture->TransitionToLayout(cmdbuf, VulkanTexture::Layout::ClearDst);
vkCmdClearColorImage(cmdbuf, null_texture->GetImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &ccv, 1, &srr);
null_texture->TransitionToLayout(cmdbuf, VulkanTexture::Layout::General);
Vulkan::SetObjectName(m_device, null_texture->GetImage(), "Null texture");
Vulkan::SetObjectName(m_device, null_texture->GetView(), "Null texture view");
m_empty_texture = std::move(null_texture);
// Bind null texture and point sampler state to all.
GPUSampler* point_sampler = GetSampler(GPUSampler::GetNearestConfig(), error);
@ -3782,7 +3779,8 @@ bool VulkanDevice::UpdateDescriptorSetsForLayout(u32 dirty)
layout == GPUPipeline::Layout::SingleTextureAndPushConstants ||
layout == GPUPipeline::Layout::ComputeSingleTextureAndPushConstants)
{
VulkanTexture* const tex = m_current_textures[0] ? m_current_textures[0] : m_null_texture.get();
VulkanTexture* const tex =
m_current_textures[0] ? m_current_textures[0] : static_cast<VulkanTexture*>(m_empty_texture.get());
DebugAssert(tex && m_current_samplers[0] != VK_NULL_HANDLE);
ds[num_ds++] = tex->GetDescriptorSetWithSampler(m_current_samplers[0]);
}
@ -3800,7 +3798,8 @@ bool VulkanDevice::UpdateDescriptorSetsForLayout(u32 dirty)
{
for (u32 i = 0; i < MAX_TEXTURE_SAMPLERS; i++)
{
VulkanTexture* const tex = m_current_textures[i] ? m_current_textures[i] : m_null_texture.get();
VulkanTexture* const tex =
m_current_textures[i] ? m_current_textures[i] : static_cast<VulkanTexture*>(m_empty_texture.get());
DebugAssert(tex && m_current_samplers[i] != VK_NULL_HANDLE);
dsub.AddCombinedImageSamplerDescriptorWrite(VK_NULL_HANDLE, i, tex->GetView(), m_current_samplers[i],
tex->GetVkLayout());
@ -3821,7 +3820,8 @@ bool VulkanDevice::UpdateDescriptorSetsForLayout(u32 dirty)
for (u32 i = 0; i < MAX_TEXTURE_SAMPLERS; i++)
{
VulkanTexture* const tex = m_current_textures[i] ? m_current_textures[i] : m_null_texture.get();
VulkanTexture* const tex =
m_current_textures[i] ? m_current_textures[i] : static_cast<VulkanTexture*>(m_empty_texture.get());
DebugAssert(tex && m_current_samplers[i] != VK_NULL_HANDLE);
dsub.AddCombinedImageSamplerDescriptorWrite(tds, i, tex->GetView(), m_current_samplers[i], tex->GetVkLayout());
}
@ -3851,8 +3851,10 @@ bool VulkanDevice::UpdateDescriptorSetsForLayout(u32 dirty)
}
// Annoyingly, have to update all slots...
const VkImageView null_view = static_cast<VulkanTexture*>(m_empty_texture.get())->GetView();
const VkImageLayout null_layout = static_cast<VulkanTexture*>(m_empty_texture.get())->GetVkLayout();
for (u32 i = m_num_current_render_targets; i < MAX_IMAGE_RENDER_TARGETS; i++)
dsub.AddStorageImageDescriptorWrite(ids, i, m_null_texture->GetView(), m_null_texture->GetVkLayout());
dsub.AddStorageImageDescriptorWrite(ids, i, null_view, null_layout);
dsub.Update(m_device, false);
}

View File

@ -435,8 +435,6 @@ private:
OptionalExtensions m_optional_extensions = {};
std::optional<bool> m_exclusive_fullscreen_control;
std::unique_ptr<VulkanTexture> m_null_texture;
VkDescriptorSetLayout m_ubo_ds_layout = VK_NULL_HANDLE;
VkDescriptorSetLayout m_single_texture_ds_layout = VK_NULL_HANDLE;
VkDescriptorSetLayout m_single_texture_buffer_ds_layout = VK_NULL_HANDLE;