Compare commits

...

22 commits

Author SHA1 Message Date
CamilleLaVey
3ad5257adc [TEST] Conformity to all barriers flags. 2026-05-18 01:41:16 -04:00
lizzie
8d45f7d80c
hotfix-performance: lizzie/togleless-approach-tomo32 (#3975)
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3975
2026-05-18 07:03:59 +02:00
CamilleLaVey
1f228f31b5 another change 2026-05-17 23:12:33 -04:00
CamilleLaVey
abca69759f Revert "test another change" 2026-05-17 23:02:01 -04:00
CamilleLaVey
85d2f62d7e test another change 2026-05-17 21:33:35 -04:00
lizzie
e9280c603e
[vk] tomodachi toggle for hotfix PR (#3974)
mostly just tomo toggle so no konflict

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3974
2026-05-18 02:39:20 +02:00
CamilleLaVey
dac80444b2 small change 2026-05-17 19:24:58 -04:00
CamilleLaVey
1ae24bc298 Fix licenses 2026-05-17 15:23:50 -04:00
lizzie
e91f934f13 fix camile wanted for fragments 2026-05-17 05:18:04 +00:00
CamilleLaVey
1da1bf9260 Revert "[vulkan] Adjustment ResetQueryPool" 2026-05-15 20:11:28 -04:00
CamilleLaVey
bd3c321aed Revert "adjusting to query reset pool" 2026-05-15 20:09:41 -04:00
CamilleLaVey
b5dc68ec39 Revert "another change" 2026-05-15 20:09:02 -04:00
CamilleLaVey
18225180a2 another change 2026-05-15 19:46:11 -04:00
CamilleLaVey
8da4fdd818 adjusting to query reset pool 2026-05-15 19:19:05 -04:00
CamilleLaVey
ba1351452b Return QCOM to presync workaround 2026-05-15 18:35:13 -04:00
CamilleLaVey
d875e3d220 Revert "Small change to fix wrong blittering" 2026-05-15 18:31:23 -04:00
CamilleLaVey
af5167a9be Small change to fix wrong blittering 2026-05-15 17:21:09 -04:00
CamilleLaVey
e5584e57f6 Quick depth clamp removal test 2026-05-15 02:21:18 -04:00
CamilleLaVey
3e6603135f Revert "[spirv] mark sampled image descriptor indices non-uniform (#3900)" 2026-05-14 15:00:27 -04:00
CamilleLaVey
84150336c2 Revert "[android] Fix crash on start any games for many handhelds (Ayaneo, Retroid etc) (#3647)" 2026-05-14 14:12:05 -04:00
CamilleLaVey
dd79368c3e Revert "[shader_recompiler] handle dynamic texture descriptor strides (#3898)" 2026-05-14 13:35:16 -04:00
CamilleLaVey
df7bf0ecc6 WIP: Testing performance regressions Android
revert [shader_recompiler] handle dynamic texture descriptor strides (#3898)

this fixes dynamic texture descriptors that are not laid out as simple 8-byte entries

tested on steam deck/amd

---------------

Performance and graphical issues started from this point and forward, testing is required.

notes
- DynamicDescriptorSizeShift called twice because i moved it away from the struct but doing it this way keeps the patch just in this single file than adding a new derived field in the shared struct (i also think its just a cheap recomputation anyways)
- removed cbuf scanning because i figured out how to do a bounds check statically

credits:
- Mythrax <mythrax@mytrax-rs.org> (identified the 1024 descriptor cap fix in #3897)

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3898
Reviewed-by: crueter <crueter@eden-emu.dev>
2026-05-14 19:30:38 +02:00
19 changed files with 103 additions and 157 deletions

View file

@ -15,7 +15,6 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.graphics.Rect
import android.graphics.drawable.Icon
@ -101,7 +100,6 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
private var romSwapGeneration = 0
private var hasEmulationSession = processHasEmulationSession
private val romSwapStopTimeoutRunnable = Runnable { onRomSwapStopTimeout() }
private val pictureInPictureFailureActions: MutableSet<String> = mutableSetOf()
private fun onRomSwapStopTimeout() {
if (!isWaitingForRomSwapStop) {
@ -268,18 +266,12 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
}
override fun onUserLeaveHint() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ||
!isPictureInPictureSupported() ||
!BooleanSetting.PICTURE_IN_PICTURE.getBoolean() ||
isInPictureInPictureMode
) {
return
}
val pictureInPictureParamsBuilder = PictureInPictureParams.Builder()
.getPictureInPictureActionsBuilder().getPictureInPictureAspectBuilder()
runPictureInPictureAction("enter picture-in-picture mode") {
enterPictureInPictureMode(pictureInPictureParamsBuilder.build())
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
if (BooleanSetting.PICTURE_IN_PICTURE.getBoolean() && !isInPictureInPictureMode) {
val pictureInPictureParamsBuilder = PictureInPictureParams.Builder()
.getPictureInPictureActionsBuilder().getPictureInPictureAspectBuilder()
enterPictureInPictureMode(pictureInPictureParamsBuilder.build())
}
}
}
@ -659,29 +651,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
return this.apply { setActions(pictureInPictureActions) }
}
private fun isPictureInPictureSupported() =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)
private fun runPictureInPictureAction(actionName: String, action: () -> Unit) {
try {
action()
} catch (e: IllegalStateException) {
if (pictureInPictureFailureActions.add(actionName)) {
Log.warning("[PiP] Failed to $actionName: ${e.message}")
}
} catch (e: UnsupportedOperationException) {
if (pictureInPictureFailureActions.add(actionName)) {
Log.warning("[PiP] Failed to $actionName: ${e.message}")
}
}
}
fun buildPictureInPictureParams() {
if (!isPictureInPictureSupported()) {
return
}
val pictureInPictureParamsBuilder = PictureInPictureParams.Builder()
.getPictureInPictureActionsBuilder().getPictureInPictureAspectBuilder()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
@ -691,9 +661,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
BooleanSetting.PICTURE_IN_PICTURE.getBoolean() && isEmulationActive
)
}
runPictureInPictureAction("set picture-in-picture params") {
setPictureInPictureParams(pictureInPictureParamsBuilder.build())
}
setPictureInPictureParams(pictureInPictureParamsBuilder.build())
}
fun displayMultiplayerDialog() {

View file

@ -462,6 +462,13 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct
ctx.AddCapability(spv::Capability::ImageGatherExtended);
ctx.AddCapability(spv::Capability::ImageQuery);
ctx.AddCapability(spv::Capability::SampledBuffer);
// TODO: this usage needs to be tracked properly
if (ctx.profile.support_sampled_image_array_nonuniform_indexing) {
if (ctx.profile.supported_spirv < 0x00010400)
ctx.AddExtension("SPV_EXT_descriptor_indexing");
ctx.AddCapability(spv::Capability::ShaderNonUniform);
ctx.AddCapability(spv::Capability::SampledImageArrayNonUniformIndexing);
}
}
void PatchPhiNodes(IR::Program& program, EmitContext& ctx) {

View file

@ -14,37 +14,10 @@
namespace Shader::Backend::SPIRV {
namespace {
class DescriptorIndex {
public:
explicit DescriptorIndex(EmitContext& ctx, const IR::Value& index)
: id{index.IsImmediate() ? ctx.Const(index.U32()) : ctx.Def(index)},
is_non_uniform{ctx.profile.support_sampled_image_array_nonuniform_indexing &&
!index.IsImmediate()} {
if (!is_non_uniform) {
return;
}
if (ctx.profile.supported_spirv < 0x00010400) {
ctx.AddExtension("SPV_EXT_descriptor_indexing");
}
ctx.AddCapability(spv::Capability::ShaderNonUniform);
ctx.AddCapability(spv::Capability::SampledImageArrayNonUniformIndexing);
Decorate(ctx, id);
}
Id Value() const {
return id;
}
void Decorate(EmitContext& ctx, Id object) const {
if (is_non_uniform) {
ctx.Decorate(object, spv::Decoration::NonUniform);
}
}
private:
Id id;
bool is_non_uniform;
};
[[nodiscard]] bool IsNonUniformDescriptor(EmitContext& ctx, const IR::Value& index) noexcept {
return ctx.profile.support_sampled_image_array_nonuniform_indexing && !index.IsImmediate();
}
class ImageOperands {
public:
@ -221,11 +194,11 @@ private:
Id Texture(EmitContext& ctx, IR::TextureInstInfo info, [[maybe_unused]] const IR::Value& index) {
const TextureDefinition& def{ctx.textures.at(info.descriptor_index)};
if (def.count > 1) {
const DescriptorIndex idx{ctx, index};
const Id pointer{ctx.OpAccessChain(def.pointer_type, def.id, idx.Value())};
idx.Decorate(ctx, pointer);
auto const idx = index.IsImmediate() ? ctx.Const(index.U32()) : ctx.Def(index);
const Id pointer{ctx.OpAccessChain(def.pointer_type, def.id, idx)};
const Id object{ctx.OpLoad(def.sampled_type, pointer)};
idx.Decorate(ctx, object);
if (IsNonUniformDescriptor(ctx, index))
ctx.Decorate(idx, spv::Decoration::NonUniform);
return object;
} else {
return ctx.OpLoad(def.sampled_type, def.id);
@ -244,13 +217,12 @@ Id TextureImage(EmitContext& ctx, IR::TextureInstInfo info, const IR::Value& ind
} else {
const TextureDefinition& def{ctx.textures.at(info.descriptor_index)};
if (def.count > 1) {
const DescriptorIndex idx{ctx, index};
const Id ptr{ctx.OpAccessChain(def.pointer_type, def.id, idx.Value())};
idx.Decorate(ctx, ptr);
const Id object{ctx.OpLoad(def.sampled_type, ptr)};
idx.Decorate(ctx, object);
const Id image{ctx.OpImage(def.image_type, object)};
idx.Decorate(ctx, image);
auto const idx = index.IsImmediate() ? ctx.Const(index.U32()) : ctx.Def(index);
const Id ptr = ctx.OpAccessChain(def.pointer_type, def.id, idx);
const Id object = ctx.OpLoad(def.sampled_type, ptr);
const Id image = ctx.OpImage(def.image_type, object);
if (IsNonUniformDescriptor(ctx, index))
ctx.Decorate(idx, spv::Decoration::NonUniform);
return image;
}
return ctx.OpImage(def.image_type, ctx.OpLoad(def.sampled_type, def.id));

View file

@ -12,6 +12,7 @@
#include <limits>
#include <boost/container/small_vector.hpp>
#include "common/settings.h"
#include "shader_recompiler/environment.h"
#include "shader_recompiler/frontend/ir/basic_block.h"
#include "shader_recompiler/frontend/ir/breadth_first_search.h"
@ -733,9 +734,8 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
break;
}
u32 index;
const u32 size_shift{cbuf.count > 1 ? DynamicDescriptorSizeShift(cbuf.dynamic_offset)
: DESCRIPTOR_SIZE_SHIFT};
u32 count{cbuf.count};
u32 size_shift = cbuf.count > 1 ? DynamicDescriptorSizeShift(cbuf.dynamic_offset) : DESCRIPTOR_SIZE_SHIFT;
u32 count = cbuf.count;
switch (inst->GetOpcode()) {
case IR::Opcode::ImageRead:
case IR::Opcode::ImageAtomicIAdd32:
@ -821,8 +821,7 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
const auto insert_point{IR::Block::InstructionList::s_iterator_to(*inst)};
IR::IREmitter ir{*texture_inst.block, insert_point};
const IR::U32 shift{ir.Imm32(size_shift)};
inst->SetArg(0, ir.UMin(ir.ShiftRightLogical(cbuf.dynamic_offset, shift),
ir.Imm32(count - 1)));
inst->SetArg(0, ir.UMin(ir.ShiftRightLogical(cbuf.dynamic_offset, shift), ir.Imm32(count - 1)));
} else {
inst->SetArg(0, IR::Value{});
}

View file

@ -436,7 +436,7 @@ void TransitionImageLayout(vk::CommandBuffer& cmdbuf, VkImage image, VkImageLayo
.layerCount = 1,
},
};
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, vk::PIPELINE_STAGE_GRAPHICS_COMPUTE,
0, barrier);
}

View file

@ -69,7 +69,7 @@ void TransitionImageLayout(vk::CommandBuffer& cmdbuf, VkImage image, VkImageLayo
.layerCount = 1,
},
};
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, vk::PIPELINE_STAGE_GRAPHICS_COMPUTE,
0, barrier);
}
@ -171,10 +171,10 @@ void DownloadColorImage(vk::CommandBuffer& cmdbuf, VkImage image, VkBuffer buffe
.imageOffset{.x = 0, .y = 0, .z = 0},
.imageExtent{extent},
};
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
read_barrier);
cmdbuf.CopyImageToBuffer(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, copy);
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0,
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, 0,
memory_write_barrier, nullptr, image_write_barrier);
}

