video_core: Remove all Core::System references in renderer
Now that the GPU is initialized when video backends are initialized, it's no longer needed to query components once the game is running: it can be done when yuzu is booting. This allows us to pass components between constructors and in the process remove all Core::System references in the video backend.
This commit is contained in:
parent
045f50bc7f
commit
9e87193725
53 changed files with 573 additions and 633 deletions
|
@ -86,7 +86,7 @@ Common::DynamicLibrary OpenVulkanLibrary() {
|
|||
if (!library.Open(filename.c_str())) {
|
||||
// Android devices may not have libvulkan.so.1, only libvulkan.so.
|
||||
filename = Common::DynamicLibrary::GetVersionedFilename("vulkan");
|
||||
library.Open(filename.c_str());
|
||||
(void)library.Open(filename.c_str());
|
||||
}
|
||||
#endif
|
||||
return library;
|
||||
|
@ -237,10 +237,12 @@ std::string BuildCommaSeparatedExtensions(std::vector<std::string> available_ext
|
|||
|
||||
} // Anonymous namespace
|
||||
|
||||
RendererVulkan::RendererVulkan(Core::System& system_, Core::Frontend::EmuWindow& emu_window,
|
||||
Tegra::GPU& gpu_,
|
||||
RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_,
|
||||
Core::Frontend::EmuWindow& emu_window,
|
||||
Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_,
|
||||
std::unique_ptr<Core::Frontend::GraphicsContext> context)
|
||||
: RendererBase{emu_window, std::move(context)}, system{system_}, gpu{gpu_} {}
|
||||
: RendererBase{emu_window, std::move(context)}, telemetry_session{telemetry_session_},
|
||||
cpu_memory{cpu_memory_}, gpu{gpu_} {}
|
||||
|
||||
RendererVulkan::~RendererVulkan() {
|
||||
ShutDown();
|
||||
|
@ -304,15 +306,15 @@ bool RendererVulkan::Init() {
|
|||
swapchain = std::make_unique<VKSwapchain>(*surface, *device);
|
||||
swapchain->Create(framebuffer.width, framebuffer.height, false);
|
||||
|
||||
state_tracker = std::make_unique<StateTracker>(system);
|
||||
state_tracker = std::make_unique<StateTracker>(gpu);
|
||||
|
||||
scheduler = std::make_unique<VKScheduler>(*device, *resource_manager, *state_tracker);
|
||||
|
||||
rasterizer = std::make_unique<RasterizerVulkan>(system, render_window, screen_info, *device,
|
||||
*resource_manager, *memory_manager,
|
||||
*state_tracker, *scheduler);
|
||||
rasterizer = std::make_unique<RasterizerVulkan>(
|
||||
render_window, gpu, gpu.MemoryManager(), cpu_memory, screen_info, *device,
|
||||
*resource_manager, *memory_manager, *state_tracker, *scheduler);
|
||||
|
||||
blit_screen = std::make_unique<VKBlitScreen>(system, render_window, *rasterizer, *device,
|
||||
blit_screen = std::make_unique<VKBlitScreen>(cpu_memory, render_window, *rasterizer, *device,
|
||||
*resource_manager, *memory_manager, *swapchain,
|
||||
*scheduler, screen_info);
|
||||
|
||||
|
@ -440,8 +442,7 @@ void RendererVulkan::Report() const {
|
|||
LOG_INFO(Render_Vulkan, "Device: {}", model_name);
|
||||
LOG_INFO(Render_Vulkan, "Vulkan: {}", api_version);
|
||||
|
||||
auto& telemetry_session = system.TelemetrySession();
|
||||
constexpr auto field = Common::Telemetry::FieldType::UserSystem;
|
||||
static constexpr auto field = Common::Telemetry::FieldType::UserSystem;
|
||||
telemetry_session.AddField(field, "GPU_Vendor", vendor_name);
|
||||
telemetry_session.AddField(field, "GPU_Model", model_name);
|
||||
telemetry_session.AddField(field, "GPU_Vulkan_Driver", driver_name);
|
||||
|
|
|
@ -14,7 +14,15 @@
|
|||
#include "video_core/renderer_vulkan/wrapper.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
class TelemetrySession;
|
||||
}
|
||||
|
||||
namespace Core::Memory {
|
||||
class Memory;
|
||||
}
|
||||
|
||||
namespace Tegra {
|
||||
class GPU;
|
||||
}
|
||||
|
||||
namespace Vulkan {
|
||||
|
@ -38,7 +46,8 @@ struct VKScreenInfo {
|
|||
|
||||
class RendererVulkan final : public VideoCore::RendererBase {
|
||||
public:
|
||||
explicit RendererVulkan(Core::System& system, Core::Frontend::EmuWindow& emu_window,
|
||||
explicit RendererVulkan(Core::TelemetrySession& telemtry_session,
|
||||
Core::Frontend::EmuWindow& emu_window, Core::Memory::Memory& cpu_memory,
|
||||
Tegra::GPU& gpu,
|
||||
std::unique_ptr<Core::Frontend::GraphicsContext> context);
|
||||
~RendererVulkan() override;
|
||||
|
@ -59,7 +68,8 @@ private:
|
|||
|
||||
void Report() const;
|
||||
|
||||
Core::System& system;
|
||||
Core::TelemetrySession& telemetry_session;
|
||||
Core::Memory::Memory& cpu_memory;
|
||||
Tegra::GPU& gpu;
|
||||
|
||||
Common::DynamicLibrary library;
|
||||
|
|
|
@ -210,14 +210,16 @@ struct VKBlitScreen::BufferData {
|
|||
// Unaligned image data goes here
|
||||
};
|
||||
|
||||
VKBlitScreen::VKBlitScreen(Core::System& system, Core::Frontend::EmuWindow& render_window,
|
||||
VideoCore::RasterizerInterface& rasterizer, const VKDevice& device,
|
||||
VKResourceManager& resource_manager, VKMemoryManager& memory_manager,
|
||||
VKSwapchain& swapchain, VKScheduler& scheduler,
|
||||
const VKScreenInfo& screen_info)
|
||||
: system{system}, render_window{render_window}, rasterizer{rasterizer}, device{device},
|
||||
resource_manager{resource_manager}, memory_manager{memory_manager}, swapchain{swapchain},
|
||||
scheduler{scheduler}, image_count{swapchain.GetImageCount()}, screen_info{screen_info} {
|
||||
VKBlitScreen::VKBlitScreen(Core::Memory::Memory& cpu_memory_,
|
||||
Core::Frontend::EmuWindow& render_window_,
|
||||
VideoCore::RasterizerInterface& rasterizer_, const VKDevice& device_,
|
||||
VKResourceManager& resource_manager_, VKMemoryManager& memory_manager_,
|
||||
VKSwapchain& swapchain_, VKScheduler& scheduler_,
|
||||
const VKScreenInfo& screen_info_)
|
||||
: cpu_memory{cpu_memory_}, render_window{render_window_},
|
||||
rasterizer{rasterizer_}, device{device_}, resource_manager{resource_manager_},
|
||||
memory_manager{memory_manager_}, swapchain{swapchain_}, scheduler{scheduler_},
|
||||
image_count{swapchain.GetImageCount()}, screen_info{screen_info_} {
|
||||
watches.resize(image_count);
|
||||
std::generate(watches.begin(), watches.end(),
|
||||
[]() { return std::make_unique<VKFenceWatch>(); });
|
||||
|
@ -259,7 +261,7 @@ std::tuple<VKFence&, VkSemaphore> VKBlitScreen::Draw(const Tegra::FramebufferCon
|
|||
const auto pixel_format =
|
||||
VideoCore::Surface::PixelFormatFromGPUPixelFormat(framebuffer.pixel_format);
|
||||
const VAddr framebuffer_addr = framebuffer.address + framebuffer.offset;
|
||||
const auto host_ptr = system.Memory().GetPointer(framebuffer_addr);
|
||||
const auto host_ptr = cpu_memory.GetPointer(framebuffer_addr);
|
||||
rasterizer.FlushRegion(ToCacheAddr(host_ptr), GetSizeInBytes(framebuffer));
|
||||
|
||||
// TODO(Rodrigo): Read this from HLE
|
||||
|
|
|
@ -15,6 +15,10 @@ namespace Core {
|
|||
class System;
|
||||
}
|
||||
|
||||
namespace Core::Memory {
|
||||
class Memory;
|
||||
}
|
||||
|
||||
namespace Core::Frontend {
|
||||
class EmuWindow;
|
||||
}
|
||||
|
@ -39,7 +43,8 @@ class VKSwapchain;
|
|||
|
||||
class VKBlitScreen final {
|
||||
public:
|
||||
explicit VKBlitScreen(Core::System& system, Core::Frontend::EmuWindow& render_window,
|
||||
explicit VKBlitScreen(Core::Memory::Memory& cpu_memory,
|
||||
Core::Frontend::EmuWindow& render_window,
|
||||
VideoCore::RasterizerInterface& rasterizer, const VKDevice& device,
|
||||
VKResourceManager& resource_manager, VKMemoryManager& memory_manager,
|
||||
VKSwapchain& swapchain, VKScheduler& scheduler,
|
||||
|
@ -81,7 +86,7 @@ private:
|
|||
u64 GetRawImageOffset(const Tegra::FramebufferConfig& framebuffer,
|
||||
std::size_t image_index) const;
|
||||
|
||||
Core::System& system;
|
||||
Core::Memory::Memory& cpu_memory;
|
||||
Core::Frontend::EmuWindow& render_window;
|
||||
VideoCore::RasterizerInterface& rasterizer;
|
||||
const VKDevice& device;
|
||||
|
|
|
@ -145,14 +145,15 @@ void Buffer::CopyFrom(const Buffer& src, std::size_t src_offset, std::size_t dst
|
|||
});
|
||||
}
|
||||
|
||||
VKBufferCache::VKBufferCache(VideoCore::RasterizerInterface& rasterizer, Core::System& system,
|
||||
const VKDevice& device, VKMemoryManager& memory_manager,
|
||||
VKScheduler& scheduler, VKStagingBufferPool& staging_pool)
|
||||
: VideoCommon::BufferCache<Buffer, VkBuffer, VKStreamBuffer>{rasterizer, system,
|
||||
CreateStreamBuffer(device,
|
||||
scheduler)},
|
||||
device{device}, memory_manager{memory_manager}, scheduler{scheduler}, staging_pool{
|
||||
staging_pool} {}
|
||||
VKBufferCache::VKBufferCache(VideoCore::RasterizerInterface& rasterizer,
|
||||
Tegra::MemoryManager& gpu_memory, Core::Memory::Memory& cpu_memory,
|
||||
const VKDevice& device_, VKMemoryManager& memory_manager_,
|
||||
VKScheduler& scheduler_, VKStagingBufferPool& staging_pool_)
|
||||
: VideoCommon::BufferCache<Buffer, VkBuffer, VKStreamBuffer>{rasterizer, gpu_memory, cpu_memory,
|
||||
CreateStreamBuffer(device_,
|
||||
scheduler_)},
|
||||
device{device_}, memory_manager{memory_manager_}, scheduler{scheduler_}, staging_pool{
|
||||
staging_pool_} {}
|
||||
|
||||
VKBufferCache::~VKBufferCache() = default;
|
||||
|
||||
|
|
|
@ -13,10 +13,6 @@
|
|||
#include "video_core/renderer_vulkan/vk_stream_buffer.h"
|
||||
#include "video_core/renderer_vulkan/wrapper.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
class VKDevice;
|
||||
|
@ -53,7 +49,8 @@ private:
|
|||
|
||||
class VKBufferCache final : public VideoCommon::BufferCache<Buffer, VkBuffer, VKStreamBuffer> {
|
||||
public:
|
||||
explicit VKBufferCache(VideoCore::RasterizerInterface& rasterizer, Core::System& system,
|
||||
explicit VKBufferCache(VideoCore::RasterizerInterface& rasterizer,
|
||||
Tegra::MemoryManager& gpu_memory, Core::Memory::Memory& cpu_memory,
|
||||
const VKDevice& device, VKMemoryManager& memory_manager,
|
||||
VKScheduler& scheduler, VKStagingBufferPool& staging_pool);
|
||||
~VKBufferCache();
|
||||
|
|
|
@ -71,12 +71,12 @@ bool InnerFence::IsEventSignalled() const {
|
|||
}
|
||||
}
|
||||
|
||||
VKFenceManager::VKFenceManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer,
|
||||
const VKDevice& device, VKScheduler& scheduler,
|
||||
VKTextureCache& texture_cache, VKBufferCache& buffer_cache,
|
||||
VKQueryCache& query_cache)
|
||||
: GenericFenceManager(system, rasterizer, texture_cache, buffer_cache, query_cache),
|
||||
device{device}, scheduler{scheduler} {}
|
||||
VKFenceManager::VKFenceManager(VideoCore::RasterizerInterface& rasterizer, Tegra::GPU& gpu,
|
||||
Tegra::MemoryManager& memory_manager, VKTextureCache& texture_cache,
|
||||
VKBufferCache& buffer_cache, VKQueryCache& query_cache,
|
||||
const VKDevice& device_, VKScheduler& scheduler_)
|
||||
: GenericFenceManager(rasterizer, gpu, texture_cache, buffer_cache, query_cache),
|
||||
device{device_}, scheduler{scheduler_} {}
|
||||
|
||||
Fence VKFenceManager::CreateFence(u32 value, bool is_stubbed) {
|
||||
return std::make_shared<InnerFence>(device, scheduler, value, is_stubbed);
|
||||
|
|
|
@ -55,10 +55,10 @@ using GenericFenceManager =
|
|||
|
||||
class VKFenceManager final : public GenericFenceManager {
|
||||
public:
|
||||
explicit VKFenceManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer,
|
||||
const VKDevice& device, VKScheduler& scheduler,
|
||||
VKTextureCache& texture_cache, VKBufferCache& buffer_cache,
|
||||
VKQueryCache& query_cache);
|
||||
explicit VKFenceManager(VideoCore::RasterizerInterface& rasterizer, Tegra::GPU& gpu,
|
||||
Tegra::MemoryManager& memory_manager, VKTextureCache& texture_cache,
|
||||
VKBufferCache& buffer_cache, VKQueryCache& query_cache,
|
||||
const VKDevice& device, VKScheduler& scheduler);
|
||||
|
||||
protected:
|
||||
Fence CreateFence(u32 value, bool is_stubbed) override;
|
||||
|
|
|
@ -135,64 +135,56 @@ bool ComputePipelineCacheKey::operator==(const ComputePipelineCacheKey& rhs) con
|
|||
return std::memcmp(&rhs, this, sizeof *this) == 0;
|
||||
}
|
||||
|
||||
Shader::Shader(Core::System& system, Tegra::Engines::ShaderType stage, GPUVAddr gpu_addr,
|
||||
VideoCommon::Shader::ProgramCode program_code, u32 main_offset)
|
||||
: gpu_addr{gpu_addr}, program_code{std::move(program_code)},
|
||||
registry{stage, GetEngine(system, stage)}, shader_ir{this->program_code, main_offset,
|
||||
compiler_settings, registry},
|
||||
entries{GenerateShaderEntries(shader_ir)} {}
|
||||
Shader::Shader(Tegra::Engines::ConstBufferEngineInterface& engine, Tegra::Engines::ShaderType stage,
|
||||
GPUVAddr gpu_addr_, VAddr cpu_addr, VideoCommon::Shader::ProgramCode program_code_,
|
||||
u32 main_offset)
|
||||
: gpu_addr(gpu_addr_), program_code(std::move(program_code_)), registry(stage, engine),
|
||||
shader_ir(program_code, main_offset, compiler_settings, registry),
|
||||
entries(GenerateShaderEntries(shader_ir)) {}
|
||||
|
||||
Shader::~Shader() = default;
|
||||
|
||||
Tegra::Engines::ConstBufferEngineInterface& Shader::GetEngine(Core::System& system,
|
||||
Tegra::Engines::ShaderType stage) {
|
||||
if (stage == ShaderType::Compute) {
|
||||
return system.GPU().KeplerCompute();
|
||||
} else {
|
||||
return system.GPU().Maxwell3D();
|
||||
}
|
||||
}
|
||||
|
||||
VKPipelineCache::VKPipelineCache(Core::System& system, RasterizerVulkan& rasterizer,
|
||||
const VKDevice& device, VKScheduler& scheduler,
|
||||
VKDescriptorPool& descriptor_pool,
|
||||
VKUpdateDescriptorQueue& update_descriptor_queue,
|
||||
VKRenderPassCache& renderpass_cache)
|
||||
: VideoCommon::ShaderCache<Shader>{rasterizer}, system{system}, device{device},
|
||||
scheduler{scheduler}, descriptor_pool{descriptor_pool},
|
||||
update_descriptor_queue{update_descriptor_queue}, renderpass_cache{renderpass_cache} {}
|
||||
VKPipelineCache::VKPipelineCache(RasterizerVulkan& rasterizer, Tegra::GPU& gpu_,
|
||||
Tegra::Engines::Maxwell3D& maxwell3d_,
|
||||
Tegra::Engines::KeplerCompute& kepler_compute_,
|
||||
Tegra::MemoryManager& gpu_memory_, const VKDevice& device_,
|
||||
VKScheduler& scheduler_, VKDescriptorPool& descriptor_pool_,
|
||||
VKUpdateDescriptorQueue& update_descriptor_queue_,
|
||||
VKRenderPassCache& renderpass_cache_)
|
||||
: 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_}, renderpass_cache{renderpass_cache_} {}
|
||||
|
||||
VKPipelineCache::~VKPipelineCache() = default;
|
||||
|
||||
std::array<Shader*, Maxwell::MaxShaderProgram> VKPipelineCache::GetShaders() {
|
||||
const auto& gpu = system.GPU().Maxwell3D();
|
||||
|
||||
std::array<Shader*, Maxwell::MaxShaderProgram> shaders{};
|
||||
|
||||
for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) {
|
||||
const auto program{static_cast<Maxwell::ShaderProgram>(index)};
|
||||
|
||||
// Skip stages that are not enabled
|
||||
if (!gpu.regs.IsShaderConfigEnabled(index)) {
|
||||
if (!maxwell3d.regs.IsShaderConfigEnabled(index)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto& memory_manager{system.GPU().MemoryManager()};
|
||||
const GPUVAddr program_addr{GetShaderAddress(system, program)};
|
||||
const std::optional cpu_addr = memory_manager.GpuToCpuAddress(program_addr);
|
||||
const GPUVAddr gpu_addr{GetShaderAddress(maxwell3d, program)};
|
||||
const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
|
||||
ASSERT(cpu_addr);
|
||||
|
||||
Shader* result = cpu_addr ? TryGet(*cpu_addr) : null_shader.get();
|
||||
if (!result) {
|
||||
const auto host_ptr{memory_manager.GetPointer(program_addr)};
|
||||
const u8* const host_ptr{gpu_memory.GetPointer(gpu_addr)};
|
||||
|
||||
// No shader found - create a new one
|
||||
constexpr u32 stage_offset = STAGE_MAIN_OFFSET;
|
||||
static constexpr u32 stage_offset = STAGE_MAIN_OFFSET;
|
||||
const auto stage = static_cast<ShaderType>(index == 0 ? 0 : index - 1);
|
||||
ProgramCode code = GetShaderCode(memory_manager, program_addr, host_ptr, false);
|
||||
ProgramCode code = GetShaderCode(gpu_memory, gpu_addr, host_ptr, false);
|
||||
const std::size_t size_in_bytes = code.size() * sizeof(u64);
|
||||
|
||||
auto shader = std::make_unique<Shader>(system, stage, program_addr, std::move(code),
|
||||
stage_offset);
|
||||
auto shader = std::make_unique<Shader>(maxwell3d, stage, gpu_addr, *cpu_addr,
|
||||
std::move(code), stage_offset);
|
||||
result = shader.get();
|
||||
|
||||
if (cpu_addr) {
|
||||
|
@ -215,11 +207,11 @@ VKGraphicsPipeline* VKPipelineCache::GetGraphicsPipeline(
|
|||
}
|
||||
last_graphics_key = key;
|
||||
|
||||
if (device.UseAsynchronousShaders() && async_shaders.IsShaderAsync(system.GPU())) {
|
||||
if (device.UseAsynchronousShaders() && async_shaders.IsShaderAsync(gpu)) {
|
||||
std::unique_lock lock{pipeline_cache};
|
||||
const auto [pair, is_cache_miss] = graphics_cache.try_emplace(key);
|
||||
if (is_cache_miss) {
|
||||
system.GPU().ShaderNotify().MarkSharderBuilding();
|
||||
gpu.ShaderNotify().MarkSharderBuilding();
|
||||
LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash());
|
||||
const auto [program, bindings] = DecompileShaders(key.fixed_state);
|
||||
async_shaders.QueueVulkanShader(this, device, scheduler, descriptor_pool,
|
||||
|
@ -233,13 +225,13 @@ VKGraphicsPipeline* VKPipelineCache::GetGraphicsPipeline(
|
|||
const auto [pair, is_cache_miss] = graphics_cache.try_emplace(key);
|
||||
auto& entry = pair->second;
|
||||
if (is_cache_miss) {
|
||||
system.GPU().ShaderNotify().MarkSharderBuilding();
|
||||
gpu.ShaderNotify().MarkSharderBuilding();
|
||||
LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash());
|
||||
const auto [program, bindings] = DecompileShaders(key.fixed_state);
|
||||
entry = std::make_unique<VKGraphicsPipeline>(device, scheduler, descriptor_pool,
|
||||
update_descriptor_queue, renderpass_cache, key,
|
||||
bindings, program);
|
||||
system.GPU().ShaderNotify().MarkShaderComplete();
|
||||
gpu.ShaderNotify().MarkShaderComplete();
|
||||
}
|
||||
last_graphics_pipeline = entry.get();
|
||||
return last_graphics_pipeline;
|
||||
|
@ -255,22 +247,21 @@ VKComputePipeline& VKPipelineCache::GetComputePipeline(const ComputePipelineCach
|
|||
}
|
||||
LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash());
|
||||
|
||||
auto& memory_manager = system.GPU().MemoryManager();
|
||||
const auto program_addr = key.shader;
|
||||
const GPUVAddr gpu_addr = key.shader;
|
||||
|
||||
const auto cpu_addr = memory_manager.GpuToCpuAddress(program_addr);
|
||||
const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
|
||||
ASSERT(cpu_addr);
|
||||
|
||||
Shader* shader = cpu_addr ? TryGet(*cpu_addr) : null_kernel.get();
|
||||
if (!shader) {
|
||||
// No shader found - create a new one
|
||||
const auto host_ptr = memory_manager.GetPointer(program_addr);
|
||||
const auto host_ptr = gpu_memory.GetPointer(gpu_addr);
|
||||
|
||||
ProgramCode code = GetShaderCode(memory_manager, program_addr, host_ptr, true);
|
||||
ProgramCode code = GetShaderCode(gpu_memory, gpu_addr, host_ptr, true);
|
||||
const std::size_t size_in_bytes = code.size() * sizeof(u64);
|
||||
|
||||
auto shader_info = std::make_unique<Shader>(system, ShaderType::Compute, program_addr,
|
||||
std::move(code), KERNEL_MAIN_OFFSET);
|
||||
auto shader_info = std::make_unique<Shader>(kepler_compute, ShaderType::Compute, gpu_addr,
|
||||
*cpu_addr, std::move(code), KERNEL_MAIN_OFFSET);
|
||||
shader = shader_info.get();
|
||||
|
||||
if (cpu_addr) {
|
||||
|
@ -298,7 +289,7 @@ VKComputePipeline& VKPipelineCache::GetComputePipeline(const ComputePipelineCach
|
|||
}
|
||||
|
||||
void VKPipelineCache::EmplacePipeline(std::unique_ptr<VKGraphicsPipeline> pipeline) {
|
||||
system.GPU().ShaderNotify().MarkShaderComplete();
|
||||
gpu.ShaderNotify().MarkShaderComplete();
|
||||
std::unique_lock lock{pipeline_cache};
|
||||
graphics_cache.at(pipeline->GetCacheKey()) = std::move(pipeline);
|
||||
}
|
||||
|
@ -339,9 +330,6 @@ void VKPipelineCache::OnShaderRemoval(Shader* shader) {
|
|||
|
||||
std::pair<SPIRVProgram, std::vector<VkDescriptorSetLayoutBinding>>
|
||||
VKPipelineCache::DecompileShaders(const FixedPipelineState& fixed_state) {
|
||||
auto& memory_manager = system.GPU().MemoryManager();
|
||||
const auto& gpu = system.GPU().Maxwell3D();
|
||||
|
||||
Specialization specialization;
|
||||
if (fixed_state.dynamic_state.Topology() == Maxwell::PrimitiveTopology::Points ||
|
||||
device.IsExtExtendedDynamicStateSupported()) {
|
||||
|
@ -364,12 +352,12 @@ VKPipelineCache::DecompileShaders(const FixedPipelineState& fixed_state) {
|
|||
const auto program_enum = static_cast<Maxwell::ShaderProgram>(index);
|
||||
|
||||
// Skip stages that are not enabled
|
||||
if (!gpu.regs.IsShaderConfigEnabled(index)) {
|
||||
if (!maxwell3d.regs.IsShaderConfigEnabled(index)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const GPUVAddr gpu_addr = GetShaderAddress(system, program_enum);
|
||||
const std::optional<VAddr> cpu_addr = memory_manager.GpuToCpuAddress(gpu_addr);
|
||||
const GPUVAddr gpu_addr = GetShaderAddress(maxwell3d, program_enum);
|
||||
const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
|
||||
Shader* const shader = cpu_addr ? TryGet(*cpu_addr) : null_shader.get();
|
||||
|
||||
const std::size_t stage = index == 0 ? 0 : index - 1; // Stage indices are 0 - 5
|
||||
|
|
|
@ -85,7 +85,8 @@ namespace Vulkan {
|
|||
|
||||
class Shader {
|
||||
public:
|
||||
explicit Shader(Core::System& system, Tegra::Engines::ShaderType stage, GPUVAddr gpu_addr,
|
||||
explicit Shader(Tegra::Engines::ConstBufferEngineInterface& engine,
|
||||
Tegra::Engines::ShaderType stage, GPUVAddr gpu_addr, VAddr cpu_addr,
|
||||
VideoCommon::Shader::ProgramCode program_code, u32 main_offset);
|
||||
~Shader();
|
||||
|
||||
|
@ -97,22 +98,19 @@ public:
|
|||
return shader_ir;
|
||||
}
|
||||
|
||||
const VideoCommon::Shader::Registry& GetRegistry() const {
|
||||
return registry;
|
||||
}
|
||||
|
||||
const VideoCommon::Shader::ShaderIR& GetIR() const {
|
||||
return shader_ir;
|
||||
}
|
||||
|
||||
const VideoCommon::Shader::Registry& GetRegistry() const {
|
||||
return registry;
|
||||
}
|
||||
|
||||
const ShaderEntries& GetEntries() const {
|
||||
return entries;
|
||||
}
|
||||
|
||||
private:
|
||||
static Tegra::Engines::ConstBufferEngineInterface& GetEngine(Core::System& system,
|
||||
Tegra::Engines::ShaderType stage);
|
||||
|
||||
GPUVAddr gpu_addr{};
|
||||
VideoCommon::Shader::ProgramCode program_code;
|
||||
VideoCommon::Shader::Registry registry;
|
||||
|
@ -122,9 +120,11 @@ private:
|
|||
|
||||
class VKPipelineCache final : public VideoCommon::ShaderCache<Shader> {
|
||||
public:
|
||||
explicit VKPipelineCache(Core::System& system, RasterizerVulkan& rasterizer,
|
||||
const VKDevice& device, VKScheduler& scheduler,
|
||||
VKDescriptorPool& descriptor_pool,
|
||||
explicit VKPipelineCache(RasterizerVulkan& rasterizer, Tegra::GPU& gpu,
|
||||
Tegra::Engines::Maxwell3D& maxwell3d,
|
||||
Tegra::Engines::KeplerCompute& kepler_compute,
|
||||
Tegra::MemoryManager& gpu_memory, const VKDevice& device,
|
||||
VKScheduler& scheduler, VKDescriptorPool& descriptor_pool,
|
||||
VKUpdateDescriptorQueue& update_descriptor_queue,
|
||||
VKRenderPassCache& renderpass_cache);
|
||||
~VKPipelineCache() override;
|
||||
|
@ -145,7 +145,11 @@ private:
|
|||
std::pair<SPIRVProgram, std::vector<VkDescriptorSetLayoutBinding>> DecompileShaders(
|
||||
const FixedPipelineState& fixed_state);
|
||||
|
||||
Core::System& system;
|
||||
Tegra::GPU& gpu;
|
||||
Tegra::Engines::Maxwell3D& maxwell3d;
|
||||
Tegra::Engines::KeplerCompute& kepler_compute;
|
||||
Tegra::MemoryManager& gpu_memory;
|
||||
|
||||
const VKDevice& device;
|
||||
VKScheduler& scheduler;
|
||||
VKDescriptorPool& descriptor_pool;
|
||||
|
|
|
@ -68,10 +68,11 @@ void QueryPool::Reserve(std::pair<VkQueryPool, u32> query) {
|
|||
usage[pool_index * GROW_STEP + static_cast<std::ptrdiff_t>(query.second)] = false;
|
||||
}
|
||||
|
||||
VKQueryCache::VKQueryCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer,
|
||||
VKQueryCache::VKQueryCache(VideoCore::RasterizerInterface& rasterizer,
|
||||
Tegra::Engines::Maxwell3D& maxwell3d, Tegra::MemoryManager& gpu_memory,
|
||||
const VKDevice& device, VKScheduler& scheduler)
|
||||
: VideoCommon::QueryCacheBase<VKQueryCache, CachedQuery, CounterStream, HostCounter,
|
||||
QueryPool>{system, rasterizer},
|
||||
QueryPool>{rasterizer, maxwell3d, gpu_memory},
|
||||
device{device}, scheduler{scheduler} {
|
||||
for (std::size_t i = 0; i < static_cast<std::size_t>(VideoCore::NumQueryTypes); ++i) {
|
||||
query_pools[i].Initialize(device, static_cast<VideoCore::QueryType>(i));
|
||||
|
|
|
@ -56,7 +56,8 @@ class VKQueryCache final
|
|||
: public VideoCommon::QueryCacheBase<VKQueryCache, CachedQuery, CounterStream, HostCounter,
|
||||
QueryPool> {
|
||||
public:
|
||||
explicit VKQueryCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer,
|
||||
explicit VKQueryCache(VideoCore::RasterizerInterface& rasterizer,
|
||||
Tegra::Engines::Maxwell3D& maxwell3d, Tegra::MemoryManager& gpu_memory,
|
||||
const VKDevice& device, VKScheduler& scheduler);
|
||||
~VKQueryCache();
|
||||
|
||||
|
|
|
@ -381,28 +381,30 @@ void RasterizerVulkan::DrawParameters::Draw(vk::CommandBuffer cmdbuf) const {
|
|||
}
|
||||
}
|
||||
|
||||
RasterizerVulkan::RasterizerVulkan(Core::System& system, Core::Frontend::EmuWindow& renderer,
|
||||
VKScreenInfo& screen_info, const VKDevice& device,
|
||||
VKResourceManager& resource_manager,
|
||||
VKMemoryManager& memory_manager, StateTracker& state_tracker,
|
||||
VKScheduler& scheduler)
|
||||
: RasterizerAccelerated{system.Memory()}, system{system}, render_window{renderer},
|
||||
screen_info{screen_info}, device{device}, resource_manager{resource_manager},
|
||||
memory_manager{memory_manager}, state_tracker{state_tracker}, scheduler{scheduler},
|
||||
RasterizerVulkan::RasterizerVulkan(Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu_,
|
||||
Tegra::MemoryManager& gpu_memory_,
|
||||
Core::Memory::Memory& cpu_memory, VKScreenInfo& screen_info_,
|
||||
const VKDevice& device_, VKResourceManager& resource_manager_,
|
||||
VKMemoryManager& memory_manager_, StateTracker& state_tracker_,
|
||||
VKScheduler& scheduler_)
|
||||
: RasterizerAccelerated(cpu_memory), gpu(gpu_), gpu_memory(gpu_memory_),
|
||||
maxwell3d(gpu.Maxwell3D()), kepler_compute(gpu.KeplerCompute()), screen_info(screen_info_),
|
||||
device(device_), resource_manager(resource_manager_), memory_manager(memory_manager_),
|
||||
state_tracker(state_tracker_), scheduler(scheduler_),
|
||||
staging_pool(device, memory_manager, scheduler), descriptor_pool(device),
|
||||
update_descriptor_queue(device, scheduler), renderpass_cache(device),
|
||||
quad_array_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue),
|
||||
quad_indexed_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue),
|
||||
uint8_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue),
|
||||
texture_cache(system, *this, device, resource_manager, memory_manager, scheduler,
|
||||
staging_pool),
|
||||
pipeline_cache(system, *this, device, scheduler, descriptor_pool, update_descriptor_queue,
|
||||
renderpass_cache),
|
||||
buffer_cache(*this, system, device, memory_manager, scheduler, staging_pool),
|
||||
sampler_cache(device),
|
||||
fence_manager(system, *this, device, scheduler, texture_cache, buffer_cache, query_cache),
|
||||
query_cache(system, *this, device, scheduler),
|
||||
wfi_event{device.GetLogical().CreateNewEvent()}, async_shaders{renderer} {
|
||||
texture_cache(*this, maxwell3d, gpu_memory, device, resource_manager, memory_manager,
|
||||
scheduler, staging_pool),
|
||||
pipeline_cache(*this, gpu, maxwell3d, kepler_compute, gpu_memory, device, scheduler,
|
||||
descriptor_pool, update_descriptor_queue, renderpass_cache),
|
||||
buffer_cache(*this, gpu_memory, cpu_memory, device, memory_manager, scheduler, staging_pool),
|
||||
sampler_cache(device), query_cache(*this, maxwell3d, gpu_memory, device, scheduler),
|
||||
fence_manager(*this, gpu, gpu_memory, texture_cache, buffer_cache, query_cache, device,
|
||||
scheduler),
|
||||
wfi_event(device.GetLogical().CreateNewEvent()), async_shaders(emu_window) {
|
||||
scheduler.SetQueryCache(query_cache);
|
||||
if (device.UseAsynchronousShaders()) {
|
||||
async_shaders.AllocateWorkers();
|
||||
|
@ -414,15 +416,13 @@ RasterizerVulkan::~RasterizerVulkan() = default;
|
|||
void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) {
|
||||
MICROPROFILE_SCOPE(Vulkan_Drawing);
|
||||
|
||||
SCOPE_EXIT({ gpu.TickWork(); });
|
||||
FlushWork();
|
||||
|
||||
query_cache.UpdateCounters();
|
||||
|
||||
SCOPE_EXIT({ system.GPU().TickWork(); });
|
||||
|
||||
const auto& gpu = system.GPU().Maxwell3D();
|
||||
GraphicsPipelineCacheKey key;
|
||||
key.fixed_state.Fill(gpu.regs, device.IsExtExtendedDynamicStateSupported());
|
||||
key.fixed_state.Fill(maxwell3d.regs, device.IsExtExtendedDynamicStateSupported());
|
||||
|
||||
buffer_cache.Map(CalculateGraphicsStreamBufferSize(is_indexed));
|
||||
|
||||
|
@ -480,8 +480,7 @@ void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) {
|
|||
void RasterizerVulkan::Clear() {
|
||||
MICROPROFILE_SCOPE(Vulkan_Clearing);
|
||||
|
||||
const auto& gpu = system.GPU().Maxwell3D();
|
||||
if (!system.GPU().Maxwell3D().ShouldExecute()) {
|
||||
if (!maxwell3d.ShouldExecute()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -490,7 +489,7 @@ void RasterizerVulkan::Clear() {
|
|||
|
||||
query_cache.UpdateCounters();
|
||||
|
||||
const auto& regs = gpu.regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
const bool use_color = regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B ||
|
||||
regs.clear_buffers.A;
|
||||
const bool use_depth = regs.clear_buffers.Z;
|
||||
|
@ -559,7 +558,7 @@ void RasterizerVulkan::DispatchCompute(GPUVAddr code_addr) {
|
|||
|
||||
query_cache.UpdateCounters();
|
||||
|
||||
const auto& launch_desc = system.GPU().KeplerCompute().launch_description;
|
||||
const auto& launch_desc = kepler_compute.launch_description;
|
||||
auto& pipeline = pipeline_cache.GetComputePipeline({
|
||||
.shader = code_addr,
|
||||
.shared_memory_size = launch_desc.shared_alloc,
|
||||
|
@ -655,16 +654,14 @@ void RasterizerVulkan::SyncGuestHost() {
|
|||
}
|
||||
|
||||
void RasterizerVulkan::SignalSemaphore(GPUVAddr addr, u32 value) {
|
||||
auto& gpu{system.GPU()};
|
||||
if (!gpu.IsAsync()) {
|
||||
gpu.MemoryManager().Write<u32>(addr, value);
|
||||
gpu_memory.Write<u32>(addr, value);
|
||||
return;
|
||||
}
|
||||
fence_manager.SignalSemaphore(addr, value);
|
||||
}
|
||||
|
||||
void RasterizerVulkan::SignalSyncPoint(u32 value) {
|
||||
auto& gpu{system.GPU()};
|
||||
if (!gpu.IsAsync()) {
|
||||
gpu.IncrementSyncPoint(value);
|
||||
return;
|
||||
|
@ -673,7 +670,6 @@ void RasterizerVulkan::SignalSyncPoint(u32 value) {
|
|||
}
|
||||
|
||||
void RasterizerVulkan::ReleaseFences() {
|
||||
auto& gpu{system.GPU()};
|
||||
if (!gpu.IsAsync()) {
|
||||
return;
|
||||
}
|
||||
|
@ -751,10 +747,6 @@ bool RasterizerVulkan::AccelerateDisplay(const Tegra::FramebufferConfig& config,
|
|||
return true;
|
||||
}
|
||||
|
||||
void RasterizerVulkan::SetupDirtyFlags() {
|
||||
state_tracker.Initialize();
|
||||
}
|
||||
|
||||
void RasterizerVulkan::FlushWork() {
|
||||
static constexpr u32 DRAWS_TO_DISPATCH = 4096;
|
||||
|
||||
|
@ -778,10 +770,9 @@ void RasterizerVulkan::FlushWork() {
|
|||
|
||||
RasterizerVulkan::Texceptions RasterizerVulkan::UpdateAttachments(bool is_clear) {
|
||||
MICROPROFILE_SCOPE(Vulkan_RenderTargets);
|
||||
auto& maxwell3d = system.GPU().Maxwell3D();
|
||||
auto& dirty = maxwell3d.dirty.flags;
|
||||
auto& regs = maxwell3d.regs;
|
||||
|
||||
const auto& regs = maxwell3d.regs;
|
||||
auto& dirty = maxwell3d.dirty.flags;
|
||||
const bool update_rendertargets = dirty[VideoCommon::Dirty::RenderTargets];
|
||||
dirty[VideoCommon::Dirty::RenderTargets] = false;
|
||||
|
||||
|
@ -844,7 +835,7 @@ std::tuple<VkFramebuffer, VkExtent2D> RasterizerVulkan::ConfigureFramebuffers(
|
|||
return true;
|
||||
};
|
||||
|
||||
const auto& regs = system.GPU().Maxwell3D().regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
const std::size_t num_attachments = static_cast<std::size_t>(regs.rt_control.count);
|
||||
for (std::size_t index = 0; index < num_attachments; ++index) {
|
||||
if (try_push(color_attachments[index])) {
|
||||
|
@ -880,13 +871,12 @@ RasterizerVulkan::DrawParameters RasterizerVulkan::SetupGeometry(FixedPipelineSt
|
|||
bool is_instanced) {
|
||||
MICROPROFILE_SCOPE(Vulkan_Geometry);
|
||||
|
||||
const auto& gpu = system.GPU().Maxwell3D();
|
||||
const auto& regs = gpu.regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
|
||||
SetupVertexArrays(buffer_bindings);
|
||||
|
||||
const u32 base_instance = regs.vb_base_instance;
|
||||
const u32 num_instances = is_instanced ? gpu.mme_draw.instance_count : 1;
|
||||
const u32 num_instances = is_instanced ? maxwell3d.mme_draw.instance_count : 1;
|
||||
const u32 base_vertex = is_indexed ? regs.vb_element_base : regs.vertex_buffer.first;
|
||||
const u32 num_vertices = is_indexed ? regs.index_array.count : regs.vertex_buffer.count;
|
||||
|
||||
|
@ -947,7 +937,7 @@ void RasterizerVulkan::SetupImageTransitions(
|
|||
}
|
||||
|
||||
void RasterizerVulkan::UpdateDynamicStates() {
|
||||
auto& regs = system.GPU().Maxwell3D().regs;
|
||||
auto& regs = maxwell3d.regs;
|
||||
UpdateViewportsState(regs);
|
||||
UpdateScissorsState(regs);
|
||||
UpdateDepthBias(regs);
|
||||
|
@ -968,7 +958,7 @@ void RasterizerVulkan::UpdateDynamicStates() {
|
|||
}
|
||||
|
||||
void RasterizerVulkan::BeginTransformFeedback() {
|
||||
const auto& regs = system.GPU().Maxwell3D().regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
if (regs.tfb_enabled == 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -1000,7 +990,7 @@ void RasterizerVulkan::BeginTransformFeedback() {
|
|||
}
|
||||
|
||||
void RasterizerVulkan::EndTransformFeedback() {
|
||||
const auto& regs = system.GPU().Maxwell3D().regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
if (regs.tfb_enabled == 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -1013,7 +1003,7 @@ void RasterizerVulkan::EndTransformFeedback() {
|
|||
}
|
||||
|
||||
void RasterizerVulkan::SetupVertexArrays(BufferBindings& buffer_bindings) {
|
||||
const auto& regs = system.GPU().Maxwell3D().regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
|
||||
for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
|
||||
const auto& vertex_array = regs.vertex_array[index];
|
||||
|
@ -1039,7 +1029,7 @@ void RasterizerVulkan::SetupIndexBuffer(BufferBindings& buffer_bindings, DrawPar
|
|||
if (params.num_vertices == 0) {
|
||||
return;
|
||||
}
|
||||
const auto& regs = system.GPU().Maxwell3D().regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
switch (regs.draw.topology) {
|
||||
case Maxwell::PrimitiveTopology::Quads: {
|
||||
if (!params.is_indexed) {
|
||||
|
@ -1087,8 +1077,7 @@ void RasterizerVulkan::SetupIndexBuffer(BufferBindings& buffer_bindings, DrawPar
|
|||
|
||||
void RasterizerVulkan::SetupGraphicsConstBuffers(const ShaderEntries& entries, std::size_t stage) {
|
||||
MICROPROFILE_SCOPE(Vulkan_ConstBuffers);
|
||||
const auto& gpu = system.GPU().Maxwell3D();
|
||||
const auto& shader_stage = gpu.state.shader_stages[stage];
|
||||
const auto& shader_stage = maxwell3d.state.shader_stages[stage];
|
||||
for (const auto& entry : entries.const_buffers) {
|
||||
SetupConstBuffer(entry, shader_stage.const_buffers[entry.GetIndex()]);
|
||||
}
|
||||
|
@ -1096,8 +1085,7 @@ void RasterizerVulkan::SetupGraphicsConstBuffers(const ShaderEntries& entries, s
|
|||
|
||||
void RasterizerVulkan::SetupGraphicsGlobalBuffers(const ShaderEntries& entries, std::size_t stage) {
|
||||
MICROPROFILE_SCOPE(Vulkan_GlobalBuffers);
|
||||
auto& gpu{system.GPU()};
|
||||
const auto cbufs{gpu.Maxwell3D().state.shader_stages[stage]};
|
||||
const auto& cbufs{maxwell3d.state.shader_stages[stage]};
|
||||
|
||||
for (const auto& entry : entries.global_buffers) {
|
||||
const auto addr = cbufs.const_buffers[entry.GetCbufIndex()].address + entry.GetCbufOffset();
|
||||
|
@ -1107,19 +1095,17 @@ void RasterizerVulkan::SetupGraphicsGlobalBuffers(const ShaderEntries& entries,
|
|||
|
||||
void RasterizerVulkan::SetupGraphicsUniformTexels(const ShaderEntries& entries, std::size_t stage) {
|
||||
MICROPROFILE_SCOPE(Vulkan_Textures);
|
||||
const auto& gpu = system.GPU().Maxwell3D();
|
||||
for (const auto& entry : entries.uniform_texels) {
|
||||
const auto image = GetTextureInfo(gpu, entry, stage).tic;
|
||||
const auto image = GetTextureInfo(maxwell3d, entry, stage).tic;
|
||||
SetupUniformTexels(image, entry);
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerVulkan::SetupGraphicsTextures(const ShaderEntries& entries, std::size_t stage) {
|
||||
MICROPROFILE_SCOPE(Vulkan_Textures);
|
||||
const auto& gpu = system.GPU().Maxwell3D();
|
||||
for (const auto& entry : entries.samplers) {
|
||||
for (std::size_t i = 0; i < entry.size; ++i) {
|
||||
const auto texture = GetTextureInfo(gpu, entry, stage, i);
|
||||
const auto texture = GetTextureInfo(maxwell3d, entry, stage, i);
|
||||
SetupTexture(texture, entry);
|
||||
}
|
||||
}
|
||||
|
@ -1127,25 +1113,23 @@ void RasterizerVulkan::SetupGraphicsTextures(const ShaderEntries& entries, std::
|
|||
|
||||
void RasterizerVulkan::SetupGraphicsStorageTexels(const ShaderEntries& entries, std::size_t stage) {
|
||||
MICROPROFILE_SCOPE(Vulkan_Textures);
|
||||
const auto& gpu = system.GPU().Maxwell3D();
|
||||
for (const auto& entry : entries.storage_texels) {
|
||||
const auto image = GetTextureInfo(gpu, entry, stage).tic;
|
||||
const auto image = GetTextureInfo(maxwell3d, entry, stage).tic;
|
||||
SetupStorageTexel(image, entry);
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerVulkan::SetupGraphicsImages(const ShaderEntries& entries, std::size_t stage) {
|
||||
MICROPROFILE_SCOPE(Vulkan_Images);
|
||||
const auto& gpu = system.GPU().Maxwell3D();
|
||||
for (const auto& entry : entries.images) {
|
||||
const auto tic = GetTextureInfo(gpu, entry, stage).tic;
|
||||
const auto tic = GetTextureInfo(maxwell3d, entry, stage).tic;
|
||||
SetupImage(tic, entry);
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerVulkan::SetupComputeConstBuffers(const ShaderEntries& entries) {
|
||||
MICROPROFILE_SCOPE(Vulkan_ConstBuffers);
|
||||
const auto& launch_desc = system.GPU().KeplerCompute().launch_description;
|
||||
const auto& launch_desc = kepler_compute.launch_description;
|
||||
for (const auto& entry : entries.const_buffers) {
|
||||
const auto& config = launch_desc.const_buffer_config[entry.GetIndex()];
|
||||
const std::bitset<8> mask = launch_desc.const_buffer_enable_mask.Value();
|
||||
|
@ -1159,7 +1143,7 @@ void RasterizerVulkan::SetupComputeConstBuffers(const ShaderEntries& entries) {
|
|||
|
||||
void RasterizerVulkan::SetupComputeGlobalBuffers(const ShaderEntries& entries) {
|
||||
MICROPROFILE_SCOPE(Vulkan_GlobalBuffers);
|
||||
const auto cbufs{system.GPU().KeplerCompute().launch_description.const_buffer_config};
|
||||
const auto& cbufs{kepler_compute.launch_description.const_buffer_config};
|
||||
for (const auto& entry : entries.global_buffers) {
|
||||
const auto addr{cbufs[entry.GetCbufIndex()].Address() + entry.GetCbufOffset()};
|
||||
SetupGlobalBuffer(entry, addr);
|
||||
|
@ -1168,19 +1152,17 @@ void RasterizerVulkan::SetupComputeGlobalBuffers(const ShaderEntries& entries) {
|
|||
|
||||
void RasterizerVulkan::SetupComputeUniformTexels(const ShaderEntries& entries) {
|
||||
MICROPROFILE_SCOPE(Vulkan_Textures);
|
||||
const auto& gpu = system.GPU().KeplerCompute();
|
||||
for (const auto& entry : entries.uniform_texels) {
|
||||
const auto image = GetTextureInfo(gpu, entry, ComputeShaderIndex).tic;
|
||||
const auto image = GetTextureInfo(kepler_compute, entry, ComputeShaderIndex).tic;
|
||||
SetupUniformTexels(image, entry);
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerVulkan::SetupComputeTextures(const ShaderEntries& entries) {
|
||||
MICROPROFILE_SCOPE(Vulkan_Textures);
|
||||
const auto& gpu = system.GPU().KeplerCompute();
|
||||
for (const auto& entry : entries.samplers) {
|
||||
for (std::size_t i = 0; i < entry.size; ++i) {
|
||||
const auto texture = GetTextureInfo(gpu, entry, ComputeShaderIndex, i);
|
||||
const auto texture = GetTextureInfo(kepler_compute, entry, ComputeShaderIndex, i);
|
||||
SetupTexture(texture, entry);
|
||||
}
|
||||
}
|
||||
|
@ -1188,18 +1170,16 @@ void RasterizerVulkan::SetupComputeTextures(const ShaderEntries& entries) {
|
|||
|
||||
void RasterizerVulkan::SetupComputeStorageTexels(const ShaderEntries& entries) {
|
||||
MICROPROFILE_SCOPE(Vulkan_Textures);
|
||||
const auto& gpu = system.GPU().KeplerCompute();
|
||||
for (const auto& entry : entries.storage_texels) {
|
||||
const auto image = GetTextureInfo(gpu, entry, ComputeShaderIndex).tic;
|
||||
const auto image = GetTextureInfo(kepler_compute, entry, ComputeShaderIndex).tic;
|
||||
SetupStorageTexel(image, entry);
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerVulkan::SetupComputeImages(const ShaderEntries& entries) {
|
||||
MICROPROFILE_SCOPE(Vulkan_Images);
|
||||
const auto& gpu = system.GPU().KeplerCompute();
|
||||
for (const auto& entry : entries.images) {
|
||||
const auto tic = GetTextureInfo(gpu, entry, ComputeShaderIndex).tic;
|
||||
const auto tic = GetTextureInfo(kepler_compute, entry, ComputeShaderIndex).tic;
|
||||
SetupImage(tic, entry);
|
||||
}
|
||||
}
|
||||
|
@ -1223,9 +1203,8 @@ void RasterizerVulkan::SetupConstBuffer(const ConstBufferEntry& entry,
|
|||
}
|
||||
|
||||
void RasterizerVulkan::SetupGlobalBuffer(const GlobalBufferEntry& entry, GPUVAddr address) {
|
||||
auto& memory_manager{system.GPU().MemoryManager()};
|
||||
const auto actual_addr = memory_manager.Read<u64>(address);
|
||||
const auto size = memory_manager.Read<u32>(address + 8);
|
||||
const u64 actual_addr = gpu_memory.Read<u64>(address);
|
||||
const u32 size = gpu_memory.Read<u32>(address + 8);
|
||||
|
||||
if (size == 0) {
|
||||
// Sometimes global memory pointers don't have a proper size. Upload a dummy entry
|
||||
|
@ -1508,7 +1487,7 @@ std::size_t RasterizerVulkan::CalculateComputeStreamBufferSize() const {
|
|||
}
|
||||
|
||||
std::size_t RasterizerVulkan::CalculateVertexArraysSize() const {
|
||||
const auto& regs = system.GPU().Maxwell3D().regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
|
||||
std::size_t size = 0;
|
||||
for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) {
|
||||
|
@ -1523,9 +1502,8 @@ std::size_t RasterizerVulkan::CalculateVertexArraysSize() const {
|
|||
}
|
||||
|
||||
std::size_t RasterizerVulkan::CalculateIndexBufferSize() const {
|
||||
const auto& regs = system.GPU().Maxwell3D().regs;
|
||||
return static_cast<std::size_t>(regs.index_array.count) *
|
||||
static_cast<std::size_t>(regs.index_array.FormatSizeInBytes());
|
||||
return static_cast<std::size_t>(maxwell3d.regs.index_array.count) *
|
||||
static_cast<std::size_t>(maxwell3d.regs.index_array.FormatSizeInBytes());
|
||||
}
|
||||
|
||||
std::size_t RasterizerVulkan::CalculateConstBufferSize(
|
||||
|
@ -1540,7 +1518,7 @@ std::size_t RasterizerVulkan::CalculateConstBufferSize(
|
|||
}
|
||||
|
||||
RenderPassParams RasterizerVulkan::GetRenderPassParams(Texceptions texceptions) const {
|
||||
const auto& regs = system.GPU().Maxwell3D().regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
const std::size_t num_attachments = static_cast<std::size_t>(regs.rt_control.count);
|
||||
|
||||
RenderPassParams params;
|
||||
|
|
|
@ -106,7 +106,8 @@ struct ImageView {
|
|||
|
||||
class RasterizerVulkan final : public VideoCore::RasterizerAccelerated {
|
||||
public:
|
||||
explicit RasterizerVulkan(Core::System& system, Core::Frontend::EmuWindow& render_window,
|
||||
explicit RasterizerVulkan(Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu,
|
||||
Tegra::MemoryManager& gpu_memory, Core::Memory::Memory& cpu_memory,
|
||||
VKScreenInfo& screen_info, const VKDevice& device,
|
||||
VKResourceManager& resource_manager, VKMemoryManager& memory_manager,
|
||||
StateTracker& state_tracker, VKScheduler& scheduler);
|
||||
|
@ -135,7 +136,6 @@ public:
|
|||
const Tegra::Engines::Fermi2D::Config& copy_config) override;
|
||||
bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
|
||||
u32 pixel_stride) override;
|
||||
void SetupDirtyFlags() override;
|
||||
|
||||
VideoCommon::Shader::AsyncShaders& GetAsyncShaders() {
|
||||
return async_shaders;
|
||||
|
@ -279,8 +279,11 @@ private:
|
|||
|
||||
VkBuffer DefaultBuffer();
|
||||
|
||||
Core::System& system;
|
||||
Core::Frontend::EmuWindow& render_window;
|
||||
Tegra::GPU& gpu;
|
||||
Tegra::MemoryManager& gpu_memory;
|
||||
Tegra::Engines::Maxwell3D& maxwell3d;
|
||||
Tegra::Engines::KeplerCompute& kepler_compute;
|
||||
|
||||
VKScreenInfo& screen_info;
|
||||
const VKDevice& device;
|
||||
VKResourceManager& resource_manager;
|
||||
|
@ -300,8 +303,8 @@ private:
|
|||
VKPipelineCache pipeline_cache;
|
||||
VKBufferCache buffer_cache;
|
||||
VKSamplerCache sampler_cache;
|
||||
VKFenceManager fence_manager;
|
||||
VKQueryCache query_cache;
|
||||
VKFenceManager fence_manager;
|
||||
|
||||
vk::Buffer default_buffer;
|
||||
VKMemoryCommit default_buffer_commit;
|
||||
|
|
|
@ -132,12 +132,9 @@ void SetupDirtyStencilTestEnable(Tables& tables) {
|
|||
|
||||
} // Anonymous namespace
|
||||
|
||||
StateTracker::StateTracker(Core::System& system)
|
||||
: system{system}, invalidation_flags{MakeInvalidationFlags()} {}
|
||||
|
||||
void StateTracker::Initialize() {
|
||||
auto& dirty = system.GPU().Maxwell3D().dirty;
|
||||
auto& tables = dirty.tables;
|
||||
StateTracker::StateTracker(Tegra::GPU& gpu)
|
||||
: flags{gpu.Maxwell3D().dirty.flags}, invalidation_flags{MakeInvalidationFlags()} {
|
||||
auto& tables = gpu.Maxwell3D().dirty.tables;
|
||||
SetupDirtyRenderTargets(tables);
|
||||
SetupDirtyViewports(tables);
|
||||
SetupDirtyScissors(tables);
|
||||
|
@ -155,9 +152,4 @@ void StateTracker::Initialize() {
|
|||
SetupDirtyStencilTestEnable(tables);
|
||||
}
|
||||
|
||||
void StateTracker::InvalidateCommandBufferState() {
|
||||
system.GPU().Maxwell3D().dirty.flags |= invalidation_flags;
|
||||
current_topology = INVALID_TOPOLOGY;
|
||||
}
|
||||
|
||||
} // namespace Vulkan
|
||||
|
|
|
@ -45,11 +45,12 @@ class StateTracker {
|
|||
using Maxwell = Tegra::Engines::Maxwell3D::Regs;
|
||||
|
||||
public:
|
||||
explicit StateTracker(Core::System& system);
|
||||
explicit StateTracker(Tegra::GPU& gpu);
|
||||
|
||||
void Initialize();
|
||||
|
||||
void InvalidateCommandBufferState();
|
||||
void InvalidateCommandBufferState() {
|
||||
flags |= invalidation_flags;
|
||||
current_topology = INVALID_TOPOLOGY;
|
||||
}
|
||||
|
||||
bool TouchViewports() {
|
||||
return Exchange(Dirty::Viewports, false);
|
||||
|
@ -121,13 +122,12 @@ private:
|
|||
static constexpr auto INVALID_TOPOLOGY = static_cast<Maxwell::PrimitiveTopology>(~0u);
|
||||
|
||||
bool Exchange(std::size_t id, bool new_value) const noexcept {
|
||||
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||
const bool is_dirty = flags[id];
|
||||
flags[id] = new_value;
|
||||
return is_dirty;
|
||||
}
|
||||
|
||||
Core::System& system;
|
||||
Tegra::Engines::Maxwell3D::DirtyState::Flags& flags;
|
||||
Tegra::Engines::Maxwell3D::DirtyState::Flags invalidation_flags;
|
||||
Maxwell::PrimitiveTopology current_topology = INVALID_TOPOLOGY;
|
||||
};
|
||||
|
|
|
@ -57,9 +57,9 @@ u32 GetMemoryType(const VkPhysicalDeviceMemoryProperties& properties,
|
|||
|
||||
} // Anonymous namespace
|
||||
|
||||
VKStreamBuffer::VKStreamBuffer(const VKDevice& device, VKScheduler& scheduler,
|
||||
VKStreamBuffer::VKStreamBuffer(const VKDevice& device_, VKScheduler& scheduler_,
|
||||
VkBufferUsageFlags usage)
|
||||
: device{device}, scheduler{scheduler} {
|
||||
: device{device_}, scheduler{scheduler_} {
|
||||
CreateBuffers(usage);
|
||||
ReserveWatches(current_watches, WATCHES_INITIAL_RESERVE);
|
||||
ReserveWatches(previous_watches, WATCHES_INITIAL_RESERVE);
|
||||
|
|
|
@ -188,13 +188,13 @@ u32 EncodeSwizzle(Tegra::Texture::SwizzleSource x_source, Tegra::Texture::Swizzl
|
|||
|
||||
} // Anonymous namespace
|
||||
|
||||
CachedSurface::CachedSurface(Core::System& system, const VKDevice& device,
|
||||
VKResourceManager& resource_manager, VKMemoryManager& memory_manager,
|
||||
VKScheduler& scheduler, VKStagingBufferPool& staging_pool,
|
||||
GPUVAddr gpu_addr, const SurfaceParams& params)
|
||||
: SurfaceBase<View>{gpu_addr, params, device.IsOptimalAstcSupported()}, system{system},
|
||||
device{device}, resource_manager{resource_manager},
|
||||
memory_manager{memory_manager}, scheduler{scheduler}, staging_pool{staging_pool} {
|
||||
CachedSurface::CachedSurface(const VKDevice& device, VKResourceManager& resource_manager,
|
||||
VKMemoryManager& memory_manager, VKScheduler& scheduler,
|
||||
VKStagingBufferPool& staging_pool, GPUVAddr gpu_addr,
|
||||
const SurfaceParams& params)
|
||||
: SurfaceBase<View>{gpu_addr, params, device.IsOptimalAstcSupported()}, device{device},
|
||||
resource_manager{resource_manager}, memory_manager{memory_manager}, scheduler{scheduler},
|
||||
staging_pool{staging_pool} {
|
||||
if (params.IsBuffer()) {
|
||||
buffer = CreateBuffer(device, params, host_memory_size);
|
||||
commit = memory_manager.Commit(buffer, false);
|
||||
|
@ -490,19 +490,21 @@ VkImageView CachedSurfaceView::GetAttachment() {
|
|||
return *render_target;
|
||||
}
|
||||
|
||||
VKTextureCache::VKTextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer,
|
||||
const VKDevice& device, VKResourceManager& resource_manager,
|
||||
VKMemoryManager& memory_manager, VKScheduler& scheduler,
|
||||
VKStagingBufferPool& staging_pool)
|
||||
: TextureCache(system, rasterizer, device.IsOptimalAstcSupported()), device{device},
|
||||
resource_manager{resource_manager}, memory_manager{memory_manager}, scheduler{scheduler},
|
||||
staging_pool{staging_pool} {}
|
||||
VKTextureCache::VKTextureCache(VideoCore::RasterizerInterface& rasterizer,
|
||||
Tegra::Engines::Maxwell3D& maxwell3d,
|
||||
Tegra::MemoryManager& gpu_memory, const VKDevice& device_,
|
||||
VKResourceManager& resource_manager_,
|
||||
VKMemoryManager& memory_manager_, VKScheduler& scheduler_,
|
||||
VKStagingBufferPool& staging_pool_)
|
||||
: TextureCache(rasterizer, maxwell3d, gpu_memory, device_.IsOptimalAstcSupported()),
|
||||
device{device_}, resource_manager{resource_manager_},
|
||||
memory_manager{memory_manager_}, scheduler{scheduler_}, staging_pool{staging_pool_} {}
|
||||
|
||||
VKTextureCache::~VKTextureCache() = default;
|
||||
|
||||
Surface VKTextureCache::CreateSurface(GPUVAddr gpu_addr, const SurfaceParams& params) {
|
||||
return std::make_shared<CachedSurface>(system, device, resource_manager, memory_manager,
|
||||
scheduler, staging_pool, gpu_addr, params);
|
||||
return std::make_shared<CachedSurface>(device, resource_manager, memory_manager, scheduler,
|
||||
staging_pool, gpu_addr, params);
|
||||
}
|
||||
|
||||
void VKTextureCache::ImageCopy(Surface& src_surface, Surface& dst_surface,
|
||||
|
|
|
@ -15,10 +15,6 @@
|
|||
#include "video_core/texture_cache/surface_base.h"
|
||||
#include "video_core/texture_cache/texture_cache.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace VideoCore {
|
||||
class RasterizerInterface;
|
||||
}
|
||||
|
@ -45,10 +41,10 @@ class CachedSurface final : public VideoCommon::SurfaceBase<View> {
|
|||
friend CachedSurfaceView;
|
||||
|
||||
public:
|
||||
explicit CachedSurface(Core::System& system, const VKDevice& device,
|
||||
VKResourceManager& resource_manager, VKMemoryManager& memory_manager,
|
||||
VKScheduler& scheduler, VKStagingBufferPool& staging_pool,
|
||||
GPUVAddr gpu_addr, const SurfaceParams& params);
|
||||
explicit CachedSurface(const VKDevice& device, VKResourceManager& resource_manager,
|
||||
VKMemoryManager& memory_manager, VKScheduler& scheduler,
|
||||
VKStagingBufferPool& staging_pool, GPUVAddr gpu_addr,
|
||||
const SurfaceParams& params);
|
||||
~CachedSurface();
|
||||
|
||||
void UploadTexture(const std::vector<u8>& staging_buffer) override;
|
||||
|
@ -101,7 +97,6 @@ private:
|
|||
|
||||
VkImageSubresourceRange GetImageSubresourceRange() const;
|
||||
|
||||
Core::System& system;
|
||||
const VKDevice& device;
|
||||
VKResourceManager& resource_manager;
|
||||
VKMemoryManager& memory_manager;
|
||||
|
@ -201,7 +196,8 @@ private:
|
|||
|
||||
class VKTextureCache final : public TextureCacheBase {
|
||||
public:
|
||||
explicit VKTextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer,
|
||||
explicit VKTextureCache(VideoCore::RasterizerInterface& rasterizer,
|
||||
Tegra::Engines::Maxwell3D& maxwell3d, Tegra::MemoryManager& gpu_memory,
|
||||
const VKDevice& device, VKResourceManager& resource_manager,
|
||||
VKMemoryManager& memory_manager, VKScheduler& scheduler,
|
||||
VKStagingBufferPool& staging_pool);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue