mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 19:07:01 +02:00
graphics: clean up draw setup
This commit is contained in:
@@ -41,16 +41,13 @@ static bool DccAlphaOnMsb(const HW::ColorInfo& info) {
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
||||
void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, CommandBuffer& buffer,
|
||||
RenderColorInfo& r,
|
||||
void RenderExecutor::ResolveRenderColorTarget(CommandBuffer& buffer, RenderColorInfo& r,
|
||||
uint32_t render_target_slice_offset,
|
||||
uint32_t render_target_slot, bool ignore_target_mask,
|
||||
uint32_t rt_slot, bool ignore_target_mask,
|
||||
bool exact_format) {
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
const auto& hw = buffer.GetRegisters();
|
||||
|
||||
const auto rt_slot = (render_target_slot == UINT32_MAX ? render_target_first_bound_slot(buffer)
|
||||
: render_target_slot);
|
||||
const auto& rt = hw.GetRenderTarget(rt_slot);
|
||||
auto mask = render_target_mask_slot(hw.GetRenderTargetMask(), rt_slot);
|
||||
if (ignore_target_mask && rt.base.addr != 0 && mask == 0) {
|
||||
|
||||
@@ -97,10 +97,8 @@ 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, CommandBuffer& buffer,
|
||||
RenderDepthInfo& r) {
|
||||
void RenderExecutor::ResolveRenderDepthTarget(CommandBuffer& buffer, RenderDepthInfo& r) {
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
(void)submit_id;
|
||||
const auto& hw = buffer.GetRegisters();
|
||||
const auto& z = hw.GetDepthRenderTarget();
|
||||
const auto& rc = hw.GetRenderControl();
|
||||
@@ -235,7 +233,6 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, CommandBuffer&
|
||||
DepthFatal("layered depth backing range is invalid");
|
||||
}
|
||||
r.depth_clear_enable = rc.depth_clear_enable;
|
||||
r.depth_meta_clear_enable = false;
|
||||
r.depth_load_clear_enable = r.depth_clear_enable;
|
||||
r.depth_clear_value = hw.GetDepthClearValue();
|
||||
r.depth_test_enable = dc.z_enable;
|
||||
|
||||
@@ -23,7 +23,6 @@ struct RenderDepthInfo {
|
||||
TextureCache::ImageDesc desc;
|
||||
bool depth_clear_enable = false;
|
||||
bool depth_load_clear_enable = false;
|
||||
bool depth_meta_clear_enable = false;
|
||||
float depth_clear_value = 0.0f;
|
||||
bool depth_test_enable = false;
|
||||
// Effective draw writes; discovery applies test, target-write and clear controls.
|
||||
|
||||
@@ -404,30 +404,22 @@ void ValidateStorageTexture(const ShaderRecompiler::IR::ImageResource& resource,
|
||||
descriptor.fields[5], descriptor.fields[6], descriptor.fields[7]);
|
||||
}
|
||||
|
||||
struct NullImageSpec {
|
||||
vk::Format format;
|
||||
Prospero::BufferFormat guest_format;
|
||||
};
|
||||
|
||||
static NullImageSpec NullTextureSpec(const ShaderRecompiler::IR::ImageResource& resource) {
|
||||
switch (resource.numeric_class) {
|
||||
case Prospero::TextureNumericClass::Float:
|
||||
return {vk::Format::eR32Sfloat, Prospero::BufferFormat::k32Float};
|
||||
case Prospero::TextureNumericClass::Uint:
|
||||
return {vk::Format::eR32Uint, Prospero::BufferFormat::k32UInt};
|
||||
case Prospero::TextureNumericClass::Sint:
|
||||
return {vk::Format::eR32Sint, Prospero::BufferFormat::k32SInt};
|
||||
case Prospero::TextureNumericClass::Unsupported: break;
|
||||
}
|
||||
EXIT("null image has unsupported numeric class\n");
|
||||
}
|
||||
|
||||
static TextureCache::ImageDesc NullTextureDesc(const ShaderRecompiler::IR::ImageResource& resource,
|
||||
TextureCache::BindingType binding) {
|
||||
const auto spec = NullTextureSpec(resource);
|
||||
TextureCache::ImageDesc desc {};
|
||||
desc.info.pixel_format = spec.format;
|
||||
desc.info.guest_format = spec.guest_format;
|
||||
switch (resource.numeric_class) {
|
||||
case Prospero::TextureNumericClass::Float:
|
||||
desc.info.guest_format = Prospero::BufferFormat::k32Float;
|
||||
break;
|
||||
case Prospero::TextureNumericClass::Uint:
|
||||
desc.info.guest_format = Prospero::BufferFormat::k32UInt;
|
||||
break;
|
||||
case Prospero::TextureNumericClass::Sint:
|
||||
desc.info.guest_format = Prospero::BufferFormat::k32SInt;
|
||||
break;
|
||||
default: EXIT("null image has unsupported numeric class\n");
|
||||
}
|
||||
desc.info.pixel_format = VulkanFormat(desc.info.guest_format);
|
||||
desc.info.type = Prospero::ImageType::kColor2D;
|
||||
desc.info.extent = {1, 1, 1};
|
||||
desc.info.resources = {1, 1};
|
||||
@@ -769,8 +761,7 @@ PreparedBindings RenderExecutor::PrepareBindings(const ShaderStageRuntime& runti
|
||||
const auto& program = *runtime.program;
|
||||
const auto& snapshot = runtime.resources;
|
||||
PreparedBindings prepared;
|
||||
prepared.program = runtime.program;
|
||||
prepared.snapshot = &runtime.resources;
|
||||
prepared.runtime = &runtime;
|
||||
prepared.images.reserve(program.info.images.size());
|
||||
for (uint32_t i = 0; i < program.info.images.size(); i++) {
|
||||
auto binding = ResolveTexture(program.info.images[i], snapshot.images[i]);
|
||||
@@ -795,9 +786,9 @@ PreparedBindings RenderExecutor::PrepareBindings(const ShaderStageRuntime& runti
|
||||
|
||||
void RenderExecutor::FindBuffers(PreparedBindings& prepared) {
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
EXIT_IF(prepared.program == nullptr || prepared.snapshot == nullptr);
|
||||
const auto& program = *prepared.program;
|
||||
const auto& snapshot = *prepared.snapshot;
|
||||
EXIT_IF(prepared.runtime == nullptr || !*prepared.runtime);
|
||||
const auto& program = *prepared.runtime->program;
|
||||
const auto& snapshot = prepared.runtime->resources;
|
||||
auto& cache = m_context.GetBufferCache();
|
||||
|
||||
prepared.buffer_sources.clear();
|
||||
@@ -820,9 +811,9 @@ void RenderExecutor::FindBuffers(PreparedBindings& prepared) {
|
||||
|
||||
void RenderExecutor::RebindBuffers(PreparedBindings& prepared) {
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
EXIT_IF(prepared.program == nullptr || prepared.snapshot == nullptr);
|
||||
const auto& program = *prepared.program;
|
||||
const auto& snapshot = *prepared.snapshot;
|
||||
EXIT_IF(prepared.runtime == nullptr || !*prepared.runtime);
|
||||
const auto& program = *prepared.runtime->program;
|
||||
const auto& snapshot = prepared.runtime->resources;
|
||||
const auto& layout = program.bindings;
|
||||
EXIT_IF(prepared.buffer_sources.size() != program.info.buffers.size());
|
||||
|
||||
@@ -855,9 +846,9 @@ void RenderExecutor::RebindBuffers(PreparedBindings& prepared) {
|
||||
|
||||
void RenderExecutor::RebindImages(PreparedBindings& prepared) {
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
EXIT_IF(prepared.program == nullptr || prepared.snapshot == nullptr);
|
||||
const auto& program = *prepared.program;
|
||||
const auto& snapshot = *prepared.snapshot;
|
||||
EXIT_IF(prepared.runtime == nullptr || !*prepared.runtime);
|
||||
const auto& program = *prepared.runtime->program;
|
||||
const auto& snapshot = prepared.runtime->resources;
|
||||
auto& images = prepared.images;
|
||||
EXIT_IF(images.size() != program.info.images.size());
|
||||
auto& texture_cache = m_context.GetTextureCache();
|
||||
@@ -915,8 +906,8 @@ RenderExecutor::PrepareGraphicsBindings(const ShaderStageRuntime& vertex,
|
||||
if (bindings.pixel) {
|
||||
FindBuffers(*bindings.pixel);
|
||||
}
|
||||
if (bindings.vertex.program->info.uses_dma ||
|
||||
(bindings.pixel && bindings.pixel->program->info.uses_dma)) {
|
||||
if (bindings.vertex.runtime->program->info.uses_dma ||
|
||||
(bindings.pixel && bindings.pixel->runtime->program->info.uses_dma)) {
|
||||
m_context.GetGpuResources().PrepareBda();
|
||||
}
|
||||
RebindBuffers(bindings.vertex);
|
||||
@@ -947,13 +938,13 @@ void RenderExecutor::CommitBindings(CommandBuffer& buffer,
|
||||
? vk::ShaderStageFlagBits::eFragment
|
||||
: vk::ShaderStageFlags {};
|
||||
for (const auto* prepared: prepared_bindings) {
|
||||
EXIT_IF(prepared == nullptr || prepared->program == nullptr ||
|
||||
prepared->snapshot == nullptr);
|
||||
write_count += prepared->program->bindings.descriptors.size();
|
||||
for (const auto& binding: prepared->program->bindings.descriptors) {
|
||||
EXIT_IF(prepared == nullptr || prepared->runtime == nullptr || !*prepared->runtime);
|
||||
const auto& program = *prepared->runtime->program;
|
||||
write_count += program.bindings.descriptors.size();
|
||||
for (const auto& binding: program.bindings.descriptors) {
|
||||
descriptor_count += NativeDescriptorCount(binding);
|
||||
}
|
||||
const auto shader_stage = NativeShaderStage(prepared->program->stage);
|
||||
const auto shader_stage = NativeShaderStage(program.stage);
|
||||
push_stages |= shader_stage;
|
||||
EXIT_IF((pipeline_bind_point == vk::PipelineBindPoint::eGraphics &&
|
||||
(shader_stage & GraphicsStages) == vk::ShaderStageFlags {}) ||
|
||||
@@ -968,7 +959,7 @@ void RenderExecutor::CommitBindings(CommandBuffer& buffer,
|
||||
m_descriptor_writes.reserve(write_count);
|
||||
|
||||
for (auto* prepared: prepared_bindings) {
|
||||
const auto& program = *prepared->program;
|
||||
const auto& program = *prepared->runtime->program;
|
||||
auto& descriptors = *prepared;
|
||||
const auto shader_stage = NativeShaderStage(program.stage);
|
||||
const auto shader_stages = ShaderPipelineStages(shader_stage);
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
|
||||
namespace Libs::Graphics {
|
||||
|
||||
namespace ShaderRecompiler::IR {
|
||||
struct ResourceSnapshot;
|
||||
}
|
||||
struct ShaderStageRuntime;
|
||||
|
||||
struct TextureBinding {
|
||||
ImageId image_id;
|
||||
@@ -35,8 +33,8 @@ struct PreparedBindings {
|
||||
BufferId id;
|
||||
};
|
||||
|
||||
const ShaderRecompiler::IR::CompiledShaderInfo* program = nullptr;
|
||||
const ShaderRecompiler::IR::ResourceSnapshot* snapshot = nullptr;
|
||||
// The draw owns the immutable compiled-program/runtime-snapshot association through commit.
|
||||
const ShaderStageRuntime* runtime = nullptr;
|
||||
// Keep the resolved guest range through cache preparation; only the host buffer ID may
|
||||
// become stale and need resolving again when bindings are rebound.
|
||||
std::vector<BufferSource> buffer_sources;
|
||||
|
||||
@@ -179,13 +179,11 @@ private:
|
||||
[[nodiscard]] GraphicsBindings PrepareGraphicsBindings(const ShaderStageRuntime& vertex,
|
||||
const ShaderStageRuntime& pixel,
|
||||
bool pixel_active);
|
||||
void ResolveRenderColorTarget(uint64_t submit_id, CommandBuffer& buffer,
|
||||
RenderColorInfo& target, uint32_t render_target_slice_offset = 0,
|
||||
uint32_t render_target_slot = UINT32_MAX,
|
||||
void ResolveRenderColorTarget(CommandBuffer& buffer, RenderColorInfo& target,
|
||||
uint32_t render_target_slice_offset, uint32_t render_target_slot,
|
||||
bool ignore_target_mask = false, bool exact_format = false);
|
||||
void ResolveRenderDepthTarget(uint64_t submit_id, CommandBuffer& buffer,
|
||||
RenderDepthInfo& target);
|
||||
[[nodiscard]] bool PrepareDrawRenderState(uint64_t submit_id, CommandBuffer& buffer,
|
||||
void ResolveRenderDepthTarget(CommandBuffer& buffer, RenderDepthInfo& target);
|
||||
[[nodiscard]] bool PrepareDrawRenderState(CommandBuffer& buffer,
|
||||
const DrawCallInfo& draw,
|
||||
uint32_t render_target_slice_offset,
|
||||
bool log_setup_phases, DrawRenderState& state);
|
||||
@@ -197,7 +195,7 @@ private:
|
||||
[[nodiscard]] RenderState AcquireRenderTargets(CommandBuffer& buffer, RenderColorInfo* colors,
|
||||
uint32_t color_count, RenderDepthInfo& depth,
|
||||
const std::optional<PreparedBindings>& pixel = std::nullopt);
|
||||
[[nodiscard]] bool ResolveColorTargets(uint64_t submit_id, CommandBuffer& buffer,
|
||||
[[nodiscard]] bool ResolveColorTargets(CommandBuffer& buffer,
|
||||
uint32_t render_target_slice_offset);
|
||||
void BindImage(ImageId id, bool storage);
|
||||
void BindRenderTarget(ImageId id);
|
||||
|
||||
@@ -544,11 +544,11 @@ RenderState RenderExecutor::AcquireRenderTargets(CommandBuffer& buffer, RenderCo
|
||||
!cache.ClearMeta(metadata.range.address)) {
|
||||
EXIT("failed to acquire HTile metadata for a depth clear\n");
|
||||
}
|
||||
depth.depth_meta_clear_enable =
|
||||
const bool meta_clear =
|
||||
metadata.kind == ImageMetadataKind::Htile &&
|
||||
cache.IsMetaCleared(metadata.range.address, depth.desc.view_info.base_layer);
|
||||
depth.depth_load_clear_enable = depth.depth_clear_enable || depth.depth_meta_clear_enable;
|
||||
if (depth.depth_meta_clear_enable &&
|
||||
depth.depth_load_clear_enable = depth.depth_clear_enable || meta_clear;
|
||||
if (meta_clear &&
|
||||
!cache.TouchMeta(metadata.range.address, depth.desc.view_info.base_layer, false)) {
|
||||
EXIT("failed to consume HTile clear state\n");
|
||||
}
|
||||
@@ -898,13 +898,12 @@ static bool ResolvePrimitiveRestart(const CommandBuffer& buffer, vk::PrimitiveTo
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RenderExecutor::PrepareDrawRenderState(uint64_t submit_id, CommandBuffer& buffer,
|
||||
const DrawCallInfo& draw,
|
||||
bool RenderExecutor::PrepareDrawRenderState(CommandBuffer& buffer, const DrawCallInfo& draw,
|
||||
uint32_t render_target_slice_offset,
|
||||
bool log_setup_phases, DrawRenderState& state) {
|
||||
auto& ctx = buffer.GetRegisters();
|
||||
|
||||
if (ResolveColorTargets(submit_id, buffer, render_target_slice_offset)) {
|
||||
if (ResolveColorTargets(buffer, render_target_slice_offset)) {
|
||||
return false;
|
||||
}
|
||||
if (log_setup_phases) {
|
||||
@@ -913,7 +912,7 @@ bool RenderExecutor::PrepareDrawRenderState(uint64_t submit_id, CommandBuffer& b
|
||||
for (uint32_t slot = 0; slot < RENDER_COLOR_ATTACHMENTS_MAX; slot++) {
|
||||
if (slot == 0 || (render_target_mask_slot(ctx.GetRenderTargetMask(), slot) != 0 &&
|
||||
ctx.GetRenderTarget(slot).base.addr != 0)) {
|
||||
ResolveRenderColorTarget(submit_id, buffer, state.color_info[state.color_count],
|
||||
ResolveRenderColorTarget(buffer, state.color_info[state.color_count],
|
||||
render_target_slice_offset, slot);
|
||||
if (state.color_info[state.color_count].image_id) {
|
||||
state.color_count++;
|
||||
@@ -923,7 +922,7 @@ bool RenderExecutor::PrepareDrawRenderState(uint64_t submit_id, CommandBuffer& b
|
||||
if (log_setup_phases) {
|
||||
LogDrawPhase(draw.name, "ResolveRenderDepthTarget");
|
||||
}
|
||||
ResolveRenderDepthTarget(submit_id, buffer, state.depth_info);
|
||||
ResolveRenderDepthTarget(buffer, state.depth_info);
|
||||
|
||||
state.ps_active = DrawHasActivePixelShader(buffer);
|
||||
if (state.color_count == 0 && !state.depth_info.image_id && !state.ps_active) {
|
||||
@@ -1316,7 +1315,7 @@ void RenderExecutor::DrawIndex(uint64_t submit_id, CommandBuffer& buffer,
|
||||
index_source.guest_element_size = static_cast<uint32_t>(index_size / args.index_count);
|
||||
|
||||
DrawRenderState state {};
|
||||
if (!PrepareDrawRenderState(submit_id, buffer, draw, args.render_target_slice_offset, true,
|
||||
if (!PrepareDrawRenderState(buffer, draw, args.render_target_slice_offset, true,
|
||||
state)) {
|
||||
ResetBindings();
|
||||
return;
|
||||
@@ -1393,7 +1392,7 @@ void RenderExecutor::DrawAuto(uint64_t submit_id, CommandBuffer& buffer, const D
|
||||
args.vertex_count, args.instance_count, args.first_instance};
|
||||
|
||||
DrawRenderState state {};
|
||||
if (!PrepareDrawRenderState(submit_id, buffer, draw, args.render_target_slice_offset, false,
|
||||
if (!PrepareDrawRenderState(buffer, draw, args.render_target_slice_offset, false,
|
||||
state)) {
|
||||
ResetBindings();
|
||||
return;
|
||||
@@ -1440,8 +1439,7 @@ void RenderExecutor::DrawAuto(uint64_t submit_id, CommandBuffer& buffer, const D
|
||||
ResetBindings();
|
||||
}
|
||||
|
||||
bool RenderExecutor::ResolveColorTargets(uint64_t submit_id, CommandBuffer& buffer,
|
||||
uint32_t render_target_slice_offset) {
|
||||
bool RenderExecutor::ResolveColorTargets(CommandBuffer& buffer, uint32_t render_target_slice_offset) {
|
||||
const auto& hw = buffer.GetRegisters();
|
||||
if (hw.GetColorControl().mode != 3) {
|
||||
return false;
|
||||
@@ -1455,8 +1453,8 @@ bool RenderExecutor::ResolveColorTargets(uint64_t submit_id, CommandBuffer& buff
|
||||
|
||||
RenderColorInfo src {};
|
||||
RenderColorInfo dst {};
|
||||
ResolveRenderColorTarget(submit_id, buffer, src, render_target_slice_offset, 0, true, true);
|
||||
ResolveRenderColorTarget(submit_id, buffer, dst, render_target_slice_offset, 1, true, true);
|
||||
ResolveRenderColorTarget(buffer, src, render_target_slice_offset, 0, true, true);
|
||||
ResolveRenderColorTarget(buffer, dst, render_target_slice_offset, 1, true, true);
|
||||
if (!src.image_id || !dst.image_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user