graphics: clean up draw setup

This commit is contained in:
nmzik
2026-09-08 10:58:53 +04:00
parent c6f6e306e0
commit c725ec50ff
8 changed files with 84 additions and 114 deletions
@@ -41,16 +41,13 @@ static bool DccAlphaOnMsb(const HW::ColorInfo& info) {
} }
// NOLINTNEXTLINE(readability-function-cognitive-complexity) // NOLINTNEXTLINE(readability-function-cognitive-complexity)
void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, CommandBuffer& buffer, void RenderExecutor::ResolveRenderColorTarget(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 rt_slot, bool ignore_target_mask,
bool exact_format) { bool exact_format) {
KYTY_PROFILER_FUNCTION(); KYTY_PROFILER_FUNCTION();
const auto& hw = buffer.GetRegisters(); 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); const auto& rt = hw.GetRenderTarget(rt_slot);
auto mask = render_target_mask_slot(hw.GetRenderTargetMask(), rt_slot); auto mask = render_target_mask_slot(hw.GetRenderTargetMask(), rt_slot);
if (ignore_target_mask && rt.base.addr != 0 && mask == 0) { 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) // NOLINTNEXTLINE(readability-function-cognitive-complexity)
void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, CommandBuffer& buffer, void RenderExecutor::ResolveRenderDepthTarget(CommandBuffer& buffer, RenderDepthInfo& r) {
RenderDepthInfo& r) {
KYTY_PROFILER_FUNCTION(); KYTY_PROFILER_FUNCTION();
(void)submit_id;
const auto& hw = buffer.GetRegisters(); const auto& hw = buffer.GetRegisters();
const auto& z = hw.GetDepthRenderTarget(); const auto& z = hw.GetDepthRenderTarget();
const auto& rc = hw.GetRenderControl(); const auto& rc = hw.GetRenderControl();
@@ -235,7 +233,6 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, CommandBuffer&
DepthFatal("layered depth backing range is invalid"); DepthFatal("layered depth backing range is invalid");
} }
r.depth_clear_enable = rc.depth_clear_enable; 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_load_clear_enable = r.depth_clear_enable;
r.depth_clear_value = hw.GetDepthClearValue(); r.depth_clear_value = hw.GetDepthClearValue();
r.depth_test_enable = dc.z_enable; r.depth_test_enable = dc.z_enable;
@@ -23,7 +23,6 @@ struct RenderDepthInfo {
TextureCache::ImageDesc desc; TextureCache::ImageDesc desc;
bool depth_clear_enable = false; bool depth_clear_enable = false;
bool depth_load_clear_enable = false; bool depth_load_clear_enable = false;
bool depth_meta_clear_enable = false;
float depth_clear_value = 0.0f; float depth_clear_value = 0.0f;
bool depth_test_enable = false; bool depth_test_enable = false;
// Effective draw writes; discovery applies test, target-write and clear controls. // 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]); 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, static TextureCache::ImageDesc NullTextureDesc(const ShaderRecompiler::IR::ImageResource& resource,
TextureCache::BindingType binding) { TextureCache::BindingType binding) {
const auto spec = NullTextureSpec(resource);
TextureCache::ImageDesc desc {}; TextureCache::ImageDesc desc {};
desc.info.pixel_format = spec.format; switch (resource.numeric_class) {
desc.info.guest_format = spec.guest_format; 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.type = Prospero::ImageType::kColor2D;
desc.info.extent = {1, 1, 1}; desc.info.extent = {1, 1, 1};
desc.info.resources = {1, 1}; desc.info.resources = {1, 1};
@@ -769,8 +761,7 @@ PreparedBindings RenderExecutor::PrepareBindings(const ShaderStageRuntime& runti
const auto& program = *runtime.program; const auto& program = *runtime.program;
const auto& snapshot = runtime.resources; const auto& snapshot = runtime.resources;
PreparedBindings prepared; PreparedBindings prepared;
prepared.program = runtime.program; prepared.runtime = &runtime;
prepared.snapshot = &runtime.resources;
prepared.images.reserve(program.info.images.size()); prepared.images.reserve(program.info.images.size());
for (uint32_t i = 0; i < program.info.images.size(); i++) { for (uint32_t i = 0; i < program.info.images.size(); i++) {
auto binding = ResolveTexture(program.info.images[i], snapshot.images[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) { void RenderExecutor::FindBuffers(PreparedBindings& prepared) {
KYTY_PROFILER_FUNCTION(); KYTY_PROFILER_FUNCTION();
EXIT_IF(prepared.program == nullptr || prepared.snapshot == nullptr); EXIT_IF(prepared.runtime == nullptr || !*prepared.runtime);
const auto& program = *prepared.program; const auto& program = *prepared.runtime->program;
const auto& snapshot = *prepared.snapshot; const auto& snapshot = prepared.runtime->resources;
auto& cache = m_context.GetBufferCache(); auto& cache = m_context.GetBufferCache();
prepared.buffer_sources.clear(); prepared.buffer_sources.clear();
@@ -820,9 +811,9 @@ void RenderExecutor::FindBuffers(PreparedBindings& prepared) {
void RenderExecutor::RebindBuffers(PreparedBindings& prepared) { void RenderExecutor::RebindBuffers(PreparedBindings& prepared) {
KYTY_PROFILER_FUNCTION(); KYTY_PROFILER_FUNCTION();
EXIT_IF(prepared.program == nullptr || prepared.snapshot == nullptr); EXIT_IF(prepared.runtime == nullptr || !*prepared.runtime);
const auto& program = *prepared.program; const auto& program = *prepared.runtime->program;
const auto& snapshot = *prepared.snapshot; const auto& snapshot = prepared.runtime->resources;
const auto& layout = program.bindings; const auto& layout = program.bindings;
EXIT_IF(prepared.buffer_sources.size() != program.info.buffers.size()); EXIT_IF(prepared.buffer_sources.size() != program.info.buffers.size());
@@ -855,9 +846,9 @@ void RenderExecutor::RebindBuffers(PreparedBindings& prepared) {
void RenderExecutor::RebindImages(PreparedBindings& prepared) { void RenderExecutor::RebindImages(PreparedBindings& prepared) {
KYTY_PROFILER_FUNCTION(); KYTY_PROFILER_FUNCTION();
EXIT_IF(prepared.program == nullptr || prepared.snapshot == nullptr); EXIT_IF(prepared.runtime == nullptr || !*prepared.runtime);
const auto& program = *prepared.program; const auto& program = *prepared.runtime->program;
const auto& snapshot = *prepared.snapshot; const auto& snapshot = prepared.runtime->resources;
auto& images = prepared.images; auto& images = prepared.images;
EXIT_IF(images.size() != program.info.images.size()); EXIT_IF(images.size() != program.info.images.size());
auto& texture_cache = m_context.GetTextureCache(); auto& texture_cache = m_context.GetTextureCache();
@@ -915,8 +906,8 @@ RenderExecutor::PrepareGraphicsBindings(const ShaderStageRuntime& vertex,
if (bindings.pixel) { if (bindings.pixel) {
FindBuffers(*bindings.pixel); FindBuffers(*bindings.pixel);
} }
if (bindings.vertex.program->info.uses_dma || if (bindings.vertex.runtime->program->info.uses_dma ||
(bindings.pixel && bindings.pixel->program->info.uses_dma)) { (bindings.pixel && bindings.pixel->runtime->program->info.uses_dma)) {
m_context.GetGpuResources().PrepareBda(); m_context.GetGpuResources().PrepareBda();
} }
RebindBuffers(bindings.vertex); RebindBuffers(bindings.vertex);
@@ -947,13 +938,13 @@ void RenderExecutor::CommitBindings(CommandBuffer& buffer,
? vk::ShaderStageFlagBits::eFragment ? vk::ShaderStageFlagBits::eFragment
: vk::ShaderStageFlags {}; : vk::ShaderStageFlags {};
for (const auto* prepared: prepared_bindings) { for (const auto* prepared: prepared_bindings) {
EXIT_IF(prepared == nullptr || prepared->program == nullptr || EXIT_IF(prepared == nullptr || prepared->runtime == nullptr || !*prepared->runtime);
prepared->snapshot == nullptr); const auto& program = *prepared->runtime->program;
write_count += prepared->program->bindings.descriptors.size(); write_count += program.bindings.descriptors.size();
for (const auto& binding: prepared->program->bindings.descriptors) { for (const auto& binding: program.bindings.descriptors) {
descriptor_count += NativeDescriptorCount(binding); descriptor_count += NativeDescriptorCount(binding);
} }
const auto shader_stage = NativeShaderStage(prepared->program->stage); const auto shader_stage = NativeShaderStage(program.stage);
push_stages |= shader_stage; push_stages |= shader_stage;
EXIT_IF((pipeline_bind_point == vk::PipelineBindPoint::eGraphics && EXIT_IF((pipeline_bind_point == vk::PipelineBindPoint::eGraphics &&
(shader_stage & GraphicsStages) == vk::ShaderStageFlags {}) || (shader_stage & GraphicsStages) == vk::ShaderStageFlags {}) ||
@@ -968,7 +959,7 @@ void RenderExecutor::CommitBindings(CommandBuffer& buffer,
m_descriptor_writes.reserve(write_count); m_descriptor_writes.reserve(write_count);
for (auto* prepared: prepared_bindings) { for (auto* prepared: prepared_bindings) {
const auto& program = *prepared->program; const auto& program = *prepared->runtime->program;
auto& descriptors = *prepared; auto& descriptors = *prepared;
const auto shader_stage = NativeShaderStage(program.stage); const auto shader_stage = NativeShaderStage(program.stage);
const auto shader_stages = ShaderPipelineStages(shader_stage); const auto shader_stages = ShaderPipelineStages(shader_stage);
@@ -16,9 +16,7 @@
namespace Libs::Graphics { namespace Libs::Graphics {
namespace ShaderRecompiler::IR { struct ShaderStageRuntime;
struct ResourceSnapshot;
}
struct TextureBinding { struct TextureBinding {
ImageId image_id; ImageId image_id;
@@ -35,8 +33,8 @@ struct PreparedBindings {
BufferId id; BufferId id;
}; };
const ShaderRecompiler::IR::CompiledShaderInfo* program = nullptr; // The draw owns the immutable compiled-program/runtime-snapshot association through commit.
const ShaderRecompiler::IR::ResourceSnapshot* snapshot = nullptr; const ShaderStageRuntime* runtime = nullptr;
// Keep the resolved guest range through cache preparation; only the host buffer ID may // Keep the resolved guest range through cache preparation; only the host buffer ID may
// become stale and need resolving again when bindings are rebound. // become stale and need resolving again when bindings are rebound.
std::vector<BufferSource> buffer_sources; std::vector<BufferSource> buffer_sources;
+5 -7
View File
@@ -179,13 +179,11 @@ 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, CommandBuffer& buffer, void ResolveRenderColorTarget(CommandBuffer& buffer, RenderColorInfo& target,
RenderColorInfo& target, uint32_t render_target_slice_offset = 0, uint32_t render_target_slice_offset, uint32_t render_target_slot,
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, CommandBuffer& buffer, void ResolveRenderDepthTarget(CommandBuffer& buffer, RenderDepthInfo& target);
RenderDepthInfo& target); [[nodiscard]] bool PrepareDrawRenderState(CommandBuffer& 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);
@@ -197,7 +195,7 @@ private:
[[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,
const std::optional<PreparedBindings>& pixel = std::nullopt); 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); 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);
+12 -14
View File
@@ -544,11 +544,11 @@ RenderState RenderExecutor::AcquireRenderTargets(CommandBuffer& buffer, RenderCo
!cache.ClearMeta(metadata.range.address)) { !cache.ClearMeta(metadata.range.address)) {
EXIT("failed to acquire HTile metadata for a depth clear\n"); EXIT("failed to acquire HTile metadata for a depth clear\n");
} }
depth.depth_meta_clear_enable = const bool meta_clear =
metadata.kind == ImageMetadataKind::Htile && metadata.kind == ImageMetadataKind::Htile &&
cache.IsMetaCleared(metadata.range.address, depth.desc.view_info.base_layer); 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; depth.depth_load_clear_enable = depth.depth_clear_enable || meta_clear;
if (depth.depth_meta_clear_enable && if (meta_clear &&
!cache.TouchMeta(metadata.range.address, depth.desc.view_info.base_layer, false)) { !cache.TouchMeta(metadata.range.address, depth.desc.view_info.base_layer, false)) {
EXIT("failed to consume HTile clear state\n"); EXIT("failed to consume HTile clear state\n");
} }
@@ -898,13 +898,12 @@ static bool ResolvePrimitiveRestart(const CommandBuffer& buffer, vk::PrimitiveTo
return true; return true;
} }
bool RenderExecutor::PrepareDrawRenderState(uint64_t submit_id, CommandBuffer& buffer, bool RenderExecutor::PrepareDrawRenderState(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) {
auto& ctx = buffer.GetRegisters(); auto& ctx = buffer.GetRegisters();
if (ResolveColorTargets(submit_id, buffer, render_target_slice_offset)) { if (ResolveColorTargets(buffer, render_target_slice_offset)) {
return false; return false;
} }
if (log_setup_phases) { 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++) { for (uint32_t slot = 0; slot < RENDER_COLOR_ATTACHMENTS_MAX; slot++) {
if (slot == 0 || (render_target_mask_slot(ctx.GetRenderTargetMask(), slot) != 0 && if (slot == 0 || (render_target_mask_slot(ctx.GetRenderTargetMask(), slot) != 0 &&
ctx.GetRenderTarget(slot).base.addr != 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); render_target_slice_offset, slot);
if (state.color_info[state.color_count].image_id) { if (state.color_info[state.color_count].image_id) {
state.color_count++; state.color_count++;
@@ -923,7 +922,7 @@ bool RenderExecutor::PrepareDrawRenderState(uint64_t submit_id, CommandBuffer& b
if (log_setup_phases) { if (log_setup_phases) {
LogDrawPhase(draw.name, "ResolveRenderDepthTarget"); LogDrawPhase(draw.name, "ResolveRenderDepthTarget");
} }
ResolveRenderDepthTarget(submit_id, buffer, state.depth_info); ResolveRenderDepthTarget(buffer, state.depth_info);
state.ps_active = DrawHasActivePixelShader(buffer); state.ps_active = DrawHasActivePixelShader(buffer);
if (state.color_count == 0 && !state.depth_info.image_id && !state.ps_active) { 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); index_source.guest_element_size = static_cast<uint32_t>(index_size / args.index_count);
DrawRenderState state {}; 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)) { state)) {
ResetBindings(); ResetBindings();
return; 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}; args.vertex_count, args.instance_count, args.first_instance};
DrawRenderState state {}; 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)) { state)) {
ResetBindings(); ResetBindings();
return; return;
@@ -1440,8 +1439,7 @@ void RenderExecutor::DrawAuto(uint64_t submit_id, CommandBuffer& buffer, const D
ResetBindings(); ResetBindings();
} }
bool RenderExecutor::ResolveColorTargets(uint64_t submit_id, CommandBuffer& buffer, bool RenderExecutor::ResolveColorTargets(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) {
return false; return false;
@@ -1455,8 +1453,8 @@ bool RenderExecutor::ResolveColorTargets(uint64_t submit_id, CommandBuffer& buff
RenderColorInfo src {}; RenderColorInfo src {};
RenderColorInfo dst {}; RenderColorInfo dst {};
ResolveRenderColorTarget(submit_id, buffer, src, render_target_slice_offset, 0, true, true); ResolveRenderColorTarget(buffer, src, render_target_slice_offset, 0, true, true);
ResolveRenderColorTarget(submit_id, buffer, dst, render_target_slice_offset, 1, true, true); ResolveRenderColorTarget(buffer, dst, render_target_slice_offset, 1, true, true);
if (!src.image_id || !dst.image_id) { if (!src.image_id || !dst.image_id) {
return false; return false;
} }
+30 -38
View File
@@ -410,7 +410,7 @@ struct RenderExecutorTestAccess {
std::vector<vk::DescriptorSetLayoutBinding> layout_bindings; std::vector<vk::DescriptorSetLayoutBinding> layout_bindings;
bool compute = false; bool compute = false;
for (const auto *prepared : stages) { for (const auto *prepared : stages) {
const auto &program = *prepared->program; const auto &program = *prepared->runtime->program;
compute |= program.stage == ShaderType::Compute; compute |= program.stage == ShaderType::Compute;
const auto shader_stage = program.stage == ShaderType::Vertex const auto shader_stage = program.stage == ShaderType::Vertex
? vk::ShaderStageFlagBits::eVertex ? vk::ShaderStageFlagBits::eVertex
@@ -460,7 +460,7 @@ struct RenderExecutorTestAccess {
PreparedBindings &bindings) { PreparedBindings &bindings) {
std::array<PreparedBindings *, 1> stages{&bindings}; std::array<PreparedBindings *, 1> stages{&bindings};
auto pipeline = CreateDescriptorPipeline(executor, stages); auto pipeline = CreateDescriptorPipeline(executor, stages);
const auto bind_point = bindings.program->stage == ShaderType::Compute const auto bind_point = bindings.runtime->program->stage == ShaderType::Compute
? vk::PipelineBindPoint::eCompute ? vk::PipelineBindPoint::eCompute
: vk::PipelineBindPoint::eGraphics; : vk::PipelineBindPoint::eGraphics;
executor.CommitBindings(buffer, bind_point, pipeline, stages); executor.CommitBindings(buffer, bind_point, pipeline, stages);
@@ -498,17 +498,15 @@ struct RenderExecutorTestAccess {
} }
static void ResolveRenderDepthTarget(RenderExecutor &executor, static void ResolveRenderDepthTarget(RenderExecutor &executor,
uint64_t submit_id,
CommandBuffer &buffer, CommandBuffer &buffer,
RenderDepthInfo &depth) { RenderDepthInfo &depth) {
executor.ResolveRenderDepthTarget(submit_id, buffer, depth); executor.ResolveRenderDepthTarget(buffer, depth);
} }
static void ResolveRenderColorTarget(RenderExecutor &executor, static void ResolveRenderColorTarget(RenderExecutor &executor,
uint64_t submit_id,
CommandBuffer &buffer, CommandBuffer &buffer,
RenderColorInfo &color, uint32_t slot) { RenderColorInfo &color, uint32_t slot) {
executor.ResolveRenderColorTarget(submit_id, buffer, color, 0, slot); executor.ResolveRenderColorTarget(buffer, color, 0, slot);
} }
static void BindRenderTarget(RenderExecutor &executor, ImageId id) { static void BindRenderTarget(RenderExecutor &executor, ImageId id) {
@@ -1848,15 +1846,12 @@ public:
pixel_program.bindings.push_data_start_dword = 0; pixel_program.bindings.push_data_start_dword = 0;
pixel_program.bindings.user_data_registers = {0, 1}; pixel_program.bindings.user_data_registers = {0, 1};
pixel_program.bindings.memory_offset_dword = 2; pixel_program.bindings.memory_offset_dword = 2;
ShaderRecompiler::IR::ResourceSnapshot snapshot{}; ShaderStageRuntime vertex_runtime{.program = &vertex_program};
PreparedBindings vertex{}; vertex_runtime.resources.user_data = {0x11111111u, 0x22222222u};
vertex.program = &vertex_program; ShaderStageRuntime pixel_runtime{.program = &pixel_program};
vertex.snapshot = &snapshot; pixel_runtime.resources.user_data = {0x33333333u, 0x44444444u};
vertex.shader_data = {0x11111111u, 0x22222222u}; auto vertex = context.GetRenderExecutor().PrepareBindings(vertex_runtime);
PreparedBindings pixel{}; auto pixel = context.GetRenderExecutor().PrepareBindings(pixel_runtime);
pixel.program = &pixel_program;
pixel.snapshot = &snapshot;
pixel.shader_data = {0x33333333u, 0x44444444u};
const auto pipeline = RenderExecutorTestAccess::CommitBindings( const auto pipeline = RenderExecutorTestAccess::CommitBindings(
context.GetRenderExecutor(), scheduler.Current(), vertex, pixel); context.GetRenderExecutor(), scheduler.Current(), vertex, pixel);
@@ -7853,7 +7848,7 @@ public:
RenderColorInfo color{}; RenderColorInfo color{};
RenderExecutorTestAccess::ResolveRenderColorTarget( RenderExecutorTestAccess::ResolveRenderColorTarget(
executor, 1, scheduler.Current(), color, 0); executor, scheduler.Current(), color, 0);
const auto attachment = const auto attachment =
texture_cache.FindRenderTarget(color.image_id, color.desc); texture_cache.FindRenderTarget(color.image_id, color.desc);
const auto &image = texture_cache.GetImage(color.image_id); const auto &image = texture_cache.GetImage(color.image_id);
@@ -7955,7 +7950,7 @@ public:
RenderColorInfo color{}; RenderColorInfo color{};
RenderExecutorTestAccess::ResolveRenderColorTarget( RenderExecutorTestAccess::ResolveRenderColorTarget(
executor, 1, scheduler.Current(), color, 0); executor, scheduler.Current(), color, 0);
const auto attachment = const auto attachment =
texture_cache.FindRenderTarget(color.image_id, color.desc); texture_cache.FindRenderTarget(color.image_id, color.desc);
const auto &image = texture_cache.GetImage(color.image_id); const auto &image = texture_cache.GetImage(color.image_id);
@@ -7988,7 +7983,7 @@ public:
0, {.base_array_slice_index = 7, .last_array_slice_index = 7}); 0, {.base_array_slice_index = 7, .last_array_slice_index = 7});
RenderColorInfo sliced_color{}; RenderColorInfo sliced_color{};
RenderExecutorTestAccess::ResolveRenderColorTarget( RenderExecutorTestAccess::ResolveRenderColorTarget(
executor, 2, scheduler.Current(), sliced_color, 0); executor, scheduler.Current(), sliced_color, 0);
RenderDepthInfo no_depth{}; RenderDepthInfo no_depth{};
const auto sliced_rendering = const auto sliced_rendering =
RenderExecutorTestAccess::AcquireRenderTargets( RenderExecutorTestAccess::AcquireRenderTargets(
@@ -8074,7 +8069,7 @@ public:
.last_array_slice_index = 32}); .last_array_slice_index = 32});
RenderColorInfo volume_color{}; RenderColorInfo volume_color{};
RenderExecutorTestAccess::ResolveRenderColorTarget( RenderExecutorTestAccess::ResolveRenderColorTarget(
executor, 3, scheduler.Current(), volume_color, 0); executor, scheduler.Current(), volume_color, 0);
const auto volume_rendering = const auto volume_rendering =
RenderExecutorTestAccess::AcquireRenderTargets( RenderExecutorTestAccess::AcquireRenderTargets(
executor, scheduler.Current(), &volume_color, 1, no_depth); executor, scheduler.Current(), &volume_color, 1, no_depth);
@@ -8210,7 +8205,7 @@ public:
RenderColorInfo color{}; RenderColorInfo color{};
RenderExecutorTestAccess::ResolveRenderColorTarget( RenderExecutorTestAccess::ResolveRenderColorTarget(
executor, 1, scheduler.Current(), color, 0); executor, scheduler.Current(), color, 0);
RenderDepthInfo no_depth{}; RenderDepthInfo no_depth{};
const auto rendering = RenderExecutorTestAccess::AcquireRenderTargets( const auto rendering = RenderExecutorTestAccess::AcquireRenderTargets(
executor, scheduler.Current(), &color, 1, no_depth); executor, scheduler.Current(), &color, 1, no_depth);
@@ -8603,7 +8598,7 @@ public:
RenderColorInfo color{}; RenderColorInfo color{};
RenderExecutorTestAccess::ResolveRenderColorTarget( RenderExecutorTestAccess::ResolveRenderColorTarget(
executor, 1, scheduler.Current(), color, 0); executor, scheduler.Current(), color, 0);
const auto attachment = const auto attachment =
texture_cache.FindRenderTarget(color.image_id, color.desc); texture_cache.FindRenderTarget(color.image_id, color.desc);
const auto &image = texture_cache.GetImage(color.image_id); const auto &image = texture_cache.GetImage(color.image_id);
@@ -8713,7 +8708,7 @@ public:
RenderColorInfo color{}; RenderColorInfo color{};
RenderExecutorTestAccess::ResolveRenderColorTarget( RenderExecutorTestAccess::ResolveRenderColorTarget(
executor, 1, scheduler.Current(), color, 0); executor, scheduler.Current(), color, 0);
const auto attachment = const auto attachment =
texture_cache.FindRenderTarget(color.image_id, color.desc); texture_cache.FindRenderTarget(color.image_id, color.desc);
const auto &image = texture_cache.GetImage(color.image_id); const auto &image = texture_cache.GetImage(color.image_id);
@@ -9120,8 +9115,8 @@ public:
mipped_storage_descriptor, mipped_storage_descriptor,
overwide_mipped_storage_descriptor, overwide_mipped_storage_descriptor,
overwide_mipped_storage_descriptor}; overwide_mipped_storage_descriptor};
mipped_prepared.program = &mipped_program; ShaderStageRuntime mipped_runtime{&mipped_program, std::move(mipped_snapshot)};
mipped_prepared.snapshot = &mipped_snapshot; mipped_prepared.runtime = &mipped_runtime;
mipped_prepared.images.push_back( mipped_prepared.images.push_back(
std::move(plain_mipped_storage_binding)); std::move(plain_mipped_storage_binding));
mipped_prepared.images.push_back( mipped_prepared.images.push_back(
@@ -9516,9 +9511,8 @@ public:
split_program.info = std::move(split_ir.info); split_program.info = std::move(split_ir.info);
split_program.bindings = std::move(split_ir.bindings); split_program.bindings = std::move(split_ir.bindings);
PreparedBindings split_bindings{}; PreparedBindings split_bindings{};
ShaderRecompiler::IR::ResourceSnapshot split_snapshot{}; ShaderStageRuntime split_runtime{.program = &split_program};
split_bindings.program = &split_program; split_bindings.runtime = &split_runtime;
split_bindings.snapshot = &split_snapshot;
split_bindings.images.push_back( split_bindings.images.push_back(
{split_id, texture_cache.FindTexture(split_id, split_storage_desc), {split_id, texture_cache.FindTexture(split_id, split_storage_desc),
split_storage_desc}); split_storage_desc});
@@ -9594,7 +9588,7 @@ public:
registers.SetRenderControl({}); registers.SetRenderControl({});
RenderDepthInfo disabled_depth{}; RenderDepthInfo disabled_depth{};
RenderExecutorTestAccess::ResolveRenderDepthTarget( RenderExecutorTestAccess::ResolveRenderDepthTarget(
executor, 1, scheduler.Current(), disabled_depth); executor, scheduler.Current(), disabled_depth);
Require(name, "disabled tests with stale depth write enable", Require(name, "disabled tests with stale depth write enable",
!disabled_depth.image_id, !disabled_depth.image_id,
"a dormant depth write bit bound a depth attachment"); "a dormant depth write bit bound a depth attachment");
@@ -9606,7 +9600,7 @@ public:
RenderDepthInfo phased_depth{}; RenderDepthInfo phased_depth{};
RenderExecutorTestAccess::ResolveRenderDepthTarget( RenderExecutorTestAccess::ResolveRenderDepthTarget(
executor, 1, scheduler.Current(), phased_depth); executor, scheduler.Current(), phased_depth);
auto non_texture_compatible_target = phased_depth_target; auto non_texture_compatible_target = phased_depth_target;
non_texture_compatible_target.z_info.texture_compatibility = non_texture_compatible_target.z_info.texture_compatibility =
Prospero::TextureCompatiblePlaneCompression::kDisable; Prospero::TextureCompatiblePlaneCompression::kDisable;
@@ -9615,7 +9609,7 @@ public:
registers.SetDepthRenderTarget(non_texture_compatible_target); registers.SetDepthRenderTarget(non_texture_compatible_target);
RenderDepthInfo non_texture_compatible_depth{}; RenderDepthInfo non_texture_compatible_depth{};
RenderExecutorTestAccess::ResolveRenderDepthTarget( RenderExecutorTestAccess::ResolveRenderDepthTarget(
executor, 1, scheduler.Current(), non_texture_compatible_depth); executor, scheduler.Current(), non_texture_compatible_depth);
Require( Require(
name, "depth texture compatibility identity", name, "depth texture compatibility identity",
phased_depth.image_id && (phased_depth.desc.info.metadata.kind == ImageMetadataKind::Htile) && phased_depth.image_id && (phased_depth.desc.info.metadata.kind == ImageMetadataKind::Htile) &&
@@ -9628,7 +9622,6 @@ public:
phased_depth.desc.info.metadata.range && phased_depth.desc.info.metadata.range &&
phased_depth.desc.info.metadata.stencil_compressed && phased_depth.desc.info.metadata.stencil_compressed &&
!phased_depth.depth_clear_enable && !phased_depth.depth_clear_enable &&
!phased_depth.depth_meta_clear_enable &&
!texture_cache.IsMeta(phased_depth.desc.info.metadata.range.address) && !texture_cache.IsMeta(phased_depth.desc.info.metadata.range.address) &&
!texture_cache.GetImage(phased_depth.image_id).IsGpuModified() && !texture_cache.GetImage(phased_depth.image_id).IsGpuModified() &&
!texture_cache.GetImage(phased_depth.image_id).usage.depth_target, !texture_cache.GetImage(phased_depth.image_id).usage.depth_target,
@@ -9661,7 +9654,7 @@ public:
registers.SetStencilMask(read_only_stencil_mask); registers.SetStencilMask(read_only_stencil_mask);
RenderDepthInfo read_only_depth{}; RenderDepthInfo read_only_depth{};
RenderExecutorTestAccess::ResolveRenderDepthTarget( RenderExecutorTestAccess::ResolveRenderDepthTarget(
executor, 1, scheduler.Current(), read_only_depth); executor, scheduler.Current(), read_only_depth);
Require( Require(
name, "read-only depth/stencil target without write addresses", name, "read-only depth/stencil target without write addresses",
read_only_depth.image_id == phased_depth.image_id && read_only_depth.image_id == phased_depth.image_id &&
@@ -9685,7 +9678,7 @@ public:
registers.SetRenderControl(read_only_render_control); registers.SetRenderControl(read_only_render_control);
RenderDepthInfo read_only_clear_depth{}; RenderDepthInfo read_only_clear_depth{};
RenderExecutorTestAccess::ResolveRenderDepthTarget( RenderExecutorTestAccess::ResolveRenderDepthTarget(
executor, 1, scheduler.Current(), read_only_clear_depth); executor, scheduler.Current(), read_only_clear_depth);
Require(name, "read-only stencil clear suppression", Require(name, "read-only stencil clear suppression",
read_only_clear_depth.image_id == phased_depth.image_id && read_only_clear_depth.image_id == phased_depth.image_id &&
!read_only_clear_depth.stencil_clear_enable && !read_only_clear_depth.stencil_clear_enable &&
@@ -9707,7 +9700,7 @@ public:
phased_rendering.depth_stencil_attachment.image_view != nullptr && phased_rendering.depth_stencil_attachment.image_view != nullptr &&
phased_rendering.num_color_attachments == 0 && phased_rendering.num_color_attachments == 0 &&
phased_rendering.depth_stencil_attachment.has_depth && phased_rendering.depth_stencil_attachment.has_depth &&
phased_depth.depth_meta_clear_enable && phased_rendering.depth_stencil_attachment.depth_clear &&
phased_depth.depth_load_clear_enable && phased_depth.depth_load_clear_enable &&
texture_cache.IsMeta(phased_depth.desc.info.metadata.range.address) && texture_cache.IsMeta(phased_depth.desc.info.metadata.range.address) &&
!texture_cache.IsMetaCleared( !texture_cache.IsMetaCleared(
@@ -9745,7 +9738,7 @@ public:
registers.SetRenderControl(depth_only_render_control); registers.SetRenderControl(depth_only_render_control);
RenderDepthInfo depth_only{}; RenderDepthInfo depth_only{};
RenderExecutorTestAccess::ResolveRenderDepthTarget( RenderExecutorTestAccess::ResolveRenderDepthTarget(
executor, 1, scheduler.Current(), depth_only); executor, scheduler.Current(), depth_only);
Require( Require(
name, "depth-only target with stale stencil state", name, "depth-only target with stale stencil state",
depth_only.image_id && depth_only.desc.view_info.format == vk::Format::eD32Sfloat && depth_only.image_id && depth_only.desc.view_info.format == vk::Format::eD32Sfloat &&
@@ -9870,7 +9863,7 @@ public:
} }
RenderDepthInfo bounds_depth{}; RenderDepthInfo bounds_depth{};
RenderExecutorTestAccess::ResolveRenderDepthTarget( RenderExecutorTestAccess::ResolveRenderDepthTarget(
executor, 1, scheduler.Current(), bounds_depth); executor, scheduler.Current(), bounds_depth);
auto bounds_bindings = RenderExecutorTestAccess::PrepareGraphicsBindings( auto bounds_bindings = RenderExecutorTestAccess::PrepareGraphicsBindings(
executor, bounds_vertex, bounds_pixel, true); executor, bounds_vertex, bounds_pixel, true);
const auto bounds_rendering = RenderExecutorTestAccess::AcquireRenderTargets( const auto bounds_rendering = RenderExecutorTestAccess::AcquireRenderTargets(
@@ -9884,7 +9877,6 @@ public:
bounds_depth.image_id == depth_only.image_id && bounds_depth.image_id == depth_only.image_id &&
bounds_depth.depth_bounds_test_enable && bounds_depth.depth_bounds_test_enable &&
!bounds_depth.depth_write_enable && !bounds_depth.depth_write_enable &&
bounds_depth.depth_meta_clear_enable == (pass == 0) &&
bounds_depth.depth_load_clear_enable == (pass == 0) && bounds_depth.depth_load_clear_enable == (pass == 0) &&
!texture_cache.IsMetaCleared(depth_only_htile_address, 0) && !texture_cache.IsMetaCleared(depth_only_htile_address, 0) &&
bounds_rendering.depth_stencil_attachment.image_layout == readonly_layout && bounds_rendering.depth_stencil_attachment.image_layout == readonly_layout &&
@@ -9955,7 +9947,7 @@ public:
registers.SetStencilMask(shared_stencil_mask); registers.SetStencilMask(shared_stencil_mask);
RenderDepthInfo shared_depth{}; RenderDepthInfo shared_depth{};
RenderExecutorTestAccess::ResolveRenderDepthTarget( RenderExecutorTestAccess::ResolveRenderDepthTarget(
executor, 1, scheduler.Current(), shared_depth); executor, scheduler.Current(), shared_depth);
auto shared_bindings = auto shared_bindings =
RenderExecutorTestAccess::PrepareGraphicsBindings( RenderExecutorTestAccess::PrepareGraphicsBindings(
executor, shared_depth_vertex, shared_depth_pixel, true); executor, shared_depth_vertex, shared_depth_pixel, true);