View file

@ -8,7 +8,6 @@
#include <array>
#include <cstring>
#include <memory>
#include <mutex>
#include <optional>
#include <string>
#include <vector>
@ -172,11 +171,7 @@ try
RendererVulkan::~RendererVulkan() {
scheduler.RegisterOnSubmit([] {});
scheduler.Finish();
{
std::scoped_lock lock{scheduler.submit_mutex};
void(device.GetLogical().WaitIdle());
}
void(device.GetLogical().WaitIdle());
}
void RendererVulkan::Composite(std::span<const Tegra::FramebufferConfig> framebuffers) {

View file

@ -8,7 +8,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <vulkan/vulkan_core.h>
#include <mutex>
#include "video_core/framebuffer_config.h"
#include "video_core/present.h"
#include "video_core/renderer_vulkan/present/filters.h"
@ -32,10 +31,7 @@ BlitScreen::~BlitScreen() = default;
void BlitScreen::WaitIdle() {
present_manager.WaitPresent();
scheduler.Finish();
{
std::scoped_lock lock{scheduler.submit_mutex};
device.GetLogical().WaitIdle();
}
device.GetLogical().WaitIdle();
}
void BlitScreen::SetWindowAdaptPass() {

View file

@ -437,13 +437,13 @@ void BufferCacheRuntime::CopyBuffer(VkBuffer dst_buffer, VkBuffer src_buffer,
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([src_buffer, dst_buffer, vk_copies, barrier](vk::CommandBuffer cmdbuf) {
if (barrier) {
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER,
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, READ_BARRIER);
}
cmdbuf.CopyBuffer(src_buffer, dst_buffer, VideoCommon::FixSmallVectorADL(vk_copies));
if (barrier) {
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, WRITE_BARRIER);
vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, 0, WRITE_BARRIER);
}
});
}
@ -457,7 +457,7 @@ void BufferCacheRuntime::PreCopyBarrier() {
};
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([](vk::CommandBuffer cmdbuf) {
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, VK_PIPELINE_STAGE_TRANSFER_BIT,
0, READ_BARRIER);
});
}
@ -471,7 +471,7 @@ void BufferCacheRuntime::PostCopyBarrier() {
};
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([](vk::CommandBuffer cmdbuf) {
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, vk::PIPELINE_STAGE_GRAPHICS_COMPUTE,
0, WRITE_BARRIER);
});
}
@ -495,10 +495,10 @@ void BufferCacheRuntime::ClearBuffer(VkBuffer dest_buffer, u32 offset, size_t si
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([dest_buffer, offset, size, value](vk::CommandBuffer cmdbuf) {
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, VK_PIPELINE_STAGE_TRANSFER_BIT,
0, READ_BARRIER);
cmdbuf.FillBuffer(dest_buffer, offset, size, value);
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, vk::PIPELINE_STAGE_GRAPHICS_COMPUTE,
0, WRITE_BARRIER);
});
}

