VideoBackends: support multiple compute images for some backends (D3D, OGL, Vulkan)

This commit is contained in:
iwubcode
2023-06-10 12:35:36 -05:00
parent 61c45e8d68
commit 3627398cf5
21 changed files with 107 additions and 59 deletions

View File

@ -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};