summaryrefslogtreecommitdiff
path: root/src/video_core/renderer_vulkan
diff options
context:
space:
mode:
authorGravatar bunnei2020-04-28 12:05:50 -0400
committerGravatar GitHub2020-04-28 12:05:50 -0400
commit72b73d22abd0e1ee96190e898838c0f0ff02fd9a (patch)
tree916ee99f8ac6eaf9688ca9d35e9838bce528e46f /src/video_core/renderer_vulkan
parentMerge pull request #3814 from ogniK5377/getinfo-err (diff)
parentshader/memory_util: Deduplicate code (diff)
downloadyuzu-72b73d22abd0e1ee96190e898838c0f0ff02fd9a.tar.gz
yuzu-72b73d22abd0e1ee96190e898838c0f0ff02fd9a.tar.xz
yuzu-72b73d22abd0e1ee96190e898838c0f0ff02fd9a.zip
Merge pull request #3784 from ReinUsesLisp/shader-memory-util
shader/memory_util: Deduplicate code
Diffstat (limited to 'src/video_core/renderer_vulkan')
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp69
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.h8
2 files changed, 14 insertions, 63 deletions
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index e6d4adc92..9b703a2f0 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -27,12 +27,18 @@
27#include "video_core/renderer_vulkan/vk_update_descriptor.h" 27#include "video_core/renderer_vulkan/vk_update_descriptor.h"
28#include "video_core/renderer_vulkan/wrapper.h" 28#include "video_core/renderer_vulkan/wrapper.h"
29#include "video_core/shader/compiler_settings.h" 29#include "video_core/shader/compiler_settings.h"
30#include "video_core/shader/memory_util.h"
30 31
31namespace Vulkan { 32namespace Vulkan {
32 33
33MICROPROFILE_DECLARE(Vulkan_PipelineCache); 34MICROPROFILE_DECLARE(Vulkan_PipelineCache);
34 35
35using Tegra::Engines::ShaderType; 36using Tegra::Engines::ShaderType;
37using VideoCommon::Shader::GetShaderAddress;
38using VideoCommon::Shader::GetShaderCode;
39using VideoCommon::Shader::KERNEL_MAIN_OFFSET;
40using VideoCommon::Shader::ProgramCode;
41using VideoCommon::Shader::STAGE_MAIN_OFFSET;
36 42
37namespace { 43namespace {
38 44
@@ -45,60 +51,6 @@ constexpr VkDescriptorType STORAGE_IMAGE = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
45constexpr VideoCommon::Shader::CompilerSettings compiler_settings{ 51constexpr VideoCommon::Shader::CompilerSettings compiler_settings{
46 VideoCommon::Shader::CompileDepth::FullDecompile}; 52 VideoCommon::Shader::CompileDepth::FullDecompile};
47 53
48/// Gets the address for the specified shader stage program
49GPUVAddr GetShaderAddress(Core::System& system, Maxwell::ShaderProgram program) {
50 const auto& gpu{system.GPU().Maxwell3D()};
51 const auto& shader_config{gpu.regs.shader_config[static_cast<std::size_t>(program)]};
52 return gpu.regs.code_address.CodeAddress() + shader_config.offset;
53}
54
55/// Gets if the current instruction offset is a scheduler instruction
56constexpr bool IsSchedInstruction(std::size_t offset, std::size_t main_offset) {
57 // Sched instructions appear once every 4 instructions.
58 constexpr std::size_t SchedPeriod = 4;
59 const std::size_t absolute_offset = offset - main_offset;
60 return (absolute_offset % SchedPeriod) == 0;
61}
62
63/// Calculates the size of a program stream
64std::size_t CalculateProgramSize(const ProgramCode& program, bool is_compute) {
65 const std::size_t start_offset = is_compute ? 0 : 10;
66 // This is the encoded version of BRA that jumps to itself. All Nvidia
67 // shaders end with one.
68 constexpr u64 self_jumping_branch = 0xE2400FFFFF07000FULL;
69 constexpr u64 mask = 0xFFFFFFFFFF7FFFFFULL;
70 std::size_t offset = start_offset;
71 while (offset < program.size()) {
72 const u64 instruction = program[offset];
73 if (!IsSchedInstruction(offset, start_offset)) {
74 if ((instruction & mask) == self_jumping_branch) {
75 // End on Maxwell's "nop" instruction
76 break;
77 }
78 if (instruction == 0) {
79 break;
80 }
81 }
82 ++offset;
83 }
84 // The last instruction is included in the program size
85 return std::min(offset + 1, program.size());
86}
87
88/// Gets the shader program code from memory for the specified address
89ProgramCode GetShaderCode(Tegra::MemoryManager& memory_manager, const GPUVAddr gpu_addr,
90 const u8* host_ptr, bool is_compute) {
91 ProgramCode program_code(VideoCommon::Shader::MAX_PROGRAM_LENGTH);
92 ASSERT_OR_EXECUTE(host_ptr != nullptr, {
93 std::fill(program_code.begin(), program_code.end(), 0);
94 return program_code;
95 });
96 memory_manager.ReadBlockUnsafe(gpu_addr, program_code.data(),
97 program_code.size() * sizeof(u64));
98 program_code.resize(CalculateProgramSize(program_code, is_compute));
99 return program_code;
100}
101
102constexpr std::size_t GetStageFromProgram(std::size_t program) { 54constexpr std::size_t GetStageFromProgram(std::size_t program) {
103 return program == 0 ? 0 : program - 1; 55 return program == 0 ? 0 : program - 1;
104} 56}
@@ -230,9 +182,9 @@ std::array<Shader, Maxwell::MaxShaderProgram> VKPipelineCache::GetShaders() {
230 const auto host_ptr{memory_manager.GetPointer(program_addr)}; 182 const auto host_ptr{memory_manager.GetPointer(program_addr)};
231 183
232 // No shader found - create a new one 184 // No shader found - create a new one
233 constexpr u32 stage_offset = 10; 185 constexpr u32 stage_offset = STAGE_MAIN_OFFSET;
234 const auto stage = static_cast<Tegra::Engines::ShaderType>(index == 0 ? 0 : index - 1); 186 const auto stage = static_cast<Tegra::Engines::ShaderType>(index == 0 ? 0 : index - 1);
235 auto code = GetShaderCode(memory_manager, program_addr, host_ptr, false); 187 ProgramCode code = GetShaderCode(memory_manager, program_addr, host_ptr, false);
236 188
237 shader = std::make_shared<CachedShader>(system, stage, program_addr, *cpu_addr, 189 shader = std::make_shared<CachedShader>(system, stage, program_addr, *cpu_addr,
238 std::move(code), stage_offset); 190 std::move(code), stage_offset);
@@ -288,11 +240,10 @@ VKComputePipeline& VKPipelineCache::GetComputePipeline(const ComputePipelineCach
288 // No shader found - create a new one 240 // No shader found - create a new one
289 const auto host_ptr = memory_manager.GetPointer(program_addr); 241 const auto host_ptr = memory_manager.GetPointer(program_addr);
290 242
291 auto code = GetShaderCode(memory_manager, program_addr, host_ptr, true); 243 ProgramCode code = GetShaderCode(memory_manager, program_addr, host_ptr, true);
292 constexpr u32 kernel_main_offset = 0;
293 shader = std::make_shared<CachedShader>(system, Tegra::Engines::ShaderType::Compute, 244 shader = std::make_shared<CachedShader>(system, Tegra::Engines::ShaderType::Compute,
294 program_addr, *cpu_addr, std::move(code), 245 program_addr, *cpu_addr, std::move(code),
295 kernel_main_offset); 246 KERNEL_MAIN_OFFSET);
296 if (cpu_addr) { 247 if (cpu_addr) {
297 Register(shader); 248 Register(shader);
298 } else { 249 } else {
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h
index 84d26b822..ebddafb73 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h
@@ -24,6 +24,7 @@
24#include "video_core/renderer_vulkan/vk_resource_manager.h" 24#include "video_core/renderer_vulkan/vk_resource_manager.h"
25#include "video_core/renderer_vulkan/vk_shader_decompiler.h" 25#include "video_core/renderer_vulkan/vk_shader_decompiler.h"
26#include "video_core/renderer_vulkan/wrapper.h" 26#include "video_core/renderer_vulkan/wrapper.h"
27#include "video_core/shader/memory_util.h"
27#include "video_core/shader/registry.h" 28#include "video_core/shader/registry.h"
28#include "video_core/shader/shader_ir.h" 29#include "video_core/shader/shader_ir.h"
29#include "video_core/surface.h" 30#include "video_core/surface.h"
@@ -46,8 +47,6 @@ class CachedShader;
46using Shader = std::shared_ptr<CachedShader>; 47using Shader = std::shared_ptr<CachedShader>;
47using Maxwell = Tegra::Engines::Maxwell3D::Regs; 48using Maxwell = Tegra::Engines::Maxwell3D::Regs;
48 49
49using ProgramCode = std::vector<u64>;
50
51struct GraphicsPipelineCacheKey { 50struct GraphicsPipelineCacheKey {
52 FixedPipelineState fixed_state; 51 FixedPipelineState fixed_state;
53 RenderPassParams renderpass_params; 52 RenderPassParams renderpass_params;
@@ -108,7 +107,8 @@ namespace Vulkan {
108class CachedShader final : public RasterizerCacheObject { 107class CachedShader final : public RasterizerCacheObject {
109public: 108public:
110 explicit CachedShader(Core::System& system, Tegra::Engines::ShaderType stage, GPUVAddr gpu_addr, 109 explicit CachedShader(Core::System& system, Tegra::Engines::ShaderType stage, GPUVAddr gpu_addr,
111 VAddr cpu_addr, ProgramCode program_code, u32 main_offset); 110 VAddr cpu_addr, VideoCommon::Shader::ProgramCode program_code,
111 u32 main_offset);
112 ~CachedShader(); 112 ~CachedShader();
113 113
114 GPUVAddr GetGpuAddr() const { 114 GPUVAddr GetGpuAddr() const {
@@ -140,7 +140,7 @@ private:
140 Tegra::Engines::ShaderType stage); 140 Tegra::Engines::ShaderType stage);
141 141
142 GPUVAddr gpu_addr{}; 142 GPUVAddr gpu_addr{};
143 ProgramCode program_code; 143 VideoCommon::Shader::ProgramCode program_code;
144 VideoCommon::Shader::Registry registry; 144 VideoCommon::Shader::Registry registry;
145 VideoCommon::Shader::ShaderIR shader_ir; 145 VideoCommon::Shader::ShaderIR shader_ir;
146 ShaderEntries entries; 146 ShaderEntries entries;