mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
Merge pull request #10890 from tellowkrinkle/VertexLineExpand
VideoCommon: Add vertex shader point/line expansion
This commit is contained in:
@@ -84,6 +84,8 @@ const Info<int> GFX_SHADER_PRECOMPILER_THREADS{
|
||||
{System::GFX, "Settings", "ShaderPrecompilerThreads"}, -1};
|
||||
const Info<bool> GFX_SAVE_TEXTURE_CACHE_TO_STATE{
|
||||
{System::GFX, "Settings", "SaveTextureCacheToState"}, true};
|
||||
const Info<bool> GFX_PREFER_VS_FOR_LINE_POINT_EXPANSION{
|
||||
{System::GFX, "Settings", "PreferVSForLinePointExpansion"}, false};
|
||||
|
||||
const Info<bool> GFX_SW_DUMP_OBJECTS{{System::GFX, "Settings", "SWDumpObjects"}, false};
|
||||
const Info<bool> GFX_SW_DUMP_TEV_STAGES{{System::GFX, "Settings", "SWDumpTevStages"}, false};
|
||||
|
||||
@@ -73,6 +73,7 @@ extern const Info<ShaderCompilationMode> GFX_SHADER_COMPILATION_MODE;
|
||||
extern const Info<int> GFX_SHADER_COMPILER_THREADS;
|
||||
extern const Info<int> GFX_SHADER_PRECOMPILER_THREADS;
|
||||
extern const Info<bool> GFX_SAVE_TEXTURE_CACHE_TO_STATE;
|
||||
extern const Info<bool> GFX_PREFER_VS_FOR_LINE_POINT_EXPANSION;
|
||||
|
||||
extern const Info<bool> GFX_SW_DUMP_OBJECTS;
|
||||
extern const Info<bool> GFX_SW_DUMP_TEV_STAGES;
|
||||
|
||||
@@ -94,7 +94,7 @@ static size_t s_state_writes_in_queue;
|
||||
static std::condition_variable s_state_write_queue_is_empty;
|
||||
|
||||
// Don't forget to increase this after doing changes on the savestate system
|
||||
constexpr u32 STATE_VERSION = 154; // Last changed in PR 11177
|
||||
constexpr u32 STATE_VERSION = 155; // Last changed in PR 10890
|
||||
|
||||
// Maps savestate versions to Dolphin versions.
|
||||
// Versions after 42 don't need to be added to this list,
|
||||
|
||||
@@ -128,15 +128,18 @@ void AdvancedWidget::CreateWidgets()
|
||||
m_enable_prog_scan = new ToolTipCheckBox(tr("Enable Progressive Scan"));
|
||||
m_backend_multithreading =
|
||||
new GraphicsBool(tr("Backend Multithreading"), Config::GFX_BACKEND_MULTITHREADING);
|
||||
m_prefer_vs_for_point_line_expansion = new GraphicsBool(
|
||||
tr("Prefer VS for Point/Line Expansion"), Config::GFX_PREFER_VS_FOR_LINE_POINT_EXPANSION);
|
||||
|
||||
misc_layout->addWidget(m_enable_cropping, 0, 0);
|
||||
misc_layout->addWidget(m_enable_prog_scan, 0, 1);
|
||||
misc_layout->addWidget(m_backend_multithreading, 1, 0);
|
||||
misc_layout->addWidget(m_prefer_vs_for_point_line_expansion, 1, 1);
|
||||
#ifdef _WIN32
|
||||
m_borderless_fullscreen =
|
||||
new GraphicsBool(tr("Borderless Fullscreen"), Config::GFX_BORDERLESS_FULLSCREEN);
|
||||
|
||||
misc_layout->addWidget(m_borderless_fullscreen, 1, 1);
|
||||
misc_layout->addWidget(m_borderless_fullscreen, 2, 0);
|
||||
#endif
|
||||
|
||||
// Experimental.
|
||||
@@ -198,6 +201,10 @@ void AdvancedWidget::SaveSettings()
|
||||
void AdvancedWidget::OnBackendChanged()
|
||||
{
|
||||
m_backend_multithreading->setEnabled(g_Config.backend_info.bSupportsMultithreading);
|
||||
m_prefer_vs_for_point_line_expansion->setEnabled(
|
||||
g_Config.backend_info.bSupportsGeometryShaders &&
|
||||
g_Config.backend_info.bSupportsVSLinePointExpand);
|
||||
AddDescriptions();
|
||||
}
|
||||
|
||||
void AdvancedWidget::OnEmulationStateChanged(bool running)
|
||||
@@ -289,6 +296,11 @@ void AdvancedWidget::AddDescriptions()
|
||||
"this option may result in a performance improvement on systems with more than "
|
||||
"two CPU cores. Currently, this is limited to the Vulkan backend.<br><br>"
|
||||
"<dolphin_emphasis>If unsure, leave this checked.</dolphin_emphasis>");
|
||||
static const char TR_PREFER_VS_FOR_POINT_LINE_EXPANSION_DESCRIPTION[] =
|
||||
QT_TR_NOOP("On backends that support both using the geometry shader and the vertex shader "
|
||||
"for expanding points and lines, selects the vertex shader for the job. May "
|
||||
"affect performance."
|
||||
"<br><br>%1");
|
||||
static const char TR_DEFER_EFB_ACCESS_INVALIDATION_DESCRIPTION[] = QT_TR_NOOP(
|
||||
"Defers invalidation of the EFB access cache until a GPU synchronization command "
|
||||
"is executed. If disabled, the cache will be invalidated with every draw call. "
|
||||
@@ -316,6 +328,9 @@ void AdvancedWidget::AddDescriptions()
|
||||
"unchecked.</dolphin_emphasis>");
|
||||
#endif
|
||||
|
||||
static const char IF_UNSURE_UNCHECKED[] =
|
||||
QT_TR_NOOP("<dolphin_emphasis>If unsure, leave this unchecked.</dolphin_emphasis>");
|
||||
|
||||
m_enable_wireframe->SetDescription(tr(TR_WIREFRAME_DESCRIPTION));
|
||||
m_show_statistics->SetDescription(tr(TR_SHOW_STATS_DESCRIPTION));
|
||||
m_enable_format_overlay->SetDescription(tr(TR_TEXTURE_FORMAT_DESCRIPTION));
|
||||
@@ -337,6 +352,17 @@ void AdvancedWidget::AddDescriptions()
|
||||
m_enable_cropping->SetDescription(tr(TR_CROPPING_DESCRIPTION));
|
||||
m_enable_prog_scan->SetDescription(tr(TR_PROGRESSIVE_SCAN_DESCRIPTION));
|
||||
m_backend_multithreading->SetDescription(tr(TR_BACKEND_MULTITHREADING_DESCRIPTION));
|
||||
QString vsexpand_extra;
|
||||
if (!g_Config.backend_info.bSupportsGeometryShaders)
|
||||
vsexpand_extra = tr("Forced on because %1 doesn't support geometry shaders.")
|
||||
.arg(tr(g_Config.backend_info.DisplayName.c_str()));
|
||||
else if (!g_Config.backend_info.bSupportsVSLinePointExpand)
|
||||
vsexpand_extra = tr("Forced off because %1 doesn't support VS expansion.")
|
||||
.arg(tr(g_Config.backend_info.DisplayName.c_str()));
|
||||
else
|
||||
vsexpand_extra = tr(IF_UNSURE_UNCHECKED);
|
||||
m_prefer_vs_for_point_line_expansion->SetDescription(
|
||||
tr(TR_PREFER_VS_FOR_POINT_LINE_EXPANSION_DESCRIPTION).arg(vsexpand_extra));
|
||||
#ifdef _WIN32
|
||||
m_borderless_fullscreen->SetDescription(tr(TR_BORDERLESS_FULLSCREEN_DESCRIPTION));
|
||||
#endif
|
||||
|
||||
@@ -59,6 +59,7 @@ private:
|
||||
GraphicsBool* m_enable_cropping;
|
||||
ToolTipCheckBox* m_enable_prog_scan;
|
||||
GraphicsBool* m_backend_multithreading;
|
||||
GraphicsBool* m_prefer_vs_for_point_line_expansion;
|
||||
GraphicsBool* m_borderless_fullscreen;
|
||||
|
||||
// Experimental
|
||||
|
||||
@@ -19,6 +19,14 @@
|
||||
|
||||
namespace DX12
|
||||
{
|
||||
static bool UsesDynamicVertexLoader(const AbstractPipeline* pipeline)
|
||||
{
|
||||
const AbstractPipelineUsage usage = static_cast<const DXPipeline*>(pipeline)->GetUsage();
|
||||
return (g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader &&
|
||||
usage == AbstractPipelineUsage::GXUber) ||
|
||||
(g_ActiveConfig.UseVSForLinePointExpand() && usage != AbstractPipelineUsage::Utility);
|
||||
}
|
||||
|
||||
Renderer::Renderer(std::unique_ptr<SwapChain> swap_chain, float backbuffer_scale)
|
||||
: ::Renderer(swap_chain ? swap_chain->GetWidth() : 0, swap_chain ? swap_chain->GetHeight() : 0,
|
||||
backbuffer_scale,
|
||||
@@ -364,8 +372,7 @@ void Renderer::DrawIndexed(u32 base_index, u32 num_indices, u32 base_vertex)
|
||||
return;
|
||||
|
||||
// DX12 is great and doesn't include the base vertex in SV_VertexID
|
||||
if (static_cast<const DXPipeline*>(m_current_pipeline)->GetUsage() ==
|
||||
AbstractPipelineUsage::GXUber)
|
||||
if (UsesDynamicVertexLoader(m_current_pipeline))
|
||||
g_dx_context->GetCommandList()->SetGraphicsRoot32BitConstant(
|
||||
ROOT_PARAMETER_BASE_VERTEX_CONSTANT, base_vertex, 0);
|
||||
g_dx_context->GetCommandList()->DrawIndexedInstanced(num_indices, 1, base_index, base_vertex, 0);
|
||||
@@ -601,8 +608,7 @@ bool Renderer::ApplyState()
|
||||
}
|
||||
}
|
||||
|
||||
if (dirty_bits & DirtyState_VS_SRV_Descriptor &&
|
||||
pipeline->GetUsage() == AbstractPipelineUsage::GXUber)
|
||||
if (dirty_bits & DirtyState_VS_SRV_Descriptor && UsesDynamicVertexLoader(pipeline))
|
||||
{
|
||||
cmdlist->SetGraphicsRootDescriptorTable(ROOT_PARAMETER_VS_SRV,
|
||||
m_state.vertex_srv_descriptor_base);
|
||||
@@ -724,9 +730,7 @@ bool Renderer::UpdateUAVDescriptorTable()
|
||||
|
||||
bool Renderer::UpdateVSSRVDescriptorTable()
|
||||
{
|
||||
if (!g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader ||
|
||||
static_cast<const DXPipeline*>(m_current_pipeline)->GetUsage() !=
|
||||
AbstractPipelineUsage::GXUber)
|
||||
if (!UsesDynamicVertexLoader(m_current_pipeline))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -353,12 +353,15 @@ bool DXContext::CreateGXRootSignature()
|
||||
param_count++;
|
||||
SetRootParamCBV(¶ms[param_count], 1, D3D12_SHADER_VISIBILITY_VERTEX);
|
||||
param_count++;
|
||||
SetRootParamCBV(¶ms[param_count], 0, D3D12_SHADER_VISIBILITY_GEOMETRY);
|
||||
if (g_ActiveConfig.UseVSForLinePointExpand())
|
||||
SetRootParamCBV(¶ms[param_count], 2, D3D12_SHADER_VISIBILITY_VERTEX);
|
||||
else
|
||||
SetRootParamCBV(¶ms[param_count], 0, D3D12_SHADER_VISIBILITY_GEOMETRY);
|
||||
param_count++;
|
||||
SetRootParamTable(¶ms[param_count], &ranges[param_count], D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 3,
|
||||
1, D3D12_SHADER_VISIBILITY_VERTEX);
|
||||
param_count++;
|
||||
SetRootParamConstant(¶ms[param_count], 2, 1, D3D12_SHADER_VISIBILITY_VERTEX);
|
||||
SetRootParamConstant(¶ms[param_count], 3, 1, D3D12_SHADER_VISIBILITY_VERTEX);
|
||||
param_count++;
|
||||
|
||||
// Since these must be contiguous, pixel lighting goes to bbox if not enabled.
|
||||
|
||||
@@ -88,6 +88,7 @@ void VideoBackend::FillBackendInfo()
|
||||
g_Config.backend_info.bSupportsSettingObjectNames = true;
|
||||
g_Config.backend_info.bSupportsPartialMultisampleResolve = true;
|
||||
g_Config.backend_info.bSupportsDynamicVertexLoader = true;
|
||||
g_Config.backend_info.bSupportsVSLinePointExpand = true;
|
||||
|
||||
// We can only check texture support once we have a device.
|
||||
if (g_dx_context)
|
||||
|
||||
@@ -83,7 +83,7 @@ public:
|
||||
void SetTexture(u32 idx, id<MTLTexture> texture);
|
||||
void SetSampler(u32 idx, const SamplerState& sampler);
|
||||
void SetComputeTexture(const Texture* texture);
|
||||
void InvalidateUniforms(bool vertex, bool fragment);
|
||||
void InvalidateUniforms(bool vertex, bool geometry, bool fragment);
|
||||
void SetUtilityUniform(const void* buffer, size_t size);
|
||||
void SetTexelBuffer(id<MTLBuffer> buffer, u32 offset0, u32 offset1);
|
||||
void SetVerticesAndIndices(id<MTLBuffer> vertices, id<MTLBuffer> indices);
|
||||
@@ -180,6 +180,7 @@ private:
|
||||
{
|
||||
// clang-format off
|
||||
bool has_gx_vs_uniform : 1;
|
||||
bool has_gx_gs_uniform : 1;
|
||||
bool has_gx_ps_uniform : 1;
|
||||
bool has_utility_vs_uniform : 1;
|
||||
bool has_utility_ps_uniform : 1;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "VideoBackends/Metal/MTLTexture.h"
|
||||
#include "VideoBackends/Metal/MTLUtil.h"
|
||||
|
||||
#include "VideoCommon/GeometryShaderManager.h"
|
||||
#include "VideoCommon/PixelShaderManager.h"
|
||||
#include "VideoCommon/Statistics.h"
|
||||
#include "VideoCommon/VertexShaderManager.h"
|
||||
@@ -462,9 +463,10 @@ void Metal::StateTracker::UnbindTexture(id<MTLTexture> texture)
|
||||
}
|
||||
}
|
||||
|
||||
void Metal::StateTracker::InvalidateUniforms(bool vertex, bool fragment)
|
||||
void Metal::StateTracker::InvalidateUniforms(bool vertex, bool geometry, bool fragment)
|
||||
{
|
||||
m_flags.has_gx_vs_uniform &= !vertex;
|
||||
m_flags.has_gx_gs_uniform &= !geometry;
|
||||
m_flags.has_gx_ps_uniform &= !fragment;
|
||||
}
|
||||
|
||||
@@ -722,6 +724,14 @@ void Metal::StateTracker::PrepareRender()
|
||||
ADDSTAT(g_stats.this_frame.bytes_uniform_streamed,
|
||||
Align(sizeof(VertexShaderConstants), AlignMask::Uniform));
|
||||
}
|
||||
if (!m_flags.has_gx_gs_uniform && pipe->UsesVertexBuffer(2))
|
||||
{
|
||||
m_flags.has_gx_gs_uniform = true;
|
||||
[m_current_render_encoder setVertexBytes:&GeometryShaderManager::constants
|
||||
length:sizeof(GeometryShaderConstants)
|
||||
atIndex:2];
|
||||
ADDSTAT(g_stats.this_frame.bytes_uniform_streamed, sizeof(GeometryShaderConstants));
|
||||
}
|
||||
if (!m_flags.has_gx_ps_uniform)
|
||||
{
|
||||
m_flags.has_gx_ps_uniform = true;
|
||||
|
||||
@@ -75,6 +75,7 @@ void Metal::Util::PopulateBackendInfo(VideoConfig* config)
|
||||
// Metal requires multisample resolve to be done on a render pass
|
||||
config->backend_info.bSupportsPartialMultisampleResolve = false;
|
||||
config->backend_info.bSupportsDynamicVertexLoader = true;
|
||||
config->backend_info.bSupportsVSLinePointExpand = true;
|
||||
}
|
||||
|
||||
void Metal::Util::PopulateBackendInfoAdapters(VideoConfig* config,
|
||||
@@ -427,6 +428,7 @@ std::optional<std::string> Metal::Util::TranslateShaderToMSL(ShaderStage stage,
|
||||
static const spirv_cross::MSLResourceBinding resource_bindings[] = {
|
||||
MakeResourceBinding(spv::ExecutionModelVertex, 0, 0, 1, 0, 0), // vs/ubo
|
||||
MakeResourceBinding(spv::ExecutionModelVertex, 0, 1, 1, 0, 0), // vs/ubo
|
||||
MakeResourceBinding(spv::ExecutionModelVertex, 0, 2, 2, 0, 0), // vs/ubo
|
||||
MakeResourceBinding(spv::ExecutionModelVertex, 2, 1, 0, 0, 0), // vs/ssbo
|
||||
MakeResourceBinding(spv::ExecutionModelFragment, 0, 0, 0, 0, 0), // vs/ubo
|
||||
MakeResourceBinding(spv::ExecutionModelFragment, 0, 1, 1, 0, 0), // vs/ubo
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "VideoBackends/Metal/MTLStateTracker.h"
|
||||
|
||||
#include "VideoCommon/GeometryShaderManager.h"
|
||||
#include "VideoCommon/PixelShaderManager.h"
|
||||
#include "VideoCommon/Statistics.h"
|
||||
#include "VideoCommon/VertexShaderManager.h"
|
||||
@@ -88,7 +89,9 @@ void Metal::VertexManager::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32
|
||||
|
||||
void Metal::VertexManager::UploadUniforms()
|
||||
{
|
||||
g_state_tracker->InvalidateUniforms(VertexShaderManager::dirty, PixelShaderManager::dirty);
|
||||
g_state_tracker->InvalidateUniforms(VertexShaderManager::dirty, GeometryShaderManager::dirty,
|
||||
PixelShaderManager::dirty);
|
||||
VertexShaderManager::dirty = false;
|
||||
GeometryShaderManager::dirty = false;
|
||||
PixelShaderManager::dirty = false;
|
||||
}
|
||||
|
||||
@@ -423,6 +423,8 @@ Renderer::Renderer(std::unique_ptr<GLContext> main_gl_context, float backbuffer_
|
||||
((GLExtensions::Version() >= 310) || GLExtensions::Supports("GL_NV_primitive_restart"));
|
||||
g_Config.backend_info.bSupportsFragmentStoresAndAtomics =
|
||||
GLExtensions::Supports("GL_ARB_shader_storage_buffer_object");
|
||||
g_Config.backend_info.bSupportsVSLinePointExpand =
|
||||
GLExtensions::Supports("GL_ARB_shader_storage_buffer_object");
|
||||
g_Config.backend_info.bSupportsGSInstancing = GLExtensions::Supports("GL_ARB_gpu_shader5");
|
||||
g_Config.backend_info.bSupportsSSAA = GLExtensions::Supports("GL_ARB_gpu_shader5") &&
|
||||
GLExtensions::Supports("GL_ARB_sample_shading");
|
||||
|
||||
@@ -58,6 +58,11 @@ bool VertexManager::Initialize()
|
||||
|
||||
m_vertex_buffer = StreamBuffer::Create(GL_ARRAY_BUFFER, VERTEX_STREAM_BUFFER_SIZE);
|
||||
m_index_buffer = StreamBuffer::Create(GL_ELEMENT_ARRAY_BUFFER, INDEX_STREAM_BUFFER_SIZE);
|
||||
if (g_ActiveConfig.UseVSForLinePointExpand() ||
|
||||
g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader)
|
||||
{
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_vertex_buffer->GetGLBufferId());
|
||||
}
|
||||
|
||||
if (g_ActiveConfig.backend_info.bSupportsPaletteConversion)
|
||||
{
|
||||
|
||||
@@ -156,9 +156,11 @@ bool ObjectCache::CreateDescriptorSetLayouts()
|
||||
{5, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
}};
|
||||
|
||||
std::array<VkDescriptorSetLayoutBinding, 3> ubo_bindings = standard_ubo_bindings;
|
||||
|
||||
std::array<VkDescriptorSetLayoutCreateInfo, NUM_DESCRIPTOR_SET_LAYOUTS> create_infos{{
|
||||
{VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0,
|
||||
static_cast<u32>(standard_ubo_bindings.size()), standard_ubo_bindings.data()},
|
||||
static_cast<u32>(ubo_bindings.size()), ubo_bindings.data()},
|
||||
{VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0,
|
||||
static_cast<u32>(standard_sampler_bindings.size()), standard_sampler_bindings.data()},
|
||||
{VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0,
|
||||
@@ -172,8 +174,17 @@ bool ObjectCache::CreateDescriptorSetLayouts()
|
||||
}};
|
||||
|
||||
// Don't set the GS bit if geometry shaders aren't available.
|
||||
if (!g_ActiveConfig.backend_info.bSupportsGeometryShaders)
|
||||
if (g_ActiveConfig.UseVSForLinePointExpand())
|
||||
{
|
||||
if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
|
||||
ubo_bindings[UBO_DESCRIPTOR_SET_BINDING_GS].stageFlags |= VK_SHADER_STAGE_VERTEX_BIT;
|
||||
else
|
||||
ubo_bindings[UBO_DESCRIPTOR_SET_BINDING_GS].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
}
|
||||
else if (!g_ActiveConfig.backend_info.bSupportsGeometryShaders)
|
||||
{
|
||||
create_infos[DESCRIPTOR_SET_LAYOUT_STANDARD_UNIFORM_BUFFERS].bindingCount--;
|
||||
}
|
||||
|
||||
// Remove the dynamic vertex loader's buffer if it'll never be needed
|
||||
if (!g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader)
|
||||
@@ -244,12 +255,14 @@ bool ObjectCache::CreatePipelineLayouts()
|
||||
static_cast<u32>(compute_sets.size()), compute_sets.data(), 0, nullptr},
|
||||
}};
|
||||
|
||||
const bool ssbos_in_standard =
|
||||
g_ActiveConfig.backend_info.bSupportsBBox || g_ActiveConfig.UseVSForLinePointExpand();
|
||||
|
||||
// If bounding box is unsupported, don't bother with the SSBO descriptor set.
|
||||
if (!g_ActiveConfig.backend_info.bSupportsBBox)
|
||||
if (!ssbos_in_standard)
|
||||
pipeline_layout_info[PIPELINE_LAYOUT_STANDARD].setLayoutCount--;
|
||||
// If neither SSBO-using feature is supported, skip in ubershaders too
|
||||
if (!g_ActiveConfig.backend_info.bSupportsBBox &&
|
||||
!g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader)
|
||||
if (!ssbos_in_standard && !g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader)
|
||||
pipeline_layout_info[PIPELINE_LAYOUT_UBER].setLayoutCount--;
|
||||
|
||||
for (size_t i = 0; i < pipeline_layout_info.size(); i++)
|
||||
|
||||
@@ -458,6 +458,9 @@ void StateTracker::UpdateGXDescriptorSet()
|
||||
std::array<VkWriteDescriptorSet, MAX_DESCRIPTOR_WRITES> writes;
|
||||
u32 num_writes = 0;
|
||||
|
||||
const bool needs_gs_ubo = g_ActiveConfig.backend_info.bSupportsGeometryShaders ||
|
||||
g_ActiveConfig.UseVSForLinePointExpand();
|
||||
|
||||
if (m_dirty_flags & DIRTY_FLAG_GX_UBOS || m_gx_descriptor_sets[0] == VK_NULL_HANDLE)
|
||||
{
|
||||
m_gx_descriptor_sets[0] = g_command_buffer_mgr->AllocateDescriptorSet(
|
||||
@@ -465,8 +468,7 @@ void StateTracker::UpdateGXDescriptorSet()
|
||||
|
||||
for (size_t i = 0; i < NUM_UBO_DESCRIPTOR_SET_BINDINGS; i++)
|
||||
{
|
||||
if (i == UBO_DESCRIPTOR_SET_BINDING_GS &&
|
||||
!g_ActiveConfig.backend_info.bSupportsGeometryShaders)
|
||||
if (i == UBO_DESCRIPTOR_SET_BINDING_GS && !needs_gs_ubo)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -505,8 +507,9 @@ void StateTracker::UpdateGXDescriptorSet()
|
||||
}
|
||||
|
||||
const bool needs_bbox_ssbo = g_ActiveConfig.backend_info.bSupportsBBox;
|
||||
const bool needs_vertex_ssbo = g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader &&
|
||||
m_pipeline->GetUsage() == AbstractPipelineUsage::GXUber;
|
||||
const bool needs_vertex_ssbo = (g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader &&
|
||||
m_pipeline->GetUsage() == AbstractPipelineUsage::GXUber) ||
|
||||
g_ActiveConfig.UseVSForLinePointExpand();
|
||||
const bool needs_ssbo = needs_bbox_ssbo || needs_vertex_ssbo;
|
||||
|
||||
if (needs_ssbo &&
|
||||
@@ -520,7 +523,8 @@ void StateTracker::UpdateGXDescriptorSet()
|
||||
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, nullptr, m_gx_descriptor_sets[2], 0, 0, 1,
|
||||
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nullptr, &m_bindings.ssbo, nullptr};
|
||||
|
||||
if (g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader)
|
||||
if (g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader ||
|
||||
g_ActiveConfig.UseVSForLinePointExpand())
|
||||
{
|
||||
writes[num_writes++] = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
nullptr,
|
||||
@@ -546,21 +550,18 @@ void StateTracker::UpdateGXDescriptorSet()
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline->GetVkPipelineLayout(), 0,
|
||||
needs_ssbo ? NUM_GX_DESCRIPTOR_SETS : (NUM_GX_DESCRIPTOR_SETS - 1),
|
||||
m_gx_descriptor_sets.data(),
|
||||
g_ActiveConfig.backend_info.bSupportsGeometryShaders ?
|
||||
NUM_UBO_DESCRIPTOR_SET_BINDINGS :
|
||||
(NUM_UBO_DESCRIPTOR_SET_BINDINGS - 1),
|
||||
needs_gs_ubo ? NUM_UBO_DESCRIPTOR_SET_BINDINGS :
|
||||
(NUM_UBO_DESCRIPTOR_SET_BINDINGS - 1),
|
||||
m_bindings.gx_ubo_offsets.data());
|
||||
m_dirty_flags &= ~(DIRTY_FLAG_DESCRIPTOR_SETS | DIRTY_FLAG_GX_UBO_OFFSETS);
|
||||
}
|
||||
else if (m_dirty_flags & DIRTY_FLAG_GX_UBO_OFFSETS)
|
||||
{
|
||||
vkCmdBindDescriptorSets(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline->GetVkPipelineLayout(), 0,
|
||||
1, m_gx_descriptor_sets.data(),
|
||||
g_ActiveConfig.backend_info.bSupportsGeometryShaders ?
|
||||
NUM_UBO_DESCRIPTOR_SET_BINDINGS :
|
||||
(NUM_UBO_DESCRIPTOR_SET_BINDINGS - 1),
|
||||
m_bindings.gx_ubo_offsets.data());
|
||||
vkCmdBindDescriptorSets(
|
||||
g_command_buffer_mgr->GetCurrentCommandBuffer(), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
m_pipeline->GetVkPipelineLayout(), 0, 1, m_gx_descriptor_sets.data(),
|
||||
needs_gs_ubo ? NUM_UBO_DESCRIPTOR_SET_BINDINGS : (NUM_UBO_DESCRIPTOR_SET_BINDINGS - 1),
|
||||
m_bindings.gx_ubo_offsets.data());
|
||||
m_dirty_flags &= ~DIRTY_FLAG_GX_UBO_OFFSETS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,6 +304,7 @@ void VulkanContext::PopulateBackendInfo(VideoConfig* config)
|
||||
config->backend_info.bSupportsSettingObjectNames = false; // Dependent on features.
|
||||
config->backend_info.bSupportsPartialMultisampleResolve = true; // Assumed support.
|
||||
config->backend_info.bSupportsDynamicVertexLoader = true; // Assumed support.
|
||||
config->backend_info.bSupportsVSLinePointExpand = true; // Assumed support.
|
||||
}
|
||||
|
||||
void VulkanContext::PopulateBackendInfoAdapters(VideoConfig* config, const GPUList& gpu_list)
|
||||
|
||||
@@ -102,9 +102,18 @@ struct VertexShaderConstants
|
||||
std::array<u32, 8> vertex_offset_texcoords;
|
||||
};
|
||||
|
||||
enum class VSExpand : u32
|
||||
{
|
||||
None = 0,
|
||||
Point,
|
||||
Line,
|
||||
};
|
||||
|
||||
struct GeometryShaderConstants
|
||||
{
|
||||
float4 stereoparams;
|
||||
float4 lineptparams;
|
||||
int4 texoffset;
|
||||
VSExpand vs_expand; // Used by VS point/line expansion in ubershaders
|
||||
u32 pad[3];
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace VideoCommon
|
||||
// As pipelines encompass both shader UIDs and render states, changes to either of these should
|
||||
// also increment the pipeline UID version. Incrementing the UID version will cause all UID
|
||||
// caches to be invalidated.
|
||||
constexpr u32 GX_PIPELINE_UID_VERSION = 5; // Last changed in PR 10747
|
||||
constexpr u32 GX_PIPELINE_UID_VERSION = 6; // Last changed in PR 10890
|
||||
|
||||
struct GXPipelineUid
|
||||
{
|
||||
|
||||
@@ -97,10 +97,8 @@ ShaderCode GenerateGeometryShaderCode(APIType api_type, const ShaderHostConfig&
|
||||
else
|
||||
out.Write("cbuffer GSBlock {{\n");
|
||||
|
||||
out.Write("\tfloat4 " I_STEREOPARAMS ";\n"
|
||||
"\tfloat4 " I_LINEPTPARAMS ";\n"
|
||||
"\tint4 " I_TEXOFFSET ";\n"
|
||||
"}};\n");
|
||||
out.Write("{}", s_geometry_shader_uniforms);
|
||||
out.Write("}};\n");
|
||||
|
||||
out.Write("struct VS_OUTPUT {{\n");
|
||||
GenerateVSOutputMembers(out, api_type, uid_data->numTexGens, host_config, "",
|
||||
@@ -171,22 +169,7 @@ ShaderCode GenerateGeometryShaderCode(APIType api_type, const ShaderHostConfig&
|
||||
"\tVS_OUTPUT end = o[1];\n");
|
||||
}
|
||||
|
||||
// GameCube/Wii's line drawing algorithm is a little quirky. It does not
|
||||
// use the correct line caps. Instead, the line caps are vertical or
|
||||
// horizontal depending the slope of the line.
|
||||
out.Write("\tfloat2 offset;\n"
|
||||
"\tfloat2 to = abs(end.pos.xy / end.pos.w - start.pos.xy / start.pos.w);\n"
|
||||
// FIXME: What does real hardware do when line is at a 45-degree angle?
|
||||
// FIXME: Lines aren't drawn at the correct width. See Twilight Princess map.
|
||||
"\tif (" I_LINEPTPARAMS ".y * to.y > " I_LINEPTPARAMS ".x * to.x) {{\n"
|
||||
// Line is more tall. Extend geometry left and right.
|
||||
// Lerp LineWidth/2 from [0..VpWidth] to [-1..1]
|
||||
"\t\toffset = float2(" I_LINEPTPARAMS ".z / " I_LINEPTPARAMS ".x, 0);\n"
|
||||
"\t}} else {{\n"
|
||||
// Line is more wide. Extend geometry up and down.
|
||||
// Lerp LineWidth/2 from [0..VpHeight] to [1..-1]
|
||||
"\t\toffset = float2(0, -" I_LINEPTPARAMS ".z / " I_LINEPTPARAMS ".y);\n"
|
||||
"\t}}\n");
|
||||
GenerateLineOffset(out, "\t", "\t\t", "end.pos", "start.pos", "");
|
||||
}
|
||||
else if (primitive_type == PrimitiveType::Points)
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user