mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-21 11:26:56 +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 render_target_slice_offset, uint32_t first_vertex,
|
||||||
uint32_t first_instance);
|
uint32_t first_instance);
|
||||||
|
|
||||||
CommandScheduler& GetScheduler() const { return m_renderer.GetCommandScheduler(); }
|
CommandScheduler& GetScheduler() const { return m_renderer.GetCommandScheduler(); }
|
||||||
RenderCommandBuffer& CurrentBuffer() { return GetScheduler().Current(); }
|
CommandBuffer& CurrentBuffer() { return GetScheduler().Current(); }
|
||||||
void CheckBuffer() const { GetScheduler().CheckActive(); }
|
void CheckBuffer() const { GetScheduler().CheckActive(); }
|
||||||
GpuResourceManager& GetGpuResources() const { return m_renderer.GetGpuResources(); }
|
GpuResourceManager& GetGpuResources() const { return m_renderer.GetGpuResources(); }
|
||||||
|
|
||||||
RenderContext& m_renderer;
|
RenderContext& m_renderer;
|
||||||
HW::Context m_ctx;
|
HW::Context m_ctx;
|
||||||
|
|||||||
@@ -3,20 +3,88 @@
|
|||||||
|
|
||||||
#include "common/abi.h"
|
#include "common/abi.h"
|
||||||
#include "common/common.h"
|
#include "common/common.h"
|
||||||
|
#include "common/threads.h"
|
||||||
#include "graphics/host_gpu/vulkanCommon.h" // IWYU pragma: export
|
#include "graphics/host_gpu/vulkanCommon.h" // IWYU pragma: export
|
||||||
#include "graphics/host_gpu/vulkanInstance.h"
|
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <mutex>
|
||||||
|
#include <tuple>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <vk_mem_alloc.h>
|
#include <vk_mem_alloc.h>
|
||||||
|
|
||||||
namespace Libs::Graphics {
|
namespace Libs::Graphics {
|
||||||
|
|
||||||
class CommandBuffer;
|
|
||||||
struct VulkanBuffer;
|
struct VulkanBuffer;
|
||||||
struct VulkanImage;
|
struct VulkanImage;
|
||||||
struct VulkanMemory;
|
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();
|
[[nodiscard]] bool CreateAllocator();
|
||||||
void DestroyAllocator();
|
void DestroyAllocator();
|
||||||
void LogMemoryBudget() const;
|
void LogMemoryBudget() const;
|
||||||
@@ -35,6 +103,15 @@ struct GraphicContext: public VulkanInstance {
|
|||||||
|
|
||||||
uint32_t screen_width = 0;
|
uint32_t screen_width = 0;
|
||||||
uint32_t screen_height = 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 {
|
struct VulkanMemory {
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ static void ResolveDccClearInfo(RenderColorInfo& info, vk::Format format, bool h
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
// 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,
|
RenderColorInfo& r,
|
||||||
uint32_t render_target_slice_offset,
|
uint32_t render_target_slice_offset,
|
||||||
uint32_t render_target_slot, bool ignore_target_mask,
|
uint32_t render_target_slot, bool ignore_target_mask,
|
||||||
|
|||||||
@@ -10,8 +10,6 @@
|
|||||||
|
|
||||||
namespace Libs::Graphics {
|
namespace Libs::Graphics {
|
||||||
|
|
||||||
class RenderCommandBuffer;
|
|
||||||
|
|
||||||
enum class RenderColorType {
|
enum class RenderColorType {
|
||||||
NoColorOutput,
|
NoColorOutput,
|
||||||
RenderTexture,
|
RenderTexture,
|
||||||
|
|||||||
@@ -346,7 +346,7 @@ void CommandScheduler::CheckActive() const {
|
|||||||
EXIT_IF(!Active());
|
EXIT_IF(!Active());
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderCommandBuffer& CommandScheduler::Current() {
|
CommandBuffer& CommandScheduler::Current() {
|
||||||
CheckActive();
|
CheckActive();
|
||||||
return m_command;
|
return m_command;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] bool Active() const noexcept { return m_registers != nullptr; }
|
[[nodiscard]] bool Active() const noexcept { return m_registers != nullptr; }
|
||||||
void CheckActive() const;
|
void CheckActive() const;
|
||||||
RenderCommandBuffer& Current();
|
CommandBuffer& Current();
|
||||||
[[nodiscard]] uint64_t CurrentTick() const noexcept { return m_master.CurrentTick(); }
|
[[nodiscard]] uint64_t CurrentTick() const noexcept { return m_master.CurrentTick(); }
|
||||||
[[nodiscard]] bool IsFree(uint64_t tick);
|
[[nodiscard]] bool IsFree(uint64_t tick);
|
||||||
[[nodiscard]] MasterSemaphore& GetMasterSemaphore() noexcept { return m_master; }
|
[[nodiscard]] MasterSemaphore& GetMasterSemaphore() noexcept { return m_master; }
|
||||||
@@ -90,7 +90,7 @@ private:
|
|||||||
RenderContext& m_context;
|
RenderContext& m_context;
|
||||||
GraphicContext& m_graphics;
|
GraphicContext& m_graphics;
|
||||||
CommandPool m_command_pool;
|
CommandPool m_command_pool;
|
||||||
RenderCommandBuffer m_command;
|
CommandBuffer m_command;
|
||||||
std::queue<PendingOperation> m_pending_operations;
|
std::queue<PendingOperation> m_pending_operations;
|
||||||
std::queue<PendingOperation> m_priority_operations;
|
std::queue<PendingOperation> m_priority_operations;
|
||||||
std::mutex m_operation_mutex;
|
std::mutex m_operation_mutex;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ static bool RenderTargetMaskHasMrt(uint32_t mask) {
|
|||||||
return (mask & ~0x0fu) != 0;
|
return (mask & ~0x0fu) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool RenderTargetMaskHasBoundMrt(const RenderCommandBuffer& buffer) {
|
static bool RenderTargetMaskHasBoundMrt(const CommandBuffer& buffer) {
|
||||||
const auto& hw = buffer.GetRegisters();
|
const auto& hw = buffer.GetRegisters();
|
||||||
const auto mask = hw.GetRenderTargetMask();
|
const auto mask = hw.GetRenderTargetMask();
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ static bool RenderTargetMaskHasBoundMrt(const RenderCommandBuffer& buffer) {
|
|||||||
return bound_targets > 1;
|
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& hw = buffer.GetRegisters();
|
||||||
const auto mask = hw.GetRenderTargetMask();
|
const auto mask = hw.GetRenderTargetMask();
|
||||||
for (uint32_t i = 0; i < 8; i++) {
|
for (uint32_t i = 0; i < 8; i++) {
|
||||||
@@ -266,11 +266,10 @@ static void RtCheck(const HW::RenderTarget& rt) {
|
|||||||
logged = true;
|
logged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const bool native_2x_one_frag = rt.info.fmask_compression_enable &&
|
const bool native_2x_one_frag =
|
||||||
!rt.info.fmask_data_compression_disable &&
|
rt.info.fmask_compression_enable && !rt.info.fmask_data_compression_disable &&
|
||||||
rt.info.cmask_fast_clear_enable && rt.fmask.addr != 0 &&
|
rt.info.cmask_fast_clear_enable && rt.fmask.addr != 0 && rt.cmask.addr != 0 &&
|
||||||
rt.cmask.addr != 0 && rt.attrib.num_samples == 1 &&
|
rt.attrib.num_samples == 1 && rt.attrib.num_fragments == 1;
|
||||||
rt.attrib.num_fragments == 1;
|
|
||||||
EXIT_NOT_IMPLEMENTED(rt.info.fmask_one_frag_mode && !native_2x_one_frag);
|
EXIT_NOT_IMPLEMENTED(rt.info.fmask_one_frag_mode && !native_2x_one_frag);
|
||||||
if (rt.info.fmask_compression_enable) {
|
if (rt.info.fmask_compression_enable) {
|
||||||
EXIT_NOT_IMPLEMENTED(rt.attrib.num_samples == 0 && rt.attrib.num_fragments == 0);
|
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);
|
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& hw = buffer.GetRegisters();
|
||||||
const auto rt_slot = render_target_first_bound_slot(buffer);
|
const auto rt_slot = render_target_first_bound_slot(buffer);
|
||||||
const auto& rt = hw.GetRenderTarget(rt_slot);
|
const auto& rt = hw.GetRenderTarget(rt_slot);
|
||||||
@@ -1231,7 +1230,7 @@ void hw_check(const RenderCommandBuffer& buffer) {
|
|||||||
// EXIT_NOT_IMPLEMENTED(hw.GetStencilClearValue() != 0);
|
// 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& hw = buffer.GetRegisters();
|
||||||
const auto rt_slot = render_target_first_bound_slot(buffer);
|
const auto rt_slot = render_target_first_bound_slot(buffer);
|
||||||
const auto& rt = hw.GetRenderTarget(rt_slot);
|
const auto& rt = hw.GetRenderTarget(rt_slot);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
namespace Libs::Graphics {
|
namespace Libs::Graphics {
|
||||||
|
|
||||||
class RenderCommandBuffer;
|
class CommandBuffer;
|
||||||
|
|
||||||
namespace HW {
|
namespace HW {
|
||||||
class Context;
|
class Context;
|
||||||
@@ -28,15 +28,15 @@ struct ScissorRect {
|
|||||||
};
|
};
|
||||||
|
|
||||||
uint32_t render_target_mask_slot(uint32_t mask, uint32_t slot);
|
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();
|
bool graphics_debug_dump_enabled();
|
||||||
void uc_print(const char* func, const HW::UserConfig& uc);
|
void uc_print(const char* func, const HW::UserConfig& uc);
|
||||||
void uc_check(const HW::UserConfig& uc);
|
void uc_check(const HW::UserConfig& uc);
|
||||||
void sh_print(const char* func, const HW::Shader& uc);
|
void sh_print(const char* func, const HW::Shader& uc);
|
||||||
std::vector<std::string> rt_print(const char* func, const HW::RenderTarget& rt);
|
std::vector<std::string> rt_print(const char* func, const HW::RenderTarget& rt);
|
||||||
bool RenderIsColorTileModeLinear(Prospero::TileMode tile_mode);
|
bool RenderIsColorTileModeLinear(Prospero::TileMode tile_mode);
|
||||||
void hw_print(const RenderCommandBuffer& buffer);
|
void hw_print(const CommandBuffer& buffer);
|
||||||
void hw_check(const RenderCommandBuffer& buffer);
|
void hw_check(const CommandBuffer& buffer);
|
||||||
void LogDrawPhase(const char* draw_name, const char* phase);
|
void LogDrawPhase(const char* draw_name, const char* phase);
|
||||||
ScissorRect calc_final_scissor(const HW::ScreenViewport& vp, const HW::ScanModeControl& smc,
|
ScissorRect calc_final_scissor(const HW::ScreenViewport& vp, const HW::ScanModeControl& smc,
|
||||||
vk::Extent2D extent);
|
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;
|
return fail == replace_op || pass == replace_op || depth_fail == replace_op;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] static vk::Format ResolveHostDepthAttachmentFormat(const RenderCommandBuffer& buffer,
|
[[nodiscard]] static vk::Format ResolveHostDepthAttachmentFormat(const CommandBuffer& buffer,
|
||||||
const DepthFormatPolicy& policy,
|
const DepthFormatPolicy& policy,
|
||||||
bool has_stencil,
|
bool has_stencil,
|
||||||
uint32_t samples) {
|
uint32_t samples) {
|
||||||
auto& graphics = buffer.GetGraphics();
|
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)
|
// 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) {
|
RenderDepthInfo& r) {
|
||||||
KYTY_PROFILER_FUNCTION();
|
KYTY_PROFILER_FUNCTION();
|
||||||
(void)submit_id;
|
(void)submit_id;
|
||||||
|
|||||||
@@ -11,8 +11,6 @@
|
|||||||
|
|
||||||
namespace Libs::Graphics {
|
namespace Libs::Graphics {
|
||||||
|
|
||||||
class RenderCommandBuffer;
|
|
||||||
|
|
||||||
inline constexpr bool depth_htile_stencil_acceleration_compatible(bool has_stencil, bool has_htile,
|
inline constexpr bool depth_htile_stencil_acceleration_compatible(bool has_stencil, bool has_htile,
|
||||||
bool htile_stencil_disabled) {
|
bool htile_stencil_disabled) {
|
||||||
return htile_stencil_disabled || (has_stencil && has_htile);
|
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;
|
return std::memcmp(this, &other, sizeof(*this)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PipelineCache::GraphicsPipeline& PipelineCache::CreateGraphicsPipeline(
|
PipelineCache::GraphicsPipeline&
|
||||||
RenderColorInfo* colors, uint32_t color_count, RenderDepthInfo& depth,
|
PipelineCache::CreateGraphicsPipeline(RenderColorInfo* colors, uint32_t color_count,
|
||||||
ShaderVertexInputInfo& vs_input_info, RenderCommandBuffer& command,
|
RenderDepthInfo& depth, ShaderVertexInputInfo& vs_input_info,
|
||||||
ShaderPixelInputInfo* ps_input_info, vk::PrimitiveTopology topology,
|
CommandBuffer& command, ShaderPixelInputInfo* ps_input_info,
|
||||||
bool primitive_restart_enable, bool ps_active, std::span<const uint32_t> vs_spirv,
|
vk::PrimitiveTopology topology, bool primitive_restart_enable,
|
||||||
std::span<const uint32_t> ps_spirv) {
|
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);
|
KYTY_PROFILER_BLOCK("PipelineCache::CreatePipeline(Gfx)", profiler::colors::DeepOrangeA200);
|
||||||
|
|
||||||
EXIT_IF(colors == nullptr);
|
EXIT_IF(colors == nullptr);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace Libs::Graphics {
|
|||||||
struct GraphicContext;
|
struct GraphicContext;
|
||||||
struct RenderColorInfo;
|
struct RenderColorInfo;
|
||||||
struct RenderDepthInfo;
|
struct RenderDepthInfo;
|
||||||
class RenderCommandBuffer;
|
class CommandBuffer;
|
||||||
|
|
||||||
namespace HW {
|
namespace HW {
|
||||||
class Context;
|
class Context;
|
||||||
@@ -121,7 +121,7 @@ public:
|
|||||||
|
|
||||||
GraphicsPipeline&
|
GraphicsPipeline&
|
||||||
CreateGraphicsPipeline(RenderColorInfo* colors, uint32_t color_count, RenderDepthInfo& depth,
|
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,
|
ShaderPixelInputInfo* ps_input_info, vk::PrimitiveTopology topology,
|
||||||
bool primitive_restart_enable, bool ps_active,
|
bool primitive_restart_enable, bool ps_active,
|
||||||
std::span<const uint32_t> vs_spirv, std::span<const uint32_t> ps_spirv);
|
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]] vk::CommandBuffer Handle() const;
|
||||||
[[nodiscard]] GraphicContext& GetGraphics() const noexcept { return m_graphics; }
|
[[nodiscard]] GraphicContext& GetGraphics() const noexcept { return m_graphics; }
|
||||||
[[nodiscard]] RenderContext& GetContext() const noexcept { return m_context; }
|
[[nodiscard]] RenderContext& GetContext() const noexcept { return m_context; }
|
||||||
|
[[nodiscard]] HW::Context& GetRegisters() const noexcept { return *m_registers; }
|
||||||
protected:
|
[[nodiscard]] HW::UserConfig& GetUserConfig() const noexcept { return *m_user_config; }
|
||||||
explicit CommandBuffer(CommandScheduler& scheduler);
|
[[nodiscard]] HW::Shader& GetShaders() const noexcept { return *m_shaders; }
|
||||||
|
|
||||||
private:
|
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 Begin();
|
||||||
void End() const;
|
void End() const;
|
||||||
|
|
||||||
@@ -109,29 +116,10 @@ private:
|
|||||||
uint32_t m_debug_arg3 = 0;
|
uint32_t m_debug_arg3 = 0;
|
||||||
uint64_t m_debug_arg4 = 0;
|
uint64_t m_debug_arg4 = 0;
|
||||||
mutable RenderState m_render_state;
|
mutable RenderState m_render_state;
|
||||||
mutable bool m_rendering = false;
|
mutable bool m_rendering = false;
|
||||||
|
HW::Context* m_registers = nullptr;
|
||||||
friend class CommandScheduler;
|
HW::UserConfig* m_user_config = nullptr;
|
||||||
};
|
HW::Shader* m_shaders = nullptr;
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
friend class CommandScheduler;
|
friend class CommandScheduler;
|
||||||
};
|
};
|
||||||
@@ -141,15 +129,14 @@ public:
|
|||||||
explicit RenderExecutor(RenderContext& context): m_context(context) {}
|
explicit RenderExecutor(RenderContext& context): m_context(context) {}
|
||||||
KYTY_CLASS_NO_COPY(RenderExecutor);
|
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 index_count, const void* index_addr, uint32_t flags, uint32_t type,
|
||||||
uint32_t instance_count = 1, uint32_t render_target_slice_offset = 0,
|
uint32_t instance_count = 1, uint32_t render_target_slice_offset = 0,
|
||||||
int32_t vertex_offset_add = 0, uint32_t first_instance = 0);
|
int32_t vertex_offset_add = 0, uint32_t first_instance = 0);
|
||||||
void DrawAuto(uint64_t submit_id, RenderCommandBuffer& buffer, uint32_t index_count,
|
void DrawAuto(uint64_t submit_id, CommandBuffer& buffer, uint32_t index_count, uint32_t flags,
|
||||||
uint32_t flags, uint32_t render_target_slice_offset = 0,
|
uint32_t render_target_slice_offset = 0, uint32_t instance_count = 1,
|
||||||
uint32_t instance_count = 1, uint32_t first_vertex = 0,
|
uint32_t first_vertex = 0, uint32_t first_instance = 0);
|
||||||
uint32_t first_instance = 0);
|
void DispatchDirect(uint64_t submit_id, CommandBuffer& buffer, uint32_t thread_group_x,
|
||||||
void DispatchDirect(uint64_t submit_id, RenderCommandBuffer& buffer, uint32_t thread_group_x,
|
|
||||||
uint32_t thread_group_y, uint32_t thread_group_z, uint32_t mode);
|
uint32_t thread_group_y, uint32_t thread_group_z, uint32_t mode);
|
||||||
|
|
||||||
[[nodiscard]] PreparedBindings PrepareBindings(const ShaderStageRuntime& runtime);
|
[[nodiscard]] PreparedBindings PrepareBindings(const ShaderStageRuntime& runtime);
|
||||||
@@ -171,32 +158,31 @@ private:
|
|||||||
[[nodiscard]] GraphicsBindings PrepareGraphicsBindings(const ShaderStageRuntime& vertex,
|
[[nodiscard]] GraphicsBindings PrepareGraphicsBindings(const ShaderStageRuntime& vertex,
|
||||||
const ShaderStageRuntime& pixel,
|
const ShaderStageRuntime& pixel,
|
||||||
bool pixel_active);
|
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,
|
RenderColorInfo& target, uint32_t render_target_slice_offset = 0,
|
||||||
uint32_t render_target_slot = UINT32_MAX,
|
uint32_t render_target_slot = UINT32_MAX,
|
||||||
bool ignore_target_mask = false, bool exact_format = false);
|
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);
|
RenderDepthInfo& target);
|
||||||
[[nodiscard]] bool PrepareDrawRenderState(uint64_t submit_id, RenderCommandBuffer& buffer,
|
[[nodiscard]] bool PrepareDrawRenderState(uint64_t submit_id, CommandBuffer& buffer,
|
||||||
const DrawCallInfo& draw,
|
const DrawCallInfo& draw,
|
||||||
uint32_t render_target_slice_offset,
|
uint32_t render_target_slice_offset,
|
||||||
bool log_setup_phases, DrawRenderState& state);
|
bool log_setup_phases, DrawRenderState& state);
|
||||||
void ExecutePreparedDraw(uint64_t submit_id, RenderCommandBuffer& buffer,
|
void ExecutePreparedDraw(uint64_t submit_id, CommandBuffer& buffer, const DrawCallInfo& draw,
|
||||||
const DrawCallInfo& draw, DrawRenderState& state,
|
DrawRenderState& state, vk::PrimitiveTopology topology,
|
||||||
vk::PrimitiveTopology topology, const DrawEmitInfo& emit,
|
const DrawEmitInfo& emit, const DrawIndexBufferSource& index_source,
|
||||||
const DrawIndexBufferSource& index_source,
|
bool primitive_restart_enable, bool log_pipeline_phase,
|
||||||
bool primitive_restart_enable, bool log_pipeline_phase,
|
bool set_bind_debug, bool set_auto_debug);
|
||||||
bool set_bind_debug, bool set_auto_debug);
|
|
||||||
[[nodiscard]] RenderState AcquireRenderTargets(CommandBuffer& buffer, RenderColorInfo* colors,
|
[[nodiscard]] RenderState AcquireRenderTargets(CommandBuffer& buffer, RenderColorInfo* colors,
|
||||||
uint32_t color_count, RenderDepthInfo& depth);
|
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);
|
uint32_t render_target_slice_offset);
|
||||||
void BindImage(ImageId id, bool storage);
|
void BindImage(ImageId id, bool storage);
|
||||||
void BindRenderTarget(ImageId id);
|
void BindRenderTarget(ImageId id);
|
||||||
void TrackImageBinding(ImageId id);
|
void TrackImageBinding(ImageId id);
|
||||||
void ResetBindings();
|
void ResetBindings();
|
||||||
[[nodiscard]] bool TryConsumeComputeMetaClear(const ShaderComputeInputInfo& input,
|
[[nodiscard]] bool TryConsumeComputeMetaClear(const ShaderComputeInputInfo& input,
|
||||||
const RenderCommandBuffer& buffer);
|
const CommandBuffer& buffer);
|
||||||
|
|
||||||
RenderContext& m_context;
|
RenderContext& m_context;
|
||||||
std::vector<ImageId> m_bound_images;
|
std::vector<ImageId> m_bound_images;
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ static uint64_t BufferDescriptorSize(const ShaderBufferResource& descriptor) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool RenderExecutor::TryConsumeComputeMetaClear(const ShaderComputeInputInfo& input,
|
bool RenderExecutor::TryConsumeComputeMetaClear(const ShaderComputeInputInfo& input,
|
||||||
const RenderCommandBuffer& buffer) {
|
const CommandBuffer& buffer) {
|
||||||
const auto& program = *input.stage.program;
|
const auto& program = *input.stage.program;
|
||||||
const auto& resources = *input.stage.resources;
|
const auto& resources = *input.stage.resources;
|
||||||
if (resources.buffers.size() != program.info.buffers.size()) {
|
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& program = *input.stage.program;
|
||||||
const auto& resources = *input.stage.resources;
|
const auto& resources = *input.stage.resources;
|
||||||
if (program.info.buffers.size() != 1 || resources.buffers.size() != 1 ||
|
if (program.info.buffers.size() != 1 || resources.buffers.size() != 1 ||
|
||||||
!program.info.images.empty() || !program.info.samplers.empty() ||
|
!program.info.images.empty() || !program.info.samplers.empty() || program.info.uses_dma ||
|
||||||
program.info.uses_dma || !resources.images.empty() ||
|
!resources.images.empty() || !resources.samplers.empty()) {
|
||||||
!resources.samplers.empty()) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const auto& resource = program.info.buffers.front();
|
const auto& resource = program.info.buffers.front();
|
||||||
@@ -163,7 +162,7 @@ static bool TryConsumeComputeImageClear(const ShaderComputeInputInfo& input, Com
|
|||||||
return true;
|
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_x, uint32_t thread_group_y,
|
||||||
uint32_t thread_group_z, uint32_t mode) {
|
uint32_t thread_group_z, uint32_t mode) {
|
||||||
EXIT_IF(buffer.IsInvalid());
|
EXIT_IF(buffer.IsInvalid());
|
||||||
@@ -210,9 +209,8 @@ void RenderExecutor::DispatchDirect(uint64_t submit_id, RenderCommandBuffer& buf
|
|||||||
|
|
||||||
ShaderComputeInputInfo input_info {};
|
ShaderComputeInputInfo input_info {};
|
||||||
std::span<const uint32_t> cs_shader;
|
std::span<const uint32_t> cs_shader;
|
||||||
if (!ShaderCompileInfoCS(cs_regs, sh_regs,
|
if (!ShaderCompileInfoCS(cs_regs, sh_regs, !m_context.GetGraphics().compute_wave64_supported,
|
||||||
!m_context.GetGraphics().compute_wave64_supported, input_info,
|
input_info, cs_shader)) {
|
||||||
cs_shader)) {
|
|
||||||
EXIT("ShaderCompileInfoCS failed for dispatch with CS shader 0x%016" PRIx64 "\n",
|
EXIT("ShaderCompileInfoCS failed for dispatch with CS shader 0x%016" PRIx64 "\n",
|
||||||
cs_regs.cs_regs.data_addr);
|
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,
|
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) {
|
uint32_t index_count, uint32_t flags) {
|
||||||
const auto& ctx = buffer.GetRegisters();
|
const auto& ctx = buffer.GetRegisters();
|
||||||
const auto& ucfg = buffer.GetUserConfig();
|
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_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 ShaderPixelInputInfo& ps_input_info) {
|
||||||
const auto& ctx = buffer.GetRegisters();
|
const auto& ctx = buffer.GetRegisters();
|
||||||
const auto& sh_regs = ctx.GetShaderRegisters();
|
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,
|
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,
|
const ShaderPixelInputInfo& ps_input_info, uint32_t index_count,
|
||||||
uint32_t flags) {
|
uint32_t flags) {
|
||||||
const auto& ctx = buffer.GetRegisters();
|
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);
|
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,
|
const ShaderVertexInputInfo& vs_input_info,
|
||||||
uint32_t index_type_and_size, uint32_t index_count,
|
uint32_t index_type_and_size, uint32_t index_count,
|
||||||
const void* index_addr) {
|
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 RenderColorInfo* colors, uint32_t color_count,
|
||||||
const RenderDepthInfo& depth) {
|
const RenderDepthInfo& depth) {
|
||||||
KYTY_PROFILER_FUNCTION();
|
KYTY_PROFILER_FUNCTION();
|
||||||
@@ -421,7 +421,7 @@ static bool PixelShaderHasDepthOrCoverageSideEffects(const HW::ShaderRegisters&
|
|||||||
db.shader_execute_on_noop;
|
db.shader_execute_on_noop;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ShouldSkipGeShader(const RenderCommandBuffer& buffer) {
|
static bool ShouldSkipGeShader(const CommandBuffer& buffer) {
|
||||||
const auto& ctx = buffer.GetRegisters();
|
const auto& ctx = buffer.GetRegisters();
|
||||||
const auto& ucfg = buffer.GetUserConfig();
|
const auto& ucfg = buffer.GetUserConfig();
|
||||||
const auto& sh_ctx = buffer.GetShaders();
|
const auto& sh_ctx = buffer.GetShaders();
|
||||||
@@ -706,7 +706,7 @@ RenderState RenderExecutor::AcquireRenderTargets(CommandBuffer& buffer, RenderCo
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool DrawHasActivePixelShader(const RenderCommandBuffer& buffer) {
|
static bool DrawHasActivePixelShader(const CommandBuffer& buffer) {
|
||||||
const auto& ctx = buffer.GetRegisters();
|
const auto& ctx = buffer.GetRegisters();
|
||||||
const auto& sh_regs = ctx.GetShaderRegisters();
|
const auto& sh_regs = ctx.GetShaderRegisters();
|
||||||
const bool has_color_output = (ctx.GetRenderTargetMask() & sh_regs.m_cbShaderMask) != 0;
|
const bool has_color_output = (ctx.GetRenderTargetMask() & sh_regs.m_cbShaderMask) != 0;
|
||||||
@@ -723,7 +723,7 @@ enum class CbColorMode : uint8_t {
|
|||||||
DccDecompress = 6,
|
DccDecompress = 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool ConsumeMetadataColorOperation(const RenderCommandBuffer& buffer) {
|
static bool ConsumeMetadataColorOperation(const CommandBuffer& buffer) {
|
||||||
const auto& ctx = buffer.GetRegisters();
|
const auto& ctx = buffer.GetRegisters();
|
||||||
const auto mode = ctx.GetColorControl().mode;
|
const auto mode = ctx.GetColorControl().mode;
|
||||||
// These special modes run color-buffer metadata or decompression operations. The shader is a
|
// These special modes run color-buffer metadata or decompression operations. The shader is a
|
||||||
@@ -779,7 +779,7 @@ struct PreparedVertexBuffers {
|
|||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
static PreparedVertexBuffers AcquireVertexBuffers(RenderCommandBuffer& buffer,
|
static PreparedVertexBuffers AcquireVertexBuffers(CommandBuffer& buffer,
|
||||||
const ShaderVertexInputInfo& vs_input_info) {
|
const ShaderVertexInputInfo& vs_input_info) {
|
||||||
EXIT_IF(vs_input_info.buffers_num < 0 ||
|
EXIT_IF(vs_input_info.buffers_num < 0 ||
|
||||||
vs_input_info.buffers_num > ShaderVertexInputInfo::RES_MAX);
|
vs_input_info.buffers_num > ShaderVertexInputInfo::RES_MAX);
|
||||||
@@ -869,8 +869,8 @@ static PreparedVertexBuffers AcquireVertexBuffers(RenderCommandBuffer& b
|
|||||||
return prepared;
|
return prepared;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetDrawDebugPhase(RenderCommandBuffer& buffer, uint64_t submit_id,
|
static void SetDrawDebugPhase(CommandBuffer& buffer, uint64_t submit_id, const DrawCallInfo& draw,
|
||||||
const DrawCallInfo& draw, uint32_t phase) {
|
uint32_t phase) {
|
||||||
EXIT_IF(draw.name == nullptr);
|
EXIT_IF(draw.name == nullptr);
|
||||||
|
|
||||||
buffer.SetDebugInfo(static_cast<uint32_t>(draw.debug_op), submit_id, phase, draw.index_count,
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ResolvePrimitiveRestart(const RenderCommandBuffer& buffer,
|
static bool ResolvePrimitiveRestart(const CommandBuffer& buffer, vk::PrimitiveTopology topology,
|
||||||
vk::PrimitiveTopology topology, uint32_t index_type_and_size) {
|
uint32_t index_type_and_size) {
|
||||||
const auto control = buffer.GetUserConfig().GetPrimitiveResetControl();
|
const auto control = buffer.GetUserConfig().GetPrimitiveResetControl();
|
||||||
EXIT_NOT_IMPLEMENTED((control & ~0x3u) != 0);
|
EXIT_NOT_IMPLEMENTED((control & ~0x3u) != 0);
|
||||||
if ((control & 0x1u) == 0) {
|
if ((control & 0x1u) == 0) {
|
||||||
@@ -953,7 +953,7 @@ static bool ResolvePrimitiveRestart(const RenderCommandBuffer& buffer,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderExecutor::PrepareDrawRenderState(uint64_t submit_id, RenderCommandBuffer& buffer,
|
bool RenderExecutor::PrepareDrawRenderState(uint64_t submit_id, CommandBuffer& buffer,
|
||||||
const DrawCallInfo& draw,
|
const DrawCallInfo& draw,
|
||||||
uint32_t render_target_slice_offset,
|
uint32_t render_target_slice_offset,
|
||||||
bool log_setup_phases, DrawRenderState& state) {
|
bool log_setup_phases, DrawRenderState& state) {
|
||||||
@@ -993,7 +993,7 @@ bool RenderExecutor::PrepareDrawRenderState(uint64_t submit_id, RenderCommandBuf
|
|||||||
return true;
|
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) {
|
DrawRenderState& state) {
|
||||||
EXIT_IF(draw.name == nullptr);
|
EXIT_IF(draw.name == nullptr);
|
||||||
auto& ctx = buffer.GetRegisters();
|
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 DrawCallInfo& draw,
|
||||||
const ShaderVertexInputInfo& vs_input_info) {
|
const ShaderVertexInputInfo& vs_input_info) {
|
||||||
EXIT_IF(draw.name == nullptr);
|
EXIT_IF(draw.name == nullptr);
|
||||||
@@ -1041,7 +1041,7 @@ static PreparedVertexBuffers PrepareVertexBuffers(uint64_t submit_id, RenderComm
|
|||||||
return AcquireVertexBuffers(buffer, vs_input_info);
|
return AcquireVertexBuffers(buffer, vs_input_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PreparedIndexBuffer PrepareIndexBuffer(RenderCommandBuffer& buffer,
|
static PreparedIndexBuffer PrepareIndexBuffer(CommandBuffer& buffer,
|
||||||
const DrawIndexBufferSource& source) {
|
const DrawIndexBufferSource& source) {
|
||||||
PreparedIndexBuffer prepared;
|
PreparedIndexBuffer prepared;
|
||||||
if (!source.enabled) {
|
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);
|
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,
|
const DrawRenderState& state, bool always_log,
|
||||||
bool force_legacy_rect_log, uint32_t index_type_and_size,
|
bool force_legacy_rect_log, uint32_t index_type_and_size,
|
||||||
const void* index_addr) {
|
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,
|
const DrawCallInfo& draw, DrawRenderState& state,
|
||||||
vk::PrimitiveTopology topology, const DrawEmitInfo& emit,
|
vk::PrimitiveTopology topology, const DrawEmitInfo& emit,
|
||||||
const DrawIndexBufferSource& index_source,
|
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,
|
uint32_t index_type_and_size, uint32_t index_count,
|
||||||
const void* index_addr, uint32_t flags, uint32_t type,
|
const void* index_addr, uint32_t flags, uint32_t type,
|
||||||
uint32_t instance_count, uint32_t render_target_slice_offset,
|
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)
|
// 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 flags, uint32_t render_target_slice_offset,
|
||||||
uint32_t instance_count, uint32_t first_vertex,
|
uint32_t instance_count, uint32_t first_vertex,
|
||||||
uint32_t first_instance) {
|
uint32_t first_instance) {
|
||||||
@@ -1475,7 +1475,7 @@ void RenderExecutor::DrawAuto(uint64_t submit_id, RenderCommandBuffer& buffer, u
|
|||||||
ResetBindings();
|
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) {
|
uint32_t render_target_slice_offset) {
|
||||||
const auto& hw = buffer.GetRegisters();
|
const auto& hw = buffer.GetRegisters();
|
||||||
if (hw.GetColorControl().mode != 3) {
|
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_
|
|
||||||
@@ -459,14 +459,14 @@ struct RenderExecutorTestAccess {
|
|||||||
|
|
||||||
static void ResolveRenderDepthTarget(RenderExecutor &executor,
|
static void ResolveRenderDepthTarget(RenderExecutor &executor,
|
||||||
uint64_t submit_id,
|
uint64_t submit_id,
|
||||||
RenderCommandBuffer &buffer,
|
CommandBuffer &buffer,
|
||||||
RenderDepthInfo &depth) {
|
RenderDepthInfo &depth) {
|
||||||
executor.ResolveRenderDepthTarget(submit_id, buffer, depth);
|
executor.ResolveRenderDepthTarget(submit_id, buffer, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ResolveRenderColorTarget(RenderExecutor &executor,
|
static void ResolveRenderColorTarget(RenderExecutor &executor,
|
||||||
uint64_t submit_id,
|
uint64_t submit_id,
|
||||||
RenderCommandBuffer &buffer,
|
CommandBuffer &buffer,
|
||||||
RenderColorInfo &color, uint32_t slot) {
|
RenderColorInfo &color, uint32_t slot) {
|
||||||
executor.ResolveRenderColorTarget(submit_id, buffer, color, 0, slot);
|
executor.ResolveRenderColorTarget(submit_id, buffer, color, 0, slot);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user