mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 19:07:01 +02:00
graphics: collapse redundant Vulkan and command buffer types
This commit is contained in:
@@ -153,10 +153,10 @@ private:
|
||||
uint32_t render_target_slice_offset, uint32_t first_vertex,
|
||||
uint32_t first_instance);
|
||||
|
||||
CommandScheduler& GetScheduler() const { return m_renderer.GetCommandScheduler(); }
|
||||
RenderCommandBuffer& CurrentBuffer() { return GetScheduler().Current(); }
|
||||
void CheckBuffer() const { GetScheduler().CheckActive(); }
|
||||
GpuResourceManager& GetGpuResources() const { return m_renderer.GetGpuResources(); }
|
||||
CommandScheduler& GetScheduler() const { return m_renderer.GetCommandScheduler(); }
|
||||
CommandBuffer& CurrentBuffer() { return GetScheduler().Current(); }
|
||||
void CheckBuffer() const { GetScheduler().CheckActive(); }
|
||||
GpuResourceManager& GetGpuResources() const { return m_renderer.GetGpuResources(); }
|
||||
|
||||
RenderContext& m_renderer;
|
||||
HW::Context m_ctx;
|
||||
|
||||
@@ -3,20 +3,88 @@
|
||||
|
||||
#include "common/abi.h"
|
||||
#include "common/common.h"
|
||||
#include "common/threads.h"
|
||||
#include "graphics/host_gpu/vulkanCommon.h" // IWYU pragma: export
|
||||
#include "graphics/host_gpu/vulkanInstance.h"
|
||||
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
#include <vk_mem_alloc.h>
|
||||
|
||||
namespace Libs::Graphics {
|
||||
|
||||
class CommandBuffer;
|
||||
struct VulkanBuffer;
|
||||
struct VulkanImage;
|
||||
struct VulkanMemory;
|
||||
|
||||
struct GraphicContext: public VulkanInstance {
|
||||
inline constexpr uint32_t VULKAN_TARGET_API_VERSION = VK_API_VERSION_1_3;
|
||||
|
||||
struct GraphicContext {
|
||||
vk::Instance instance = nullptr;
|
||||
vk::DebugUtilsMessengerEXT debug_messenger = nullptr;
|
||||
vk::PhysicalDevice physical_device = nullptr;
|
||||
vk::PhysicalDeviceProperties physical_device_properties = {};
|
||||
vk::PhysicalDeviceMemoryProperties physical_device_memory_properties = {};
|
||||
vk::Device device = nullptr;
|
||||
VmaAllocator allocator = nullptr;
|
||||
bool memory_budget_ext_enabled = false;
|
||||
bool rt_extensions_enabled = false;
|
||||
bool compute_subgroup_size_control_enabled = false;
|
||||
bool compute_wave64_supported = false;
|
||||
bool sample_rate_shading_enabled = false;
|
||||
uint32_t subgroup_size = 0;
|
||||
uint32_t min_subgroup_size = 0;
|
||||
uint32_t max_subgroup_size = 0;
|
||||
uint32_t max_push_descriptors = 0;
|
||||
vk::ShaderStageFlags required_subgroup_size_stages = {};
|
||||
Common::Mutex queue_mutex;
|
||||
uint32_t queue_family = static_cast<uint32_t>(-1);
|
||||
vk::Queue queue = nullptr;
|
||||
|
||||
[[nodiscard]] const vk::PhysicalDeviceProperties& GetPhysicalDeviceProperties() const {
|
||||
return physical_device_properties;
|
||||
}
|
||||
|
||||
[[nodiscard]] const vk::PhysicalDeviceMemoryProperties&
|
||||
GetPhysicalDeviceMemoryProperties() const {
|
||||
return physical_device_memory_properties;
|
||||
}
|
||||
|
||||
[[nodiscard]] vk::FormatProperties GetFormatProperties(vk::Format format) const {
|
||||
std::scoped_lock lock(m_format_properties_mutex);
|
||||
auto [it, inserted] = m_format_properties.try_emplace(format);
|
||||
if (inserted) {
|
||||
physical_device.getFormatProperties(format, &it->second);
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
[[nodiscard]] vk::Result GetImageFormatProperties(vk::Format format, vk::ImageType type,
|
||||
vk::ImageTiling tiling,
|
||||
vk::ImageUsageFlags usage,
|
||||
vk::ImageCreateFlags flags,
|
||||
vk::ImageFormatProperties* properties) const {
|
||||
using Key = std::tuple<vk::Format, vk::ImageType, vk::ImageTiling, vk::ImageUsageFlags,
|
||||
vk::ImageCreateFlags>;
|
||||
std::scoped_lock lock(m_image_format_properties_mutex);
|
||||
auto [it, inserted] =
|
||||
m_image_format_properties.try_emplace(Key {format, type, tiling, usage, flags});
|
||||
if (inserted) {
|
||||
it->second.first = physical_device.getImageFormatProperties(format, type, tiling, usage,
|
||||
flags, &it->second.second);
|
||||
}
|
||||
if (properties != nullptr) {
|
||||
*properties = it->second.second;
|
||||
}
|
||||
return it->second.first;
|
||||
}
|
||||
|
||||
[[nodiscard]] vk::DeviceSize StorageMinAlignment() const {
|
||||
const auto alignment = physical_device_properties.limits.minStorageBufferOffsetAlignment;
|
||||
return alignment != 0 ? alignment : 1;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool CreateAllocator();
|
||||
void DestroyAllocator();
|
||||
void LogMemoryBudget() const;
|
||||
@@ -35,6 +103,15 @@ struct GraphicContext: public VulkanInstance {
|
||||
|
||||
uint32_t screen_width = 0;
|
||||
uint32_t screen_height = 0;
|
||||
|
||||
private:
|
||||
mutable std::mutex m_format_properties_mutex;
|
||||
mutable std::map<vk::Format, vk::FormatProperties> m_format_properties;
|
||||
mutable std::mutex m_image_format_properties_mutex;
|
||||
mutable std::map<std::tuple<vk::Format, vk::ImageType, vk::ImageTiling, vk::ImageUsageFlags,
|
||||
vk::ImageCreateFlags>,
|
||||
std::pair<vk::Result, vk::ImageFormatProperties>>
|
||||
m_image_format_properties;
|
||||
};
|
||||
|
||||
struct VulkanMemory {
|
||||
|
||||
@@ -43,7 +43,7 @@ static void ResolveDccClearInfo(RenderColorInfo& info, vk::Format format, bool h
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
||||
void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, RenderCommandBuffer& buffer,
|
||||
void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, CommandBuffer& buffer,
|
||||
RenderColorInfo& r,
|
||||
uint32_t render_target_slice_offset,
|
||||
uint32_t render_target_slot, bool ignore_target_mask,
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
|
||||
namespace Libs::Graphics {
|
||||
|
||||
class RenderCommandBuffer;
|
||||
|
||||
enum class RenderColorType {
|
||||
NoColorOutput,
|
||||
RenderTexture,
|
||||
|
||||
@@ -346,7 +346,7 @@ void CommandScheduler::CheckActive() const {
|
||||
EXIT_IF(!Active());
|
||||
}
|
||||
|
||||
RenderCommandBuffer& CommandScheduler::Current() {
|
||||
CommandBuffer& CommandScheduler::Current() {
|
||||
CheckActive();
|
||||
return m_command;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
|
||||
[[nodiscard]] bool Active() const noexcept { return m_registers != nullptr; }
|
||||
void CheckActive() const;
|
||||
RenderCommandBuffer& Current();
|
||||
CommandBuffer& Current();
|
||||
[[nodiscard]] uint64_t CurrentTick() const noexcept { return m_master.CurrentTick(); }
|
||||
[[nodiscard]] bool IsFree(uint64_t tick);
|
||||
[[nodiscard]] MasterSemaphore& GetMasterSemaphore() noexcept { return m_master; }
|
||||
@@ -90,7 +90,7 @@ private:
|
||||
RenderContext& m_context;
|
||||
GraphicContext& m_graphics;
|
||||
CommandPool m_command_pool;
|
||||
RenderCommandBuffer m_command;
|
||||
CommandBuffer m_command;
|
||||
std::queue<PendingOperation> m_pending_operations;
|
||||
std::queue<PendingOperation> m_priority_operations;
|
||||
std::mutex m_operation_mutex;
|
||||
|
||||
@@ -27,7 +27,7 @@ static bool RenderTargetMaskHasMrt(uint32_t mask) {
|
||||
return (mask & ~0x0fu) != 0;
|
||||
}
|
||||
|
||||
static bool RenderTargetMaskHasBoundMrt(const RenderCommandBuffer& buffer) {
|
||||
static bool RenderTargetMaskHasBoundMrt(const CommandBuffer& buffer) {
|
||||
const auto& hw = buffer.GetRegisters();
|
||||
const auto mask = hw.GetRenderTargetMask();
|
||||
|
||||
@@ -45,7 +45,7 @@ static bool RenderTargetMaskHasBoundMrt(const RenderCommandBuffer& buffer) {
|
||||
return bound_targets > 1;
|
||||
}
|
||||
|
||||
uint32_t render_target_first_bound_slot(const RenderCommandBuffer& buffer) {
|
||||
uint32_t render_target_first_bound_slot(const CommandBuffer& buffer) {
|
||||
const auto& hw = buffer.GetRegisters();
|
||||
const auto mask = hw.GetRenderTargetMask();
|
||||
for (uint32_t i = 0; i < 8; i++) {
|
||||
@@ -266,11 +266,10 @@ static void RtCheck(const HW::RenderTarget& rt) {
|
||||
logged = true;
|
||||
}
|
||||
}
|
||||
const bool native_2x_one_frag = rt.info.fmask_compression_enable &&
|
||||
!rt.info.fmask_data_compression_disable &&
|
||||
rt.info.cmask_fast_clear_enable && rt.fmask.addr != 0 &&
|
||||
rt.cmask.addr != 0 && rt.attrib.num_samples == 1 &&
|
||||
rt.attrib.num_fragments == 1;
|
||||
const bool native_2x_one_frag =
|
||||
rt.info.fmask_compression_enable && !rt.info.fmask_data_compression_disable &&
|
||||
rt.info.cmask_fast_clear_enable && rt.fmask.addr != 0 && rt.cmask.addr != 0 &&
|
||||
rt.attrib.num_samples == 1 && rt.attrib.num_fragments == 1;
|
||||
EXIT_NOT_IMPLEMENTED(rt.info.fmask_one_frag_mode && !native_2x_one_frag);
|
||||
if (rt.info.fmask_compression_enable) {
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib.num_samples == 0 && rt.attrib.num_fragments == 0);
|
||||
@@ -1158,7 +1157,7 @@ ScissorRect calc_final_scissor(const HW::ScreenViewport& vp, const HW::ScanModeC
|
||||
return ScissorRectClamp(final, extent.width, extent.height);
|
||||
}
|
||||
|
||||
void hw_check(const RenderCommandBuffer& buffer) {
|
||||
void hw_check(const CommandBuffer& buffer) {
|
||||
const auto& hw = buffer.GetRegisters();
|
||||
const auto rt_slot = render_target_first_bound_slot(buffer);
|
||||
const auto& rt = hw.GetRenderTarget(rt_slot);
|
||||
@@ -1231,7 +1230,7 @@ void hw_check(const RenderCommandBuffer& buffer) {
|
||||
// EXIT_NOT_IMPLEMENTED(hw.GetStencilClearValue() != 0);
|
||||
}
|
||||
|
||||
void hw_print(const RenderCommandBuffer& buffer) {
|
||||
void hw_print(const CommandBuffer& buffer) {
|
||||
const auto& hw = buffer.GetRegisters();
|
||||
const auto rt_slot = render_target_first_bound_slot(buffer);
|
||||
const auto& rt = hw.GetRenderTarget(rt_slot);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
namespace Libs::Graphics {
|
||||
|
||||
class RenderCommandBuffer;
|
||||
class CommandBuffer;
|
||||
|
||||
namespace HW {
|
||||
class Context;
|
||||
@@ -28,15 +28,15 @@ struct ScissorRect {
|
||||
};
|
||||
|
||||
uint32_t render_target_mask_slot(uint32_t mask, uint32_t slot);
|
||||
uint32_t render_target_first_bound_slot(const RenderCommandBuffer& buffer);
|
||||
uint32_t render_target_first_bound_slot(const CommandBuffer& buffer);
|
||||
bool graphics_debug_dump_enabled();
|
||||
void uc_print(const char* func, const HW::UserConfig& uc);
|
||||
void uc_check(const HW::UserConfig& uc);
|
||||
void sh_print(const char* func, const HW::Shader& uc);
|
||||
std::vector<std::string> rt_print(const char* func, const HW::RenderTarget& rt);
|
||||
bool RenderIsColorTileModeLinear(Prospero::TileMode tile_mode);
|
||||
void hw_print(const RenderCommandBuffer& buffer);
|
||||
void hw_check(const RenderCommandBuffer& buffer);
|
||||
void hw_print(const CommandBuffer& buffer);
|
||||
void hw_check(const CommandBuffer& buffer);
|
||||
void LogDrawPhase(const char* draw_name, const char* phase);
|
||||
ScissorRect calc_final_scissor(const HW::ScreenViewport& vp, const HW::ScanModeControl& smc,
|
||||
vk::Extent2D extent);
|
||||
|
||||
@@ -70,8 +70,8 @@ static bool UsesStencilOpValue(uint8_t fail, uint8_t pass, uint8_t depth_fail) {
|
||||
return fail == replace_op || pass == replace_op || depth_fail == replace_op;
|
||||
}
|
||||
|
||||
[[nodiscard]] static vk::Format ResolveHostDepthAttachmentFormat(const RenderCommandBuffer& buffer,
|
||||
const DepthFormatPolicy& policy,
|
||||
[[nodiscard]] static vk::Format ResolveHostDepthAttachmentFormat(const CommandBuffer& buffer,
|
||||
const DepthFormatPolicy& policy,
|
||||
bool has_stencil,
|
||||
uint32_t samples) {
|
||||
auto& graphics = buffer.GetGraphics();
|
||||
@@ -97,7 +97,7 @@ static bool UsesStencilOpValue(uint8_t fail, uint8_t pass, uint8_t depth_fail) {
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
||||
void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, RenderCommandBuffer& buffer,
|
||||
void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, CommandBuffer& buffer,
|
||||
RenderDepthInfo& r) {
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
(void)submit_id;
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
|
||||
namespace Libs::Graphics {
|
||||
|
||||
class RenderCommandBuffer;
|
||||
|
||||
inline constexpr bool depth_htile_stencil_acceleration_compatible(bool has_stencil, bool has_htile,
|
||||
bool htile_stencil_disabled) {
|
||||
return htile_stencil_disabled || (has_stencil && has_htile);
|
||||
|
||||
@@ -53,12 +53,13 @@ bool PipelineStaticParameters::operator==(const PipelineStaticParameters& other)
|
||||
return std::memcmp(this, &other, sizeof(*this)) == 0;
|
||||
}
|
||||
|
||||
PipelineCache::GraphicsPipeline& PipelineCache::CreateGraphicsPipeline(
|
||||
RenderColorInfo* colors, uint32_t color_count, RenderDepthInfo& depth,
|
||||
ShaderVertexInputInfo& vs_input_info, RenderCommandBuffer& command,
|
||||
ShaderPixelInputInfo* ps_input_info, vk::PrimitiveTopology topology,
|
||||
bool primitive_restart_enable, bool ps_active, std::span<const uint32_t> vs_spirv,
|
||||
std::span<const uint32_t> ps_spirv) {
|
||||
PipelineCache::GraphicsPipeline&
|
||||
PipelineCache::CreateGraphicsPipeline(RenderColorInfo* colors, uint32_t color_count,
|
||||
RenderDepthInfo& depth, ShaderVertexInputInfo& vs_input_info,
|
||||
CommandBuffer& command, ShaderPixelInputInfo* ps_input_info,
|
||||
vk::PrimitiveTopology topology, bool primitive_restart_enable,
|
||||
bool ps_active, std::span<const uint32_t> vs_spirv,
|
||||
std::span<const uint32_t> ps_spirv) {
|
||||
KYTY_PROFILER_BLOCK("PipelineCache::CreatePipeline(Gfx)", profiler::colors::DeepOrangeA200);
|
||||
|
||||
EXIT_IF(colors == nullptr);
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Libs::Graphics {
|
||||
struct GraphicContext;
|
||||
struct RenderColorInfo;
|
||||
struct RenderDepthInfo;
|
||||
class RenderCommandBuffer;
|
||||
class CommandBuffer;
|
||||
|
||||
namespace HW {
|
||||
class Context;
|
||||
@@ -121,7 +121,7 @@ public:
|
||||
|
||||
GraphicsPipeline&
|
||||
CreateGraphicsPipeline(RenderColorInfo* colors, uint32_t color_count, RenderDepthInfo& depth,
|
||||
ShaderVertexInputInfo& vs_input_info, RenderCommandBuffer& command,
|
||||
ShaderVertexInputInfo& vs_input_info, CommandBuffer& command,
|
||||
ShaderPixelInputInfo* ps_input_info, vk::PrimitiveTopology topology,
|
||||
bool primitive_restart_enable, bool ps_active,
|
||||
std::span<const uint32_t> vs_spirv, std::span<const uint32_t> ps_spirv);
|
||||
|
||||
@@ -90,11 +90,18 @@ public:
|
||||
[[nodiscard]] vk::CommandBuffer Handle() const;
|
||||
[[nodiscard]] GraphicContext& GetGraphics() const noexcept { return m_graphics; }
|
||||
[[nodiscard]] RenderContext& GetContext() const noexcept { return m_context; }
|
||||
|
||||
protected:
|
||||
explicit CommandBuffer(CommandScheduler& scheduler);
|
||||
[[nodiscard]] HW::Context& GetRegisters() const noexcept { return *m_registers; }
|
||||
[[nodiscard]] HW::UserConfig& GetUserConfig() const noexcept { return *m_user_config; }
|
||||
[[nodiscard]] HW::Shader& GetShaders() const noexcept { return *m_shaders; }
|
||||
|
||||
private:
|
||||
explicit CommandBuffer(CommandScheduler& scheduler);
|
||||
void Bind(HW::Context& registers, HW::UserConfig& user_config, HW::Shader& shaders) noexcept {
|
||||
m_registers = ®isters;
|
||||
m_user_config = &user_config;
|
||||
m_shaders = &shaders;
|
||||
}
|
||||
|
||||
void Begin();
|
||||
void End() const;
|
||||
|
||||
@@ -109,29 +116,10 @@ private:
|
||||
uint32_t m_debug_arg3 = 0;
|
||||
uint64_t m_debug_arg4 = 0;
|
||||
mutable RenderState m_render_state;
|
||||
mutable bool m_rendering = false;
|
||||
|
||||
friend class CommandScheduler;
|
||||
};
|
||||
|
||||
class RenderCommandBuffer final: public CommandBuffer {
|
||||
public:
|
||||
void Bind(HW::Context& registers, HW::UserConfig& user_config, HW::Shader& shaders) noexcept {
|
||||
m_registers = ®isters;
|
||||
m_user_config = &user_config;
|
||||
m_shaders = &shaders;
|
||||
}
|
||||
|
||||
[[nodiscard]] HW::Context& GetRegisters() const noexcept { return *m_registers; }
|
||||
[[nodiscard]] HW::UserConfig& GetUserConfig() const noexcept { return *m_user_config; }
|
||||
[[nodiscard]] HW::Shader& GetShaders() const noexcept { return *m_shaders; }
|
||||
|
||||
private:
|
||||
explicit RenderCommandBuffer(CommandScheduler& scheduler): CommandBuffer(scheduler) {}
|
||||
|
||||
HW::Context* m_registers = nullptr;
|
||||
HW::UserConfig* m_user_config = nullptr;
|
||||
HW::Shader* m_shaders = nullptr;
|
||||
mutable bool m_rendering = false;
|
||||
HW::Context* m_registers = nullptr;
|
||||
HW::UserConfig* m_user_config = nullptr;
|
||||
HW::Shader* m_shaders = nullptr;
|
||||
|
||||
friend class CommandScheduler;
|
||||
};
|
||||
@@ -141,15 +129,14 @@ public:
|
||||
explicit RenderExecutor(RenderContext& context): m_context(context) {}
|
||||
KYTY_CLASS_NO_COPY(RenderExecutor);
|
||||
|
||||
void DrawIndex(uint64_t submit_id, RenderCommandBuffer& buffer, uint32_t index_type_and_size,
|
||||
void DrawIndex(uint64_t submit_id, CommandBuffer& buffer, uint32_t index_type_and_size,
|
||||
uint32_t index_count, const void* index_addr, uint32_t flags, uint32_t type,
|
||||
uint32_t instance_count = 1, uint32_t render_target_slice_offset = 0,
|
||||
int32_t vertex_offset_add = 0, uint32_t first_instance = 0);
|
||||
void DrawAuto(uint64_t submit_id, RenderCommandBuffer& buffer, uint32_t index_count,
|
||||
uint32_t flags, uint32_t render_target_slice_offset = 0,
|
||||
uint32_t instance_count = 1, uint32_t first_vertex = 0,
|
||||
uint32_t first_instance = 0);
|
||||
void DispatchDirect(uint64_t submit_id, RenderCommandBuffer& buffer, uint32_t thread_group_x,
|
||||
void DrawAuto(uint64_t submit_id, CommandBuffer& buffer, uint32_t index_count, uint32_t flags,
|
||||
uint32_t render_target_slice_offset = 0, uint32_t instance_count = 1,
|
||||
uint32_t first_vertex = 0, uint32_t first_instance = 0);
|
||||
void DispatchDirect(uint64_t submit_id, CommandBuffer& buffer, uint32_t thread_group_x,
|
||||
uint32_t thread_group_y, uint32_t thread_group_z, uint32_t mode);
|
||||
|
||||
[[nodiscard]] PreparedBindings PrepareBindings(const ShaderStageRuntime& runtime);
|
||||
@@ -171,32 +158,31 @@ private:
|
||||
[[nodiscard]] GraphicsBindings PrepareGraphicsBindings(const ShaderStageRuntime& vertex,
|
||||
const ShaderStageRuntime& pixel,
|
||||
bool pixel_active);
|
||||
void ResolveRenderColorTarget(uint64_t submit_id, RenderCommandBuffer& buffer,
|
||||
void ResolveRenderColorTarget(uint64_t submit_id, CommandBuffer& buffer,
|
||||
RenderColorInfo& target, uint32_t render_target_slice_offset = 0,
|
||||
uint32_t render_target_slot = UINT32_MAX,
|
||||
bool ignore_target_mask = false, bool exact_format = false);
|
||||
void ResolveRenderDepthTarget(uint64_t submit_id, RenderCommandBuffer& buffer,
|
||||
void ResolveRenderDepthTarget(uint64_t submit_id, CommandBuffer& buffer,
|
||||
RenderDepthInfo& target);
|
||||
[[nodiscard]] bool PrepareDrawRenderState(uint64_t submit_id, RenderCommandBuffer& buffer,
|
||||
[[nodiscard]] bool PrepareDrawRenderState(uint64_t submit_id, CommandBuffer& buffer,
|
||||
const DrawCallInfo& draw,
|
||||
uint32_t render_target_slice_offset,
|
||||
bool log_setup_phases, DrawRenderState& state);
|
||||
void ExecutePreparedDraw(uint64_t submit_id, RenderCommandBuffer& buffer,
|
||||
const DrawCallInfo& draw, DrawRenderState& state,
|
||||
vk::PrimitiveTopology topology, const DrawEmitInfo& emit,
|
||||
const DrawIndexBufferSource& index_source,
|
||||
bool primitive_restart_enable, bool log_pipeline_phase,
|
||||
bool set_bind_debug, bool set_auto_debug);
|
||||
void ExecutePreparedDraw(uint64_t submit_id, CommandBuffer& buffer, const DrawCallInfo& draw,
|
||||
DrawRenderState& state, vk::PrimitiveTopology topology,
|
||||
const DrawEmitInfo& emit, const DrawIndexBufferSource& index_source,
|
||||
bool primitive_restart_enable, bool log_pipeline_phase,
|
||||
bool set_bind_debug, bool set_auto_debug);
|
||||
[[nodiscard]] RenderState AcquireRenderTargets(CommandBuffer& buffer, RenderColorInfo* colors,
|
||||
uint32_t color_count, RenderDepthInfo& depth);
|
||||
[[nodiscard]] bool ResolveColorTargets(uint64_t submit_id, RenderCommandBuffer& buffer,
|
||||
[[nodiscard]] bool ResolveColorTargets(uint64_t submit_id, CommandBuffer& buffer,
|
||||
uint32_t render_target_slice_offset);
|
||||
void BindImage(ImageId id, bool storage);
|
||||
void BindRenderTarget(ImageId id);
|
||||
void TrackImageBinding(ImageId id);
|
||||
void ResetBindings();
|
||||
[[nodiscard]] bool TryConsumeComputeMetaClear(const ShaderComputeInputInfo& input,
|
||||
const RenderCommandBuffer& buffer);
|
||||
const CommandBuffer& buffer);
|
||||
|
||||
RenderContext& m_context;
|
||||
std::vector<ImageId> m_bound_images;
|
||||
|
||||
@@ -44,7 +44,7 @@ static uint64_t BufferDescriptorSize(const ShaderBufferResource& descriptor) {
|
||||
}
|
||||
|
||||
bool RenderExecutor::TryConsumeComputeMetaClear(const ShaderComputeInputInfo& input,
|
||||
const RenderCommandBuffer& buffer) {
|
||||
const CommandBuffer& buffer) {
|
||||
const auto& program = *input.stage.program;
|
||||
const auto& resources = *input.stage.resources;
|
||||
if (resources.buffers.size() != program.info.buffers.size()) {
|
||||
@@ -81,9 +81,8 @@ bool ResolveComputeImageClear(const ShaderComputeInputInfo& input, uint32_t grou
|
||||
const auto& program = *input.stage.program;
|
||||
const auto& resources = *input.stage.resources;
|
||||
if (program.info.buffers.size() != 1 || resources.buffers.size() != 1 ||
|
||||
!program.info.images.empty() || !program.info.samplers.empty() ||
|
||||
program.info.uses_dma || !resources.images.empty() ||
|
||||
!resources.samplers.empty()) {
|
||||
!program.info.images.empty() || !program.info.samplers.empty() || program.info.uses_dma ||
|
||||
!resources.images.empty() || !resources.samplers.empty()) {
|
||||
return false;
|
||||
}
|
||||
const auto& resource = program.info.buffers.front();
|
||||
@@ -163,7 +162,7 @@ static bool TryConsumeComputeImageClear(const ShaderComputeInputInfo& input, Com
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderExecutor::DispatchDirect(uint64_t submit_id, RenderCommandBuffer& buffer,
|
||||
void RenderExecutor::DispatchDirect(uint64_t submit_id, CommandBuffer& buffer,
|
||||
uint32_t thread_group_x, uint32_t thread_group_y,
|
||||
uint32_t thread_group_z, uint32_t mode) {
|
||||
EXIT_IF(buffer.IsInvalid());
|
||||
@@ -210,9 +209,8 @@ void RenderExecutor::DispatchDirect(uint64_t submit_id, RenderCommandBuffer& buf
|
||||
|
||||
ShaderComputeInputInfo input_info {};
|
||||
std::span<const uint32_t> cs_shader;
|
||||
if (!ShaderCompileInfoCS(cs_regs, sh_regs,
|
||||
!m_context.GetGraphics().compute_wave64_supported, input_info,
|
||||
cs_shader)) {
|
||||
if (!ShaderCompileInfoCS(cs_regs, sh_regs, !m_context.GetGraphics().compute_wave64_supported,
|
||||
input_info, cs_shader)) {
|
||||
EXIT("ShaderCompileInfoCS failed for dispatch with CS shader 0x%016" PRIx64 "\n",
|
||||
cs_regs.cs_regs.data_addr);
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ static bool IsDualSourceBlendFactor(uint32_t factor) {
|
||||
}
|
||||
|
||||
static void LogFramebufferSkip(const char* draw_name, const RenderColorInfo& color,
|
||||
const RenderDepthInfo& depth, const RenderCommandBuffer& buffer,
|
||||
const RenderDepthInfo& depth, const CommandBuffer& buffer,
|
||||
uint32_t index_count, uint32_t flags) {
|
||||
const auto& ctx = buffer.GetRegisters();
|
||||
const auto& ucfg = buffer.GetUserConfig();
|
||||
@@ -126,7 +126,7 @@ static void LogFramebufferSkip(const char* draw_name, const RenderColorInfo& col
|
||||
static_cast<uint32_t>(ucfg.GetPrimType()), index_count, flags);
|
||||
}
|
||||
|
||||
static void LogMrtState(const char* draw_name, const RenderCommandBuffer& buffer,
|
||||
static void LogMrtState(const char* draw_name, const CommandBuffer& buffer,
|
||||
const ShaderPixelInputInfo& ps_input_info) {
|
||||
const auto& ctx = buffer.GetRegisters();
|
||||
const auto& sh_regs = ctx.GetShaderRegisters();
|
||||
@@ -177,7 +177,7 @@ static void LogMrtState(const char* draw_name, const RenderCommandBuffer& buffer
|
||||
}
|
||||
|
||||
static void LogDrawTargetState(const char* draw_name, const RenderColorInfo& color,
|
||||
const RenderDepthInfo& depth, const RenderCommandBuffer& buffer,
|
||||
const RenderDepthInfo& depth, const CommandBuffer& buffer,
|
||||
const ShaderPixelInputInfo& ps_input_info, uint32_t index_count,
|
||||
uint32_t flags) {
|
||||
const auto& ctx = buffer.GetRegisters();
|
||||
@@ -231,7 +231,7 @@ static void LogDrawTargetState(const char* draw_name, const RenderColorInfo& col
|
||||
LogMrtState(draw_name, buffer, ps_input_info);
|
||||
}
|
||||
|
||||
static void LogDrawInputState(const RenderCommandBuffer& buffer, const RenderColorInfo& color,
|
||||
static void LogDrawInputState(const CommandBuffer& buffer, const RenderColorInfo& color,
|
||||
const ShaderVertexInputInfo& vs_input_info,
|
||||
uint32_t index_type_and_size, uint32_t index_count,
|
||||
const void* index_addr) {
|
||||
@@ -309,7 +309,7 @@ static void LogDrawInputState(const RenderCommandBuffer& buffer, const RenderCol
|
||||
}
|
||||
}
|
||||
|
||||
static void SetGraphicsDynamicParams(const RenderCommandBuffer& buffer, vk::CommandBuffer vk_buffer,
|
||||
static void SetGraphicsDynamicParams(const CommandBuffer& buffer, vk::CommandBuffer vk_buffer,
|
||||
const RenderColorInfo* colors, uint32_t color_count,
|
||||
const RenderDepthInfo& depth) {
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
@@ -421,7 +421,7 @@ static bool PixelShaderHasDepthOrCoverageSideEffects(const HW::ShaderRegisters&
|
||||
db.shader_execute_on_noop;
|
||||
}
|
||||
|
||||
static bool ShouldSkipGeShader(const RenderCommandBuffer& buffer) {
|
||||
static bool ShouldSkipGeShader(const CommandBuffer& buffer) {
|
||||
const auto& ctx = buffer.GetRegisters();
|
||||
const auto& ucfg = buffer.GetUserConfig();
|
||||
const auto& sh_ctx = buffer.GetShaders();
|
||||
@@ -706,7 +706,7 @@ RenderState RenderExecutor::AcquireRenderTargets(CommandBuffer& buffer, RenderCo
|
||||
return state;
|
||||
}
|
||||
|
||||
static bool DrawHasActivePixelShader(const RenderCommandBuffer& buffer) {
|
||||
static bool DrawHasActivePixelShader(const CommandBuffer& buffer) {
|
||||
const auto& ctx = buffer.GetRegisters();
|
||||
const auto& sh_regs = ctx.GetShaderRegisters();
|
||||
const bool has_color_output = (ctx.GetRenderTargetMask() & sh_regs.m_cbShaderMask) != 0;
|
||||
@@ -723,7 +723,7 @@ enum class CbColorMode : uint8_t {
|
||||
DccDecompress = 6,
|
||||
};
|
||||
|
||||
static bool ConsumeMetadataColorOperation(const RenderCommandBuffer& buffer) {
|
||||
static bool ConsumeMetadataColorOperation(const CommandBuffer& buffer) {
|
||||
const auto& ctx = buffer.GetRegisters();
|
||||
const auto mode = ctx.GetColorControl().mode;
|
||||
// These special modes run color-buffer metadata or decompression operations. The shader is a
|
||||
@@ -779,7 +779,7 @@ struct PreparedVertexBuffers {
|
||||
uint32_t count = 0;
|
||||
};
|
||||
|
||||
static PreparedVertexBuffers AcquireVertexBuffers(RenderCommandBuffer& buffer,
|
||||
static PreparedVertexBuffers AcquireVertexBuffers(CommandBuffer& buffer,
|
||||
const ShaderVertexInputInfo& vs_input_info) {
|
||||
EXIT_IF(vs_input_info.buffers_num < 0 ||
|
||||
vs_input_info.buffers_num > ShaderVertexInputInfo::RES_MAX);
|
||||
@@ -869,8 +869,8 @@ static PreparedVertexBuffers AcquireVertexBuffers(RenderCommandBuffer& b
|
||||
return prepared;
|
||||
}
|
||||
|
||||
static void SetDrawDebugPhase(RenderCommandBuffer& buffer, uint64_t submit_id,
|
||||
const DrawCallInfo& draw, uint32_t phase) {
|
||||
static void SetDrawDebugPhase(CommandBuffer& buffer, uint64_t submit_id, const DrawCallInfo& draw,
|
||||
uint32_t phase) {
|
||||
EXIT_IF(draw.name == nullptr);
|
||||
|
||||
buffer.SetDebugInfo(static_cast<uint32_t>(draw.debug_op), submit_id, phase, draw.index_count,
|
||||
@@ -918,8 +918,8 @@ static bool GetDrawTopology(const HW::UserConfig& ucfg, bool auto_draw,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ResolvePrimitiveRestart(const RenderCommandBuffer& buffer,
|
||||
vk::PrimitiveTopology topology, uint32_t index_type_and_size) {
|
||||
static bool ResolvePrimitiveRestart(const CommandBuffer& buffer, vk::PrimitiveTopology topology,
|
||||
uint32_t index_type_and_size) {
|
||||
const auto control = buffer.GetUserConfig().GetPrimitiveResetControl();
|
||||
EXIT_NOT_IMPLEMENTED((control & ~0x3u) != 0);
|
||||
if ((control & 0x1u) == 0) {
|
||||
@@ -953,7 +953,7 @@ static bool ResolvePrimitiveRestart(const RenderCommandBuffer& buffer,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RenderExecutor::PrepareDrawRenderState(uint64_t submit_id, RenderCommandBuffer& buffer,
|
||||
bool RenderExecutor::PrepareDrawRenderState(uint64_t submit_id, CommandBuffer& buffer,
|
||||
const DrawCallInfo& draw,
|
||||
uint32_t render_target_slice_offset,
|
||||
bool log_setup_phases, DrawRenderState& state) {
|
||||
@@ -993,7 +993,7 @@ bool RenderExecutor::PrepareDrawRenderState(uint64_t submit_id, RenderCommandBuf
|
||||
return true;
|
||||
}
|
||||
|
||||
static void RefreshShaders(RenderCommandBuffer& buffer, const DrawCallInfo& draw, bool log_phases,
|
||||
static void RefreshShaders(CommandBuffer& buffer, const DrawCallInfo& draw, bool log_phases,
|
||||
DrawRenderState& state) {
|
||||
EXIT_IF(draw.name == nullptr);
|
||||
auto& ctx = buffer.GetRegisters();
|
||||
@@ -1031,7 +1031,7 @@ static void RefreshShaders(RenderCommandBuffer& buffer, const DrawCallInfo& draw
|
||||
}
|
||||
}
|
||||
|
||||
static PreparedVertexBuffers PrepareVertexBuffers(uint64_t submit_id, RenderCommandBuffer& buffer,
|
||||
static PreparedVertexBuffers PrepareVertexBuffers(uint64_t submit_id, CommandBuffer& buffer,
|
||||
const DrawCallInfo& draw,
|
||||
const ShaderVertexInputInfo& vs_input_info) {
|
||||
EXIT_IF(draw.name == nullptr);
|
||||
@@ -1041,7 +1041,7 @@ static PreparedVertexBuffers PrepareVertexBuffers(uint64_t submit_id, RenderComm
|
||||
return AcquireVertexBuffers(buffer, vs_input_info);
|
||||
}
|
||||
|
||||
static PreparedIndexBuffer PrepareIndexBuffer(RenderCommandBuffer& buffer,
|
||||
static PreparedIndexBuffer PrepareIndexBuffer(CommandBuffer& buffer,
|
||||
const DrawIndexBufferSource& source) {
|
||||
PreparedIndexBuffer prepared;
|
||||
if (!source.enabled) {
|
||||
@@ -1091,7 +1091,7 @@ static void CommitIndexBuffer(vk::CommandBuffer vk_buffer, const PreparedIndexBu
|
||||
vk_buffer.bindIndexBuffer(prepared.buffer, prepared.offset, prepared.type);
|
||||
}
|
||||
|
||||
static void LogDrawStateIfNeeded(const RenderCommandBuffer& buffer, const DrawCallInfo& draw,
|
||||
static void LogDrawStateIfNeeded(const CommandBuffer& buffer, const DrawCallInfo& draw,
|
||||
const DrawRenderState& state, bool always_log,
|
||||
bool force_legacy_rect_log, uint32_t index_type_and_size,
|
||||
const void* index_addr) {
|
||||
@@ -1159,7 +1159,7 @@ static void EmitDrawPrimitives(const HW::UserConfig& ucfg, vk::CommandBuffer vk_
|
||||
}
|
||||
}
|
||||
|
||||
void RenderExecutor::ExecutePreparedDraw(uint64_t submit_id, RenderCommandBuffer& buffer,
|
||||
void RenderExecutor::ExecutePreparedDraw(uint64_t submit_id, CommandBuffer& buffer,
|
||||
const DrawCallInfo& draw, DrawRenderState& state,
|
||||
vk::PrimitiveTopology topology, const DrawEmitInfo& emit,
|
||||
const DrawIndexBufferSource& index_source,
|
||||
@@ -1243,7 +1243,7 @@ void RenderExecutor::ExecutePreparedDraw(uint64_t submit_id, RenderCommandBuffer
|
||||
}
|
||||
}
|
||||
|
||||
void RenderExecutor::DrawIndex(uint64_t submit_id, RenderCommandBuffer& buffer,
|
||||
void RenderExecutor::DrawIndex(uint64_t submit_id, CommandBuffer& buffer,
|
||||
uint32_t index_type_and_size, uint32_t index_count,
|
||||
const void* index_addr, uint32_t flags, uint32_t type,
|
||||
uint32_t instance_count, uint32_t render_target_slice_offset,
|
||||
@@ -1376,7 +1376,7 @@ void RenderExecutor::DrawIndex(uint64_t submit_id, RenderCommandBuffer& buffer,
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
||||
void RenderExecutor::DrawAuto(uint64_t submit_id, RenderCommandBuffer& buffer, uint32_t index_count,
|
||||
void RenderExecutor::DrawAuto(uint64_t submit_id, CommandBuffer& buffer, uint32_t index_count,
|
||||
uint32_t flags, uint32_t render_target_slice_offset,
|
||||
uint32_t instance_count, uint32_t first_vertex,
|
||||
uint32_t first_instance) {
|
||||
@@ -1475,7 +1475,7 @@ void RenderExecutor::DrawAuto(uint64_t submit_id, RenderCommandBuffer& buffer, u
|
||||
ResetBindings();
|
||||
}
|
||||
|
||||
bool RenderExecutor::ResolveColorTargets(uint64_t submit_id, RenderCommandBuffer& buffer,
|
||||
bool RenderExecutor::ResolveColorTargets(uint64_t submit_id, CommandBuffer& buffer,
|
||||
uint32_t render_target_slice_offset) {
|
||||
const auto& hw = buffer.GetRegisters();
|
||||
if (hw.GetColorControl().mode != 3) {
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
#ifndef EMULATOR_SRC_GRAPHICS_HOST_GPU_VULKANINSTANCE_H_
|
||||
#define EMULATOR_SRC_GRAPHICS_HOST_GPU_VULKANINSTANCE_H_
|
||||
|
||||
#include "common/abi.h"
|
||||
#include "common/common.h"
|
||||
#include "common/threads.h"
|
||||
#include "graphics/host_gpu/vulkanCommon.h"
|
||||
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <tuple>
|
||||
#include <vk_mem_alloc.h>
|
||||
|
||||
namespace Libs::Graphics {
|
||||
|
||||
inline constexpr uint32_t VULKAN_TARGET_API_VERSION = VK_API_VERSION_1_3;
|
||||
|
||||
struct VulkanInstance {
|
||||
vk::Instance instance = nullptr;
|
||||
vk::DebugUtilsMessengerEXT debug_messenger = nullptr;
|
||||
vk::PhysicalDevice physical_device = nullptr;
|
||||
vk::PhysicalDeviceProperties physical_device_properties = {};
|
||||
vk::PhysicalDeviceMemoryProperties physical_device_memory_properties = {};
|
||||
vk::Device device = nullptr;
|
||||
VmaAllocator allocator = nullptr;
|
||||
bool memory_budget_ext_enabled = false;
|
||||
bool rt_extensions_enabled = false;
|
||||
bool compute_subgroup_size_control_enabled = false;
|
||||
bool compute_wave64_supported = false;
|
||||
bool sample_rate_shading_enabled = false;
|
||||
uint32_t subgroup_size = 0;
|
||||
uint32_t min_subgroup_size = 0;
|
||||
uint32_t max_subgroup_size = 0;
|
||||
uint32_t max_push_descriptors = 0;
|
||||
vk::ShaderStageFlags required_subgroup_size_stages = {};
|
||||
Common::Mutex queue_mutex;
|
||||
uint32_t queue_family = static_cast<uint32_t>(-1);
|
||||
vk::Queue queue = nullptr;
|
||||
|
||||
[[nodiscard]] const vk::PhysicalDeviceProperties& GetPhysicalDeviceProperties() const {
|
||||
return physical_device_properties;
|
||||
}
|
||||
|
||||
[[nodiscard]] const vk::PhysicalDeviceMemoryProperties&
|
||||
GetPhysicalDeviceMemoryProperties() const {
|
||||
return physical_device_memory_properties;
|
||||
}
|
||||
|
||||
[[nodiscard]] vk::FormatProperties GetFormatProperties(vk::Format format) const {
|
||||
std::scoped_lock lock(m_format_properties_mutex);
|
||||
auto [it, inserted] = m_format_properties.try_emplace(format);
|
||||
if (inserted) {
|
||||
physical_device.getFormatProperties(format, &it->second);
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
[[nodiscard]] vk::Result GetImageFormatProperties(vk::Format format, vk::ImageType type,
|
||||
vk::ImageTiling tiling,
|
||||
vk::ImageUsageFlags usage,
|
||||
vk::ImageCreateFlags flags,
|
||||
vk::ImageFormatProperties* properties) const {
|
||||
using Key = std::tuple<vk::Format, vk::ImageType, vk::ImageTiling, vk::ImageUsageFlags,
|
||||
vk::ImageCreateFlags>;
|
||||
std::scoped_lock lock(m_image_format_properties_mutex);
|
||||
auto [it, inserted] =
|
||||
m_image_format_properties.try_emplace(Key {format, type, tiling, usage, flags});
|
||||
if (inserted) {
|
||||
it->second.first = physical_device.getImageFormatProperties(format, type, tiling, usage,
|
||||
flags, &it->second.second);
|
||||
}
|
||||
if (properties != nullptr) {
|
||||
*properties = it->second.second;
|
||||
}
|
||||
return it->second.first;
|
||||
}
|
||||
|
||||
[[nodiscard]] vk::DeviceSize StorageMinAlignment() const {
|
||||
const auto alignment = physical_device_properties.limits.minStorageBufferOffsetAlignment;
|
||||
return alignment != 0 ? alignment : 1;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::mutex m_format_properties_mutex;
|
||||
mutable std::map<vk::Format, vk::FormatProperties> m_format_properties;
|
||||
mutable std::mutex m_image_format_properties_mutex;
|
||||
mutable std::map<std::tuple<vk::Format, vk::ImageType, vk::ImageTiling, vk::ImageUsageFlags,
|
||||
vk::ImageCreateFlags>,
|
||||
std::pair<vk::Result, vk::ImageFormatProperties>>
|
||||
m_image_format_properties;
|
||||
};
|
||||
|
||||
} // namespace Libs::Graphics
|
||||
|
||||
#endif // EMULATOR_SRC_GRAPHICS_HOST_GPU_VULKANINSTANCE_H_
|
||||
Reference in New Issue
Block a user