mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-02 22:28:45 +00:00
video_core: added rebinding of changed textures after overlap resolve
This commit is contained in:
parent
3d2ea32dae
commit
e1a7c737d8
9 changed files with 150 additions and 100 deletions
|
@ -579,6 +579,8 @@ set(VIDEO_CORE src/video_core/amdgpu/liverpool.cpp
|
||||||
src/video_core/renderer_vulkan/vk_master_semaphore.h
|
src/video_core/renderer_vulkan/vk_master_semaphore.h
|
||||||
src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
|
src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
|
||||||
src/video_core/renderer_vulkan/vk_pipeline_cache.h
|
src/video_core/renderer_vulkan/vk_pipeline_cache.h
|
||||||
|
src/video_core/renderer_vulkan/vk_pipeline_common.cpp
|
||||||
|
src/video_core/renderer_vulkan/vk_pipeline_common.h
|
||||||
src/video_core/renderer_vulkan/vk_platform.cpp
|
src/video_core/renderer_vulkan/vk_platform.cpp
|
||||||
src/video_core/renderer_vulkan/vk_platform.h
|
src/video_core/renderer_vulkan/vk_platform.h
|
||||||
src/video_core/renderer_vulkan/vk_rasterizer.cpp
|
src/video_core/renderer_vulkan/vk_rasterizer.cpp
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
|
|
||||||
#include "common/alignment.h"
|
#include "common/alignment.h"
|
||||||
#include "video_core/buffer_cache/buffer_cache.h"
|
#include "video_core/buffer_cache/buffer_cache.h"
|
||||||
#include "video_core/renderer_vulkan/vk_compute_pipeline.h"
|
#include "video_core/renderer_vulkan/vk_compute_pipeline.h"
|
||||||
|
@ -15,7 +16,7 @@ ComputePipeline::ComputePipeline(const Instance& instance_, Scheduler& scheduler
|
||||||
DescriptorHeap& desc_heap_, vk::PipelineCache pipeline_cache,
|
DescriptorHeap& desc_heap_, vk::PipelineCache pipeline_cache,
|
||||||
u64 compute_key_, const Shader::Info& info_,
|
u64 compute_key_, const Shader::Info& info_,
|
||||||
vk::ShaderModule module)
|
vk::ShaderModule module)
|
||||||
: instance{instance_}, scheduler{scheduler_}, desc_heap{desc_heap_}, compute_key{compute_key_},
|
: Pipeline{instance_, scheduler_, desc_heap_, pipeline_cache}, compute_key{compute_key_},
|
||||||
info{&info_} {
|
info{&info_} {
|
||||||
const vk::PipelineShaderStageCreateInfo shader_ci = {
|
const vk::PipelineShaderStageCreateInfo shader_ci = {
|
||||||
.stage = vk::ShaderStageFlagBits::eCompute,
|
.stage = vk::ShaderStageFlagBits::eCompute,
|
||||||
|
@ -213,36 +214,8 @@ bool ComputePipeline::BindResources(VideoCore::BufferCache& buffer_cache,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& image_desc : info->images) {
|
BindTextures(texture_cache, *info, binding, set_writes);
|
||||||
const auto tsharp = image_desc.GetSharp(*info);
|
|
||||||
if (tsharp.GetDataFmt() != AmdGpu::DataFormat::FormatInvalid) {
|
|
||||||
VideoCore::ImageInfo image_info{tsharp, image_desc.is_depth};
|
|
||||||
VideoCore::ImageViewInfo view_info{tsharp, image_desc.is_storage};
|
|
||||||
const auto& image_view = texture_cache.FindTexture(image_info, view_info);
|
|
||||||
const auto& image = texture_cache.GetImage(image_view.image_id);
|
|
||||||
image_infos.emplace_back(VK_NULL_HANDLE, *image_view.image_view,
|
|
||||||
image.last_state.layout);
|
|
||||||
} else if (instance.IsNullDescriptorSupported()) {
|
|
||||||
image_infos.emplace_back(VK_NULL_HANDLE, VK_NULL_HANDLE, vk::ImageLayout::eGeneral);
|
|
||||||
} else {
|
|
||||||
auto& null_image = texture_cache.GetImageView(VideoCore::NULL_IMAGE_VIEW_ID);
|
|
||||||
image_infos.emplace_back(VK_NULL_HANDLE, *null_image.image_view,
|
|
||||||
vk::ImageLayout::eGeneral);
|
|
||||||
}
|
|
||||||
set_writes.push_back({
|
|
||||||
.dstSet = VK_NULL_HANDLE,
|
|
||||||
.dstBinding = binding++,
|
|
||||||
.dstArrayElement = 0,
|
|
||||||
.descriptorCount = 1,
|
|
||||||
.descriptorType = image_desc.is_storage ? vk::DescriptorType::eStorageImage
|
|
||||||
: vk::DescriptorType::eSampledImage,
|
|
||||||
.pImageInfo = &image_infos.back(),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (texture_cache.IsMeta(tsharp.Address())) {
|
|
||||||
LOG_WARNING(Render_Vulkan, "Unexpected metadata read by a CS shader (texture)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const auto& sampler : info->samplers) {
|
for (const auto& sampler : info->samplers) {
|
||||||
const auto ssharp = sampler.GetSharp(*info);
|
const auto ssharp = sampler.GetSharp(*info);
|
||||||
if (ssharp.force_degamma) {
|
if (ssharp.force_degamma) {
|
||||||
|
|
|
@ -3,9 +3,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <boost/container/small_vector.hpp>
|
|
||||||
#include "shader_recompiler/info.h"
|
|
||||||
#include "video_core/renderer_vulkan/vk_common.h"
|
#include "video_core/renderer_vulkan/vk_common.h"
|
||||||
|
#include "video_core/renderer_vulkan/vk_pipeline_common.h"
|
||||||
|
|
||||||
namespace VideoCore {
|
namespace VideoCore {
|
||||||
class BufferCache;
|
class BufferCache;
|
||||||
|
@ -18,27 +17,17 @@ class Instance;
|
||||||
class Scheduler;
|
class Scheduler;
|
||||||
class DescriptorHeap;
|
class DescriptorHeap;
|
||||||
|
|
||||||
class ComputePipeline {
|
class ComputePipeline : public Pipeline {
|
||||||
public:
|
public:
|
||||||
explicit ComputePipeline(const Instance& instance, Scheduler& scheduler,
|
ComputePipeline(const Instance& instance, Scheduler& scheduler, DescriptorHeap& desc_heap,
|
||||||
DescriptorHeap& desc_heap, vk::PipelineCache pipeline_cache,
|
vk::PipelineCache pipeline_cache, u64 compute_key, const Shader::Info& info,
|
||||||
u64 compute_key, const Shader::Info& info, vk::ShaderModule module);
|
vk::ShaderModule module);
|
||||||
~ComputePipeline();
|
~ComputePipeline();
|
||||||
|
|
||||||
[[nodiscard]] vk::Pipeline Handle() const noexcept {
|
|
||||||
return *pipeline;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BindResources(VideoCore::BufferCache& buffer_cache,
|
bool BindResources(VideoCore::BufferCache& buffer_cache,
|
||||||
VideoCore::TextureCache& texture_cache) const;
|
VideoCore::TextureCache& texture_cache) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Instance& instance;
|
|
||||||
Scheduler& scheduler;
|
|
||||||
DescriptorHeap& desc_heap;
|
|
||||||
vk::UniquePipeline pipeline;
|
|
||||||
vk::UniquePipelineLayout pipeline_layout;
|
|
||||||
vk::UniqueDescriptorSetLayout desc_layout;
|
|
||||||
u64 compute_key;
|
u64 compute_key;
|
||||||
const Shader::Info* info;
|
const Shader::Info* info;
|
||||||
bool uses_push_descriptors{};
|
bool uses_push_descriptors{};
|
||||||
|
|
|
@ -21,7 +21,7 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul
|
||||||
vk::PipelineCache pipeline_cache,
|
vk::PipelineCache pipeline_cache,
|
||||||
std::span<const Shader::Info*, MaxShaderStages> infos,
|
std::span<const Shader::Info*, MaxShaderStages> infos,
|
||||||
std::span<const vk::ShaderModule> modules)
|
std::span<const vk::ShaderModule> modules)
|
||||||
: instance{instance_}, scheduler{scheduler_}, desc_heap{desc_heap_}, key{key_} {
|
: Pipeline{instance_, scheduler_, desc_heap_, pipeline_cache}, key{key_} {
|
||||||
const vk::Device device = instance.GetDevice();
|
const vk::Device device = instance.GetDevice();
|
||||||
std::ranges::copy(infos, stages.begin());
|
std::ranges::copy(infos, stages.begin());
|
||||||
BuildDescSetLayout();
|
BuildDescSetLayout();
|
||||||
|
@ -444,45 +444,15 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::container::static_vector<AmdGpu::Image, 32> tsharps;
|
BindTextures(texture_cache, *stage, binding, set_writes);
|
||||||
for (const auto& image_desc : stage->images) {
|
|
||||||
const auto tsharp = image_desc.GetSharp(*stage);
|
|
||||||
if (tsharp.GetDataFmt() != AmdGpu::DataFormat::FormatInvalid) {
|
|
||||||
tsharps.emplace_back(tsharp);
|
|
||||||
VideoCore::ImageInfo image_info{tsharp, image_desc.is_depth};
|
|
||||||
VideoCore::ImageViewInfo view_info{tsharp, image_desc.is_storage};
|
|
||||||
const auto& image_view = texture_cache.FindTexture(image_info, view_info);
|
|
||||||
const auto& image = texture_cache.GetImage(image_view.image_id);
|
|
||||||
image_infos.emplace_back(VK_NULL_HANDLE, *image_view.image_view,
|
|
||||||
image.last_state.layout);
|
|
||||||
} else if (instance.IsNullDescriptorSupported()) {
|
|
||||||
image_infos.emplace_back(VK_NULL_HANDLE, VK_NULL_HANDLE, vk::ImageLayout::eGeneral);
|
|
||||||
} else {
|
|
||||||
auto& null_image = texture_cache.GetImageView(VideoCore::NULL_IMAGE_VIEW_ID);
|
|
||||||
image_infos.emplace_back(VK_NULL_HANDLE, *null_image.image_view,
|
|
||||||
vk::ImageLayout::eGeneral);
|
|
||||||
}
|
|
||||||
set_writes.push_back({
|
|
||||||
.dstSet = VK_NULL_HANDLE,
|
|
||||||
.dstBinding = binding++,
|
|
||||||
.dstArrayElement = 0,
|
|
||||||
.descriptorCount = 1,
|
|
||||||
.descriptorType = image_desc.is_storage ? vk::DescriptorType::eStorageImage
|
|
||||||
: vk::DescriptorType::eSampledImage,
|
|
||||||
.pImageInfo = &image_infos.back(),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (texture_cache.IsMeta(tsharp.Address())) {
|
|
||||||
LOG_WARNING(Render_Vulkan, "Unexpected metadata read by a PS shader (texture)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const auto& sampler : stage->samplers) {
|
for (const auto& sampler : stage->samplers) {
|
||||||
auto ssharp = sampler.GetSharp(*stage);
|
auto ssharp = sampler.GetSharp(*stage);
|
||||||
if (ssharp.force_degamma) {
|
if (ssharp.force_degamma) {
|
||||||
LOG_WARNING(Render_Vulkan, "Texture requires gamma correction");
|
LOG_WARNING(Render_Vulkan, "Texture requires gamma correction");
|
||||||
}
|
}
|
||||||
if (sampler.disable_aniso) {
|
if (sampler.disable_aniso) {
|
||||||
const auto& tsharp = tsharps[sampler.associated_image];
|
const auto& tsharp = stage->images[sampler.associated_image].GetSharp(*stage);
|
||||||
if (tsharp.base_level == 0 && tsharp.last_level == 0) {
|
if (tsharp.base_level == 0 && tsharp.last_level == 0) {
|
||||||
ssharp.max_aniso.Assign(AmdGpu::AnisoRatio::One);
|
ssharp.max_aniso.Assign(AmdGpu::AnisoRatio::One);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
#include "video_core/renderer_vulkan/liverpool_to_vk.h"
|
#include "video_core/renderer_vulkan/liverpool_to_vk.h"
|
||||||
#include "video_core/renderer_vulkan/vk_common.h"
|
#include "video_core/renderer_vulkan/vk_common.h"
|
||||||
#include "video_core/renderer_vulkan/vk_compute_pipeline.h"
|
#include "video_core/renderer_vulkan/vk_pipeline_common.h"
|
||||||
|
|
||||||
namespace VideoCore {
|
namespace VideoCore {
|
||||||
class BufferCache;
|
class BufferCache;
|
||||||
|
@ -50,26 +50,17 @@ struct GraphicsPipelineKey {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class GraphicsPipeline {
|
class GraphicsPipeline : public Pipeline {
|
||||||
public:
|
public:
|
||||||
explicit GraphicsPipeline(const Instance& instance, Scheduler& scheduler,
|
GraphicsPipeline(const Instance& instance, Scheduler& scheduler, DescriptorHeap& desc_heap,
|
||||||
DescriptorHeap& desc_heap, const GraphicsPipelineKey& key,
|
const GraphicsPipelineKey& key, vk::PipelineCache pipeline_cache,
|
||||||
vk::PipelineCache pipeline_cache,
|
std::span<const Shader::Info*, MaxShaderStages> stages,
|
||||||
std::span<const Shader::Info*, MaxShaderStages> stages,
|
std::span<const vk::ShaderModule> modules);
|
||||||
std::span<const vk::ShaderModule> modules);
|
|
||||||
~GraphicsPipeline();
|
~GraphicsPipeline();
|
||||||
|
|
||||||
void BindResources(const Liverpool::Regs& regs, VideoCore::BufferCache& buffer_cache,
|
void BindResources(const Liverpool::Regs& regs, VideoCore::BufferCache& buffer_cache,
|
||||||
VideoCore::TextureCache& texture_cache) const;
|
VideoCore::TextureCache& texture_cache) const;
|
||||||
|
|
||||||
vk::Pipeline Handle() const noexcept {
|
|
||||||
return *pipeline;
|
|
||||||
}
|
|
||||||
|
|
||||||
vk::PipelineLayout GetLayout() const {
|
|
||||||
return *pipeline_layout;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Shader::Info& GetStage(Shader::Stage stage) const noexcept {
|
const Shader::Info& GetStage(Shader::Stage stage) const noexcept {
|
||||||
return *stages[u32(stage)];
|
return *stages[u32(stage)];
|
||||||
}
|
}
|
||||||
|
@ -91,12 +82,6 @@ private:
|
||||||
void BuildDescSetLayout();
|
void BuildDescSetLayout();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Instance& instance;
|
|
||||||
Scheduler& scheduler;
|
|
||||||
DescriptorHeap& desc_heap;
|
|
||||||
vk::UniquePipeline pipeline;
|
|
||||||
vk::UniquePipelineLayout pipeline_layout;
|
|
||||||
vk::UniqueDescriptorSetLayout desc_layout;
|
|
||||||
std::array<const Shader::Info*, MaxShaderStages> stages{};
|
std::array<const Shader::Info*, MaxShaderStages> stages{};
|
||||||
GraphicsPipelineKey key;
|
GraphicsPipelineKey key;
|
||||||
bool uses_push_descriptors{};
|
bool uses_push_descriptors{};
|
||||||
|
|
78
src/video_core/renderer_vulkan/vk_pipeline_common.cpp
Normal file
78
src/video_core/renderer_vulkan/vk_pipeline_common.cpp
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <boost/container/static_vector.hpp>
|
||||||
|
|
||||||
|
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||||
|
#include "video_core/renderer_vulkan/vk_pipeline_common.h"
|
||||||
|
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
||||||
|
#include "video_core/texture_cache/texture_cache.h"
|
||||||
|
|
||||||
|
namespace Vulkan {
|
||||||
|
|
||||||
|
Pipeline::Pipeline(const Instance& instance_, Scheduler& scheduler_, DescriptorHeap& desc_heap_,
|
||||||
|
vk::PipelineCache pipeline_cache)
|
||||||
|
: instance{instance_}, scheduler{scheduler_}, desc_heap{desc_heap_} {}
|
||||||
|
|
||||||
|
Pipeline::~Pipeline() = default;
|
||||||
|
|
||||||
|
void Pipeline::BindTextures(VideoCore::TextureCache& texture_cache, const Shader::Info& stage,
|
||||||
|
u32& binding, DescriptorWrites& set_writes) const {
|
||||||
|
static boost::container::static_vector<vk::DescriptorImageInfo, 32> image_infos;
|
||||||
|
image_infos.clear();
|
||||||
|
|
||||||
|
using ImageBindingInfo = std::tuple<VideoCore::Image*, VideoCore::ImageView*, bool>;
|
||||||
|
boost::container::static_vector<ImageBindingInfo, 32> image_bindings;
|
||||||
|
|
||||||
|
for (const auto& image_desc : stage.images) {
|
||||||
|
const auto tsharp = image_desc.GetSharp(stage);
|
||||||
|
if (tsharp.GetDataFmt() != AmdGpu::DataFormat::FormatInvalid) {
|
||||||
|
VideoCore::ImageInfo image_info{tsharp, image_desc.is_depth};
|
||||||
|
VideoCore::ImageViewInfo view_info{tsharp, image_desc.is_storage};
|
||||||
|
auto& image_view = texture_cache.FindTexture(image_info, view_info);
|
||||||
|
auto& image = texture_cache.GetImage(image_view.image_id);
|
||||||
|
image.flags |= VideoCore::ImageFlagBits::Bound;
|
||||||
|
image_bindings.emplace_back(&image, &image_view, image_desc.is_storage);
|
||||||
|
} else {
|
||||||
|
image_bindings.emplace_back(nullptr, nullptr, image_desc.is_storage);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texture_cache.IsMeta(tsharp.Address())) {
|
||||||
|
LOG_WARNING(Render_Vulkan, "Unexpected metadata read by a PS shader (texture)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second pass to re-bind images that were updated after binding
|
||||||
|
for (auto& [image, image_view, is_storage] : image_bindings) {
|
||||||
|
if (!image || !image_view) {
|
||||||
|
if (instance.IsNullDescriptorSupported()) {
|
||||||
|
image_infos.emplace_back(VK_NULL_HANDLE, VK_NULL_HANDLE, vk::ImageLayout::eGeneral);
|
||||||
|
} else {
|
||||||
|
auto& null_image = texture_cache.GetImageView(VideoCore::NULL_IMAGE_VIEW_ID);
|
||||||
|
image_infos.emplace_back(VK_NULL_HANDLE, *null_image.image_view,
|
||||||
|
vk::ImageLayout::eGeneral);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
vk::ImageLayout layout = image->last_state.layout;
|
||||||
|
if (True(image->flags & VideoCore::ImageFlagBits::NeedsRebind)) {
|
||||||
|
image_view = &texture_cache.FindTexture(image->info, image_view->info);
|
||||||
|
layout = texture_cache.GetImage(image_view->image_id).last_state.layout;
|
||||||
|
}
|
||||||
|
image_infos.emplace_back(VK_NULL_HANDLE, *image_view->image_view, layout);
|
||||||
|
image->flags &=
|
||||||
|
~(VideoCore::ImageFlagBits::NeedsRebind | VideoCore::ImageFlagBits::Bound);
|
||||||
|
}
|
||||||
|
|
||||||
|
set_writes.push_back({
|
||||||
|
.dstSet = VK_NULL_HANDLE,
|
||||||
|
.dstBinding = binding++,
|
||||||
|
.dstArrayElement = 0,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.descriptorType =
|
||||||
|
is_storage ? vk::DescriptorType::eStorageImage : vk::DescriptorType::eSampledImage,
|
||||||
|
.pImageInfo = &image_infos.back(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Vulkan
|
47
src/video_core/renderer_vulkan/vk_pipeline_common.h
Normal file
47
src/video_core/renderer_vulkan/vk_pipeline_common.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "shader_recompiler/info.h"
|
||||||
|
#include "video_core/renderer_vulkan/vk_common.h"
|
||||||
|
|
||||||
|
namespace VideoCore {
|
||||||
|
class BufferCache;
|
||||||
|
class TextureCache;
|
||||||
|
} // namespace VideoCore
|
||||||
|
|
||||||
|
namespace Vulkan {
|
||||||
|
|
||||||
|
class Instance;
|
||||||
|
class Scheduler;
|
||||||
|
class DescriptorHeap;
|
||||||
|
|
||||||
|
class Pipeline {
|
||||||
|
public:
|
||||||
|
Pipeline(const Instance& instance, Scheduler& scheduler, DescriptorHeap& desc_heap,
|
||||||
|
vk::PipelineCache pipeline_cache);
|
||||||
|
virtual ~Pipeline();
|
||||||
|
|
||||||
|
vk::Pipeline Handle() const noexcept {
|
||||||
|
return *pipeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::PipelineLayout GetLayout() const noexcept {
|
||||||
|
return *pipeline_layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
using DescriptorWrites = boost::container::small_vector<vk::WriteDescriptorSet, 16>;
|
||||||
|
void BindTextures(VideoCore::TextureCache& texture_cache, const Shader::Info& stage,
|
||||||
|
u32& binding, DescriptorWrites& set_writes) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const Instance& instance;
|
||||||
|
Scheduler& scheduler;
|
||||||
|
DescriptorHeap& desc_heap;
|
||||||
|
vk::UniquePipeline pipeline;
|
||||||
|
vk::UniquePipelineLayout pipeline_layout;
|
||||||
|
vk::UniqueDescriptorSetLayout desc_layout;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Vulkan
|
|
@ -32,6 +32,8 @@ enum ImageFlagBits : u32 {
|
||||||
Registered = 1 << 6, ///< True when the image is registered
|
Registered = 1 << 6, ///< True when the image is registered
|
||||||
Picked = 1 << 7, ///< Temporary flag to mark the image as picked
|
Picked = 1 << 7, ///< Temporary flag to mark the image as picked
|
||||||
MetaRegistered = 1 << 8, ///< True when metadata for this surface is known and registered
|
MetaRegistered = 1 << 8, ///< True when metadata for this surface is known and registered
|
||||||
|
Bound = 1 << 9, ///< True when the image is bound to a descriptor set
|
||||||
|
NeedsRebind = 1 << 10, ///< True when the image needs to be rebound
|
||||||
};
|
};
|
||||||
DECLARE_ENUM_FLAG_OPERATORS(ImageFlagBits)
|
DECLARE_ENUM_FLAG_OPERATORS(ImageFlagBits)
|
||||||
|
|
||||||
|
|
|
@ -179,6 +179,10 @@ ImageId TextureCache::ExpandImage(const ImageInfo& info, ImageId image_id) {
|
||||||
src_image.Transit(vk::ImageLayout::eTransferSrcOptimal, vk::AccessFlagBits2::eTransferRead, {});
|
src_image.Transit(vk::ImageLayout::eTransferSrcOptimal, vk::AccessFlagBits2::eTransferRead, {});
|
||||||
new_image.CopyImage(src_image);
|
new_image.CopyImage(src_image);
|
||||||
|
|
||||||
|
if (True(src_image.flags & ImageFlagBits::Bound)) {
|
||||||
|
src_image.flags |= ImageFlagBits::NeedsRebind;
|
||||||
|
}
|
||||||
|
|
||||||
FreeImage(image_id);
|
FreeImage(image_id);
|
||||||
|
|
||||||
TrackImage(new_image_id);
|
TrackImage(new_image_id);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue