mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 22:29:39 -06:00
Merge pull request #11923 from iwubcode/multi-texture-compute-support
VideoBackends: support multiple compute images for some backends
This commit is contained in:
@ -157,8 +157,9 @@ VkDescriptorPool CommandBufferManager::CreateDescriptorPool(u32 max_descriptor_s
|
||||
const std::array<VkDescriptorPoolSize, 5> pool_sizes{{
|
||||
{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, max_descriptor_sets * 3},
|
||||
{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
max_descriptor_sets * (VideoCommon::MAX_PIXEL_SHADER_SAMPLERS + NUM_COMPUTE_SHADER_SAMPLERS +
|
||||
NUM_UTILITY_PIXEL_SAMPLERS)},
|
||||
max_descriptor_sets *
|
||||
(VideoCommon::MAX_PIXEL_SHADER_SAMPLERS + VideoCommon::MAX_COMPUTE_SHADER_SAMPLERS +
|
||||
NUM_UTILITY_PIXEL_SAMPLERS)},
|
||||
{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, max_descriptor_sets * 2},
|
||||
{VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, max_descriptor_sets * 3},
|
||||
{VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, max_descriptor_sets * 1},
|
||||
|
@ -49,9 +49,9 @@ enum DESCRIPTOR_SET_LAYOUT
|
||||
// - 1 texel buffer (accessible from PS) [set=1, binding=8]
|
||||
// - Compute
|
||||
// - 1 uniform buffer [set=0, binding=0]
|
||||
// - 2 combined image samplers [set=0, binding=1-2]
|
||||
// - 2 texel buffers [set=0, binding=3-4]
|
||||
// - 1 storage image [set=0, binding=5]
|
||||
// - 8 combined image samplers [set=0, binding=1-8]
|
||||
// - 2 texel buffers [set=0, binding=9-10]
|
||||
// - 8 storage image [set=0, binding=11-18]
|
||||
//
|
||||
// All four pipeline layout share the first two descriptor sets (uniform buffers, PS samplers).
|
||||
// The third descriptor set (see bind points above) is used for storage or texel buffers.
|
||||
@ -78,7 +78,6 @@ enum UNIFORM_BUFFER_DESCRIPTOR_SET_BINDING
|
||||
constexpr u32 MAX_VERTEX_ATTRIBUTES = 16;
|
||||
|
||||
// Number of pixel shader texture slots
|
||||
constexpr u32 NUM_COMPUTE_SHADER_SAMPLERS = 2;
|
||||
constexpr u32 NUM_UTILITY_PIXEL_SAMPLERS = 8;
|
||||
|
||||
// Number of texel buffer binding points.
|
||||
|
@ -148,13 +148,26 @@ bool ObjectCache::CreateDescriptorSetLayouts()
|
||||
{8, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
||||
}};
|
||||
|
||||
static const std::array<VkDescriptorSetLayoutBinding, 6> compute_set_bindings{{
|
||||
static const std::array<VkDescriptorSetLayoutBinding, 19> compute_set_bindings{{
|
||||
{0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
{1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
{2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
{3, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
{4, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
{5, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
{3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
{4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
{5, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
{6, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
{7, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
{8, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
{9, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
{10, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
{11, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
{12, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
{13, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
{14, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
{15, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
{16, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
{17, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
{18, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
}};
|
||||
|
||||
std::array<VkDescriptorSetLayoutBinding, 3> ubo_bindings = standard_ubo_bindings;
|
||||
|
@ -58,8 +58,8 @@ static const char COMPUTE_SHADER_HEADER[] = R"(
|
||||
// All resources are packed into one descriptor set for compute.
|
||||
#define UBO_BINDING(packing, x) layout(packing, set = 0, binding = (x - 1))
|
||||
#define SAMPLER_BINDING(x) layout(set = 0, binding = (1 + x))
|
||||
#define TEXEL_BUFFER_BINDING(x) layout(set = 0, binding = (3 + x))
|
||||
#define IMAGE_BINDING(format, x) layout(format, set = 0, binding = (5 + x))
|
||||
#define TEXEL_BUFFER_BINDING(x) layout(set = 0, binding = (9 + x))
|
||||
#define IMAGE_BINDING(format, x) layout(format, set = 0, binding = (11 + x))
|
||||
|
||||
// hlsl to glsl function translation
|
||||
#define API_VULKAN 1
|
||||
|
@ -49,8 +49,10 @@ void StateTracker::DestroyInstance()
|
||||
// Clear everything out so this doesn't happen.
|
||||
for (auto& it : s_state_tracker->m_bindings.samplers)
|
||||
it.imageView = VK_NULL_HANDLE;
|
||||
s_state_tracker->m_bindings.image_texture.imageView = VK_NULL_HANDLE;
|
||||
for (auto& it : s_state_tracker->m_bindings.image_textures)
|
||||
it.imageView = VK_NULL_HANDLE;
|
||||
s_state_tracker->m_dummy_texture.reset();
|
||||
s_state_tracker->m_dummy_compute_texture.reset();
|
||||
|
||||
s_state_tracker.reset();
|
||||
}
|
||||
@ -64,6 +66,14 @@ bool StateTracker::Initialize()
|
||||
return false;
|
||||
m_dummy_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentInitCommandBuffer(),
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
// Create a dummy compute texture which can be used in place of a real binding
|
||||
m_dummy_compute_texture = VKTexture::Create(
|
||||
TextureConfig(1, 1, 1, 1, 1, AbstractTextureFormat::RGBA8, AbstractTextureFlag_ComputeImage),
|
||||
"");
|
||||
if (!m_dummy_compute_texture)
|
||||
return false;
|
||||
m_dummy_compute_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentInitCommandBuffer(),
|
||||
VK_IMAGE_LAYOUT_GENERAL);
|
||||
|
||||
// Initialize all samplers to point by default
|
||||
for (size_t i = 0; i < VideoCommon::MAX_PIXEL_SHADER_SAMPLERS; i++)
|
||||
@ -73,6 +83,13 @@ bool StateTracker::Initialize()
|
||||
m_bindings.samplers[i].sampler = g_object_cache->GetPointSampler();
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < VideoCommon::MAX_COMPUTE_SHADER_SAMPLERS; i++)
|
||||
{
|
||||
m_bindings.image_textures[i].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
m_bindings.image_textures[i].imageView = m_dummy_compute_texture->GetView();
|
||||
m_bindings.image_textures[i].sampler = g_object_cache->GetPointSampler();
|
||||
}
|
||||
|
||||
// Default dirty flags include all descriptors
|
||||
InvalidateCachedState();
|
||||
return true;
|
||||
@ -217,13 +234,13 @@ void StateTracker::SetTexelBuffer(u32 index, VkBufferView view)
|
||||
m_dirty_flags |= DIRTY_FLAG_UTILITY_BINDINGS | DIRTY_FLAG_COMPUTE_BINDINGS;
|
||||
}
|
||||
|
||||
void StateTracker::SetImageTexture(VkImageView view)
|
||||
void StateTracker::SetImageTexture(u32 index, VkImageView view)
|
||||
{
|
||||
if (m_bindings.image_texture.imageView == view)
|
||||
if (m_bindings.image_textures[index].imageView == view)
|
||||
return;
|
||||
|
||||
m_bindings.image_texture.imageView = view;
|
||||
m_bindings.image_texture.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
m_bindings.image_textures[index].imageView = view;
|
||||
m_bindings.image_textures[index].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
m_dirty_flags |= DIRTY_FLAG_COMPUTE_BINDINGS;
|
||||
}
|
||||
|
||||
@ -238,10 +255,13 @@ void StateTracker::UnbindTexture(VkImageView view)
|
||||
}
|
||||
}
|
||||
|
||||
if (m_bindings.image_texture.imageView == view)
|
||||
for (VkDescriptorImageInfo& it : m_bindings.image_textures)
|
||||
{
|
||||
m_bindings.image_texture.imageView = m_dummy_texture->GetView();
|
||||
m_bindings.image_texture.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
if (it.imageView == view)
|
||||
{
|
||||
it.imageView = m_dummy_compute_texture->GetView();
|
||||
it.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -667,7 +687,7 @@ void StateTracker::UpdateComputeDescriptorSet()
|
||||
m_compute_descriptor_set,
|
||||
1,
|
||||
0,
|
||||
NUM_COMPUTE_SHADER_SAMPLERS,
|
||||
VideoCommon::MAX_COMPUTE_SHADER_SAMPLERS,
|
||||
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
m_bindings.samplers.data(),
|
||||
nullptr,
|
||||
@ -675,7 +695,7 @@ void StateTracker::UpdateComputeDescriptorSet()
|
||||
dswrites[2] = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
nullptr,
|
||||
m_compute_descriptor_set,
|
||||
3,
|
||||
1 + VideoCommon::MAX_COMPUTE_SHADER_SAMPLERS,
|
||||
0,
|
||||
NUM_COMPUTE_TEXEL_BUFFERS,
|
||||
VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
|
||||
@ -685,11 +705,11 @@ void StateTracker::UpdateComputeDescriptorSet()
|
||||
dswrites[3] = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
nullptr,
|
||||
m_compute_descriptor_set,
|
||||
5,
|
||||
1 + VideoCommon::MAX_COMPUTE_SHADER_SAMPLERS + NUM_COMPUTE_TEXEL_BUFFERS,
|
||||
0,
|
||||
1,
|
||||
VideoCommon::MAX_COMPUTE_SHADER_SAMPLERS,
|
||||
VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
&m_bindings.image_texture,
|
||||
m_bindings.image_textures.data(),
|
||||
nullptr,
|
||||
nullptr};
|
||||
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
void SetSampler(u32 index, VkSampler sampler);
|
||||
void SetSSBO(VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range);
|
||||
void SetTexelBuffer(u32 index, VkBufferView view);
|
||||
void SetImageTexture(VkImageView view);
|
||||
void SetImageTexture(u32 index, VkImageView view);
|
||||
|
||||
void UnbindTexture(VkImageView view);
|
||||
|
||||
@ -146,7 +146,7 @@ private:
|
||||
std::array<VkBufferView, NUM_COMPUTE_TEXEL_BUFFERS> texel_buffers;
|
||||
VkDescriptorBufferInfo ssbo;
|
||||
VkDescriptorBufferInfo gx_uber_vertex_ssbo;
|
||||
VkDescriptorImageInfo image_texture;
|
||||
std::array<VkDescriptorImageInfo, VideoCommon::MAX_COMPUTE_SHADER_SAMPLERS> image_textures;
|
||||
} m_bindings = {};
|
||||
std::array<VkDescriptorSet, NUM_GX_DESCRIPTOR_SETS> m_gx_descriptor_sets = {};
|
||||
std::array<VkDescriptorSet, NUM_UTILITY_DESCRIPTOR_SETS> m_utility_descriptor_sets = {};
|
||||
@ -158,6 +158,7 @@ private:
|
||||
|
||||
// uniform buffers
|
||||
std::unique_ptr<VKTexture> m_dummy_texture;
|
||||
std::unique_ptr<VKTexture> m_dummy_compute_texture;
|
||||
|
||||
VKFramebuffer* m_framebuffer = nullptr;
|
||||
VkRenderPass m_current_render_pass = VK_NULL_HANDLE;
|
||||
|
@ -512,13 +512,13 @@ void VKGfx::SetSamplerState(u32 index, const SamplerState& state)
|
||||
m_sampler_states[index] = state;
|
||||
}
|
||||
|
||||
void VKGfx::SetComputeImageTexture(AbstractTexture* texture, bool read, bool write)
|
||||
void VKGfx::SetComputeImageTexture(u32 index, AbstractTexture* texture, bool read, bool write)
|
||||
{
|
||||
VKTexture* vk_texture = static_cast<VKTexture*>(texture);
|
||||
if (vk_texture)
|
||||
{
|
||||
StateTracker::GetInstance()->EndRenderPass();
|
||||
StateTracker::GetInstance()->SetImageTexture(vk_texture->GetView());
|
||||
StateTracker::GetInstance()->SetImageTexture(index, vk_texture->GetView());
|
||||
vk_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
read ? (write ? VKTexture::ComputeImageLayout::ReadWrite :
|
||||
VKTexture::ComputeImageLayout::ReadOnly) :
|
||||
@ -526,7 +526,7 @@ void VKGfx::SetComputeImageTexture(AbstractTexture* texture, bool read, bool wri
|
||||
}
|
||||
else
|
||||
{
|
||||
StateTracker::GetInstance()->SetImageTexture(VK_NULL_HANDLE);
|
||||
StateTracker::GetInstance()->SetImageTexture(index, VK_NULL_HANDLE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ public:
|
||||
void SetScissorRect(const MathUtil::Rectangle<int>& rc) override;
|
||||
void SetTexture(u32 index, const AbstractTexture* texture) override;
|
||||
void SetSamplerState(u32 index, const SamplerState& state) override;
|
||||
void SetComputeImageTexture(AbstractTexture* texture, bool read, bool write) override;
|
||||
void SetComputeImageTexture(u32 index, AbstractTexture* texture, bool read, bool write) override;
|
||||
void UnbindTexture(const AbstractTexture* texture) override;
|
||||
void SetViewport(float x, float y, float width, float height, float near_depth,
|
||||
float far_depth) override;
|
||||
|
Reference in New Issue
Block a user