diff options
| author | 2020-04-28 12:05:50 -0400 | |
|---|---|---|
| committer | 2020-04-28 12:05:50 -0400 | |
| commit | 72b73d22abd0e1ee96190e898838c0f0ff02fd9a (patch) | |
| tree | 916ee99f8ac6eaf9688ca9d35e9838bce528e46f /src/video_core/renderer_vulkan | |
| parent | Merge pull request #3814 from ogniK5377/getinfo-err (diff) | |
| parent | shader/memory_util: Deduplicate code (diff) | |
| download | yuzu-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.cpp | 69 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_pipeline_cache.h | 8 |
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 | ||
| 31 | namespace Vulkan { | 32 | namespace Vulkan { |
| 32 | 33 | ||
| 33 | MICROPROFILE_DECLARE(Vulkan_PipelineCache); | 34 | MICROPROFILE_DECLARE(Vulkan_PipelineCache); |
| 34 | 35 | ||
| 35 | using Tegra::Engines::ShaderType; | 36 | using Tegra::Engines::ShaderType; |
| 37 | using VideoCommon::Shader::GetShaderAddress; | ||
| 38 | using VideoCommon::Shader::GetShaderCode; | ||
| 39 | using VideoCommon::Shader::KERNEL_MAIN_OFFSET; | ||
| 40 | using VideoCommon::Shader::ProgramCode; | ||
| 41 | using VideoCommon::Shader::STAGE_MAIN_OFFSET; | ||
| 36 | 42 | ||
| 37 | namespace { | 43 | namespace { |
| 38 | 44 | ||
| @@ -45,60 +51,6 @@ constexpr VkDescriptorType STORAGE_IMAGE = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; | |||
| 45 | constexpr VideoCommon::Shader::CompilerSettings compiler_settings{ | 51 | constexpr 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 | ||
| 49 | GPUVAddr 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 | ||
| 56 | constexpr 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 | ||
| 64 | std::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 | ||
| 89 | ProgramCode 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 | |||
| 102 | constexpr std::size_t GetStageFromProgram(std::size_t program) { | 54 | constexpr 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; | |||
| 46 | using Shader = std::shared_ptr<CachedShader>; | 47 | using Shader = std::shared_ptr<CachedShader>; |
| 47 | using Maxwell = Tegra::Engines::Maxwell3D::Regs; | 48 | using Maxwell = Tegra::Engines::Maxwell3D::Regs; |
| 48 | 49 | ||
| 49 | using ProgramCode = std::vector<u64>; | ||
| 50 | |||
| 51 | struct GraphicsPipelineCacheKey { | 50 | struct GraphicsPipelineCacheKey { |
| 52 | FixedPipelineState fixed_state; | 51 | FixedPipelineState fixed_state; |
| 53 | RenderPassParams renderpass_params; | 52 | RenderPassParams renderpass_params; |
| @@ -108,7 +107,8 @@ namespace Vulkan { | |||
| 108 | class CachedShader final : public RasterizerCacheObject { | 107 | class CachedShader final : public RasterizerCacheObject { |
| 109 | public: | 108 | public: |
| 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; |