Skip to content

Commit

Permalink
VideoBackends: support multiple compute images for some backends (D3D…
Browse files Browse the repository at this point in the history
…, OGL, Vulkan)
  • Loading branch information
iwubcode committed Jun 28, 2023
1 parent 78f4a91 commit 30a3196
Show file tree
Hide file tree
Showing 21 changed files with 127 additions and 59 deletions.
5 changes: 3 additions & 2 deletions Source/Core/VideoBackends/D3D/D3DGfx.cpp
Expand Up @@ -239,9 +239,10 @@ void Gfx::SetSamplerState(u32 index, const SamplerState& state)
D3D::stateman->SetSampler(index, m_state_cache.Get(state));
}

void Gfx::SetComputeImageTexture(AbstractTexture* texture, bool read, bool write)
void Gfx::SetComputeImageTexture(u32 index, AbstractTexture* texture, bool read, bool write)
{
D3D::stateman->SetComputeUAV(texture ? static_cast<DXTexture*>(texture)->GetD3DUAV() : nullptr);
D3D::stateman->SetComputeUAV(index,
texture ? static_cast<DXTexture*>(texture)->GetD3DUAV() : nullptr);
}

void Gfx::UnbindTexture(const AbstractTexture* texture)
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/VideoBackends/D3D/D3DGfx.h
Expand Up @@ -52,7 +52,7 @@ class Gfx final : public ::AbstractGfx
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;
Expand Down
28 changes: 24 additions & 4 deletions Source/Core/VideoBackends/D3D/D3DState.cpp
Expand Up @@ -222,13 +222,14 @@ void StateManager::SetTextureByMask(u32 textureSlotMask, ID3D11ShaderResourceVie
}
}

void StateManager::SetComputeUAV(ID3D11UnorderedAccessView* uav)
void StateManager::SetComputeUAV(u32 index, ID3D11UnorderedAccessView* uav)
{
if (m_compute_image == uav)
if (m_compute_images[index] == uav)
return;

m_compute_image = uav;
D3D::context->CSSetUnorderedAccessViews(0, 1, &uav, nullptr);
m_compute_images[index] = uav;
D3D::context->CSSetUnorderedAccessViews(0, static_cast<u32>(m_compute_images.size()),
m_compute_images.data(), nullptr);
}

void StateManager::SetComputeShader(ID3D11ComputeShader* shader)
Expand All @@ -242,6 +243,25 @@ void StateManager::SetComputeShader(ID3D11ComputeShader* shader)

void StateManager::SyncComputeBindings()
{
if (m_last_compute_rtv_count != m_pending.framebuffer->GetNumRTVs())
{
std::vector<ID3D11RenderTargetView*> rtv_null(m_pending.framebuffer->GetNumRTVs());
if (g_ActiveConfig.backend_info.bSupportsBBox)
{
ID3D11UnorderedAccessView* uav = nullptr;
D3D::context->OMSetRenderTargetsAndUnorderedAccessViews(
m_pending.framebuffer->GetNumRTVs(), rtv_null.data(), nullptr,
m_pending.framebuffer->GetNumRTVs() + 1, 1, &uav, nullptr);
}
else
{
D3D::context->OMSetRenderTargets(m_pending.framebuffer->GetNumRTVs(), rtv_null.data(),
nullptr);
}
m_dirtyFlags |= DirtyFlag_Framebuffer;
m_last_compute_rtv_count = m_pending.framebuffer->GetNumRTVs();
}

if (m_compute_constants != m_pending.pixelConstants[0])
{
m_compute_constants = m_pending.pixelConstants[0];
Expand Down
11 changes: 7 additions & 4 deletions Source/Core/VideoBackends/D3D/D3DState.h
Expand Up @@ -218,7 +218,7 @@ class StateManager

// Binds constant buffers/textures/samplers to the compute shader stage.
// We don't track these explicitly because it's not often-used.
void SetComputeUAV(ID3D11UnorderedAccessView* uav);
void SetComputeUAV(u32 index, ID3D11UnorderedAccessView* uav);
void SetComputeShader(ID3D11ComputeShader* shader);
void SyncComputeBindings();

Expand Down Expand Up @@ -277,10 +277,13 @@ class StateManager

// Compute resources are synced with the graphics resources when we need them.
ID3D11Buffer* m_compute_constants = nullptr;
std::array<ID3D11ShaderResourceView*, 8> m_compute_textures{};
std::array<ID3D11SamplerState*, 8> m_compute_samplers{};
ID3D11UnorderedAccessView* m_compute_image = nullptr;
std::array<ID3D11ShaderResourceView*, VideoCommon::MAX_COMPUTE_SHADER_SAMPLERS>
m_compute_textures{};
std::array<ID3D11SamplerState*, VideoCommon::MAX_COMPUTE_SHADER_SAMPLERS> m_compute_samplers{};
std::array<ID3D11UnorderedAccessView*, VideoCommon::MAX_COMPUTE_SHADER_SAMPLERS>
m_compute_images{};
ID3D11ComputeShader* m_compute_shader = nullptr;
u32 m_last_compute_rtv_count = 0;
};

extern std::unique_ptr<StateManager> stateman;
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/VideoBackends/D3D12/D3D12Gfx.cpp
Expand Up @@ -263,7 +263,7 @@ void Gfx::SetSamplerState(u32 index, const SamplerState& state)
m_dirty_bits |= DirtyState_Samplers;
}

