summaryrefslogtreecommitdiff
path: root/src/video_core
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-06-24 02:41:09 -0300
committerGravatar ameerj2021-07-22 21:51:39 -0400
commit7dafa96ab59892b7f1fbffdb61e4326e6443955f (patch)
tree5ab58d56860db635542ea1ec24be258bd86b40b9 /src/video_core
parentvk_graphics_pipeline: Implement conservative rendering (diff)
downloadyuzu-7dafa96ab59892b7f1fbffdb61e4326e6443955f.tar.gz
yuzu-7dafa96ab59892b7f1fbffdb61e4326e6443955f.tar.xz
yuzu-7dafa96ab59892b7f1fbffdb61e4326e6443955f.zip
shader: Rework varyings and implement passthrough geometry shaders
Put all varyings into a single std::bitset with helpers to access it. Implement passthrough geometry shaders using host's.
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/engines/maxwell_3d.h7
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp7
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp6
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp16
-rw-r--r--src/video_core/shader_environment.cpp10
-rw-r--r--src/video_core/vulkan_common/vulkan_device.cpp6
-rw-r--r--src/video_core/vulkan_common/vulkan_device.h6
7 files changed, 43 insertions, 15 deletions
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index da2ded671..471d5686a 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -961,7 +961,11 @@ public:
961 961
962 SamplerIndex sampler_index; 962 SamplerIndex sampler_index;
963 963
964 INSERT_PADDING_WORDS_NOINIT(0x25); 964 INSERT_PADDING_WORDS_NOINIT(0x2);
965
966 std::array<u32, 8> gp_passthrough_mask;
967
968 INSERT_PADDING_WORDS_NOINIT(0x1B);
965 969
966 u32 depth_test_enable; 970 u32 depth_test_enable;
967 971
@@ -1628,6 +1632,7 @@ ASSERT_REG_POSITION(zeta_width, 0x48a);
1628ASSERT_REG_POSITION(zeta_height, 0x48b); 1632ASSERT_REG_POSITION(zeta_height, 0x48b);
1629ASSERT_REG_POSITION(zeta_depth, 0x48c); 1633ASSERT_REG_POSITION(zeta_depth, 0x48c);
1630ASSERT_REG_POSITION(sampler_index, 0x48D); 1634ASSERT_REG_POSITION(sampler_index, 0x48D);
1635ASSERT_REG_POSITION(gp_passthrough_mask, 0x490);
1631ASSERT_REG_POSITION(depth_test_enable, 0x4B3); 1636ASSERT_REG_POSITION(depth_test_enable, 0x4B3);
1632ASSERT_REG_POSITION(independent_blend_enable, 0x4B9); 1637ASSERT_REG_POSITION(independent_blend_enable, 0x4B9);
1633ASSERT_REG_POSITION(depth_write_enabled, 0x4BA); 1638ASSERT_REG_POSITION(depth_write_enabled, 0x4BA);
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index 5af9b7745..06e39a503 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -61,10 +61,10 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key,
61 bool glasm_use_storage_buffers, bool use_assembly_shaders) { 61 bool glasm_use_storage_buffers, bool use_assembly_shaders) {
62 Shader::RuntimeInfo info; 62 Shader::RuntimeInfo info;
63 if (previous_program) { 63 if (previous_program) {
64 info.previous_stage_stores_generic = previous_program->info.stores_generics; 64 info.previous_stage_stores = previous_program->info.stores;
65 } else { 65 } else {
66 // Mark all stores as available 66 // Mark all stores as available for vertex shaders
67 info.previous_stage_stores_generic.flip(); 67 info.previous_stage_stores.mask.set();
68 } 68 }
69 switch (program.stage) { 69 switch (program.stage) {
70 case Shader::Stage::VertexB: 70 case Shader::Stage::VertexB:
@@ -187,6 +187,7 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo
187 .support_demote_to_helper_invocation = false, 187 .support_demote_to_helper_invocation = false,
188 .support_int64_atomics = false, 188 .support_int64_atomics = false,
189 .support_derivative_control = device.HasDerivativeControl(), 189 .support_derivative_control = device.HasDerivativeControl(),
190 .support_geometry_shader_passthrough = false, // TODO
190 .support_gl_nv_gpu_shader_5 = device.HasNvGpuShader5(), 191 .support_gl_nv_gpu_shader_5 = device.HasNvGpuShader5(),
191 .support_gl_amd_gpu_shader_half_float = device.HasAmdShaderHalfFloat(), 192 .support_gl_amd_gpu_shader_half_float = device.HasAmdShaderHalfFloat(),
192 .support_gl_texture_shadow_lod = device.HasTextureShadowLod(), 193 .support_gl_texture_shadow_lod = device.HasTextureShadowLod(),
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
index 70e183e65..6d664ed6b 100644
--- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
@@ -487,10 +487,9 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
487 static_vector<VkVertexInputBindingDivisorDescriptionEXT, 32> vertex_binding_divisors; 487 static_vector<VkVertexInputBindingDivisorDescriptionEXT, 32> vertex_binding_divisors;
488 static_vector<VkVertexInputAttributeDescription, 32> vertex_attributes; 488 static_vector<VkVertexInputAttributeDescription, 32> vertex_attributes;
489 if (key.state.dynamic_vertex_input) { 489 if (key.state.dynamic_vertex_input) {
490 const auto& input_attributes = stage_infos[0].input_generics;
491 for (size_t index = 0; index < key.state.attributes.size(); ++index) { 490 for (size_t index = 0; index < key.state.attributes.size(); ++index) {
492 const u32 type = key.state.DynamicAttributeType(index); 491 const u32 type = key.state.DynamicAttributeType(index);
493 if (!input_attributes[index].used || type == 0) { 492 if (!stage_infos[0].loads.Generic(index) || type == 0) {
494 continue; 493 continue;
495 } 494 }
496 vertex_attributes.push_back({ 495 vertex_attributes.push_back({
@@ -526,10 +525,9 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
526 }); 525 });
527 } 526 }
528 } 527 }
529 const auto& input_attributes = stage_infos[0].input_generics;
530 for (size_t index = 0; index < key.state.attributes.size(); ++index) { 528 for (size_t index = 0; index < key.state.attributes.size(); ++index) {
531 const auto& attribute = key.state.attributes[index]; 529 const auto& attribute = key.state.attributes[index];
532 if (!attribute.enabled || !input_attributes[index].used) { 530 if (!attribute.enabled || !stage_infos[0].loads.Generic(index)) {
533 continue; 531 continue;
534 } 532 }
535 vertex_attributes.push_back({ 533 vertex_attributes.push_back({
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index ec06b124f..7aaa40ef2 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -123,18 +123,21 @@ Shader::AttributeType AttributeType(const FixedPipelineState& state, size_t inde
123 return Shader::AttributeType::Disabled; 123 return Shader::AttributeType::Disabled;
124} 124}
125 125
126Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineCacheKey& key, 126Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> programs,
127 const GraphicsPipelineCacheKey& key,
127 const Shader::IR::Program& program, 128 const Shader::IR::Program& program,
128 const Shader::IR::Program* previous_program) { 129 const Shader::IR::Program* previous_program) {
129 Shader::RuntimeInfo info; 130 Shader::RuntimeInfo info;
130 if (previous_program) { 131 if (previous_program) {
131 info.previous_stage_stores_generic = previous_program->info.stores_generics; 132 info.previous_stage_stores = previous_program->info.stores;
133 if (previous_program->is_geometry_passthrough) {
134 info.previous_stage_stores.mask |= previous_program->info.passthrough.mask;
135 }
132 } else { 136 } else {
133 // Mark all stores as available 137 info.previous_stage_stores.mask.set();
134 info.previous_stage_stores_generic.flip();
135 } 138 }
136 const Shader::Stage stage{program.stage}; 139 const Shader::Stage stage{program.stage};
137 const bool has_geometry{key.unique_hashes[4] != 0}; 140 const bool has_geometry{key.unique_hashes[4] != 0 && !programs[4].is_geometry_passthrough};
138 const bool gl_ndc{key.state.ndc_minus_one_to_one != 0}; 141 const bool gl_ndc{key.state.ndc_minus_one_to_one != 0};
139 const float point_size{Common::BitCast<float>(key.state.point_size)}; 142 const float point_size{Common::BitCast<float>(key.state.point_size)};
140 switch (stage) { 143 switch (stage) {
@@ -302,6 +305,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, Tegra::Engines::Maxw
302 .support_demote_to_helper_invocation = true, 305 .support_demote_to_helper_invocation = true,
303 .support_int64_atomics = device.IsExtShaderAtomicInt64Supported(), 306 .support_int64_atomics = device.IsExtShaderAtomicInt64Supported(),
304 .support_derivative_control = true, 307 .support_derivative_control = true,
308 .support_geometry_shader_passthrough = device.IsNvGeometryShaderPassthroughSupported(),
305 309
306 .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(), 310 .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(),
307 311
@@ -518,7 +522,7 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
518 const size_t stage_index{index - 1}; 522 const size_t stage_index{index - 1};
519 infos[stage_index] = &program.info; 523 infos[stage_index] = &program.info;
520 524
521 const Shader::RuntimeInfo runtime_info{MakeRuntimeInfo(key, program, previous_stage)}; 525 const auto runtime_info{MakeRuntimeInfo(programs, key, program, previous_stage)};
522 const std::vector<u32> code{EmitSPIRV(profile, runtime_info, program, binding)}; 526 const std::vector<u32> code{EmitSPIRV(profile, runtime_info, program, binding)};
523 device.SaveShader(code); 527 device.SaveShader(code);
524 modules[stage_index] = BuildShader(device, code); 528 modules[stage_index] = BuildShader(device, code);
diff --git a/src/video_core/shader_environment.cpp b/src/video_core/shader_environment.cpp
index d463e2b56..429cab30d 100644
--- a/src/video_core/shader_environment.cpp
+++ b/src/video_core/shader_environment.cpp
@@ -22,7 +22,7 @@
22namespace VideoCommon { 22namespace VideoCommon {
23 23
24constexpr std::array<char, 8> MAGIC_NUMBER{'y', 'u', 'z', 'u', 'c', 'a', 'c', 'h'}; 24constexpr std::array<char, 8> MAGIC_NUMBER{'y', 'u', 'z', 'u', 'c', 'a', 'c', 'h'};
25constexpr u32 CACHE_VERSION = 4; 25constexpr u32 CACHE_VERSION = 5;
26 26
27constexpr size_t INST_SIZE = sizeof(u64); 27constexpr size_t INST_SIZE = sizeof(u64);
28 28
@@ -155,6 +155,10 @@ void GenericEnvironment::Serialize(std::ofstream& file) const {
155 .write(reinterpret_cast<const char*>(&shared_memory_size), sizeof(shared_memory_size)); 155 .write(reinterpret_cast<const char*>(&shared_memory_size), sizeof(shared_memory_size));
156 } else { 156 } else {
157 file.write(reinterpret_cast<const char*>(&sph), sizeof(sph)); 157 file.write(reinterpret_cast<const char*>(&sph), sizeof(sph));
158 if (stage == Shader::Stage::Geometry) {
159 file.write(reinterpret_cast<const char*>(&gp_passthrough_mask),
160 sizeof(gp_passthrough_mask));
161 }
158 } 162 }
159} 163}
160 164
@@ -202,6 +206,7 @@ GraphicsEnvironment::GraphicsEnvironment(Tegra::Engines::Maxwell3D& maxwell3d_,
202 u32 start_address_) 206 u32 start_address_)
203 : GenericEnvironment{gpu_memory_, program_base_, start_address_}, maxwell3d{&maxwell3d_} { 207 : GenericEnvironment{gpu_memory_, program_base_, start_address_}, maxwell3d{&maxwell3d_} {
204 gpu_memory->ReadBlock(program_base + start_address, &sph, sizeof(sph)); 208 gpu_memory->ReadBlock(program_base + start_address, &sph, sizeof(sph));
209 gp_passthrough_mask = maxwell3d->regs.gp_passthrough_mask;
205 switch (program) { 210 switch (program) {
206 case Maxwell::ShaderProgram::VertexA: 211 case Maxwell::ShaderProgram::VertexA:
207 stage = Shader::Stage::VertexA; 212 stage = Shader::Stage::VertexA;
@@ -319,6 +324,9 @@ void FileEnvironment::Deserialize(std::ifstream& file) {
319 .read(reinterpret_cast<char*>(&shared_memory_size), sizeof(shared_memory_size)); 324 .read(reinterpret_cast<char*>(&shared_memory_size), sizeof(shared_memory_size));
320 } else { 325 } else {
321 file.read(reinterpret_cast<char*>(&sph), sizeof(sph)); 326 file.read(reinterpret_cast<char*>(&sph), sizeof(sph));
327 if (stage == Shader::Stage::Geometry) {
328 file.read(reinterpret_cast<char*>(&gp_passthrough_mask), sizeof(gp_passthrough_mask));
329 }
322 } 330 }
323} 331}
324 332
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index 7b184d2f8..da4721e6b 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -350,6 +350,10 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
350 LOG_INFO(Render_Vulkan, "Device doesn't support viewport masks"); 350 LOG_INFO(Render_Vulkan, "Device doesn't support viewport masks");
351 } 351 }
352 352
353 if (!nv_geometry_shader_passthrough) {
354 LOG_INFO(Render_Vulkan, "Device doesn't support passthrough geometry shaders");
355 }
356
353 VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR std430_layout; 357 VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR std430_layout;
354 if (khr_uniform_buffer_standard_layout) { 358 if (khr_uniform_buffer_standard_layout) {
355 std430_layout = { 359 std430_layout = {
@@ -768,6 +772,8 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) {
768 }; 772 };
769 test(nv_viewport_swizzle, VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME, true); 773 test(nv_viewport_swizzle, VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME, true);
770 test(nv_viewport_array2, VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME, true); 774 test(nv_viewport_array2, VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME, true);
775 test(nv_geometry_shader_passthrough, VK_NV_GEOMETRY_SHADER_PASSTHROUGH_EXTENSION_NAME,
776 true);
771 test(khr_uniform_buffer_standard_layout, 777 test(khr_uniform_buffer_standard_layout,
772 VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, true); 778 VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, true);
773 test(khr_spirv_1_4, VK_KHR_SPIRV_1_4_EXTENSION_NAME, true); 779 test(khr_spirv_1_4, VK_KHR_SPIRV_1_4_EXTENSION_NAME, true);
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h
index a9c0a0e4d..d0adc0127 100644
--- a/src/video_core/vulkan_common/vulkan_device.h
+++ b/src/video_core/vulkan_common/vulkan_device.h
@@ -194,6 +194,11 @@ public:
194 return nv_viewport_array2; 194 return nv_viewport_array2;
195 } 195 }
196 196
197 /// Returns true if the device supports VK_NV_geometry_shader_passthrough.
198 bool IsNvGeometryShaderPassthroughSupported() const {
199 return nv_geometry_shader_passthrough;
200 }
201
197 /// Returns true if the device supports VK_KHR_uniform_buffer_standard_layout. 202 /// Returns true if the device supports VK_KHR_uniform_buffer_standard_layout.
198 bool IsKhrUniformBufferStandardLayoutSupported() const { 203 bool IsKhrUniformBufferStandardLayoutSupported() const {
199 return khr_uniform_buffer_standard_layout; 204 return khr_uniform_buffer_standard_layout;
@@ -363,6 +368,7 @@ private:
363 bool is_blit_depth_stencil_supported{}; ///< Support for blitting from and to depth stencil. 368 bool is_blit_depth_stencil_supported{}; ///< Support for blitting from and to depth stencil.
364 bool nv_viewport_swizzle{}; ///< Support for VK_NV_viewport_swizzle. 369 bool nv_viewport_swizzle{}; ///< Support for VK_NV_viewport_swizzle.
365 bool nv_viewport_array2{}; ///< Support for VK_NV_viewport_array2. 370 bool nv_viewport_array2{}; ///< Support for VK_NV_viewport_array2.
371 bool nv_geometry_shader_passthrough{}; ///< Support for VK_NV_geometry_shader_passthrough.
366 bool khr_uniform_buffer_standard_layout{}; ///< Support for scalar uniform buffer layouts. 372 bool khr_uniform_buffer_standard_layout{}; ///< Support for scalar uniform buffer layouts.
367 bool khr_spirv_1_4{}; ///< Support for VK_KHR_spirv_1_4. 373 bool khr_spirv_1_4{}; ///< Support for VK_KHR_spirv_1_4.
368 bool khr_workgroup_memory_explicit_layout{}; ///< Support for explicit workgroup layouts. 374 bool khr_workgroup_memory_explicit_layout{}; ///< Support for explicit workgroup layouts.