diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 6051572126..d216b2f1c3 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -1066,13 +1066,38 @@ void RasterizerVulkan::UpdateDynamicStates() { } void RasterizerVulkan::HandleTransformFeedback() { - // Temporary kill-switch: disable transform feedback counters to stop the leak/crash path. - // TODO: Re-enable behind a safe guard once the underlying leak is resolved. - static std::once_flag warn_disabled; - std::call_once(warn_disabled, [] { - LOG_WARNING(Render_Vulkan, "Transform feedback counters temporarily disabled"); - }); - query_cache.CounterEnable(VideoCommon::QueryType::StreamingByteCount, false); + static std::once_flag warn_unsupported; + + const auto& regs = maxwell3d->regs; + if (!device.IsExtTransformFeedbackSupported()) { + std::call_once(warn_unsupported, [&] { + LOG_ERROR(Render_Vulkan, "Transform feedbacks used but not supported"); + }); + query_cache.CounterEnable(VideoCommon::QueryType::StreamingByteCount, false); + return; + } + // Only enable the streamer when TFB is actually active and a buffer is bound; otherwise keep it off + const bool tfb_enabled = regs.transform_feedback_enabled != 0; + const bool has_active_tfb_buffer = [®s] { + for (size_t i = 0; i < Maxwell::Regs::NumTransformFeedbackBuffers; i++) { + if (regs.transform_feedback.buffers[i].enable != 0) { + return true; + } + } + return false; + }(); + + if (!tfb_enabled || !has_active_tfb_buffer) { + query_cache.CounterEnable(VideoCommon::QueryType::StreamingByteCount, false); + return; + } + + if (tfb_enabled) { + UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderType::TessellationInit) || + regs.IsShaderConfigEnabled(Maxwell::ShaderType::Tessellation)); + } + + query_cache.CounterEnable(VideoCommon::QueryType::StreamingByteCount, true); } void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& regs) { diff --git a/src/video_core/shader_environment.cpp b/src/video_core/shader_environment.cpp index e43f59d949..c540432a24 100644 --- a/src/video_core/shader_environment.cpp +++ b/src/video_core/shader_environment.cpp @@ -380,16 +380,8 @@ std::optional GenericEnvironment::TryFindSize() { Tegra::Texture::TICEntry GenericEnvironment::ReadTextureInfo(GPUVAddr tic_addr, u32 tic_limit, bool via_header_index, u32 raw) { const auto handle{Tegra::Texture::TexturePair(raw, via_header_index)}; - u32 tic_index = handle.first; - if (tic_index > tic_limit) { - static std::once_flag warn_oob_tic; - std::call_once(warn_oob_tic, [tic_index, tic_limit, via_header_index] { - LOG_WARNING(Shader, "TIC handle {} exceeds limit {} (via_header_index={}) — clamping", - tic_index, tic_limit, via_header_index); - }); - tic_index = tic_limit > 0 ? tic_limit : 0; - } - const GPUVAddr descriptor_addr{tic_addr + tic_index * sizeof(Tegra::Texture::TICEntry)}; + ASSERT(handle.first <= tic_limit); + const GPUVAddr descriptor_addr{tic_addr + handle.first * sizeof(Tegra::Texture::TICEntry)}; Tegra::Texture::TICEntry entry; gpu_memory->ReadBlock(descriptor_addr, &entry, sizeof(entry)); return entry;