forked from eden-emu/eden
Compare commits
9 commits
e4331fc703
...
f50488b1a6
Author | SHA1 | Date | |
---|---|---|---|
f50488b1a6 | |||
39d1c16bc8 | |||
c36cc0d3ee | |||
444b9f361e | |||
bd944b71d5 | |||
1465757ded | |||
fc88638693 | |||
2b62a41942 | |||
c8d6f23129 |
24 changed files with 261 additions and 154 deletions
|
@ -218,13 +218,7 @@ if (YUZU_USE_BUNDLED_VCPKG)
|
|||
|
||||
include(CPMUtil)
|
||||
|
||||
AddPackage(
|
||||
NAME vcpkg
|
||||
DOWNLOAD_ONLY YES
|
||||
URL "https://github.com/microsoft/vcpkg.git"
|
||||
GIT_TAG "ea2a964f93"
|
||||
SHA "ea2a964f93"
|
||||
)
|
||||
CPMAddPackage("gh:microsoft/vcpkg#10d3b37514")
|
||||
|
||||
include(${vcpkg_SOURCE_DIR}/scripts/buildsystems/vcpkg.cmake)
|
||||
elseif(NOT "$ENV{VCPKG_TOOLCHAIN_FILE}" STREQUAL "")
|
||||
|
|
|
@ -30,7 +30,7 @@ function(AddPackage)
|
|||
cmake_parse_arguments(PKG_ARGS "" "${oneValueArgs}" "${multiValueArgs}" "${ARGN}")
|
||||
|
||||
if (NOT DEFINED PKG_ARGS_NAME)
|
||||
message(FATAL_ERROR "CPMUtil: No package name defined")
|
||||
message(FATAL_ERROR "[CPMUtil] ${PKG_ARGS_NAME}: No package name defined")
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED PKG_ARGS_URL)
|
||||
|
@ -38,21 +38,21 @@ function(AddPackage)
|
|||
set(PKG_GIT_URL https://github.com/${PKG_ARGS_REPO})
|
||||
set(PKG_URL "${PKG_GIT_URL}/archive/${PKG_ARGS_SHA}.zip")
|
||||
else()
|
||||
message(FATAL_ERROR "CPMUtil: No custom URL and no repository + sha defined")
|
||||
message(FATAL_ERROR "[CPMUtil] ${PKG_ARGS_NAME}: No custom URL and no repository + sha defined")
|
||||
endif()
|
||||
else()
|
||||
set(PKG_URL ${PKG_ARGS_URL})
|
||||
set(PKG_GIT_URL ${PKG_URL})
|
||||
endif()
|
||||
|
||||
message(STATUS "CPMUtil: Downloading package ${PKG_ARGS_NAME} from ${PKG_URL}")
|
||||
message(STATUS "[CPMUtil] ${PKG_ARGS_NAME}: Downloading package from ${PKG_URL}")
|
||||
|
||||
if (NOT DEFINED PKG_ARGS_KEY)
|
||||
if (DEFINED PKG_ARGS_SHA)
|
||||
string(SUBSTRING ${PKG_ARGS_SHA} 0 4 PKG_KEY)
|
||||
message(STATUS "CPMUtil: No custom key defined, using ${PKG_KEY} from sha")
|
||||
message(STATUS "[CPMUtil] ${PKG_ARGS_NAME}: No custom key defined, using ${PKG_KEY} from sha")
|
||||
else()
|
||||
message(FATAL_ERROR "CPMUtil: No custom key and no commit sha defined")
|
||||
message(FATAL_ERROR "[CPMUtil] ${PKG_ARGS_NAME}: No custom key and no commit sha defined")
|
||||
endif()
|
||||
else()
|
||||
set(PKG_KEY ${PKG_ARGS_KEY})
|
||||
|
@ -99,7 +99,7 @@ function(AddPackage)
|
|||
elseif(DEFINED PKG_ARGS_VERSION)
|
||||
set_property(GLOBAL APPEND PROPERTY CPM_PACKAGE_SHAS ${PKG_ARGS_VERSION})
|
||||
else()
|
||||
message(WARNING "CPMUtil: Package ${PKG_ARGS_NAME} has no specified sha or version")
|
||||
message(WARNING "[CPMUtil] Package ${PKG_ARGS_NAME} has no specified sha or version")
|
||||
set_property(GLOBAL APPEND PROPERTY CPM_PACKAGE_SHAS "unknown")
|
||||
endif()
|
||||
else()
|
||||
|
|
|
@ -39,6 +39,7 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
|
|||
SOC_OVERLAY_POSITION("soc_overlay_position"),
|
||||
MEMORY_LAYOUT("memory_layout_mode"),
|
||||
FSR_SHARPENING_SLIDER("fsr_sharpening_slider"),
|
||||
RENDERER_SAMPLE_SHADING_FRACTION("sample_shading_fraction"),
|
||||
FAST_CPU_TIME("fast_cpu_time"),
|
||||
CPU_TICKS("cpu_ticks"),
|
||||
FAST_GPU_TIME("fast_gpu_time"),
|
||||
|
@ -57,7 +58,7 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
|
|||
OFFLINE_WEB_APPLET("offline_web_applet_mode"),
|
||||
LOGIN_SHARE_APPLET("login_share_applet_mode"),
|
||||
WIFI_WEB_AUTH_APPLET("wifi_web_auth_applet_mode"),
|
||||
MY_PAGE_APPLET("my_page_applet_mode")
|
||||
MY_PAGE_APPLET("my_page_applet_mode"),
|
||||
;
|
||||
|
||||
override fun getInt(needsGlobal: Boolean): Int = NativeConfig.getInt(key, needsGlobal)
|
||||
|
|
|
@ -159,6 +159,14 @@ abstract class SettingsItem(
|
|||
descriptionId = R.string.sample_shading_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SliderSetting(
|
||||
IntSetting.RENDERER_SAMPLE_SHADING_FRACTION,
|
||||
titleId = R.string.sample_shading_fraction,
|
||||
descriptionId = R.string.sample_shading_fraction_description,
|
||||
units = "%"
|
||||
)
|
||||
)
|
||||
put(
|
||||
SliderSetting(
|
||||
ShortSetting.RENDERER_SPEED_LIMIT,
|
||||
|
|
|
@ -443,6 +443,7 @@ class SettingsFragmentPresenter(
|
|||
add(BooleanSetting.RENDERER_PROVOKING_VERTEX.key)
|
||||
add(BooleanSetting.RENDERER_DESCRIPTOR_INDEXING.key)
|
||||
add(BooleanSetting.RENDERER_SAMPLE_SHADING.key)
|
||||
add(IntSetting.RENDERER_SAMPLE_SHADING_FRACTION.key)
|
||||
|
||||
add(HeaderSetting(R.string.veil_renderer))
|
||||
add(BooleanSetting.ENABLE_RAII.key)
|
||||
|
|
|
@ -82,6 +82,8 @@
|
|||
<string name="descriptor_indexing_description">Improves texture and buffer handling, as well as the Maxwell translation layer. Supported by some Vulkan 1.1 GPUs and all Vulkan 1.2+ GPUs.</string>
|
||||
<string name="sample_shading">Sample Shading</string>
|
||||
<string name="sample_shading_description">Allows the fragment shader to execute per sample in a multi-sampled fragment instead once per fragment. Improves graphics quality at the cost of some performance. Only Vulkan 1.1+ devices support this extension.</string>
|
||||
<string name="sample_shading_fraction">Sample Shading Fraction</string>
|
||||
<string name="sample_shading_fraction_description">The intensity of the sample shading pass. Higher values improve quality more but also reduce performance to a greater extent.</string>
|
||||
|
||||
<string name="veil_renderer">Renderer</string>
|
||||
<string name="enable_raii">RAII</string>
|
||||
|
|
|
@ -527,7 +527,17 @@ struct Values {
|
|||
|
||||
SwitchableSetting<bool> provoking_vertex{linkage, false, "provoking_vertex", Category::RendererExtensions};
|
||||
SwitchableSetting<bool> descriptor_indexing{linkage, false, "descriptor_indexing", Category::RendererExtensions};
|
||||
SwitchableSetting<bool> sample_shading{linkage, false, "sample_shading", Category::RendererExtensions};
|
||||
SwitchableSetting<bool> sample_shading{linkage, false, "sample_shading", Category::RendererExtensions, Specialization::Paired};
|
||||
SwitchableSetting<u32, true> sample_shading_fraction{linkage,
|
||||
50,
|
||||
0,
|
||||
100,
|
||||
"sample_shading_fraction",
|
||||
Category::RendererExtensions,
|
||||
Specialization::Scalar,
|
||||
true,
|
||||
false,
|
||||
&sample_shading};
|
||||
|
||||
Setting<bool> renderer_debug{linkage, false, "debug", Category::RendererDebug};
|
||||
Setting<bool> renderer_shader_feedback{linkage, false, "shader_feedback",
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
|
||||
// SPDX-FileCopyrightText: 2021 Skyline Team and Contributors
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
@ -312,7 +315,7 @@ NvResult nvhost_as_gpu::Remap(std::span<IoctlRemapEntry> entries) {
|
|||
NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params) {
|
||||
LOG_DEBUG(Service_NVDRV,
|
||||
"called, flags={:X}, nvmap_handle={:X}, buffer_offset={}, mapping_size={}"
|
||||
", offset={}",
|
||||
", offset=0x{:X}",
|
||||
params.flags, params.handle, params.buffer_offset, params.mapping_size,
|
||||
params.offset);
|
||||
|
||||
|
@ -406,19 +409,21 @@ NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params) {
|
|||
mapping_map[params.offset] = mapping;
|
||||
}
|
||||
|
||||
map_buffer_offsets.insert(params.offset);
|
||||
|
||||
return NvResult::Success;
|
||||
}
|
||||
|
||||
NvResult nvhost_as_gpu::UnmapBuffer(IoctlUnmapBuffer& params) {
|
||||
LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset);
|
||||
if (map_buffer_offsets.find(params.offset) != map_buffer_offsets.end()) {
|
||||
LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset);
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(mutex);
|
||||
|
||||
if (!vm.initialised) {
|
||||
return NvResult::BadValue;
|
||||
}
|
||||
if (!vm.initialised) {
|
||||
return NvResult::BadValue;
|
||||
}
|
||||
|
||||
try {
|
||||
auto mapping{mapping_map.at(params.offset)};
|
||||
|
||||
if (!mapping->fixed) {
|
||||
|
@ -440,10 +445,8 @@ NvResult nvhost_as_gpu::UnmapBuffer(IoctlUnmapBuffer& params) {
|
|||
nvmap.UnpinHandle(mapping->handle);
|
||||
|
||||
mapping_map.erase(params.offset);
|
||||
} catch (const std::out_of_range&) {
|
||||
LOG_WARNING(Service_NVDRV, "Couldn't find region to unmap at 0x{:X}", params.offset);
|
||||
map_buffer_offsets.erase(params.offset);
|
||||
}
|
||||
|
||||
return NvResult::Success;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
|
||||
// SPDX-FileCopyrightText: 2021 Skyline Team and Contributors
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
@ -10,6 +13,7 @@
|
|||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include "common/address_space.h"
|
||||
|
@ -109,6 +113,8 @@ private:
|
|||
};
|
||||
static_assert(sizeof(IoctlRemapEntry) == 20, "IoctlRemapEntry is incorrect size");
|
||||
|
||||
std::unordered_set<s64_le> map_buffer_offsets{};
|
||||
|
||||
struct IoctlMapBufferEx {
|
||||
MappingFlags flags{}; // bit0: fixed_offset, bit2: cacheable
|
||||
u32_le kind{}; // -1 is default
|
||||
|
|
|
@ -138,7 +138,6 @@ endif()
|
|||
|
||||
if (DYNARMIC_USE_BUNDLED_EXTERNALS)
|
||||
set(CMAKE_DISABLE_FIND_PACKAGE_biscuit ON)
|
||||
set(CMAKE_DISABLE_FIND_PACKAGE_Catch2 ON)
|
||||
set(CMAKE_DISABLE_FIND_PACKAGE_fmt ON)
|
||||
set(CMAKE_DISABLE_FIND_PACKAGE_mcl ON)
|
||||
set(CMAKE_DISABLE_FIND_PACKAGE_oaknut ON)
|
||||
|
|
8
src/dynarmic/externals/CMakeLists.txt
vendored
8
src/dynarmic/externals/CMakeLists.txt
vendored
|
@ -28,6 +28,7 @@ if ("riscv" IN_LIST ARCHITECTURE)
|
|||
REPO "lioncash/biscuit"
|
||||
SHA 76b0be8dae
|
||||
HASH 47d55ed02d032d6cf3dc107c6c0a9aea686d5f25aefb81d1af91db027b6815bd5add1755505e19d76625feeb17aa2db6cd1668fe0dad2e6a411519bde6ca4489
|
||||
BUNDLED_PACKAGE ${DYNARMIC_USE_BUNDLED_EXTERNALS}
|
||||
)
|
||||
endif()
|
||||
|
||||
|
@ -92,12 +93,17 @@ AddPackage(
|
|||
|
||||
# zydis
|
||||
|
||||
# TODO(crueter): maybe it's just Gentoo but zydis system package really sucks
|
||||
if ("x86_64" IN_LIST ARCHITECTURE)
|
||||
AddPackage(
|
||||
NAME Zycore
|
||||
REPO "zyantific/zycore-c"
|
||||
SHA 75a36c45ae
|
||||
HASH 15aa399f39713e042c4345bc3175c82f14dca849fde2a21d4f591f62c43e227b70d868d8bb86beb5f4eb68b1d6bd3792cdd638acf89009e787e3d10ee7401924
|
||||
OPTIONS
|
||||
"CMAKE_DISABLE_FIND_PACKAGE_Doxygen ON"
|
||||
# BUNDLED_PACKAGE ${DYNARMIC_USE_BUNDLED_EXTERNALS}
|
||||
EXCLUDE_FROM_ALL ON
|
||||
)
|
||||
|
||||
AddPackage(
|
||||
|
@ -112,5 +118,7 @@ if ("x86_64" IN_LIST ARCHITECTURE)
|
|||
"ZYDIS_BUILD_DOXYGEN OFF"
|
||||
"ZYAN_ZYCORE_PATH ${Zycore_SOURCE_DIR}"
|
||||
"CMAKE_DISABLE_FIND_PACKAGE_Doxygen ON"
|
||||
# BUNDLED_PACKAGE ${DYNARMIC_USE_BUNDLED_EXTERNALS}
|
||||
EXCLUDE_FROM_ALL ON
|
||||
)
|
||||
endif()
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -518,7 +521,7 @@ void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, VkImageView
|
|||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
scheduler.Record([this, dst_framebuffer, src_image_view, src_image, src_sampler, dst_region,
|
||||
src_region, src_size, pipeline, layout](vk::CommandBuffer cmdbuf) {
|
||||
TransitionImageLayout(cmdbuf, src_image, VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL);
|
||||
TransitionImageLayout(cmdbuf, src_image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
BeginRenderPass(cmdbuf, dst_framebuffer);
|
||||
const VkDescriptorSet descriptor_set = one_texture_descriptor_allocator.Commit();
|
||||
UpdateOneTextureDescriptorSet(device, descriptor_set, src_sampler, src_image_view);
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -55,7 +58,7 @@ ComputePipeline::ComputePipeline(const Device& device_, vk::PipelineCache& pipel
|
|||
.requiredSubgroupSize = GuestWarpSize,
|
||||
};
|
||||
VkPipelineCreateFlags flags{};
|
||||
if (device.IsKhrPipelineExecutablePropertiesEnabled()) {
|
||||
if (device.IsKhrPipelineExecutablePropertiesEnabled() && Settings::values.renderer_debug.GetValue()) {
|
||||
flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR;
|
||||
}
|
||||
pipeline = device.GetLogical().CreateComputePipeline(
|
||||
|
|
|
@ -94,7 +94,7 @@ bool IsLine(VkPrimitiveTopology topology) {
|
|||
VK_PRIMITIVE_TOPOLOGY_LINE_LIST, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
|
||||
// VK_PRIMITIVE_TOPOLOGY_LINE_LOOP_EXT,
|
||||
};
|
||||
return std::ranges::find(line_topologies, topology) == line_topologies.end();
|
||||
return std::ranges::find(line_topologies, topology) != line_topologies.end();
|
||||
}
|
||||
|
||||
VkViewportSwizzleNV UnpackViewportSwizzle(u16 swizzle) {
|
||||
|
@ -502,7 +502,6 @@ bool GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
|||
void GraphicsPipeline::ConfigureDraw(const RescalingPushConstant& rescaling,
|
||||
const RenderAreaPushConstant& render_area) {
|
||||
scheduler.RequestRenderpass(texture_cache.GetFramebuffer());
|
||||
|
||||
if (!is_built.load(std::memory_order::relaxed)) {
|
||||
// Wait for the pipeline to be built
|
||||
scheduler.Record([this](vk::CommandBuffer) {
|
||||
|
@ -744,7 +743,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
|
|||
.flags = 0,
|
||||
.rasterizationSamples = MaxwellToVK::MsaaMode(key.state.msaa_mode),
|
||||
.sampleShadingEnable = Settings::values.sample_shading.GetValue() ? VK_TRUE : VK_FALSE,
|
||||
.minSampleShading = 0.0f,
|
||||
.minSampleShading = static_cast<float>(Settings::values.sample_shading_fraction.GetValue()) / 100.0f,
|
||||
.pSampleMask = nullptr,
|
||||
.alphaToCoverageEnable = key.state.alpha_to_coverage_enabled != 0 ? VK_TRUE : VK_FALSE,
|
||||
.alphaToOneEnable = key.state.alpha_to_one_enabled != 0 ? VK_TRUE : VK_FALSE,
|
||||
|
@ -902,7 +901,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
|
|||
*/
|
||||
}
|
||||
VkPipelineCreateFlags flags{};
|
||||
if (device.IsKhrPipelineExecutablePropertiesEnabled()) {
|
||||
if (device.IsKhrPipelineExecutablePropertiesEnabled() && Settings::values.renderer_debug.GetValue()) {
|
||||
flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "video_core/renderer_vulkan/vk_texture_cache.h"
|
||||
#include "common/bit_util.h"
|
||||
#include "common/common_types.h"
|
||||
#include "video_core/engines/draw_manager.h"
|
||||
|
@ -116,11 +116,11 @@ struct HostSyncValues {
|
|||
class SamplesStreamer : public BaseStreamer {
|
||||
public:
|
||||
explicit SamplesStreamer(size_t id_, QueryCacheRuntime& runtime_,
|
||||
VideoCore::RasterizerInterface* rasterizer_, const Device& device_,
|
||||
VideoCore::RasterizerInterface* rasterizer_, TextureCache& texture_cache_, const Device& device_,
|
||||
Scheduler& scheduler_, const MemoryAllocator& memory_allocator_,
|
||||
ComputePassDescriptorQueue& compute_pass_descriptor_queue,
|
||||
DescriptorPool& descriptor_pool)
|
||||
: BaseStreamer(id_), runtime{runtime_}, rasterizer{rasterizer_}, device{device_},
|
||||
: BaseStreamer(id_), texture_cache{texture_cache_}, runtime{runtime_}, rasterizer{rasterizer_}, device{device_},
|
||||
scheduler{scheduler_}, memory_allocator{memory_allocator_} {
|
||||
current_bank = nullptr;
|
||||
current_query = nullptr;
|
||||
|
@ -153,16 +153,33 @@ public:
|
|||
if (has_started) {
|
||||
return;
|
||||
}
|
||||
|
||||
ReserveHostQuery();
|
||||
|
||||
// Ensure outside render pass
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
|
||||
// Reset query pool outside render pass
|
||||
scheduler.Record([query_pool = current_query_pool,
|
||||
query_index = current_bank_slot](vk::CommandBuffer cmdbuf) {
|
||||
query_index = current_bank_slot](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.ResetQueryPool(query_pool, static_cast<u32>(query_index), 1);
|
||||
});
|
||||
|
||||
// Manually restart the render pass (required for vkCmdClearAttachments, etc.)
|
||||
scheduler.RequestRenderpass(texture_cache.GetFramebuffer());
|
||||
|
||||
// Begin query inside the newly started render pass
|
||||
scheduler.Record([query_pool = current_query_pool,
|
||||
query_index = current_bank_slot](vk::CommandBuffer cmdbuf) {
|
||||
const bool use_precise = Settings::IsGPULevelHigh();
|
||||
cmdbuf.BeginQuery(query_pool, static_cast<u32>(query_index),
|
||||
use_precise ? VK_QUERY_CONTROL_PRECISE_BIT : 0);
|
||||
});
|
||||
|
||||
has_started = true;
|
||||
}
|
||||
|
||||
|
||||
void PauseCounter() override {
|
||||
if (!has_started) {
|
||||
return;
|
||||
|
@ -404,7 +421,7 @@ private:
|
|||
size_slots -= amount;
|
||||
}
|
||||
}
|
||||
|
||||
TextureCache& texture_cache;
|
||||
template <bool is_ordered, typename Func>
|
||||
void ApplyBanksWideOp(std::vector<size_t>& queries, Func&& func) {
|
||||
std::conditional_t<is_ordered, std::map<size_t, std::pair<size_t, size_t>>,
|
||||
|
@ -1163,13 +1180,13 @@ struct QueryCacheRuntimeImpl {
|
|||
const MemoryAllocator& memory_allocator_, Scheduler& scheduler_,
|
||||
StagingBufferPool& staging_pool_,
|
||||
ComputePassDescriptorQueue& compute_pass_descriptor_queue,
|
||||
DescriptorPool& descriptor_pool)
|
||||
DescriptorPool& descriptor_pool, TextureCache& texture_cache_)
|
||||
: rasterizer{rasterizer_}, device_memory{device_memory_}, buffer_cache{buffer_cache_},
|
||||
device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_},
|
||||
staging_pool{staging_pool_}, guest_streamer(0, runtime),
|
||||
sample_streamer(static_cast<size_t>(QueryType::ZPassPixelCount64), runtime, rasterizer,
|
||||
device, scheduler, memory_allocator, compute_pass_descriptor_queue,
|
||||
descriptor_pool),
|
||||
texture_cache_, device, scheduler, memory_allocator,
|
||||
compute_pass_descriptor_queue, descriptor_pool),
|
||||
tfb_streamer(static_cast<size_t>(QueryType::StreamingByteCount), runtime, device,
|
||||
scheduler, memory_allocator, staging_pool),
|
||||
primitives_succeeded_streamer(
|
||||
|
@ -1240,10 +1257,10 @@ QueryCacheRuntime::QueryCacheRuntime(VideoCore::RasterizerInterface* rasterizer,
|
|||
const MemoryAllocator& memory_allocator_,
|
||||
Scheduler& scheduler_, StagingBufferPool& staging_pool_,
|
||||
ComputePassDescriptorQueue& compute_pass_descriptor_queue,
|
||||
DescriptorPool& descriptor_pool) {
|
||||
DescriptorPool& descriptor_pool, TextureCache& texture_cache_) {
|
||||
impl = std::make_unique<QueryCacheRuntimeImpl>(
|
||||
*this, rasterizer, device_memory_, buffer_cache_, device_, memory_allocator_, scheduler_,
|
||||
staging_pool_, compute_pass_descriptor_queue, descriptor_pool);
|
||||
staging_pool_, compute_pass_descriptor_queue, descriptor_pool, texture_cache_);
|
||||
}
|
||||
|
||||
void QueryCacheRuntime::Bind3DEngine(Maxwell3D* maxwell3d) {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#include "video_core/query_cache/query_cache_base.h"
|
||||
#include "video_core/renderer_vulkan/vk_buffer_cache.h"
|
||||
|
||||
#include "video_core/renderer_vulkan/vk_texture_cache.h"
|
||||
namespace VideoCore {
|
||||
class RasterizerInterface;
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ class StreamerInterface;
|
|||
}
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
class Device;
|
||||
class Scheduler;
|
||||
class StagingBufferPool;
|
||||
|
@ -32,7 +31,7 @@ public:
|
|||
const MemoryAllocator& memory_allocator_, Scheduler& scheduler_,
|
||||
StagingBufferPool& staging_pool_,
|
||||
ComputePassDescriptorQueue& compute_pass_descriptor_queue,
|
||||
DescriptorPool& descriptor_pool);
|
||||
DescriptorPool& descriptor_pool, TextureCache& texture_cache_);
|
||||
~QueryCacheRuntime();
|
||||
|
||||
template <typename SyncValuesType>
|
||||
|
|
|
@ -189,7 +189,7 @@ RasterizerVulkan::RasterizerVulkan(Core::Frontend::EmuWindow& emu_window_, Tegra
|
|||
guest_descriptor_queue, compute_pass_descriptor_queue, descriptor_pool),
|
||||
buffer_cache(device_memory, buffer_cache_runtime),
|
||||
query_cache_runtime(this, device_memory, buffer_cache, device, memory_allocator, scheduler,
|
||||
staging_pool, compute_pass_descriptor_queue, descriptor_pool),
|
||||
staging_pool, compute_pass_descriptor_queue, descriptor_pool, texture_cache),
|
||||
query_cache(gpu, *this, device_memory, query_cache_runtime),
|
||||
pipeline_cache(device_memory, device, scheduler, descriptor_pool, guest_descriptor_queue,
|
||||
render_pass_cache, buffer_cache, texture_cache, gpu.ShaderNotify()),
|
||||
|
|
|
@ -136,7 +136,6 @@ public:
|
|||
void BindChannel(Tegra::Control::ChannelState& channel) override;
|
||||
|
||||
void ReleaseChannel(s32 channel_id) override;
|
||||
|
||||
std::optional<FramebufferTextureInfo> AccelerateDisplay(const Tegra::FramebufferConfig& config,
|
||||
VAddr framebuffer_addr,
|
||||
u32 pixel_stride);
|
||||
|
@ -147,7 +146,6 @@ private:
|
|||
0x0100E95004038000ULL, // XC2
|
||||
0x0100A6301214E000ULL, // FE:Engage
|
||||
};
|
||||
|
||||
static constexpr size_t MAX_TEXTURES = 192;
|
||||
static constexpr size_t MAX_IMAGES = 48;
|
||||
static constexpr size_t MAX_IMAGE_VIEWS = MAX_TEXTURES + MAX_IMAGES;
|
||||
|
|
|
@ -270,46 +270,77 @@ void Scheduler::EndPendingOperations() {
|
|||
EndRenderPass();
|
||||
}
|
||||
|
||||
void Scheduler::EndRenderPass() {
|
||||
if (!state.renderpass) {
|
||||
return;
|
||||
void Scheduler::EndRenderPass()
|
||||
{
|
||||
if (!state.renderpass) {
|
||||
return;
|
||||
}
|
||||
|
||||
query_cache->CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, false);
|
||||
query_cache->NotifySegment(false);
|
||||
|
||||
Record([num_images = num_renderpass_images,
|
||||
images = renderpass_images,
|
||||
ranges = renderpass_image_ranges](vk::CommandBuffer cmdbuf) {
|
||||
std::array<VkImageMemoryBarrier, 9> barriers;
|
||||
VkPipelineStageFlags src_stages = 0;
|
||||
|
||||
for (size_t i = 0; i < num_images; ++i) {
|
||||
const VkImageSubresourceRange& range = ranges[i];
|
||||
const bool is_color = range.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
const bool is_depth_stencil = range.aspectMask
|
||||
& (VK_IMAGE_ASPECT_DEPTH_BIT
|
||||
| VK_IMAGE_ASPECT_STENCIL_BIT);
|
||||
|
||||
VkAccessFlags src_access = 0;
|
||||
VkPipelineStageFlags this_stage = 0;
|
||||
|
||||
if (is_color) {
|
||||
src_access |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
this_stage |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
}
|
||||
|
||||
if (is_depth_stencil) {
|
||||
src_access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
this_stage |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
|
||||
| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
||||
}
|
||||
|
||||
src_stages |= this_stage;
|
||||
|
||||
barriers[i] = VkImageMemoryBarrier{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = src_access,
|
||||
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT
|
||||
| VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
|
||||
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
|
||||
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
|
||||
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = images[i],
|
||||
.subresourceRange = range,
|
||||
};
|
||||
}
|
||||
|
||||
cmdbuf.EndRenderPass();
|
||||
|
||||
cmdbuf.PipelineBarrier(src_stages,
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
0,
|
||||
{},
|
||||
{},
|
||||
{barriers.data(), num_images} // Batched image barriers
|
||||
);
|
||||
});
|
||||
|
||||
state.renderpass = nullptr;
|
||||
num_renderpass_images = 0;
|
||||
}
|
||||
|
||||
query_cache->CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, false);
|
||||
query_cache->NotifySegment(false);
|
||||
|
||||
Record([num_images = num_renderpass_images, images = renderpass_images,
|
||||
ranges = renderpass_image_ranges](vk::CommandBuffer cmdbuf) {
|
||||
std::array<VkImageMemoryBarrier, 9> barriers;
|
||||
for (size_t i = 0; i < num_images; ++i) {
|
||||
barriers[i] = VkImageMemoryBarrier{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT |
|
||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = images[i],
|
||||
.subresourceRange = ranges[i],
|
||||
};
|
||||
}
|
||||
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, 0, nullptr, nullptr,
|
||||
vk::Span(barriers.data(), num_images));
|
||||
});
|
||||
state.renderpass = nullptr;
|
||||
num_renderpass_images = 0;
|
||||
}
|
||||
|
||||
void Scheduler::AcquireNewChunk() {
|
||||
std::scoped_lock rl{reserve_mutex};
|
||||
|
|
|
@ -508,58 +508,84 @@ TransformBufferCopies(std::span<const VideoCommon::BufferCopy> copies, size_t bu
|
|||
return value;
|
||||
}
|
||||
}
|
||||
struct RangedBarrierRange {
|
||||
u32 min_mip = std::numeric_limits<u32>::max();
|
||||
u32 max_mip = std::numeric_limits<u32>::min();
|
||||
u32 min_layer = std::numeric_limits<u32>::max();
|
||||
u32 max_layer = std::numeric_limits<u32>::min();
|
||||
|
||||
void AddLayers(const VkImageSubresourceLayers& layers) {
|
||||
min_mip = std::min(min_mip, layers.mipLevel);
|
||||
max_mip = std::max(max_mip, layers.mipLevel + 1);
|
||||
min_layer = std::min(min_layer, layers.baseArrayLayer);
|
||||
max_layer = std::max(max_layer, layers.baseArrayLayer + layers.layerCount);
|
||||
}
|
||||
|
||||
VkImageSubresourceRange SubresourceRange(VkImageAspectFlags aspect_mask) const noexcept {
|
||||
return VkImageSubresourceRange{
|
||||
.aspectMask = aspect_mask,
|
||||
.baseMipLevel = min_mip,
|
||||
.levelCount = max_mip - min_mip,
|
||||
.baseArrayLayer = min_layer,
|
||||
.layerCount = max_layer - min_layer,
|
||||
};
|
||||
}
|
||||
};
|
||||
void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage image,
|
||||
VkImageAspectFlags aspect_mask, bool is_initialized,
|
||||
std::span<const VkBufferImageCopy> copies) {
|
||||
static constexpr VkAccessFlags WRITE_ACCESS_FLAGS =
|
||||
VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
static constexpr VkAccessFlags READ_ACCESS_FLAGS = VK_ACCESS_SHADER_READ_BIT |
|
||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
|
||||
|
||||
// Compute exact mip/layer range being written to
|
||||
RangedBarrierRange range;
|
||||
for (const auto& region : copies) {
|
||||
range.AddLayers(region.imageSubresource);
|
||||
}
|
||||
const VkImageSubresourceRange subresource_range = range.SubresourceRange(aspect_mask);
|
||||
|
||||
const VkImageMemoryBarrier read_barrier{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = WRITE_ACCESS_FLAGS,
|
||||
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = image,
|
||||
.subresourceRange{
|
||||
.aspectMask = aspect_mask,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = VK_REMAINING_MIP_LEVELS,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
||||
},
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = WRITE_ACCESS_FLAGS,
|
||||
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = image,
|
||||
.subresourceRange = subresource_range,
|
||||
};
|
||||
|
||||
const VkImageMemoryBarrier write_barrier{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.dstAccessMask = WRITE_ACCESS_FLAGS | READ_ACCESS_FLAGS,
|
||||
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = image,
|
||||
.subresourceRange{
|
||||
.aspectMask = aspect_mask,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = VK_REMAINING_MIP_LEVELS,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
||||
},
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.dstAccessMask = WRITE_ACCESS_FLAGS | READ_ACCESS_FLAGS,
|
||||
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = image,
|
||||
.subresourceRange = subresource_range,
|
||||
};
|
||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
|
||||
|
||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
|
||||
read_barrier);
|
||||
cmdbuf.CopyBufferToImage(src_buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, copies);
|
||||
// TODO: Move this to another API
|
||||
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_LATE_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
0, nullptr, nullptr, write_barrier);
|
||||
}
|
||||
|
||||
[[nodiscard]] VkImageBlit MakeImageBlit(const Region2D& dst_region, const Region2D& src_region,
|
||||
|
@ -652,29 +678,7 @@ void TryTransformSwizzleIfNeeded(PixelFormat format, std::array<SwizzleSource, 4
|
|||
}
|
||||
}
|
||||
|
||||
struct RangedBarrierRange {
|
||||
u32 min_mip = std::numeric_limits<u32>::max();
|
||||
u32 max_mip = std::numeric_limits<u32>::min();
|
||||
u32 min_layer = std::numeric_limits<u32>::max();
|
||||
u32 max_layer = std::numeric_limits<u32>::min();
|
||||
|
||||
void AddLayers(const VkImageSubresourceLayers& layers) {
|
||||
min_mip = std::min(min_mip, layers.mipLevel);
|
||||
max_mip = std::max(max_mip, layers.mipLevel + 1);
|
||||
min_layer = std::min(min_layer, layers.baseArrayLayer);
|
||||
max_layer = std::max(max_layer, layers.baseArrayLayer + layers.layerCount);
|
||||
}
|
||||
|
||||
VkImageSubresourceRange SubresourceRange(VkImageAspectFlags aspect_mask) const noexcept {
|
||||
return VkImageSubresourceRange{
|
||||
.aspectMask = aspect_mask,
|
||||
.baseMipLevel = min_mip,
|
||||
.levelCount = max_mip - min_mip,
|
||||
.baseArrayLayer = min_layer,
|
||||
.layerCount = max_layer - min_layer,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
[[nodiscard]] VkFormat Format(Shader::ImageFormat format) {
|
||||
switch (format) {
|
||||
|
@ -1458,12 +1462,18 @@ void TextureCacheRuntime::CopyImage(Image& dst, Image& src,
|
|||
.subresourceRange = dst_range.SubresourceRange(aspect_mask),
|
||||
},
|
||||
};
|
||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
0, {}, {}, pre_barriers);
|
||||
cmdbuf.PipelineBarrier(
|
||||
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
0, nullptr, nullptr, pre_barriers);
|
||||
cmdbuf.CopyImage(src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst_image,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, vk_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_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
0, nullptr, nullptr, post_barriers);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2377,7 +2387,7 @@ void TextureCacheRuntime::TransitionImageLayout(Image& image) {
|
|||
};
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
scheduler.Record([barrier](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, barrier);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -120,6 +120,7 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
|
|||
X(vkCmdEndConditionalRenderingEXT);
|
||||
X(vkCmdEndQuery);
|
||||
X(vkCmdEndRenderPass);
|
||||
X(vkCmdResetQueryPool);
|
||||
X(vkCmdEndTransformFeedbackEXT);
|
||||
X(vkCmdEndDebugUtilsLabelEXT);
|
||||
X(vkCmdFillBuffer);
|
||||
|
|
|
@ -219,6 +219,7 @@ struct DeviceDispatch : InstanceDispatch {
|
|||
PFN_vkCmdEndConditionalRenderingEXT vkCmdEndConditionalRenderingEXT{};
|
||||
PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT{};
|
||||
PFN_vkCmdEndQuery vkCmdEndQuery{};
|
||||
PFN_vkCmdResetQueryPool vkCmdResetQueryPool{};
|
||||
PFN_vkCmdEndRenderPass vkCmdEndRenderPass{};
|
||||
PFN_vkCmdEndTransformFeedbackEXT vkCmdEndTransformFeedbackEXT{};
|
||||
PFN_vkCmdFillBuffer vkCmdFillBuffer{};
|
||||
|
@ -1137,7 +1138,9 @@ public:
|
|||
VkCommandBuffer operator*() const noexcept {
|
||||
return handle;
|
||||
}
|
||||
|
||||
void ResetQueryPool(VkQueryPool query_pool, uint32_t first, uint32_t count) const noexcept {
|
||||
dld->vkCmdResetQueryPool(handle, query_pool, first, count);
|
||||
}
|
||||
void Begin(const VkCommandBufferBeginInfo& begin_info) const {
|
||||
Check(dld->vkBeginCommandBuffer(handle, &begin_info));
|
||||
}
|
||||
|
|
|
@ -36,7 +36,16 @@ void ConfigureGraphicsExtensions::Setup(const ConfigurationShared::Builder& buil
|
|||
|
||||
for (auto setting :
|
||||
Settings::values.linkage.by_category[Settings::Category::RendererExtensions]) {
|
||||
ConfigurationShared::Widget* widget = builder.BuildWidget(setting, apply_funcs);
|
||||
ConfigurationShared::Widget* widget = [&]() {
|
||||
if (setting->Id() == Settings::values.sample_shading_fraction.Id()) {
|
||||
// TODO(crueter): should support this natively perhaps?
|
||||
return builder.BuildWidget(
|
||||
setting, apply_funcs, ConfigurationShared::RequestType::Slider, true,
|
||||
1.0f, nullptr, tr("%", "Sample Shading percentage (e.g. 50%)"));
|
||||
} else {
|
||||
return builder.BuildWidget(setting, apply_funcs);
|
||||
}
|
||||
}();
|
||||
|
||||
if (widget == nullptr) {
|
||||
continue;
|
||||
|
|
|
@ -360,8 +360,10 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent)
|
|||
tr("Improves texture & buffer handling and the Maxwell translation layer.\n"
|
||||
"Some Vulkan 1.1+ and all 1.2+ devices support this extension."));
|
||||
|
||||
INSERT(Settings, sample_shading, QString(), QString());
|
||||
|
||||
INSERT(Settings,
|
||||
sample_shading,
|
||||
sample_shading_fraction,
|
||||
tr("Sample Shading"),
|
||||
tr("Allows the fragment shader to execute per sample in a multi-sampled fragment "
|
||||
"instead once per fragment. Improves graphics quality at the cost of some performance.\n"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue