mirror of
https://git.citron-emu.org/citron/emulator
synced 2026-01-25 12:13:27 +00:00
feat(shader): add buffer device address support to shader profile
- Add support_buffer_device_address flag to shader Profile - Add global_memory_tracking_failed flag to shader Info - Track global memory instruction coverage in optimization pass - Prepare infrastructure for global memory emulation via BDA
This commit is contained in:
@@ -31,10 +31,12 @@ void StorageOp(EmitContext& ctx, const IR::Value& binding, ScalarU32 offset,
|
||||
void GlobalStorageOp(EmitContext& ctx, Register address, bool pointer_based, std::string_view expr,
|
||||
std::string_view else_expr = {}) {
|
||||
const size_t num_buffers{ctx.info.storage_buffers_descriptors.size()};
|
||||
size_t buffers_processed{0};
|
||||
for (size_t index = 0; index < num_buffers; ++index) {
|
||||
if (!ctx.info.nvn_buffer_used[index]) {
|
||||
continue;
|
||||
}
|
||||
++buffers_processed;
|
||||
const auto& ssbo{ctx.info.storage_buffers_descriptors[index]};
|
||||
const u64 ssbo_align_mask{~(ctx.profile.min_ssbo_alignment - 1U)};
|
||||
ctx.Add("LDC.U64 DC.x,c{}[{}];" // unaligned_ssbo_addr
|
||||
@@ -65,8 +67,7 @@ void GlobalStorageOp(EmitContext& ctx, Register address, bool pointer_based, std
|
||||
if (!else_expr.empty()) {
|
||||
ctx.Add("{}", else_expr);
|
||||
}
|
||||
const size_t num_used_buffers{ctx.info.nvn_buffer_used.count()};
|
||||
for (size_t index = 0; index < num_used_buffers; ++index) {
|
||||
for (size_t index = 0; index < buffers_processed; ++index) {
|
||||
ctx.Add("ENDIF;");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,6 +110,7 @@ void AddNVNStorageBuffers(IR::Program& program) {
|
||||
throw InvalidArgument("Invalid stage {}", program.stage);
|
||||
}()};
|
||||
auto& descs{program.info.storage_buffers_descriptors};
|
||||
|
||||
for (u32 index = 0; index < num_buffers; ++index) {
|
||||
if (!program.info.nvn_buffer_used[index]) {
|
||||
continue;
|
||||
|
||||
@@ -522,14 +522,26 @@ void Replace(IR::Block& block, IR::Inst& inst, const IR::U32& storage_index,
|
||||
|
||||
void GlobalMemoryToStorageBufferPass(IR::Program& program, const HostTranslateInfo& host_info) {
|
||||
StorageInfo info;
|
||||
size_t total_global_memory_insts{0};
|
||||
for (IR::Block* const block : program.post_order_blocks) {
|
||||
for (IR::Inst& inst : block->Instructions()) {
|
||||
if (!IsGlobalMemory(inst)) {
|
||||
continue;
|
||||
}
|
||||
++total_global_memory_insts;
|
||||
CollectStorageBuffers(*block, inst, info);
|
||||
}
|
||||
}
|
||||
// Log if some global memory instructions couldn't be tracked
|
||||
// NOTE: Previously tried enabling all NVN buffers as fallback when tracking failed,
|
||||
// but this caused crashes due to shader code accessing potentially invalid buffers.
|
||||
// Now we just log a warning - untracked global memory ops will use default behavior.
|
||||
const size_t tracked_insts{info.to_replace.size()};
|
||||
if (total_global_memory_insts > 0 && tracked_insts < total_global_memory_insts) {
|
||||
LOG_WARNING(Shader, "Global memory tracking: {} of {} instructions tracked. "
|
||||
"Untracked ops may cause rendering issues.",
|
||||
tracked_insts, total_global_memory_insts);
|
||||
}
|
||||
for (const StorageBufferAddr& storage_buffer : info.set) {
|
||||
program.info.storage_buffers_descriptors.push_back({
|
||||
.cbuf_index = storage_buffer.index,
|
||||
|
||||
@@ -34,6 +34,7 @@ struct Profile {
|
||||
bool support_int64_atomics{};
|
||||
bool support_derivative_control{};
|
||||
bool support_geometry_shader_passthrough{};
|
||||
bool support_buffer_device_address{};
|
||||
bool support_native_ndc{};
|
||||
bool support_gl_nv_gpu_shader_5{};
|
||||
bool support_gl_amd_gpu_shader_half_float{};
|
||||
|
||||
@@ -313,6 +313,7 @@ struct Info {
|
||||
bool uses_atomic_s32_max{};
|
||||
bool uses_int64_bit_atomics{};
|
||||
bool uses_global_memory{};
|
||||
bool global_memory_tracking_failed{}; // True when some global memory ops couldn't be tracked
|
||||
bool uses_atomic_image_u32{};
|
||||
bool uses_shadow_lod{};
|
||||
bool uses_rescaling_uniform{};
|
||||
|
||||
Reference in New Issue
Block a user