void Gfx::SetComputeImageTexture(AbstractTexture* texture, bool read, bool write)
void Gfx::SetComputeImageTexture(u32 index, AbstractTexture* texture, bool read, bool write)
{
const DXTexture* dxtex = static_cast<const DXTexture*>(texture);
if (m_state.compute_image_texture == dxtex)
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/VideoBackends/D3D12/D3D12Gfx.h
Expand Up @@ -60,7 +60,7 @@ class Gfx final : public ::AbstractGfx
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;
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/VideoBackends/Metal/MTLGfx.h
Expand Up @@ -59,7 +59,7 @@ class Gfx final : public ::AbstractGfx
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;
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/VideoBackends/Metal/MTLGfx.mm
Expand Up @@ -386,7 +386,7 @@
g_state_tracker->SetSampler(index, state);
}

void Metal::Gfx::SetComputeImageTexture(AbstractTexture* texture, bool read, bool write)
void Metal::Gfx::SetComputeImageTexture(u32, AbstractTexture* texture, bool read, bool write)
{
g_state_tracker->SetComputeTexture(static_cast<const Texture*>(texture));
}
Expand Down
25 changes: 16 additions & 9 deletions Source/Core/VideoBackends/OGL/OGLGfx.cpp
Expand Up @@ -22,6 +22,7 @@
#include "VideoCommon/Present.h"
#include "VideoCommon/VideoConfig.h"

#include <algorithm>
#include <string_view>

namespace OGL
Expand Down Expand Up @@ -303,8 +304,11 @@ void OGLGfx::DispatchComputeShader(const AbstractShader* shader, u32 groupsize_x
static_cast<const OGLPipeline*>(m_current_pipeline)->GetProgram()->shader.Bind();

// Barrier to texture can be used for reads.
if (m_bound_image_texture)
if (std::any_of(m_bound_image_textures.begin(), m_bound_image_textures.end(),
[](auto image) { return image != nullptr; }))
{
glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
}
}

void OGLGfx::SelectLeftBuffer()
Expand Down Expand Up @@ -652,23 +656,23 @@ void OGLGfx::SetSamplerState(u32 index, const SamplerState& state)
g_sampler_cache->SetSamplerState(index, state);
}

void OGLGfx::SetComputeImageTexture(AbstractTexture* texture, bool read, bool write)
void OGLGfx::SetComputeImageTexture(u32 index, AbstractTexture* texture, bool read, bool write)
{
if (m_bound_image_texture == texture)
if (m_bound_image_textures[index] == texture)
return;

if (texture)
{
const GLenum access = read ? (write ? GL_READ_WRITE : GL_READ_ONLY) : GL_WRITE_ONLY;
glBindImageTexture(0, static_cast<OGLTexture*>(texture)->GetGLTextureId(), 0, GL_TRUE, 0,
glBindImageTexture(index, static_cast<OGLTexture*>(texture)->GetGLTextureId(), 0, GL_TRUE, 0,
access, static_cast<OGLTexture*>(texture)->GetGLFormatForImageTexture());
}
else
{
glBindImageTexture(0, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
glBindImageTexture(index, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
}

m_bound_image_texture = texture;
m_bound_image_textures[index] = texture;
}

void OGLGfx::UnbindTexture(const AbstractTexture* texture)
Expand All @@ -683,10 +687,13 @@ void OGLGfx::UnbindTexture(const AbstractTexture* texture)
m_bound_textures[i] = nullptr;
}

if (m_bound_image_texture == texture)
for (size_t i = 0; i < m_bound_image_textures.size(); i++)
{
glBindImageTexture(0, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
m_bound_image_texture = nullptr;
if (m_bound_image_textures[i] != texture)
continue;

glBindImageTexture(static_cast<GLuint>(i), 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
m_bound_image_textures[i] = nullptr;
}
}

Expand Down
4 changes: 3 additions & 1 deletion Source/Core/VideoBackends/OGL/OGLGfx.h
Expand Up @@ -49,7 +49,7 @@ class OGLGfx final : public AbstractGfx
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;
Expand Down Expand Up @@ -103,6 +103,8 @@ class OGLGfx final : public AbstractGfx
std::unique_ptr<GLContext> m_main_gl_context;
std::unique_ptr<OGLFramebuffer> m_system_framebuffer;
std::array<const OGLTexture*, VideoCommon::MAX_PIXEL_SHADER_SAMPLERS> m_bound_textures{};
std::array<const AbstractTexture*, VideoCommon::MAX_COMPUTE_SHADER_SAMPLERS>
m_bound_image_textures{};
AbstractTexture* m_bound_image_texture = nullptr;
RasterizationState m_current_rasterization_state;
DepthState m_current_depth_state;
Expand Down
5 changes: 3 additions & 2 deletions Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp
Expand Up @@ -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},
Expand Down
7 changes: 3 additions & 4 deletions Source/Core/VideoBackends/Vulkan/Constants.h
Expand Up @@ -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.
Expand All @@ -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.
Expand Down
21 changes: 17 additions & 4 deletions Source/Core/VideoBackends/Vulkan/ObjectCache.cpp
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions Source/Core/VideoBackends/Vulkan/ShaderCompiler.cpp
Expand Up @@ -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
Expand Down
46 changes: 33 additions & 13 deletions Source/Core/VideoBackends/Vulkan/StateTracker.cpp
Expand Up @@ -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();
}
Expand All @@ -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++)
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}

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

Expand Down Expand Up @@ -667,15 +687,15 @@ 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,
nullptr};
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,
Expand All @@ -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};

Expand Down

0 comments on commit 30a3196

Please sign in to comment.