View file

@ -454,8 +454,8 @@ void ConditionalRenderingResolvePass::Resolve(VkBuffer dst_buffer, VkBuffer src_
const VkDescriptorSet set = descriptor_allocator.Commit();
device.GetLogical().UpdateDescriptorSet(set, *descriptor_template, descriptor_data);
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, read_barrier);
cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, read_barrier);
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_COMPUTE, *layout, 0, set, {});
cmdbuf.PushConstants(*layout, VK_SHADER_STAGE_COMPUTE_BIT, uniforms);
@ -537,7 +537,7 @@ void QueriesPrefixScanPass::Run(VkBuffer accumulation_buffer, VkBuffer dst_buffe
cmdbuf.PushConstants(*layout, VK_SHADER_STAGE_COMPUTE_BIT, uniforms);
cmdbuf.Dispatch(1, 1, 1);
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, write_barrier);
vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, 0, write_barrier);
});
}
}
@ -589,9 +589,9 @@ void ASTCDecoderPass::Assemble(Image& image, const StagingBufferRef& map,
.layerCount = VK_REMAINING_ARRAY_LAYERS,
},
};
cmdbuf.PipelineBarrier(is_initialized ? VK_PIPELINE_STAGE_ALL_COMMANDS_BIT
: VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, image_barrier);
cmdbuf.PipelineBarrier(is_initialized ? vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER
: VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, image_barrier);
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, vk_pipeline);
});
for (const VideoCommon::SwizzleParameters& swizzle : swizzles) {
@ -648,7 +648,7 @@ void ASTCDecoderPass::Assemble(Image& image, const StagingBufferRef& map,
},
};
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, image_barrier);
vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, 0, image_barrier);
});
scheduler.Finish();
}

