2020-01-07 01:10:56 +01:00
|
|
|
// Copyright 2019 yuzu Emulator Project
|
|
|
|
// Licensed under GPLv2 or any later version
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2020-01-17 02:55:23 +01:00
|
|
|
#include <array>
|
|
|
|
#include <bitset>
|
|
|
|
#include <memory>
|
|
|
|
#include <utility>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include <boost/container/static_vector.hpp>
|
|
|
|
|
|
|
|
#include "common/common_types.h"
|
|
|
|
#include "video_core/rasterizer_accelerated.h"
|
2020-01-07 01:10:56 +01:00
|
|
|
#include "video_core/rasterizer_interface.h"
|
2020-12-30 06:25:23 +01:00
|
|
|
#include "video_core/renderer_vulkan/blit_image.h"
|
2020-01-17 02:55:23 +01:00
|
|
|
#include "video_core/renderer_vulkan/fixed_pipeline_state.h"
|
|
|
|
#include "video_core/renderer_vulkan/vk_buffer_cache.h"
|
|
|
|
#include "video_core/renderer_vulkan/vk_compute_pass.h"
|
|
|
|
#include "video_core/renderer_vulkan/vk_descriptor_pool.h"
|
2020-03-17 01:43:05 +01:00
|
|
|
#include "video_core/renderer_vulkan/vk_fence_manager.h"
|
2020-01-17 02:55:23 +01:00
|
|
|
#include "video_core/renderer_vulkan/vk_memory_manager.h"
|
|
|
|
#include "video_core/renderer_vulkan/vk_pipeline_cache.h"
|
2020-02-11 22:59:44 +01:00
|
|
|
#include "video_core/renderer_vulkan/vk_query_cache.h"
|
2020-01-17 02:55:23 +01:00
|
|
|
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
|
|
|
#include "video_core/renderer_vulkan/vk_staging_buffer_pool.h"
|
2020-12-30 06:25:23 +01:00
|
|
|
#include "video_core/renderer_vulkan/vk_stream_buffer.h"
|
2020-01-17 02:55:23 +01:00
|
|
|
#include "video_core/renderer_vulkan/vk_texture_cache.h"
|
|
|
|
#include "video_core/renderer_vulkan/vk_update_descriptor.h"
|
2020-07-28 06:08:02 +02:00
|
|
|
#include "video_core/shader/async_shaders.h"
|
2020-12-25 01:30:11 +01:00
|
|
|
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
2020-01-17 02:55:23 +01:00
|
|
|
|
|
|
|
namespace Core {
|
|
|
|
class System;
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace Core::Frontend {
|
|
|
|
class EmuWindow;
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace Tegra::Engines {
|
|
|
|
class Maxwell3D;
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace Vulkan {
|
|
|
|
|
|
|
|
struct VKScreenInfo;
|
|
|
|
|
2020-02-21 00:35:53 +01:00
|
|
|
class StateTracker;
|
2020-01-17 02:55:23 +01:00
|
|
|
class BufferBindings;
|
|
|
|
|
2020-02-11 22:59:44 +01:00
|
|
|
class RasterizerVulkan final : public VideoCore::RasterizerAccelerated {
|
2020-01-17 02:55:23 +01:00
|
|
|
public:
|
2020-12-05 17:40:14 +01:00
|
|
|
explicit RasterizerVulkan(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_,
|
|
|
|
Tegra::MemoryManager& gpu_memory_, Core::Memory::Memory& cpu_memory_,
|
2020-12-26 05:10:53 +01:00
|
|
|
VKScreenInfo& screen_info_, const Device& device_,
|
2020-12-05 17:40:14 +01:00
|
|
|
VKMemoryManager& memory_manager_, StateTracker& state_tracker_,
|
|
|
|
VKScheduler& scheduler_);
|
2020-01-17 02:55:23 +01:00
|
|
|
~RasterizerVulkan() override;
|
|
|
|
|
2020-02-14 22:09:37 +01:00
|
|
|
void Draw(bool is_indexed, bool is_instanced) override;
|
2020-01-17 02:55:23 +01:00
|
|
|
void Clear() override;
|
|
|
|
void DispatchCompute(GPUVAddr code_addr) override;
|
2020-02-11 22:59:44 +01:00
|
|
|
void ResetCounter(VideoCore::QueryType type) override;
|
|
|
|
void Query(GPUVAddr gpu_addr, VideoCore::QueryType type, std::optional<u64> timestamp) override;
|
2020-01-17 02:55:23 +01:00
|
|
|
void FlushAll() override;
|
2020-04-05 18:58:23 +02:00
|
|
|
void FlushRegion(VAddr addr, u64 size) override;
|
2020-02-18 03:29:04 +01:00
|
|
|
bool MustFlushRegion(VAddr addr, u64 size) override;
|
2020-04-05 18:58:23 +02:00
|
|
|
void InvalidateRegion(VAddr addr, u64 size) override;
|
2020-02-16 14:51:37 +01:00
|
|
|
void OnCPUWrite(VAddr addr, u64 size) override;
|
|
|
|
void SyncGuestHost() override;
|
2020-12-30 06:25:23 +01:00
|
|
|
void UnmapMemory(VAddr addr, u64 size) override;
|
2020-02-19 18:40:37 +01:00
|
|
|
void SignalSemaphore(GPUVAddr addr, u32 value) override;
|
|
|
|
void SignalSyncPoint(u32 value) override;
|
2020-02-18 18:24:38 +01:00
|
|
|
void ReleaseFences() override;
|
2020-04-05 18:58:23 +02:00
|
|
|
void FlushAndInvalidateRegion(VAddr addr, u64 size) override;
|
2020-04-28 07:14:11 +02:00
|
|
|
void WaitForIdle() override;
|
2020-12-30 06:25:23 +01:00
|
|
|
void FragmentBarrier() override;
|
|
|
|
void TiledCacheBarrier() override;
|
2020-01-17 02:55:23 +01:00
|
|
|
void FlushCommands() override;
|
|
|
|
void TickFrame() override;
|
2020-12-30 06:25:23 +01:00
|
|
|
bool AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Surface& src,
|
|
|
|
const Tegra::Engines::Fermi2D::Surface& dst,
|
2020-01-17 02:55:23 +01:00
|
|
|
const Tegra::Engines::Fermi2D::Config& copy_config) override;
|
|
|
|
bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
|
|
|
|
u32 pixel_stride) override;
|
|
|
|
|
2020-07-28 06:08:02 +02:00
|
|
|
VideoCommon::Shader::AsyncShaders& GetAsyncShaders() {
|
|
|
|
return async_shaders;
|
|
|
|
}
|
|
|
|
|
|
|
|
const VideoCommon::Shader::AsyncShaders& GetAsyncShaders() const {
|
|
|
|
return async_shaders;
|
|
|
|
}
|
|
|
|
|
2020-01-17 02:55:23 +01:00
|
|
|
/// Maximum supported size that a constbuffer can have in bytes.
|
2020-12-30 06:25:23 +01:00
|
|
|
static constexpr size_t MaxConstbufferSize = 0x10000;
|
2020-01-17 02:55:23 +01:00
|
|
|
static_assert(MaxConstbufferSize % (4 * sizeof(float)) == 0,
|
|
|
|
"The maximum size of a constbuffer must be a multiple of the size of GLvec4");
|
|
|
|
|
|
|
|
private:
|
2020-12-30 06:25:23 +01:00
|
|
|
static constexpr size_t MAX_TEXTURES = 192;
|
|
|
|
static constexpr size_t MAX_IMAGES = 48;
|
|
|
|
static constexpr size_t MAX_IMAGE_VIEWS = MAX_TEXTURES + MAX_IMAGES;
|
|
|
|
|
|
|
|
static constexpr VkDeviceSize DEFAULT_BUFFER_SIZE = 4 * sizeof(float);
|
|
|
|
|
2020-01-17 02:55:23 +01:00
|
|
|
struct DrawParameters {
|
2020-03-27 05:33:21 +01:00
|
|
|
void Draw(vk::CommandBuffer cmdbuf) const;
|
2020-01-17 02:55:23 +01:00
|
|
|
|
|
|
|
u32 base_instance = 0;
|
|
|
|
u32 num_instances = 0;
|
|
|
|
u32 base_vertex = 0;
|
|
|
|
u32 num_vertices = 0;
|
|
|
|
bool is_indexed = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
void FlushWork();
|
|
|
|
|
|
|
|
/// Setups geometry buffers and state.
|
|
|
|
DrawParameters SetupGeometry(FixedPipelineState& fixed_state, BufferBindings& buffer_bindings,
|
|
|
|
bool is_indexed, bool is_instanced);
|
|
|
|
|
|
|
|
/// Setup descriptors in the graphics pipeline.
|
2020-05-23 02:01:36 +02:00
|
|
|
void SetupShaderDescriptors(const std::array<Shader*, Maxwell::MaxShaderProgram>& shaders);
|
2020-01-17 02:55:23 +01:00
|
|
|
|
|
|
|
void UpdateDynamicStates();
|
|
|
|
|
2020-03-06 09:11:18 +01:00
|
|
|
void BeginTransformFeedback();
|
|
|
|
|
|
|
|
void EndTransformFeedback();
|
|
|
|
|
2020-06-22 00:30:23 +02:00
|
|
|
void SetupVertexArrays(BufferBindings& buffer_bindings);
|
2020-01-17 02:55:23 +01:00
|
|
|
|
|
|
|
void SetupIndexBuffer(BufferBindings& buffer_bindings, DrawParameters& params, bool is_indexed);
|
|
|
|
|
|
|
|
/// Setup constant buffers in the graphics pipeline.
|
|
|
|
void SetupGraphicsConstBuffers(const ShaderEntries& entries, std::size_t stage);
|
|
|
|
|
|
|
|
/// Setup global buffers in the graphics pipeline.
|
|
|
|
void SetupGraphicsGlobalBuffers(const ShaderEntries& entries, std::size_t stage);
|
|
|
|
|
2020-06-02 02:41:07 +02:00
|
|
|
/// Setup uniform texels in the graphics pipeline.
|
|
|
|
void SetupGraphicsUniformTexels(const ShaderEntries& entries, std::size_t stage);
|
2020-01-17 02:55:23 +01:00
|
|
|
|
|
|
|
/// Setup textures in the graphics pipeline.
|
|
|
|
void SetupGraphicsTextures(const ShaderEntries& entries, std::size_t stage);
|
|
|
|
|
2020-06-02 02:41:07 +02:00
|
|
|
/// Setup storage texels in the graphics pipeline.
|
|
|
|
void SetupGraphicsStorageTexels(const ShaderEntries& entries, std::size_t stage);
|
|
|
|
|
2020-01-17 02:55:23 +01:00
|
|
|
/// Setup images in the graphics pipeline.
|
|
|
|
void SetupGraphicsImages(const ShaderEntries& entries, std::size_t stage);
|
|
|
|
|
|
|
|
/// Setup constant buffers in the compute pipeline.
|
|
|
|
void SetupComputeConstBuffers(const ShaderEntries& entries);
|
|
|
|
|
|
|
|
/// Setup global buffers in the compute pipeline.
|
|
|
|
void SetupComputeGlobalBuffers(const ShaderEntries& entries);
|
|
|
|
|
|
|
|
/// Setup texel buffers in the compute pipeline.
|
2020-06-02 02:41:07 +02:00
|
|
|
void SetupComputeUniformTexels(const ShaderEntries& entries);
|
2020-01-17 02:55:23 +01:00
|
|
|
|
|
|
|
/// Setup textures in the compute pipeline.
|
|
|
|
void SetupComputeTextures(const ShaderEntries& entries);
|
|
|
|
|
2020-06-02 02:41:07 +02:00
|
|
|
/// Setup storage texels in the compute pipeline.
|
|
|
|
void SetupComputeStorageTexels(const ShaderEntries& entries);
|
|
|
|
|
2020-01-17 02:55:23 +01:00
|
|
|
/// Setup images in the compute pipeline.
|
|
|
|
void SetupComputeImages(const ShaderEntries& entries);
|
|
|
|
|
|
|
|
void SetupConstBuffer(const ConstBufferEntry& entry,
|
|
|
|
const Tegra::Engines::ConstBufferInfo& buffer);
|
|
|
|
|
|
|
|
void SetupGlobalBuffer(const GlobalBufferEntry& entry, GPUVAddr address);
|
|
|
|
|
2020-02-21 05:21:57 +01:00
|
|
|
void UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& regs);
|
|
|
|
void UpdateScissorsState(Tegra::Engines::Maxwell3D::Regs& regs);
|
|
|
|
void UpdateDepthBias(Tegra::Engines::Maxwell3D::Regs& regs);
|
|
|
|
void UpdateBlendConstants(Tegra::Engines::Maxwell3D::Regs& regs);
|
|
|
|
void UpdateDepthBounds(Tegra::Engines::Maxwell3D::Regs& regs);
|
|
|
|
void UpdateStencilFaces(Tegra::Engines::Maxwell3D::Regs& regs);
|
2020-01-17 02:55:23 +01:00
|
|
|
|
2020-06-22 08:03:27 +02:00
|
|
|
void UpdateCullMode(Tegra::Engines::Maxwell3D::Regs& regs);
|
|
|
|
void UpdateDepthBoundsTestEnable(Tegra::Engines::Maxwell3D::Regs& regs);
|
|
|
|
void UpdateDepthTestEnable(Tegra::Engines::Maxwell3D::Regs& regs);
|
|
|
|
void UpdateDepthWriteEnable(Tegra::Engines::Maxwell3D::Regs& regs);
|
|
|
|
void UpdateDepthCompareOp(Tegra::Engines::Maxwell3D::Regs& regs);
|
|
|
|
void UpdateFrontFace(Tegra::Engines::Maxwell3D::Regs& regs);
|
|
|
|
void UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs);
|
|
|
|
void UpdateStencilTestEnable(Tegra::Engines::Maxwell3D::Regs& regs);
|
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
size_t CalculateGraphicsStreamBufferSize(bool is_indexed) const;
|
2020-01-17 02:55:23 +01:00
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
size_t CalculateComputeStreamBufferSize() const;
|
2020-01-17 02:55:23 +01:00
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
size_t CalculateVertexArraysSize() const;
|
2020-01-17 02:55:23 +01:00
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
size_t CalculateIndexBufferSize() const;
|
2020-01-17 02:55:23 +01:00
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
size_t CalculateConstBufferSize(const ConstBufferEntry& entry,
|
|
|
|
const Tegra::Engines::ConstBufferInfo& buffer) const;
|
2020-01-17 02:55:23 +01:00
|
|
|
|
2020-04-22 00:20:53 +02:00
|
|
|
VkBuffer DefaultBuffer();
|
|
|
|
|
2020-06-12 02:24:45 +02:00
|
|
|
Tegra::GPU& gpu;
|
|
|
|
Tegra::MemoryManager& gpu_memory;
|
|
|
|
Tegra::Engines::Maxwell3D& maxwell3d;
|
|
|
|
Tegra::Engines::KeplerCompute& kepler_compute;
|
|
|
|
|
2020-01-17 02:55:23 +01:00
|
|
|
VKScreenInfo& screen_info;
|
2020-12-26 05:10:53 +01:00
|
|
|
const Device& device;
|
2020-01-17 02:55:23 +01:00
|
|
|
VKMemoryManager& memory_manager;
|
2020-02-21 00:35:53 +01:00
|
|
|
StateTracker& state_tracker;
|
2020-01-17 02:55:23 +01:00
|
|
|
VKScheduler& scheduler;
|
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
VKStreamBuffer stream_buffer;
|
2020-01-17 02:55:23 +01:00
|
|
|
VKStagingBufferPool staging_pool;
|
|
|
|
VKDescriptorPool descriptor_pool;
|
|
|
|
VKUpdateDescriptorQueue update_descriptor_queue;
|
2020-12-30 06:25:23 +01:00
|
|
|
BlitImageHelper blit_image;
|
2020-01-17 02:55:23 +01:00
|
|
|
QuadArrayPass quad_array_pass;
|
2020-04-14 22:54:45 +02:00
|
|
|
QuadIndexedPass quad_indexed_pass;
|
2020-01-17 02:55:23 +01:00
|
|
|
Uint8Pass uint8_pass;
|
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
TextureCacheRuntime texture_cache_runtime;
|
|
|
|
TextureCache texture_cache;
|
2020-01-17 02:55:23 +01:00
|
|
|
VKPipelineCache pipeline_cache;
|
|
|
|
VKBufferCache buffer_cache;
|
2020-02-11 22:59:44 +01:00
|
|
|
VKQueryCache query_cache;
|
2020-06-12 02:24:45 +02:00
|
|
|
VKFenceManager fence_manager;
|
2020-01-17 02:55:23 +01:00
|
|
|
|
2020-04-22 00:20:53 +02:00
|
|
|
vk::Buffer default_buffer;
|
|
|
|
VKMemoryCommit default_buffer_commit;
|
2020-04-28 07:14:11 +02:00
|
|
|
vk::Event wfi_event;
|
2020-07-30 21:41:11 +02:00
|
|
|
VideoCommon::Shader::AsyncShaders async_shaders;
|
2020-04-22 00:20:53 +02:00
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
boost::container::static_vector<u32, MAX_IMAGE_VIEWS> image_view_indices;
|
|
|
|
std::array<VideoCommon::ImageViewId, MAX_IMAGE_VIEWS> image_view_ids;
|
|
|
|
boost::container::static_vector<VkSampler, MAX_TEXTURES> sampler_handles;
|
2020-01-17 02:55:23 +01:00
|
|
|
|
|
|
|
u32 draw_counter = 0;
|
|
|
|
};
|
2020-01-07 01:10:56 +01:00
|
|
|
|
|
|
|
} // namespace Vulkan
|