summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/Vulkan/StateTracker.cpp
diff options
context:
space:
mode:
authorStenzek <stenzek@gmail.com>2018-02-25 01:15:35 +1000
committerStenzek <stenzek@gmail.com>2018-03-10 15:56:30 +1000
commitdec0c3bce85ceda89ea05f00b94aad00e675598d (patch)
tree8c967a47d8a531ae3f0245e419d7ec652535ee3a /Source/Core/VideoBackends/Vulkan/StateTracker.cpp
parent24df896eb8d1520706b086039743ef2dca7ce6df (diff)
Move shader caches to VideoCommon
Diffstat (limited to 'Source/Core/VideoBackends/Vulkan/StateTracker.cpp')
-rw-r--r--Source/Core/VideoBackends/Vulkan/StateTracker.cpp457
1 files changed, 24 insertions, 433 deletions
diff --git a/Source/Core/VideoBackends/Vulkan/StateTracker.cpp b/Source/Core/VideoBackends/Vulkan/StateTracker.cpp
index e5be3e2c1e..a3961daf48 100644
--- a/Source/Core/VideoBackends/Vulkan/StateTracker.cpp
+++ b/Source/Core/VideoBackends/Vulkan/StateTracker.cpp
@@ -15,6 +15,7 @@
#include "VideoBackends/Vulkan/ShaderCache.h"
#include "VideoBackends/Vulkan/StreamBuffer.h"
#include "VideoBackends/Vulkan/Util.h"
+#include "VideoBackends/Vulkan/VKPipeline.h"
#include "VideoBackends/Vulkan/VertexFormat.h"
#include "VideoBackends/Vulkan/VulkanContext.h"
@@ -53,12 +54,6 @@ void StateTracker::DestroyInstance()
bool StateTracker::Initialize()
{
- // BBox is disabled by default.
- m_pipeline_state.pipeline_layout = g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD);
- m_num_active_descriptor_sets = NUM_GX_DRAW_DESCRIPTOR_SETS;
- m_bbox_enabled = false;
- ClearShaders();
-
// Initialize all samplers to point by default
for (size_t i = 0; i < NUM_PIXEL_SHADER_SAMPLERS; i++)
{
@@ -97,122 +92,6 @@ bool StateTracker::Initialize()
return true;
}
-void StateTracker::InvalidateShaderPointers()
-{
- // Clear UIDs, forcing a false match next time.
- m_vs_uid = {};
- m_gs_uid = {};
- m_ps_uid = {};
-
- // Invalidate shader pointers.
- m_pipeline_state.vs = VK_NULL_HANDLE;
- m_pipeline_state.gs = VK_NULL_HANDLE;
- m_pipeline_state.ps = VK_NULL_HANDLE;
-}
-
-void StateTracker::ReloadPipelineUIDCache()
-{
- class PipelineInserter final : public LinearDiskCacheReader<SerializedPipelineUID, u32>
- {
- public:
- explicit PipelineInserter(StateTracker* this_ptr_) : this_ptr(this_ptr_) {}
- void Read(const SerializedPipelineUID& key, const u32* value, u32 value_size)
- {
- this_ptr->PrecachePipelineUID(key);
- }
-
- private:
- StateTracker* this_ptr;
- };
-
- m_uid_cache.Sync();
- m_uid_cache.Close();
-
- // UID caches don't contain any host state, so use a single uid cache per gameid.
- std::string filename = GetDiskShaderCacheFileName(APIType::Vulkan, "PipelineUID", true, false);
- if (g_ActiveConfig.bShaderCache)
- {
- PipelineInserter inserter(this);
- m_uid_cache.OpenAndRead(filename, inserter);
- }
-
- // If we were using background compilation, ensure everything is ready before continuing.
- if (g_ActiveConfig.bBackgroundShaderCompiling)
- g_shader_cache->WaitForBackgroundCompilesToComplete();
-}
-
-void StateTracker::AppendToPipelineUIDCache(const PipelineInfo& info)
-{
- SerializedPipelineUID sinfo;
- sinfo.blend_state_bits = info.blend_state.hex;
- sinfo.rasterizer_state_bits = info.rasterization_state.hex;
- sinfo.depth_state_bits = info.depth_state.hex;
- sinfo.vertex_decl = m_pipeline_state.vertex_format->GetVertexDeclaration();
- sinfo.vs_uid = m_vs_uid;
- sinfo.gs_uid = m_gs_uid;
- sinfo.ps_uid = m_ps_uid;
-
- u32 dummy_value = 0;
- m_uid_cache.Append(sinfo, &dummy_value, 1);
-}
-
-bool StateTracker::PrecachePipelineUID(const SerializedPipelineUID& uid)
-{
- PipelineInfo pinfo = {};
-
- // Need to create the vertex declaration first, rather than deferring to when a game creates a
- // vertex loader that uses this format, since we need it to create a pipeline.
- pinfo.vertex_format =
- static_cast<VertexFormat*>(VertexLoaderManager::GetOrCreateMatchingFormat(uid.vertex_decl));
- pinfo.pipeline_layout = uid.ps_uid.GetUidData()->bounding_box ?
- g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_BBOX) :
- g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD);
- pinfo.vs = g_shader_cache->GetVertexShaderForUid(uid.vs_uid);
- if (pinfo.vs == VK_NULL_HANDLE)
- {
- WARN_LOG(VIDEO, "Failed to get vertex shader from cached UID.");
- return false;
- }
- if (g_vulkan_context->SupportsGeometryShaders() && !uid.gs_uid.GetUidData()->IsPassthrough())
- {
- pinfo.gs = g_shader_cache->GetGeometryShaderForUid(uid.gs_uid);
- if (pinfo.gs == VK_NULL_HANDLE)
- {
- WARN_LOG(VIDEO, "Failed to get geometry shader from cached UID.");
- return false;
- }
- }
- pinfo.ps = g_shader_cache->GetPixelShaderForUid(uid.ps_uid);
- if (pinfo.ps == VK_NULL_HANDLE)
- {
- WARN_LOG(VIDEO, "Failed to get pixel shader from cached UID.");
- return false;
- }
- pinfo.render_pass = m_load_render_pass;
- pinfo.rasterization_state.hex = uid.rasterizer_state_bits;
- pinfo.depth_state.hex = uid.depth_state_bits;
- pinfo.blend_state.hex = uid.blend_state_bits;
- pinfo.multisampling_state.hex = m_pipeline_state.multisampling_state.hex;
-
- if (g_ActiveConfig.bBackgroundShaderCompiling)
- {
- // Use async for multithreaded compilation.
- g_shader_cache->GetPipelineWithCacheResultAsync(pinfo);
- }
- else
- {
- VkPipeline pipeline = g_shader_cache->GetPipeline(pinfo);
- if (pipeline == VK_NULL_HANDLE)
- {
- WARN_LOG(VIDEO, "Failed to get pipeline from cached UID.");
- return false;
- }
- }
-
- // We don't need to do anything with this pipeline, just make sure it exists.
- return true;
-}
-
void StateTracker::SetVertexBuffer(VkBuffer buffer, VkDeviceSize offset)
{
if (m_vertex_buffer == buffer && m_vertex_buffer_offset == offset)
@@ -238,14 +117,6 @@ void StateTracker::SetRenderPass(VkRenderPass load_render_pass, VkRenderPass cle
{
// Should not be changed within a render pass.
_assert_(!InRenderPass());
-
- // The clear and load render passes are compatible, so we don't need to change our pipeline.
- if (m_pipeline_state.render_pass != load_render_pass)
- {
- m_pipeline_state.render_pass = load_render_pass;
- m_dirty_flags |= DIRTY_FLAG_PIPELINE;
- }
-
m_load_render_pass = load_render_pass;
m_clear_render_pass = clear_render_pass;
}
@@ -258,169 +129,18 @@ void StateTracker::SetFramebuffer(VkFramebuffer framebuffer, const VkRect2D& ren
m_framebuffer_size = render_area;
}
-void StateTracker::SetVertexFormat(const VertexFormat* vertex_format)
-{
- if (m_vertex_format == vertex_format)
- return;
-
- m_vertex_format = vertex_format;
- UpdatePipelineVertexFormat();
-}
-
-void StateTracker::SetRasterizationState(const RasterizationState& state)
-{
- if (m_pipeline_state.rasterization_state.hex == state.hex)
- return;
-
- m_pipeline_state.rasterization_state.hex = state.hex;
- m_dirty_flags |= DIRTY_FLAG_PIPELINE;
-}
-
-void StateTracker::SetMultisamplingstate(const MultisamplingState& state)
+void StateTracker::SetPipeline(const VKPipeline* pipeline)
{
- if (m_pipeline_state.multisampling_state.hex == state.hex)
+ if (m_pipeline == pipeline)
return;
- m_pipeline_state.multisampling_state.hex = state.hex;
- m_dirty_flags |= DIRTY_FLAG_PIPELINE;
-}
-
-void StateTracker::SetDepthState(const DepthState& state)
-{
- if (m_pipeline_state.depth_state.hex == state.hex)
- return;
-
- m_pipeline_state.depth_state.hex = state.hex;
- m_dirty_flags |= DIRTY_FLAG_PIPELINE;
-}
-
-void StateTracker::SetBlendState(const BlendingState& state)
-{
- if (m_pipeline_state.blend_state.hex == state.hex)
- return;
-
- m_pipeline_state.blend_state.hex = state.hex;
- m_dirty_flags |= DIRTY_FLAG_PIPELINE;
-}
-
-bool StateTracker::CheckForShaderChanges()
-{
- VertexShaderUid vs_uid = GetVertexShaderUid();
- PixelShaderUid ps_uid = GetPixelShaderUid();
- ClearUnusedPixelShaderUidBits(APIType::Vulkan, &ps_uid);
-
- bool changed = false;
- bool use_ubershaders = g_ActiveConfig.bDisableSpecializedShaders;
- if (g_ActiveConfig.CanBackgroundCompileShaders() && !g_ActiveConfig.bDisableSpecializedShaders)
- {
- // Look up both VS and PS, and check if we can compile it asynchronously.
- auto vs = g_shader_cache->GetVertexShaderForUidAsync(vs_uid);
- auto ps = g_shader_cache->GetPixelShaderForUidAsync(ps_uid);
- if (vs.second || ps.second)
- {
- // One of the shaders is still pending. Use the ubershader for both.
- use_ubershaders = true;
- }
- else
- {
- // Use the standard shaders for both.
- if (m_pipeline_state.vs != vs.first)
- {
- m_pipeline_state.vs = vs.first;
- m_vs_uid = vs_uid;
- changed = true;
- }
- if (m_pipeline_state.ps != ps.first)
- {
- m_pipeline_state.ps = ps.first;
- m_ps_uid = ps_uid;
- changed = true;
- }
- }
- }
- else
- {
- // Normal shader path. No ubershaders.
- if (vs_uid != m_vs_uid)
- {
- m_vs_uid = vs_uid;
- m_pipeline_state.vs = g_shader_cache->GetVertexShaderForUid(vs_uid);
- changed = true;
- }
- if (ps_uid != m_ps_uid)
- {
- m_ps_uid = ps_uid;
- m_pipeline_state.ps = g_shader_cache->GetPixelShaderForUid(ps_uid);
- changed = true;
- }
- }
-
- // Switching to/from ubershaders? Have to adjust the vertex format and pipeline layout.
- if (use_ubershaders != m_using_ubershaders)
- {
- m_using_ubershaders = use_ubershaders;
- UpdatePipelineLayout();
- UpdatePipelineVertexFormat();
- }
-
- if (use_ubershaders)
- {
- UberShader::VertexShaderUid uber_vs_uid = UberShader::GetVertexShaderUid();
- VkShaderModule vs = g_shader_cache->GetVertexUberShaderForUid(uber_vs_uid);
- if (vs != m_pipeline_state.vs)
- {
- m_uber_vs_uid = uber_vs_uid;
- m_pipeline_state.vs = vs;
- changed = true;
- }
-
- UberShader::PixelShaderUid uber_ps_uid = UberShader::GetPixelShaderUid();
- UberShader::ClearUnusedPixelShaderUidBits(APIType::Vulkan, &uber_ps_uid);
- VkShaderModule ps = g_shader_cache->GetPixelUberShaderForUid(uber_ps_uid);
- if (ps != m_pipeline_state.ps)
- {
- m_uber_ps_uid = uber_ps_uid;
- m_pipeline_state.ps = ps;
- changed = true;
- }
- }
-
- if (g_vulkan_context->SupportsGeometryShaders())
- {
- GeometryShaderUid gs_uid = GetGeometryShaderUid(m_pipeline_state.rasterization_state.primitive);
- if (gs_uid != m_gs_uid)
- {
- m_gs_uid = gs_uid;
- if (gs_uid.GetUidData()->IsPassthrough())
- m_pipeline_state.gs = VK_NULL_HANDLE;
- else
- m_pipeline_state.gs = g_shader_cache->GetGeometryShaderForUid(gs_uid);
-
- changed = true;
- }
- }
-
- if (changed)
- m_dirty_flags |= DIRTY_FLAG_PIPELINE;
-
- return changed;
-}
-
-void StateTracker::ClearShaders()
-{
- // Set the UIDs to something that will never match, so on the first access they are checked.
- std::memset(&m_vs_uid, 0xFF, sizeof(m_vs_uid));
- std::memset(&m_gs_uid, 0xFF, sizeof(m_gs_uid));
- std::memset(&m_ps_uid, 0xFF, sizeof(m_ps_uid));
- std::memset(&m_uber_vs_uid, 0xFF, sizeof(m_uber_vs_uid));
- std::memset(&m_uber_ps_uid, 0xFF, sizeof(m_uber_ps_uid));
-
- m_pipeline_state.vs = VK_NULL_HANDLE;
- m_pipeline_state.gs = VK_NULL_HANDLE;
- m_pipeline_state.ps = VK_NULL_HANDLE;
- m_pipeline_state.vertex_format = nullptr;
+ const bool new_usage =
+ pipeline && (!m_pipeline || m_pipeline->GetUsage() != pipeline->GetUsage());
+ m_pipeline = pipeline;
m_dirty_flags |= DIRTY_FLAG_PIPELINE;
+ if (new_usage)
+ m_dirty_flags |= DIRTY_FLAG_ALL_DESCRIPTOR_SETS;
}
void StateTracker::UpdateVertexShaderConstants()
@@ -450,20 +170,6 @@ void StateTracker::UpdateVertexShaderConstants()
void StateTracker::UpdateGeometryShaderConstants()
{
- // Skip updating geometry shader constants if it's not in use.
- if (m_pipeline_state.gs == VK_NULL_HANDLE)
- {
- // However, if the buffer has changed, we can't skip the update, because then we'll
- // try to include the now non-existant buffer in the descriptor set.
- if (m_uniform_stream_buffer->GetBuffer() ==
- m_bindings.uniform_buffer_bindings[UBO_DESCRIPTOR_SET_BINDING_GS].buffer)
- {
- return;
- }
-
- GeometryShaderManager::dirty = true;
- }
-
if (!GeometryShaderManager::dirty || !ReserveConstantStorage())
return;
@@ -614,15 +320,6 @@ void StateTracker::SetSampler(size_t index, VkSampler sampler)
m_dirty_flags |= DIRTY_FLAG_PS_SAMPLERS;
}
-void StateTracker::SetBBoxEnable(bool enable)
-{
- if (m_bbox_enabled == enable)
- return;
-
- m_bbox_enabled = enable;
- UpdatePipelineLayout();
-}
-
void StateTracker::SetBBoxBuffer(VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range)
{
if (m_bindings.ps_ssbo.buffer == buffer && m_bindings.ps_ssbo.offset == offset &&
@@ -634,10 +331,7 @@ void StateTracker::SetBBoxBuffer(VkBuffer buffer, VkDeviceSize offset, VkDeviceS
m_bindings.ps_ssbo.buffer = buffer;
m_bindings.ps_ssbo.offset = offset;
m_bindings.ps_ssbo.range = range;
-
- // Defer descriptor update until bbox is actually enabled.
- if (IsSSBODescriptorRequired())
- m_dirty_flags |= DIRTY_FLAG_PS_SSBO;
+ m_dirty_flags |= DIRTY_FLAG_PS_SSBO;
}
void StateTracker::UnbindTexture(VkImageView view)
@@ -653,10 +347,6 @@ void StateTracker::InvalidateDescriptorSets()
{
m_descriptor_sets.fill(VK_NULL_HANDLE);
m_dirty_flags |= DIRTY_FLAG_ALL_DESCRIPTOR_SETS;
-
- // Defer SSBO descriptor update until bbox is actually enabled.
- if (!IsSSBODescriptorRequired())
- m_dirty_flags &= ~DIRTY_FLAG_PS_SSBO;
}
void StateTracker::InvalidateConstants()
@@ -669,9 +359,8 @@ void StateTracker::InvalidateConstants()
void StateTracker::SetPendingRebind()
{
m_dirty_flags |= DIRTY_FLAG_DYNAMIC_OFFSETS | DIRTY_FLAG_DESCRIPTOR_SET_BINDING |
- DIRTY_FLAG_PIPELINE_BINDING | DIRTY_FLAG_VERTEX_BUFFER |
- DIRTY_FLAG_INDEX_BUFFER | DIRTY_FLAG_VIEWPORT | DIRTY_FLAG_SCISSOR |
- DIRTY_FLAG_PIPELINE;
+ DIRTY_FLAG_VERTEX_BUFFER | DIRTY_FLAG_INDEX_BUFFER | DIRTY_FLAG_VIEWPORT |
+ DIRTY_FLAG_SCISSOR | DIRTY_FLAG_PIPELINE;
}
void StateTracker::BeginRenderPass()
@@ -743,17 +432,14 @@ void StateTracker::SetScissor(const VkRect2D& scissor)
bool StateTracker::Bind(bool rebind_all /*= false*/)
{
+ // Must have a pipeline.
+ if (!m_pipeline)
+ return false;
+
// Check the render area if we were in a clear pass.
if (m_current_render_pass == m_clear_render_pass && !IsViewportWithinRenderArea())
EndRenderPass();
- // Get new pipeline object if any parts have changed
- if (m_dirty_flags & DIRTY_FLAG_PIPELINE && !UpdatePipeline())
- {
- ERROR_LOG(VIDEO, "Failed to get pipeline object, skipping draw");
- return false;
- }
-
// Get a new descriptor set if any parts have changed
if (m_dirty_flags & DIRTY_FLAG_ALL_DESCRIPTOR_SETS && !UpdateDescriptorSet())
{
@@ -780,20 +466,20 @@ bool StateTracker::Bind(bool rebind_all /*= false*/)
if (m_dirty_flags & DIRTY_FLAG_INDEX_BUFFER || rebind_all)
vkCmdBindIndexBuffer(command_buffer, m_index_buffer, m_index_buffer_offset, m_index_type);
- if (m_dirty_flags & DIRTY_FLAG_PIPELINE_BINDING || rebind_all)
- vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_object);
+ if (m_dirty_flags & DIRTY_FLAG_PIPELINE || rebind_all)
+ vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline->GetVkPipeline());
if (m_dirty_flags & DIRTY_FLAG_DESCRIPTOR_SET_BINDING || rebind_all)
{
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
- m_pipeline_state.pipeline_layout, 0, m_num_active_descriptor_sets,
+ m_pipeline->GetVkPipelineLayout(), 0, m_num_active_descriptor_sets,
m_descriptor_sets.data(), NUM_UBO_DESCRIPTOR_SET_BINDINGS,
m_bindings.uniform_buffer_offsets.data());
}
else if (m_dirty_flags & DIRTY_FLAG_DYNAMIC_OFFSETS)
{
vkCmdBindDescriptorSets(
- command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_state.pipeline_layout,
+ command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline->GetVkPipelineLayout(),
DESCRIPTOR_SET_BIND_POINT_UNIFORM_BUFFERS, 1,
&m_descriptor_sets[DESCRIPTOR_SET_BIND_POINT_UNIFORM_BUFFERS],
NUM_UBO_DESCRIPTOR_SET_BINDINGS, m_bindings.uniform_buffer_offsets.data());
@@ -933,105 +619,6 @@ void StateTracker::EndClearRenderPass()
EndRenderPass();
}
-VkPipeline StateTracker::GetPipelineAndCacheUID()
-{
- // We can't cache ubershader uids, only normal shader uids.
- if (g_ActiveConfig.CanBackgroundCompileShaders() && !m_using_ubershaders)
- {
- // Append to UID cache if it is a new pipeline.
- auto result = g_shader_cache->GetPipelineWithCacheResultAsync(m_pipeline_state);
- if (!result.second && g_ActiveConfig.bShaderCache)
- AppendToPipelineUIDCache(m_pipeline_state);
-
- // Still waiting for the pipeline to compile?
- if (!result.first.second)
- return result.first.first;
-
- // Use ubershader instead.
- m_using_ubershaders = true;
- UpdatePipelineLayout();
- UpdatePipelineVertexFormat();
-
- PipelineInfo uber_info = m_pipeline_state;
- UberShader::VertexShaderUid uber_vuid = UberShader::GetVertexShaderUid();
- UberShader::PixelShaderUid uber_puid = UberShader::GetPixelShaderUid();
- UberShader::ClearUnusedPixelShaderUidBits(APIType::Vulkan, &uber_puid);
- uber_info.vs = g_shader_cache->GetVertexUberShaderForUid(uber_vuid);
- uber_info.ps = g_shader_cache->GetPixelUberShaderForUid(uber_puid);
-
- auto uber_result = g_shader_cache->GetPipelineWithCacheResult(uber_info);
- return uber_result.first;
- }
- else
- {
- // Add to the UID cache if it is a new pipeline.
- auto result = g_shader_cache->GetPipelineWithCacheResult(m_pipeline_state);
- if (!result.second && !m_using_ubershaders && g_ActiveConfig.bShaderCache)
- AppendToPipelineUIDCache(m_pipeline_state);
-
- return result.first;
- }
-}
-
-bool StateTracker::IsSSBODescriptorRequired() const
-{
- return m_bbox_enabled || (m_using_ubershaders && g_ActiveConfig.bBBoxEnable &&
- g_ActiveConfig.BBoxUseFragmentShaderImplementation());
-}
-
-bool StateTracker::UpdatePipeline()
-{
- // We need at least a vertex and fragment shader
- if (m_pipeline_state.vs == VK_NULL_HANDLE || m_pipeline_state.ps == VK_NULL_HANDLE)
- return false;
-
- // Grab a new pipeline object, this can fail.
- m_pipeline_object = GetPipelineAndCacheUID();
-
- m_dirty_flags |= DIRTY_FLAG_PIPELINE_BINDING;
- return m_pipeline_object != VK_NULL_HANDLE;
-}
-
-void StateTracker::UpdatePipelineLayout()
-{
- const bool use_bbox_pipeline_layout = IsSSBODescriptorRequired();
- VkPipelineLayout pipeline_layout =
- use_bbox_pipeline_layout ? g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_BBOX) :
- g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD);
- if (m_pipeline_state.pipeline_layout == pipeline_layout)
- return;
-
- // Change the number of active descriptor sets, as well as the pipeline layout
- m_pipeline_state.pipeline_layout = pipeline_layout;
- if (use_bbox_pipeline_layout)
- {
- m_num_active_descriptor_sets = NUM_GX_DRAW_WITH_BBOX_DESCRIPTOR_SETS;
-
- // The bbox buffer never changes, so we defer descriptor updates until it is enabled.
- if (m_descriptor_sets[DESCRIPTOR_SET_BIND_POINT_STORAGE_OR_TEXEL_BUFFER] == VK_NULL_HANDLE)
- m_dirty_flags |= DIRTY_FLAG_PS_SSBO;
- }
- else
- {
- m_num_active_descriptor_sets = NUM_GX_DRAW_DESCRIPTOR_SETS;
- }
-
- m_dirty_flags |= DIRTY_FLAG_PIPELINE | DIRTY_FLAG_DESCRIPTOR_SET_BINDING;
-}
-
-void StateTracker::UpdatePipelineVertexFormat()
-{
- const NativeVertexFormat* vertex_format =
- m_using_ubershaders ?
- VertexLoaderManager::GetUberVertexFormat(m_vertex_format->GetVertexDeclaration()) :
- m_vertex_format;
- if (m_pipeline_state.vertex_format == vertex_format)
- return;
-
- m_pipeline_state.vertex_format = static_cast<const VertexFormat*>(vertex_format);
- m_dirty_flags |= DIRTY_FLAG_PIPELINE;
-}
-
bool StateTracker::UpdateDescriptorSet()
{
const size_t MAX_DESCRIPTOR_WRITES = NUM_UBO_DESCRIPTOR_SET_BINDINGS + // UBO
@@ -1051,6 +638,9 @@ bool StateTracker::UpdateDescriptorSet()
for (size_t i = 0; i < NUM_UBO_DESCRIPTOR_SET_BINDINGS; i++)
{
+ if (i == UBO_DESCRIPTOR_SET_BINDING_GS && !g_vulkan_context->SupportsGeometryShaders())
+ continue;
+
writes[num_writes++] = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
nullptr,
set,
@@ -1091,7 +681,7 @@ bool StateTracker::UpdateDescriptorSet()
m_dirty_flags |= DIRTY_FLAG_DESCRIPTOR_SET_BINDING;
}
- if (IsSSBODescriptorRequired() &&
+ if (g_vulkan_context->SupportsBoundingBox() &&
(m_dirty_flags & DIRTY_FLAG_PS_SSBO ||
m_descriptor_sets[DESCRIPTOR_SET_BIND_POINT_STORAGE_OR_TEXEL_BUFFER] == VK_NULL_HANDLE))
{
@@ -1119,6 +709,7 @@ bool StateTracker::UpdateDescriptorSet()
if (num_writes > 0)
vkUpdateDescriptorSets(g_vulkan_context->GetDevice(), num_writes, writes.data(), 0, nullptr);
+ m_num_active_descriptor_sets = NUM_GX_DRAW_DESCRIPTOR_SETS;
return true;
}