View file

@ -492,8 +492,7 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
device.IsExtExtendedDynamicState3BlendingSupported();
dynamic_features.has_extended_dynamic_state_3_enables =
device.IsExtExtendedDynamicState3EnablesSupported();
dynamic_features.has_dynamic_state3_depth_clamp_enable =
device.SupportsDynamicState3DepthClampEnable();
dynamic_features.has_dynamic_state3_depth_clamp_enable = false;
dynamic_features.has_dynamic_state3_logic_op_enable =
device.SupportsDynamicState3LogicOpEnable();
dynamic_features.has_dynamic_state3_line_stipple_enable =

View file

@ -429,7 +429,7 @@ void PresentManager::CopyToSwapchainImpl(Frame* frame) {
},
};
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, {},
cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, VK_PIPELINE_STAGE_TRANSFER_BIT, {},
{}, {}, pre_barriers);
if (blit_supported) {

View file

@ -157,9 +157,8 @@ public:
ReserveHostQuery();
scheduler.Record([query_pool = current_query_pool,
query_index = current_bank_slot](vk::CommandBuffer cmdbuf) {
query_index = current_bank_slot](vk::CommandBuffer cmdbuf) {
const bool use_precise = Settings::IsGPULevelHigh();
cmdbuf.ResetQueryPool(query_pool, static_cast<u32>(query_index), 1);
cmdbuf.BeginQuery(query_pool, static_cast<u32>(query_index),
use_precise ? VK_QUERY_CONTROL_PRECISE_BIT : 0);
});
@ -221,7 +220,8 @@ public:
}
PauseCounter();
const auto driver_id = device.GetDriverID();
if (driver_id == VK_DRIVER_ID_ARM_PROPRIETARY || driver_id == VK_DRIVER_ID_MESA_TURNIP) {
if (driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY ||
driver_id == VK_DRIVER_ID_ARM_PROPRIETARY || driver_id == VK_DRIVER_ID_MESA_TURNIP) {
pending_sync.clear();
sync_values_stash.clear();
return;
@ -846,7 +846,7 @@ public:
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([](vk::CommandBuffer cmdbuf) {
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, WRITE_BARRIER);
vk::PIPELINE_STAGE_HOST, 0, WRITE_BARRIER);
});
std::scoped_lock lk(flush_guard);
@ -1587,13 +1587,13 @@ void QueryCacheRuntime::Barriers(bool is_prebarrier) {
impl->scheduler.RequestOutsideRenderPassOperationContext();
if (is_prebarrier) {
impl->scheduler.Record([](vk::CommandBuffer cmdbuf) {
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER,
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, READ_BARRIER);
});
} else {
impl->scheduler.Record([](vk::CommandBuffer cmdbuf) {
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, WRITE_BARRIER);
vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER_HOST, 0, WRITE_BARRIER);
});
}
}

