2020-01-07 01:18:38 +01:00
|
|
|
// Copyright 2019 yuzu Emulator Project
|
|
|
|
// Licensed under GPLv2 or any later version
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
2020-01-07 01:55:06 +01:00
|
|
|
#include <algorithm>
|
2020-01-07 01:18:38 +01:00
|
|
|
#include <cstddef>
|
2020-01-07 01:55:06 +01:00
|
|
|
#include <memory>
|
2020-01-07 01:18:38 +01:00
|
|
|
#include <vector>
|
|
|
|
|
2020-11-25 06:33:20 +01:00
|
|
|
#include "common/bit_cast.h"
|
2020-12-30 06:25:23 +01:00
|
|
|
#include "common/cityhash.h"
|
2020-01-07 01:55:06 +01:00
|
|
|
#include "common/microprofile.h"
|
|
|
|
#include "core/core.h"
|
|
|
|
#include "core/memory.h"
|
|
|
|
#include "video_core/engines/kepler_compute.h"
|
|
|
|
#include "video_core/engines/maxwell_3d.h"
|
|
|
|
#include "video_core/memory_manager.h"
|
|
|
|
#include "video_core/renderer_vulkan/fixed_pipeline_state.h"
|
|
|
|
#include "video_core/renderer_vulkan/maxwell_to_vk.h"
|
|
|
|
#include "video_core/renderer_vulkan/vk_compute_pipeline.h"
|
|
|
|
#include "video_core/renderer_vulkan/vk_descriptor_pool.h"
|
2020-01-07 01:18:38 +01:00
|
|
|
#include "video_core/renderer_vulkan/vk_pipeline_cache.h"
|
2020-01-07 01:55:06 +01:00
|
|
|
#include "video_core/renderer_vulkan/vk_rasterizer.h"
|
|
|
|
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
2020-01-07 01:18:38 +01:00
|
|
|
#include "video_core/renderer_vulkan/vk_update_descriptor.h"
|
2020-05-23 02:01:36 +02:00
|
|
|
#include "video_core/shader_cache.h"
|
2020-08-02 19:05:41 +02:00
|
|
|
#include "video_core/shader_notify.h"
|
2020-12-26 05:19:46 +01:00
|
|
|
#include "video_core/vulkan_common/vulkan_device.h"
|
2020-12-25 01:30:11 +01:00
|
|
|
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
2020-01-07 01:18:38 +01:00
|
|
|
|
|
|
|
namespace Vulkan {
|
2020-01-07 01:55:06 +01:00
|
|
|
MICROPROFILE_DECLARE(Vulkan_PipelineCache);
|
|
|
|
|
|
|
|
using Tegra::Engines::ShaderType;
|
|
|
|
|
|
|
|
namespace {
|
2021-02-17 00:52:12 +01:00
|
|
|
size_t StageFromProgram(size_t program) {
|
2020-01-07 01:55:06 +01:00
|
|
|
return program == 0 ? 0 : program - 1;
|
|
|
|
}
|
|
|
|
|
2021-02-17 00:52:12 +01:00
|
|
|
ShaderType StageFromProgram(Maxwell::ShaderProgram program) {
|
|
|
|
return static_cast<ShaderType>(StageFromProgram(static_cast<size_t>(program)));
|
2020-01-07 01:55:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
ShaderType GetShaderType(Maxwell::ShaderProgram program) {
|
|
|
|
switch (program) {
|
|
|
|
case Maxwell::ShaderProgram::VertexB:
|
|
|
|
return ShaderType::Vertex;
|
|
|
|
case Maxwell::ShaderProgram::TesselationControl:
|
|
|
|
return ShaderType::TesselationControl;
|
|
|
|
case Maxwell::ShaderProgram::TesselationEval:
|
|
|
|
return ShaderType::TesselationEval;
|
|
|
|
case Maxwell::ShaderProgram::Geometry:
|
|
|
|
return ShaderType::Geometry;
|
|
|
|
case Maxwell::ShaderProgram::Fragment:
|
|
|
|
return ShaderType::Fragment;
|
|
|
|
default:
|
2020-12-07 06:41:47 +01:00
|
|
|
UNIMPLEMENTED_MSG("program={}", program);
|
2020-01-07 01:55:06 +01:00
|
|
|
return ShaderType::Vertex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} // Anonymous namespace
|
|
|
|
|
2021-02-17 00:52:12 +01:00
|
|
|
size_t ComputePipelineCacheKey::Hash() const noexcept {
|
2020-04-23 01:52:29 +02:00
|
|
|
const u64 hash = Common::CityHash64(reinterpret_cast<const char*>(this), sizeof *this);
|
2021-02-17 00:52:12 +01:00
|
|
|
return static_cast<size_t>(hash);
|
2020-04-23 01:52:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ComputePipelineCacheKey::operator==(const ComputePipelineCacheKey& rhs) const noexcept {
|
|
|
|
return std::memcmp(&rhs, this, sizeof *this) == 0;
|
|
|
|
}
|
|
|
|
|
2021-02-17 00:52:12 +01:00
|
|
|
Shader::Shader() = default;
|
2020-01-07 01:55:06 +01:00
|
|
|
|
2020-05-23 02:01:36 +02:00
|
|
|
Shader::~Shader() = default;
|
2020-01-07 01:55:06 +01:00
|
|
|
|
2021-02-17 00:52:12 +01:00
|
|
|
PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, Tegra::GPU& gpu_,
|
|
|
|
Tegra::Engines::Maxwell3D& maxwell3d_,
|
|
|
|
Tegra::Engines::KeplerCompute& kepler_compute_,
|
|
|
|
Tegra::MemoryManager& gpu_memory_, const Device& device_,
|
|
|
|
VKScheduler& scheduler_, VKDescriptorPool& descriptor_pool_,
|
|
|
|
VKUpdateDescriptorQueue& update_descriptor_queue_)
|
2020-12-30 06:25:23 +01:00
|
|
|
: VideoCommon::ShaderCache<Shader>{rasterizer_}, gpu{gpu_}, maxwell3d{maxwell3d_},
|
|
|
|
kepler_compute{kepler_compute_}, gpu_memory{gpu_memory_}, device{device_},
|
|
|
|
scheduler{scheduler_}, descriptor_pool{descriptor_pool_}, update_descriptor_queue{
|
|
|
|
update_descriptor_queue_} {}
|
2020-01-07 01:55:06 +01:00
|
|
|
|
2021-02-17 00:52:12 +01:00
|
|
|
PipelineCache::~PipelineCache() = default;
|
2020-01-07 01:55:06 +01:00
|
|
|
|
2021-02-17 00:52:12 +01:00
|
|
|
ComputePipeline& PipelineCache::GetComputePipeline(const ComputePipelineCacheKey& key) {
|
2020-01-07 01:55:06 +01:00
|
|
|
MICROPROFILE_SCOPE(Vulkan_PipelineCache);
|
|
|
|
|
|
|
|
const auto [pair, is_cache_miss] = compute_cache.try_emplace(key);
|
|
|
|
auto& entry = pair->second;
|
|
|
|
if (!is_cache_miss) {
|
|
|
|
return *entry;
|
|
|
|
}
|
|
|
|
LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash());
|
2021-02-17 00:52:12 +01:00
|
|
|
throw "Bad";
|
2020-01-07 01:55:06 +01:00
|
|
|
}
|
|
|
|
|
2021-02-17 00:52:12 +01:00
|
|
|
void PipelineCache::OnShaderRemoval(Shader*) {}
|
2020-01-07 01:18:38 +01:00
|
|
|
|
|
|
|
} // namespace Vulkan
|