View file

@ -580,7 +580,7 @@ void RasterizerVulkan::DispatchCompute() {
.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
};
scheduler.Record([](vk::CommandBuffer cmdbuf) { cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
scheduler.Record([](vk::CommandBuffer cmdbuf) { cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
0, READ_BARRIER); });
scheduler.Record([dim](vk::CommandBuffer cmdbuf) { cmdbuf.Dispatch(dim[0], dim[1], dim[2]); });

View file

@ -270,8 +270,8 @@ u64 Scheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_se
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
};
upload_cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, WRITE_BARRIER);
upload_cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
| VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, WRITE_BARRIER);
upload_cmdbuf.End();
cmdbuf.End();
@ -375,7 +375,7 @@ void Scheduler::EndRenderPass()
}
cmdbuf.EndRenderPass();
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::PIPELINE_STAGE_GRAPHICS_COMPUTE,
0, nullptr, nullptr, vk::Span(barriers.data(), num_images));
});

View file

@ -860,12 +860,12 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const
.subresourceRange = subresource_range,
},
};
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
0, nullptr, nullptr, read_barriers);
cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, VK_PIPELINE_STAGE_TRANSFER_BIT,
0, nullptr, nullptr, read_barriers);
cmdbuf.BlitImage(src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst_image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, regions, vk_filter);
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
0, nullptr, nullptr, write_barriers);
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, vk::PIPELINE_STAGE_GRAPHICS_COMPUTE,
0, nullptr, nullptr, write_barriers);
});
}
} // Anonymous namespace
@ -1123,19 +1123,19 @@ void TextureCacheRuntime::ReinterpretImage(Image& dst, Image& src,
.subresourceRange = dst_range.SubresourceRange(dst_aspect_mask),
},
};
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
0, {}, {}, pre_barriers);
cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, VK_PIPELINE_STAGE_TRANSFER_BIT,
0, {}, {}, pre_barriers);
cmdbuf.CopyImageToBuffer(src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, copy_buffer,
vk_in_copies);
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
0, WRITE_BARRIER, nullptr, middle_in_barrier);
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, vk::PIPELINE_STAGE_GRAPHICS_COMPUTE,
0, WRITE_BARRIER, nullptr, middle_in_barrier);
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
0, READ_BARRIER, {}, middle_out_barrier);
cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, VK_PIPELINE_STAGE_TRANSFER_BIT,
0, READ_BARRIER, {}, middle_out_barrier);
cmdbuf.CopyBufferToImage(copy_buffer, dst_image, VK_IMAGE_LAYOUT_GENERAL, vk_out_copies);
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
0, {}, {}, post_barriers);
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, vk::PIPELINE_STAGE_GRAPHICS_COMPUTE,
0, {}, {}, post_barriers);
});
}
@ -1261,8 +1261,8 @@ void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst
.layerCount = VK_REMAINING_ARRAY_LAYERS,
},
};
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
0, nullptr, nullptr, read_barriers);
cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, VK_PIPELINE_STAGE_TRANSFER_BIT,
0, nullptr, nullptr, read_barriers);
if (is_resolve) {
cmdbuf.ResolveImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
@ -1274,8 +1274,8 @@ void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst
src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
MakeImageBlit(dst_region, src_region, dst_layers, src_layers), vk_filter);
}
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
0, write_barrier);
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, vk::PIPELINE_STAGE_GRAPHICS_COMPUTE,
0, write_barrier);
});
}
@ -1852,7 +1852,7 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<size_t> o
.layerCount = VK_REMAINING_ARRAY_LAYERS,
},
};
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, VK_PIPELINE_STAGE_TRANSFER_BIT,
0, read_barrier);
for (size_t index = 0; index < buffers.size(); index++) {
@ -1884,7 +1884,7 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<size_t> o
.layerCount = VK_REMAINING_ARRAY_LAYERS,
},
};
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, vk::PIPELINE_STAGE_GRAPHICS_COMPUTE,
0, memory_write_barrier, nullptr, image_write_barrier);
});
return;
@ -1919,7 +1919,7 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<size_t> o
.layerCount = VK_REMAINING_ARRAY_LAYERS,
},
};
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, VK_PIPELINE_STAGE_TRANSFER_BIT,
0, read_barrier);
for (size_t index = 0; index < buffers.size(); index++) {
@ -1951,7 +1951,7 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<size_t> o
.layerCount = VK_REMAINING_ARRAY_LAYERS,
},
};
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, vk::PIPELINE_STAGE_GRAPHICS_COMPUTE,
0, memory_write_barrier, nullptr, image_write_barrier);
});
}
@ -2524,8 +2524,8 @@ void TextureCacheRuntime::TransitionImageLayout(Image& image) {
};
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([barrier](vk::CommandBuffer cmdbuf) {
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, barrier);
cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE,
vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, 0, barrier);
});
}
}

View file

@ -486,11 +486,15 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
CollectToolingInfo();
if (is_qualcomm) {
// Qualcomm Adreno GPUs doesn't handle scaled vertex attributes; keep emulation enabled
LOG_WARNING(Render_Vulkan,
"Qualcomm drivers require scaled vertex format emulation");
must_emulate_scaled_formats = true;
LOG_WARNING(Render_Vulkan,
"Qualcomm drivers require scaled vertex format emulation; forcing fallback");
"Qualcomm drivers have broken provoking vertex");
RemoveExtension(extensions.provoking_vertex, VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME);
LOG_WARNING(Render_Vulkan,
"Qualcomm drivers have slow push descriptor implementation");
RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
LOG_WARNING(Render_Vulkan,
"Disabling shader float controls and 64-bit integer features on Qualcomm proprietary drivers");
RemoveExtension(extensions.shader_float_controls, VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME);

View file

@ -123,7 +123,6 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
X(vkCmdEndDebugUtilsLabelEXT);
X(vkCmdFillBuffer);
X(vkCmdPipelineBarrier);
X(vkCmdResetQueryPool);
X(vkCmdPushConstants);
X(vkCmdPushDescriptorSetWithTemplateKHR);
X(vkCmdSetBlendConstants);

View file

@ -146,6 +146,18 @@ inline VkResult Filter(VkResult result) {
return result;
}
inline constexpr VkPipelineStageFlags PIPELINE_STAGE_GRAPHICS_COMPUTE =
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
inline constexpr VkPipelineStageFlags PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER =
PIPELINE_STAGE_GRAPHICS_COMPUTE | VK_PIPELINE_STAGE_TRANSFER_BIT;
inline constexpr VkPipelineStageFlags PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER_HOST =
PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER | VK_PIPELINE_STAGE_HOST_BIT;
inline constexpr VkPipelineStageFlags PIPELINE_STAGE_HOST = VK_PIPELINE_STAGE_HOST_BIT;
/// Table holding Vulkan instance function pointers.
struct InstanceDispatch {
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr{};
@ -225,7 +237,6 @@ struct DeviceDispatch : InstanceDispatch {
PFN_vkCmdEndTransformFeedbackEXT vkCmdEndTransformFeedbackEXT{};
PFN_vkCmdFillBuffer vkCmdFillBuffer{};
PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier{};
PFN_vkCmdResetQueryPool vkCmdResetQueryPool{};
PFN_vkCmdPushConstants vkCmdPushConstants{};
PFN_vkCmdPushDescriptorSetWithTemplateKHR vkCmdPushDescriptorSetWithTemplateKHR{};
PFN_vkCmdResolveImage vkCmdResolveImage{};
@ -1169,10 +1180,6 @@ public:
dld->vkCmdEndQuery(handle, query_pool, query);
}
void ResetQueryPool(VkQueryPool query_pool, u32 first_query, u32 query_count) const noexcept {
dld->vkCmdResetQueryPool(handle, query_pool, first_query, query_count);
}
void BindDescriptorSets(VkPipelineBindPoint bind_point, VkPipelineLayout layout, u32 first,
Span<VkDescriptorSet> sets, Span<u32> dynamic_offsets) const noexcept {
dld->vkCmdBindDescriptorSets(handle, bind_point, layout, first, sets.size(), sets.data(),