Compare commits

..

1 Commits

Author SHA1 Message Date
Liam
edd54abee4 fsmitm_romfsbuild: avoid full path lookups 2023-06-27 23:25:47 -04:00
31 changed files with 199 additions and 1981 deletions

View File

@@ -157,9 +157,6 @@ endif()
add_library(stb stb/stb_dxt.cpp)
target_include_directories(stb PUBLIC ./stb)
add_library(bc_decoder bc_decoder/bc_decoder.cpp)
target_include_directories(bc_decoder PUBLIC ./bc_decoder)
if (ANDROID)
if (ARCHITECTURE_arm64)
add_subdirectory(libadrenotools)

File diff suppressed because it is too large Load Diff

View File

@@ -1,43 +0,0 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/)
#pragma once
#include <cstdint>
namespace bcn {
/**
* @brief Decodes a BC1 encoded image to R8G8B8A8
*/
void DecodeBc1(const uint8_t *src, uint8_t *dst, size_t x, size_t y, size_t width, size_t height);
/**
* @brief Decodes a BC2 encoded image to R8G8B8A8
*/
void DecodeBc2(const uint8_t *src, uint8_t *dst, size_t x, size_t y, size_t width, size_t height);
/**
* @brief Decodes a BC3 encoded image to R8G8B8A8
*/
void DecodeBc3(const uint8_t *src, uint8_t *dst, size_t x, size_t y, size_t width, size_t height);
/**
* @brief Decodes a BC4 encoded image to R8
*/
void DecodeBc4(const uint8_t *src, uint8_t *dst, size_t x, size_t y, size_t width, size_t height, bool isSigned);
/**
* @brief Decodes a BC5 encoded image to R8G8
*/
void DecodeBc5(const uint8_t *src, uint8_t *dst, size_t x, size_t y, size_t width, size_t height, bool isSigned);
/**
* @brief Decodes a BC6 encoded image to R16G16B16A16
*/
void DecodeBc6(const uint8_t *src, uint8_t *dst, size_t x, size_t y, size_t width, size_t height, bool isSigned);
/**
* @brief Decodes a BC7 encoded image to R8G8B8A8
*/
void DecodeBc7(const uint8_t *src, uint8_t *dst, size_t x, size_t y, size_t width, size_t height);
}

View File

@@ -105,19 +105,11 @@ static u64 romfs_get_hash_table_count(u64 num_entries) {
return count;
}
void RomFSBuildContext::VisitDirectory(VirtualDir root_romfs, VirtualDir ext_dir,
void RomFSBuildContext::VisitDirectory(VirtualDir romfs_dir, VirtualDir ext_dir,
std::shared_ptr<RomFSBuildDirectoryContext> parent) {
std::vector<std::shared_ptr<RomFSBuildDirectoryContext>> child_dirs;
VirtualDir dir;
if (parent->path_len == 0) {
dir = root_romfs;
} else {
dir = root_romfs->GetDirectoryRelative(parent->path);
}
const auto entries = dir->GetEntries();
const auto entries = romfs_dir->GetEntries();
for (const auto& kv : entries) {
if (kv.second == VfsEntryType::Directory) {
@@ -127,7 +119,7 @@ void RomFSBuildContext::VisitDirectory(VirtualDir root_romfs, VirtualDir ext_dir
child->path_len = child->cur_path_ofs + static_cast<u32>(kv.first.size());
child->path = parent->path + "/" + kv.first;
if (ext_dir != nullptr && ext_dir->GetFileRelative(child->path + ".stub") != nullptr) {
if (ext_dir != nullptr && ext_dir->GetFile(kv.first + ".stub") != nullptr) {
continue;
}
@@ -144,17 +136,17 @@ void RomFSBuildContext::VisitDirectory(VirtualDir root_romfs, VirtualDir ext_dir
child->path_len = child->cur_path_ofs + static_cast<u32>(kv.first.size());
child->path = parent->path + "/" + kv.first;
if (ext_dir != nullptr && ext_dir->GetFileRelative(child->path + ".stub") != nullptr) {
if (ext_dir != nullptr && ext_dir->GetFile(kv.first + ".stub") != nullptr) {
continue;
}
// Sanity check on path_len
ASSERT(child->path_len < FS_MAX_PATH);
child->source = root_romfs->GetFileRelative(child->path);
child->source = romfs_dir->GetFile(kv.first);
if (ext_dir != nullptr) {
if (const auto ips = ext_dir->GetFileRelative(child->path + ".ips")) {
if (const auto ips = ext_dir->GetFile(kv.first + ".ips")) {
if (auto patched = PatchIPS(child->source, ips)) {
child->source = std::move(patched);
}
@@ -168,23 +160,27 @@ void RomFSBuildContext::VisitDirectory(VirtualDir root_romfs, VirtualDir ext_dir
}
for (auto& child : child_dirs) {
this->VisitDirectory(root_romfs, ext_dir, child);
auto subdir_name = std::string_view(child->path).substr(child->cur_path_ofs);
auto child_romfs_dir = romfs_dir->GetSubdirectory(subdir_name);
auto child_ext_dir = ext_dir != nullptr ? ext_dir->GetSubdirectory(subdir_name) : nullptr;
this->VisitDirectory(child_romfs_dir, child_ext_dir, child);
}
}
bool RomFSBuildContext::AddDirectory(std::shared_ptr<RomFSBuildDirectoryContext> parent_dir_ctx,
std::shared_ptr<RomFSBuildDirectoryContext> dir_ctx) {
// Check whether it's already in the known directories.
const auto existing = directories.find(dir_ctx->path);
if (existing != directories.end())
const auto [it, is_new] = directories.emplace(dir_ctx->path, nullptr);
if (!is_new) {
return false;
}
// Add a new directory.
num_dirs++;
dir_table_size +=
sizeof(RomFSDirectoryEntry) + Common::AlignUp(dir_ctx->path_len - dir_ctx->cur_path_ofs, 4);
dir_ctx->parent = parent_dir_ctx;
directories.emplace(dir_ctx->path, dir_ctx);
it->second = dir_ctx;
return true;
}
@@ -192,8 +188,8 @@ bool RomFSBuildContext::AddDirectory(std::shared_ptr<RomFSBuildDirectoryContext>
bool RomFSBuildContext::AddFile(std::shared_ptr<RomFSBuildDirectoryContext> parent_dir_ctx,
std::shared_ptr<RomFSBuildFileContext> file_ctx) {
// Check whether it's already in the known files.
const auto existing = files.find(file_ctx->path);
if (existing != files.end()) {
const auto [it, is_new] = files.emplace(file_ctx->path, nullptr);
if (!is_new) {
return false;
}
@@ -202,7 +198,7 @@ bool RomFSBuildContext::AddFile(std::shared_ptr<RomFSBuildDirectoryContext> pare
file_table_size +=
sizeof(RomFSFileEntry) + Common::AlignUp(file_ctx->path_len - file_ctx->cur_path_ofs, 4);
file_ctx->parent = parent_dir_ctx;
files.emplace(file_ctx->path, file_ctx);
it->second = file_ctx;
return true;
}

View File

@@ -220,8 +220,8 @@ add_library(video_core STATIC
surface.h
texture_cache/accelerated_swizzle.cpp
texture_cache/accelerated_swizzle.h
texture_cache/decode_bc.cpp
texture_cache/decode_bc.h
texture_cache/decode_bc4.cpp
texture_cache/decode_bc4.h
texture_cache/descriptor_table.h
texture_cache/formatter.cpp
texture_cache/formatter.h
@@ -279,7 +279,7 @@ add_library(video_core STATIC
create_target_directory_groups(video_core)
target_link_libraries(video_core PUBLIC common core)
target_link_libraries(video_core PUBLIC glad shader_recompiler stb bc_decoder)
target_link_libraries(video_core PUBLIC glad shader_recompiler stb)
if (YUZU_USE_BUNDLED_FFMPEG AND NOT (WIN32 OR ANDROID))
add_dependencies(video_core ffmpeg-build)

View File

@@ -495,9 +495,6 @@ void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer,
const Region2D& dst_region, const Region2D& src_region,
Tegra::Engines::Fermi2D::Filter filter,
Tegra::Engines::Fermi2D::Operation operation) {
if (!device.IsExtShaderStencilExportSupported()) {
return;
}
ASSERT(filter == Tegra::Engines::Fermi2D::Filter::Point);
ASSERT(operation == Tegra::Engines::Fermi2D::Operation::SrcCopy);
const BlitImagePipelineKey key{

View File

@@ -259,26 +259,6 @@ FormatInfo SurfaceFormat(const Device& device, FormatType format_type, bool with
break;
}
}
// Transcode on hardware that doesn't support BCn natively
if (!device.IsOptimalBcnSupported() && VideoCore::Surface::IsPixelFormatBCn(pixel_format)) {
const bool is_srgb = with_srgb && VideoCore::Surface::IsPixelFormatSRGB(pixel_format);
if (pixel_format == PixelFormat::BC4_SNORM) {
tuple.format = VK_FORMAT_R8_SNORM;
} else if (pixel_format == PixelFormat::BC4_UNORM) {
tuple.format = VK_FORMAT_R8_UNORM;
} else if (pixel_format == PixelFormat::BC5_SNORM) {
tuple.format = VK_FORMAT_R8G8_SNORM;
} else if (pixel_format == PixelFormat::BC5_UNORM) {
tuple.format = VK_FORMAT_R8G8_UNORM;
} else if (pixel_format == PixelFormat::BC6H_SFLOAT ||
pixel_format == PixelFormat::BC6H_UFLOAT) {
tuple.format = VK_FORMAT_R16G16B16A16_SFLOAT;
} else if (is_srgb) {
tuple.format = VK_FORMAT_A8B8G8R8_SRGB_PACK32;
} else {
tuple.format = VK_FORMAT_A8B8G8R8_UNORM_PACK32;
}
}
const bool attachable = (tuple.usage & Attachable) != 0;
const bool storage = (tuple.usage & Storage) != 0;

View File

@@ -12,7 +12,6 @@
#include <fmt/format.h>
#include "common/logging/log.h"
#include "common/polyfill_ranges.h"
#include "common/scope_exit.h"
#include "common/settings.h"
#include "common/telemetry.h"
@@ -66,21 +65,6 @@ std::string BuildCommaSeparatedExtensions(
return fmt::format("{}", fmt::join(available_extensions, ","));
}
DebugCallback MakeDebugCallback(const vk::Instance& instance, const vk::InstanceDispatch& dld) {
if (!Settings::values.renderer_debug) {
return DebugCallback{};
}
const std::optional properties = vk::EnumerateInstanceExtensionProperties(dld);
const auto it = std::ranges::find_if(*properties, [](const auto& prop) {
return std::strcmp(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, prop.extensionName) == 0;
});
if (it != properties->end()) {
return CreateDebugUtilsCallback(instance);
} else {
return CreateDebugReportCallback(instance);
}
}
} // Anonymous namespace
Device CreateDevice(const vk::Instance& instance, const vk::InstanceDispatch& dld,
@@ -103,7 +87,7 @@ RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_,
cpu_memory(cpu_memory_), gpu(gpu_), library(OpenLibrary(context.get())),
instance(CreateInstance(*library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type,
Settings::values.renderer_debug.GetValue())),
debug_callback(MakeDebugCallback(instance, dld)),
debug_callback(Settings::values.renderer_debug ? CreateDebugCallback(instance) : nullptr),
surface(CreateSurface(instance, render_window.GetWindowInfo())),
device(CreateDevice(instance, dld, *surface)), memory_allocator(device), state_tracker(),
scheduler(device, state_tracker),

View File

@@ -5,7 +5,6 @@
#include <memory>
#include <string>
#include <variant>
#include "common/dynamic_library.h"
#include "video_core/renderer_base.h"
@@ -34,8 +33,6 @@ class GPU;
namespace Vulkan {
using DebugCallback = std::variant<vk::DebugUtilsMessenger, vk::DebugReportCallback>;
Device CreateDevice(const vk::Instance& instance, const vk::InstanceDispatch& dld,
VkSurfaceKHR surface);
@@ -74,7 +71,7 @@ private:
vk::InstanceDispatch dld;
vk::Instance instance;
DebugCallback debug_callback;
vk::DebugUtilsMessenger debug_callback;
vk::SurfaceKHR surface;
ScreenInfo screen_info;

View File

@@ -590,8 +590,7 @@ void BufferCacheRuntime::ReserveNullBuffer() {
.pNext = nullptr,
.flags = 0,
.size = 4,
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
VK_BUFFER_USAGE_TRANSFER_DST_BIT,
.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 0,
.pQueueFamilyIndices = nullptr,

View File

@@ -652,14 +652,13 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
.pNext = nullptr,
.negativeOneToOne = key.state.ndc_minus_one_to_one.Value() != 0 ? VK_TRUE : VK_FALSE,
};
const u32 num_viewports = std::min<u32>(device.GetMaxViewports(), Maxwell::NumViewports);
VkPipelineViewportStateCreateInfo viewport_ci{
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.viewportCount = num_viewports,
.viewportCount = Maxwell::NumViewports,
.pViewports = nullptr,
.scissorCount = num_viewports,
.scissorCount = Maxwell::NumViewports,
.pScissors = nullptr,
};
if (device.IsNvViewportSwizzleSupported()) {

View File

@@ -309,7 +309,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device
.support_int16 = device.IsShaderInt16Supported(),
.support_int64 = device.IsShaderInt64Supported(),
.support_vertex_instance_id = false,
.support_float_controls = device.IsKhrShaderFloatControlsSupported(),
.support_float_controls = true,
.support_separate_denorm_behavior =
float_control.denormBehaviorIndependence == VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL,
.support_separate_rounding_mode =
@@ -325,13 +325,12 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device
.support_fp64_signed_zero_nan_preserve =
float_control.shaderSignedZeroInfNanPreserveFloat64 != VK_FALSE,
.support_explicit_workgroup_layout = device.IsKhrWorkgroupMemoryExplicitLayoutSupported(),
.support_vote = device.IsSubgroupFeatureSupported(VK_SUBGROUP_FEATURE_VOTE_BIT),
.support_vote = true,
.support_viewport_index_layer_non_geometry =
device.IsExtShaderViewportIndexLayerSupported(),
.support_viewport_mask = device.IsNvViewportArray2Supported(),
.support_typeless_image_loads = device.IsFormatlessImageLoadSupported(),
.support_demote_to_helper_invocation =
device.IsExtShaderDemoteToHelperInvocationSupported(),
.support_demote_to_helper_invocation = true,
.support_int64_atomics = device.IsExtShaderAtomicInt64Supported(),
.support_derivative_control = true,
.support_geometry_shader_passthrough = device.IsNvGeometryShaderPassthroughSupported(),

View File

@@ -315,14 +315,7 @@ void RasterizerVulkan::Clear(u32 layer_count) {
FlushWork();
gpu_memory->FlushCaching();
#if ANDROID
if (Settings::IsGPULevelHigh()) {
// This is problematic on Android, disable on GPU Normal.
query_cache.UpdateCounters();
}
#else
query_cache.UpdateCounters();
#endif
auto& regs = maxwell3d->regs;
const bool use_color = regs.clear_surface.R || regs.clear_surface.G || regs.clear_surface.B ||
@@ -932,7 +925,7 @@ void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& reg
}
const bool is_rescaling{texture_cache.IsRescaling()};
const float scale = is_rescaling ? Settings::values.resolution_info.up_factor : 1.0f;
const std::array viewport_list{
const std::array viewports{
GetViewportState(device, regs, 0, scale), GetViewportState(device, regs, 1, scale),
GetViewportState(device, regs, 2, scale), GetViewportState(device, regs, 3, scale),
GetViewportState(device, regs, 4, scale), GetViewportState(device, regs, 5, scale),
@@ -942,11 +935,7 @@ void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& reg
GetViewportState(device, regs, 12, scale), GetViewportState(device, regs, 13, scale),
GetViewportState(device, regs, 14, scale), GetViewportState(device, regs, 15, scale),
};
scheduler.Record([this, viewport_list](vk::CommandBuffer cmdbuf) {
const u32 num_viewports = std::min<u32>(device.GetMaxViewports(), Maxwell::NumViewports);
const vk::Span<VkViewport> viewports(viewport_list.data(), num_viewports);
cmdbuf.SetViewport(0, viewports);
});
scheduler.Record([viewports](vk::CommandBuffer cmdbuf) { cmdbuf.SetViewport(0, viewports); });
}
void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D::Regs& regs) {
@@ -959,7 +948,7 @@ void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D::Regs& regs
up_scale = Settings::values.resolution_info.up_scale;
down_shift = Settings::values.resolution_info.down_shift;
}
const std::array scissor_list{
const std::array scissors{
GetScissorState(regs, 0, up_scale, down_shift),
GetScissorState(regs, 1, up_scale, down_shift),
GetScissorState(regs, 2, up_scale, down_shift),
@@ -977,11 +966,7 @@ void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D::Regs& regs
GetScissorState(regs, 14, up_scale, down_shift),
GetScissorState(regs, 15, up_scale, down_shift),
};
scheduler.Record([this, scissor_list](vk::CommandBuffer cmdbuf) {
const u32 num_scissors = std::min<u32>(device.GetMaxViewports(), Maxwell::NumViewports);
const vk::Span<VkRect2D> scissors(scissor_list.data(), num_scissors);
cmdbuf.SetScissor(0, scissors);
});
scheduler.Record([scissors](vk::CommandBuffer cmdbuf) { cmdbuf.SetScissor(0, scissors); });
}
void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D::Regs& regs) {

View File

@@ -38,20 +38,18 @@ size_t Region(size_t iterator) noexcept {
StagingBufferPool::StagingBufferPool(const Device& device_, MemoryAllocator& memory_allocator_,
Scheduler& scheduler_)
: device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_} {
VkBufferCreateInfo stream_ci = {
const VkBufferCreateInfo stream_ci = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.size = STREAM_BUFFER_SIZE,
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 0,
.pQueueFamilyIndices = nullptr,
};
if (device.IsExtTransformFeedbackSupported()) {
stream_ci.usage |= VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
}
stream_buffer = memory_allocator.CreateBuffer(stream_ci, MemoryUsage::Stream);
if (device.HasDebuggingToolAttached()) {
stream_buffer.SetObjectNameEXT("Stream Buffer");
@@ -166,21 +164,19 @@ std::optional<StagingBufferRef> StagingBufferPool::TryGetReservedBuffer(size_t s
StagingBufferRef StagingBufferPool::CreateStagingBuffer(size_t size, MemoryUsage usage,
bool deferred) {
const u32 log2 = Common::Log2Ceil64(size);
VkBufferCreateInfo buffer_ci = {
const VkBufferCreateInfo buffer_ci = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.size = 1ULL << log2,
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 0,
.pQueueFamilyIndices = nullptr,
};
if (device.IsExtTransformFeedbackSupported()) {
buffer_ci.usage |= VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
}
vk::Buffer buffer = memory_allocator.CreateBuffer(buffer_ci, usage);
if (device.HasDebuggingToolAttached()) {
++buffer_index;

View File

@@ -1279,10 +1279,6 @@ Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info_, GPUVAddr gpu
flags |= VideoCommon::ImageFlagBits::Converted;
flags |= VideoCommon::ImageFlagBits::CostlyLoad;
}
if (IsPixelFormatBCn(info.format) && !runtime->device.IsOptimalBcnSupported()) {
flags |= VideoCommon::ImageFlagBits::Converted;
flags |= VideoCommon::ImageFlagBits::CostlyLoad;
}
if (runtime->device.HasDebuggingToolAttached()) {
original_image.SetObjectNameEXT(VideoCommon::Name(*this).c_str());
}

View File

@@ -269,28 +269,6 @@ bool IsPixelFormatASTC(PixelFormat format) {
}
}
bool IsPixelFormatBCn(PixelFormat format) {
switch (format) {
case PixelFormat::BC1_RGBA_UNORM:
case PixelFormat::BC2_UNORM:
case PixelFormat::BC3_UNORM:
case PixelFormat::BC4_UNORM:
case PixelFormat::BC4_SNORM:
case PixelFormat::BC5_UNORM:
case PixelFormat::BC5_SNORM:
case PixelFormat::BC1_RGBA_SRGB:
case PixelFormat::BC2_SRGB:
case PixelFormat::BC3_SRGB:
case PixelFormat::BC7_UNORM:
case PixelFormat::BC6H_UFLOAT:
case PixelFormat::BC6H_SFLOAT:
case PixelFormat::BC7_SRGB:
return true;
default:
return false;
}
}
bool IsPixelFormatSRGB(PixelFormat format) {
switch (format) {
case PixelFormat::A8B8G8R8_SRGB:

View File

@@ -501,8 +501,6 @@ SurfaceType GetFormatType(PixelFormat pixel_format);
bool IsPixelFormatASTC(PixelFormat format);
bool IsPixelFormatBCn(PixelFormat format);
bool IsPixelFormatSRGB(PixelFormat format);
bool IsPixelFormatInteger(PixelFormat format);

View File

@@ -1,129 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <algorithm>
#include <array>
#include <span>
#include <bc_decoder.h>
#include "common/common_types.h"
#include "video_core/texture_cache/decode_bc.h"
namespace VideoCommon {
namespace {
constexpr u32 BLOCK_SIZE = 4;
using VideoCore::Surface::PixelFormat;
constexpr bool IsSigned(PixelFormat pixel_format) {
switch (pixel_format) {
case PixelFormat::BC4_SNORM:
case PixelFormat::BC4_UNORM:
case PixelFormat::BC5_SNORM:
case PixelFormat::BC5_UNORM:
case PixelFormat::BC6H_SFLOAT:
case PixelFormat::BC6H_UFLOAT:
return true;
default:
return false;
}
}
constexpr u32 BlockSize(PixelFormat pixel_format) {
switch (pixel_format) {
case PixelFormat::BC1_RGBA_SRGB:
case PixelFormat::BC1_RGBA_UNORM:
case PixelFormat::BC4_SNORM:
case PixelFormat::BC4_UNORM:
return 8;
default:
return 16;
}
}
} // Anonymous namespace
u32 ConvertedBytesPerBlock(VideoCore::Surface::PixelFormat pixel_format) {
switch (pixel_format) {
case PixelFormat::BC4_SNORM:
case PixelFormat::BC4_UNORM:
return 1;
case PixelFormat::BC5_SNORM:
case PixelFormat::BC5_UNORM:
return 2;
case PixelFormat::BC6H_SFLOAT:
case PixelFormat::BC6H_UFLOAT:
return 8;
default:
return 4;
}
}
template <auto decompress, PixelFormat pixel_format>
void DecompressBlocks(std::span<const u8> input, std::span<u8> output, Extent3D extent,
bool is_signed = false) {
const u32 out_bpp = ConvertedBytesPerBlock(pixel_format);
const u32 block_width = std::min(extent.width, BLOCK_SIZE);
const u32 block_height = std::min(extent.height, BLOCK_SIZE);
const u32 pitch = extent.width * out_bpp;
size_t input_offset = 0;
size_t output_offset = 0;
for (u32 slice = 0; slice < extent.depth; ++slice) {
for (u32 y = 0; y < extent.height; y += block_height) {
size_t row_offset = 0;
for (u32 x = 0; x < extent.width;
x += block_width, row_offset += block_width * out_bpp) {
const u8* src = input.data() + input_offset;
u8* const dst = output.data() + output_offset + row_offset;
if constexpr (IsSigned(pixel_format)) {
decompress(src, dst, x, y, extent.width, extent.height, is_signed);
} else {
decompress(src, dst, x, y, extent.width, extent.height);
}
input_offset += BlockSize(pixel_format);
}
output_offset += block_height * pitch;
}
}
}
void DecompressBCn(std::span<const u8> input, std::span<u8> output, Extent3D extent,
VideoCore::Surface::PixelFormat pixel_format) {
switch (pixel_format) {
case PixelFormat::BC1_RGBA_UNORM:
case PixelFormat::BC1_RGBA_SRGB:
DecompressBlocks<bcn::DecodeBc1, PixelFormat::BC1_RGBA_UNORM>(input, output, extent);
break;
case PixelFormat::BC2_UNORM:
case PixelFormat::BC2_SRGB:
DecompressBlocks<bcn::DecodeBc2, PixelFormat::BC2_UNORM>(input, output, extent);
break;
case PixelFormat::BC3_UNORM:
case PixelFormat::BC3_SRGB:
DecompressBlocks<bcn::DecodeBc3, PixelFormat::BC3_UNORM>(input, output, extent);
break;
case PixelFormat::BC4_SNORM:
case PixelFormat::BC4_UNORM:
DecompressBlocks<bcn::DecodeBc4, PixelFormat::BC4_UNORM>(
input, output, extent, pixel_format == PixelFormat::BC4_SNORM);
break;
case PixelFormat::BC5_SNORM:
case PixelFormat::BC5_UNORM:
DecompressBlocks<bcn::DecodeBc5, PixelFormat::BC5_UNORM>(
input, output, extent, pixel_format == PixelFormat::BC5_SNORM);
break;
case PixelFormat::BC6H_SFLOAT:
case PixelFormat::BC6H_UFLOAT:
DecompressBlocks<bcn::DecodeBc6, PixelFormat::BC6H_UFLOAT>(
input, output, extent, pixel_format == PixelFormat::BC6H_SFLOAT);
break;
case PixelFormat::BC7_SRGB:
case PixelFormat::BC7_UNORM:
DecompressBlocks<bcn::DecodeBc7, PixelFormat::BC7_UNORM>(input, output, extent);
break;
default:
LOG_WARNING(HW_GPU, "Unimplemented BCn decompression {}", pixel_format);
}
}
} // namespace VideoCommon

View File

@@ -0,0 +1,96 @@
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <algorithm>
#include <array>
#include <span>
#include "common/assert.h"
#include "common/common_types.h"
#include "video_core/texture_cache/decode_bc4.h"
#include "video_core/texture_cache/types.h"
namespace VideoCommon {
// https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_texture_compression_rgtc.txt
[[nodiscard]] constexpr u32 DecompressBlock(u64 bits, u32 x, u32 y) {
const u32 code_offset = 16 + 3 * (4 * y + x);
const u32 code = (bits >> code_offset) & 7;
const u32 red0 = (bits >> 0) & 0xff;
const u32 red1 = (bits >> 8) & 0xff;
if (red0 > red1) {
switch (code) {
case 0:
return red0;
case 1:
return red1;
case 2:
return (6 * red0 + 1 * red1) / 7;
case 3:
return (5 * red0 + 2 * red1) / 7;
case 4:
return (4 * red0 + 3 * red1) / 7;
case 5:
return (3 * red0 + 4 * red1) / 7;
case 6:
return (2 * red0 + 5 * red1) / 7;
case 7:
return (1 * red0 + 6 * red1) / 7;
}
} else {
switch (code) {
case 0:
return red0;
case 1:
return red1;
case 2:
return (4 * red0 + 1 * red1) / 5;
case 3:
return (3 * red0 + 2 * red1) / 5;
case 4:
return (2 * red0 + 3 * red1) / 5;
case 5:
return (1 * red0 + 4 * red1) / 5;
case 6:
return 0;
case 7:
return 0xff;
}
}
return 0;
}
void DecompressBC4(std::span<const u8> input, Extent3D extent, std::span<u8> output) {
UNIMPLEMENTED_IF_MSG(extent.width % 4 != 0, "Unaligned width={}", extent.width);
UNIMPLEMENTED_IF_MSG(extent.height % 4 != 0, "Unaligned height={}", extent.height);
static constexpr u32 BLOCK_SIZE = 4;
size_t input_offset = 0;
for (u32 slice = 0; slice < extent.depth; ++slice) {
for (u32 block_y = 0; block_y < extent.height / 4; ++block_y) {
for (u32 block_x = 0; block_x < extent.width / 4; ++block_x) {
u64 bits;
std::memcpy(&bits, &input[input_offset], sizeof(bits));
input_offset += sizeof(bits);
for (u32 y = 0; y < BLOCK_SIZE; ++y) {
for (u32 x = 0; x < BLOCK_SIZE; ++x) {
const u32 linear_z = slice;
const u32 linear_y = block_y * BLOCK_SIZE + y;
const u32 linear_x = block_x * BLOCK_SIZE + x;
const u32 offset_z = linear_z * extent.width * extent.height;
const u32 offset_y = linear_y * extent.width;
const u32 offset_x = linear_x;
const u32 output_offset = (offset_z + offset_y + offset_x) * 4ULL;
const u32 color = DecompressBlock(bits, x, y);
output[output_offset + 0] = static_cast<u8>(color);
output[output_offset + 1] = 0;
output[output_offset + 2] = 0;
output[output_offset + 3] = 0xff;
}
}
}
}
}
}
} // namespace VideoCommon

View File

@@ -6,14 +6,10 @@
#include <span>
#include "common/common_types.h"
#include "video_core/surface.h"
#include "video_core/texture_cache/types.h"
namespace VideoCommon {
[[nodiscard]] u32 ConvertedBytesPerBlock(VideoCore::Surface::PixelFormat pixel_format);
void DecompressBCn(std::span<const u8> input, std::span<u8> output, Extent3D extent,
VideoCore::Surface::PixelFormat pixel_format);
void DecompressBC4(std::span<const u8> data, Extent3D extent, std::span<u8> output);
} // namespace VideoCommon

View File

@@ -598,6 +598,14 @@ void TextureCache<P>::UnmapGPUMemory(size_t as_id, GPUVAddr gpu_addr, size_t siz
[&](ImageId id, Image&) { deleted_images.push_back(id); });
for (const ImageId id : deleted_images) {
Image& image = slot_images[id];
if (True(image.flags & ImageFlagBits::CpuModified)) {
return;
}
image.flags |= ImageFlagBits::CpuModified;
if (True(image.flags & ImageFlagBits::Tracked)) {
UntrackImage(image, id);
}
/*
if (True(image.flags & ImageFlagBits::Remapped)) {
continue;
}
@@ -605,6 +613,7 @@ void TextureCache<P>::UnmapGPUMemory(size_t as_id, GPUVAddr gpu_addr, size_t siz
if (True(image.flags & ImageFlagBits::Tracked)) {
UntrackImage(image, id);
}
*/
}
}

View File

@@ -24,7 +24,7 @@
#include "video_core/engines/maxwell_3d.h"
#include "video_core/memory_manager.h"
#include "video_core/surface.h"
#include "video_core/texture_cache/decode_bc.h"
#include "video_core/texture_cache/decode_bc4.h"
#include "video_core/texture_cache/format_lookup_table.h"
#include "video_core/texture_cache/formatter.h"
#include "video_core/texture_cache/samples_helper.h"
@@ -61,6 +61,8 @@ using VideoCore::Surface::PixelFormatFromDepthFormat;
using VideoCore::Surface::PixelFormatFromRenderTargetFormat;
using VideoCore::Surface::SurfaceType;
constexpr u32 CONVERTED_BYTES_PER_BLOCK = BytesPerBlock(PixelFormat::A8B8G8R8_UNORM);
struct LevelInfo {
Extent3D size;
Extent3D block;
@@ -610,8 +612,7 @@ u32 CalculateConvertedSizeBytes(const ImageInfo& info) noexcept {
}
return output_size;
}
return NumBlocksPerLayer(info, TILE_SIZE) * info.resources.layers *
ConvertedBytesPerBlock(info.format);
return NumBlocksPerLayer(info, TILE_SIZE) * info.resources.layers * CONVERTED_BYTES_PER_BLOCK;
}
u32 CalculateLayerStride(const ImageInfo& info) noexcept {
@@ -944,8 +945,7 @@ void ConvertImage(std::span<const u8> input, const ImageInfo& info, std::span<u8
tile_size.height, output.subspan(output_offset));
output_offset += copy.image_extent.width * copy.image_extent.height *
copy.image_subresource.num_layers *
BytesPerBlock(PixelFormat::A8B8G8R8_UNORM);
copy.image_subresource.num_layers * CONVERTED_BYTES_PER_BLOCK;
} else if (astc) {
// BC1 uses 0.5 bytes per texel
// BC3 uses 1 byte per texel
@@ -956,8 +956,7 @@ void ConvertImage(std::span<const u8> input, const ImageInfo& info, std::span<u8
const u32 plane_dim = copy.image_extent.width * copy.image_extent.height;
const u32 level_size = plane_dim * copy.image_extent.depth *
copy.image_subresource.num_layers *
BytesPerBlock(PixelFormat::A8B8G8R8_UNORM);
copy.image_subresource.num_layers * CONVERTED_BYTES_PER_BLOCK;
decode_scratch.resize_destructive(level_size);
Tegra::Texture::ASTC::Decompress(
@@ -977,15 +976,10 @@ void ConvertImage(std::span<const u8> input, const ImageInfo& info, std::span<u8
bpp_div;
output_offset += static_cast<u32>(copy.buffer_size);
} else {
const Extent3D image_extent{
.width = copy.image_extent.width,
.height = copy.image_extent.height * copy.image_subresource.num_layers,
.depth = copy.image_extent.depth,
};
DecompressBCn(input_offset, output.subspan(output_offset), image_extent, info.format);
DecompressBC4(input_offset, copy.image_extent, output.subspan(output_offset));
output_offset += copy.image_extent.width * copy.image_extent.height *
copy.image_subresource.num_layers *
ConvertedBytesPerBlock(info.format);
copy.image_subresource.num_layers * CONVERTED_BYTES_PER_BLOCK;
}
}
}

View File

@@ -3,6 +3,7 @@
#include <stb_dxt.h>
#include <string.h>
#include "common/alignment.h"
#include "video_core/textures/bcn.h"
#include "video_core/textures/workers.h"

View File

@@ -4,13 +4,14 @@
#pragma once
#include <span>
#include "common/common_types.h"
#include <stdint.h>
namespace Tegra::Texture::BCN {
void CompressBC1(std::span<const u8> data, u32 width, u32 height, u32 depth, std::span<u8> output);
void CompressBC1(std::span<const uint8_t> data, uint32_t width, uint32_t height, uint32_t depth,
std::span<uint8_t> output);
void CompressBC3(std::span<const u8> data, u32 width, u32 height, u32 depth, std::span<u8> output);
void CompressBC3(std::span<const uint8_t> data, uint32_t width, uint32_t height, uint32_t depth,
std::span<uint8_t> output);
} // namespace Tegra::Texture::BCN

View File

@@ -7,10 +7,10 @@
namespace Vulkan {
namespace {
VkBool32 DebugUtilCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
VkDebugUtilsMessageTypeFlagsEXT type,
const VkDebugUtilsMessengerCallbackDataEXT* data,
[[maybe_unused]] void* user_data) {
VkBool32 Callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
VkDebugUtilsMessageTypeFlagsEXT type,
const VkDebugUtilsMessengerCallbackDataEXT* data,
[[maybe_unused]] void* user_data) {
// Skip logging known false-positive validation errors
switch (static_cast<u32>(data->messageIdNumber)) {
#ifdef ANDROID
@@ -62,26 +62,9 @@ VkBool32 DebugUtilCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
}
return VK_FALSE;
}
VkBool32 DebugReportCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType,
uint64_t object, size_t location, int32_t messageCode,
const char* pLayerPrefix, const char* pMessage, void* pUserData) {
const VkDebugReportFlagBitsEXT severity = static_cast<VkDebugReportFlagBitsEXT>(flags);
const std::string_view message{pMessage};
if (severity & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
LOG_CRITICAL(Render_Vulkan, "{}", message);
} else if (severity & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
LOG_WARNING(Render_Vulkan, "{}", message);
} else if (severity & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
LOG_INFO(Render_Vulkan, "{}", message);
} else if (severity & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
LOG_DEBUG(Render_Vulkan, "{}", message);
}
return VK_FALSE;
}
} // Anonymous namespace
vk::DebugUtilsMessenger CreateDebugUtilsCallback(const vk::Instance& instance) {
vk::DebugUtilsMessenger CreateDebugCallback(const vk::Instance& instance) {
return instance.CreateDebugUtilsMessenger(VkDebugUtilsMessengerCreateInfoEXT{
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
.pNext = nullptr,
@@ -93,18 +76,7 @@ vk::DebugUtilsMessenger CreateDebugUtilsCallback(const vk::Instance& instance) {
.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
.pfnUserCallback = DebugUtilCallback,
.pUserData = nullptr,
});
}
vk::DebugReportCallback CreateDebugReportCallback(const vk::Instance& instance) {
return instance.CreateDebugReportCallback({
.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT,
.pNext = nullptr,
.flags = VK_DEBUG_REPORT_DEBUG_BIT_EXT | VK_DEBUG_REPORT_INFORMATION_BIT_EXT |
VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT,
.pfnCallback = DebugReportCallback,
.pfnUserCallback = Callback,
.pUserData = nullptr,
});
}

View File

@@ -7,8 +7,6 @@
namespace Vulkan {
vk::DebugUtilsMessenger CreateDebugUtilsCallback(const vk::Instance& instance);
vk::DebugReportCallback CreateDebugReportCallback(const vk::Instance& instance);
vk::DebugUtilsMessenger CreateDebugCallback(const vk::Instance& instance);
} // namespace Vulkan

View File

@@ -349,7 +349,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
const bool is_s8gen2 = device_id == 0x43050a01;
const bool is_arm = driver_id == VK_DRIVER_ID_ARM_PROPRIETARY;
if ((is_mvk || is_qualcomm || is_turnip || is_arm) && !is_suitable) {
if ((is_mvk || is_qualcomm || is_turnip) && !is_suitable) {
LOG_WARNING(Render_Vulkan, "Unsuitable driver, continuing anyway");
} else if (!is_suitable) {
throw vk::Exception(VK_ERROR_INCOMPATIBLE_DRIVER);
@@ -905,10 +905,6 @@ bool Device::GetSuitability(bool requires_swapchain) {
properties.driver.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
SetNext(next, properties.driver);
// Retrieve subgroup properties.
properties.subgroup_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
SetNext(next, properties.subgroup_properties);
// Retrieve relevant extension properties.
if (extensions.shader_float_controls) {
properties.float_controls.sType =

View File

@@ -293,11 +293,6 @@ public:
return features.features.textureCompressionASTC_LDR;
}
/// Returns true if BCn is natively supported.
bool IsOptimalBcnSupported() const {
return features.features.textureCompressionBC;
}
/// Returns true if descriptor aliasing is natively supported.
bool IsDescriptorAliasingSupported() const {
return GetDriverID() != VK_DRIVER_ID_QUALCOMM_PROPRIETARY;
@@ -328,11 +323,6 @@ public:
return properties.subgroup_size_control.requiredSubgroupSizeStages & stage;
}
/// Returns true if the device supports the provided subgroup feature.
bool IsSubgroupFeatureSupported(VkSubgroupFeatureFlagBits feature) const {
return properties.subgroup_properties.supportedOperations & feature;
}
/// Returns the maximum number of push descriptors.
u32 MaxPushDescriptors() const {
return properties.push_descriptor.maxPushDescriptors;
@@ -398,11 +388,6 @@ public:
return extensions.swapchain_mutable_format;
}
/// Returns true if VK_KHR_shader_float_controls is enabled.
bool IsKhrShaderFloatControlsSupported() const {
return extensions.shader_float_controls;
}
/// Returns true if the device supports VK_KHR_workgroup_memory_explicit_layout.
bool IsKhrWorkgroupMemoryExplicitLayoutSupported() const {
return extensions.workgroup_memory_explicit_layout;
@@ -428,11 +413,6 @@ public:
return extensions.sampler_filter_minmax;
}
/// Returns true if the device supports VK_EXT_shader_stencil_export.
bool IsExtShaderStencilExportSupported() const {
return extensions.shader_stencil_export;
}
/// Returns true if the device supports VK_EXT_depth_range_unrestricted.
bool IsExtDepthRangeUnrestrictedSupported() const {
return extensions.depth_range_unrestricted;
@@ -502,9 +482,9 @@ public:
return extensions.vertex_input_dynamic_state;
}
/// Returns true if the device supports VK_EXT_shader_demote_to_helper_invocation
bool IsExtShaderDemoteToHelperInvocationSupported() const {
return extensions.shader_demote_to_helper_invocation;
/// Returns true if the device supports VK_EXT_shader_stencil_export.
bool IsExtShaderStencilExportSupported() const {
return extensions.shader_stencil_export;
}
/// Returns true if the device supports VK_EXT_conservative_rasterization.
@@ -538,12 +518,12 @@ public:
if (extensions.spirv_1_4) {
return 0x00010400U;
}
return 0x00010300U;
return 0x00010000U;
}
/// Returns true when a known debugging tool is attached.
bool HasDebuggingToolAttached() const {
return has_renderdoc || has_nsight_graphics;
return has_renderdoc || has_nsight_graphics || Settings::values.renderer_debug.GetValue();
}
/// @returns True if compute pipelines can cause crashing.
@@ -608,10 +588,6 @@ public:
return properties.properties.limits.maxVertexInputBindings;
}
u32 GetMaxViewports() const {
return properties.properties.limits.maxViewports;
}
bool SupportsConditionalBarriers() const {
return supports_conditional_barriers;
}
@@ -704,7 +680,6 @@ private:
struct Properties {
VkPhysicalDeviceDriverProperties driver{};
VkPhysicalDeviceSubgroupProperties subgroup_properties{};
VkPhysicalDeviceFloatControlsProperties float_controls{};
VkPhysicalDevicePushDescriptorPropertiesKHR push_descriptor{};
VkPhysicalDeviceSubgroupSizeControlProperties subgroup_size_control{};

View File

@@ -31,34 +31,10 @@
namespace Vulkan {
namespace {
[[nodiscard]] bool AreExtensionsSupported(const vk::InstanceDispatch& dld,
std::span<const char* const> extensions) {
const std::optional properties = vk::EnumerateInstanceExtensionProperties(dld);
if (!properties) {
LOG_ERROR(Render_Vulkan, "Failed to query extension properties");
return false;
}
for (const char* extension : extensions) {
const auto it = std::ranges::find_if(*properties, [extension](const auto& prop) {
return std::strcmp(extension, prop.extensionName) == 0;
});
if (it == properties->end()) {
LOG_ERROR(Render_Vulkan, "Required instance extension {} is not available", extension);
return false;
}
}
return true;
}
[[nodiscard]] std::vector<const char*> RequiredExtensions(
const vk::InstanceDispatch& dld, Core::Frontend::WindowSystemType window_type,
bool enable_validation) {
Core::Frontend::WindowSystemType window_type, bool enable_validation) {
std::vector<const char*> extensions;
extensions.reserve(6);
#ifdef __APPLE__
extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
#endif
switch (window_type) {
case Core::Frontend::WindowSystemType::Headless:
break;
@@ -90,14 +66,35 @@ namespace {
extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
}
if (enable_validation) {
const bool debug_utils =
AreExtensionsSupported(dld, std::array{VK_EXT_DEBUG_UTILS_EXTENSION_NAME});
extensions.push_back(debug_utils ? VK_EXT_DEBUG_UTILS_EXTENSION_NAME
: VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
}
extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
#ifdef __APPLE__
extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
#endif
return extensions;
}
[[nodiscard]] bool AreExtensionsSupported(const vk::InstanceDispatch& dld,
std::span<const char* const> extensions) {
const std::optional properties = vk::EnumerateInstanceExtensionProperties(dld);
if (!properties) {
LOG_ERROR(Render_Vulkan, "Failed to query extension properties");
return false;
}
for (const char* extension : extensions) {
const auto it = std::ranges::find_if(*properties, [extension](const auto& prop) {
return std::strcmp(extension, prop.extensionName) == 0;
});
if (it == properties->end()) {
LOG_ERROR(Render_Vulkan, "Required instance extension {} is not available", extension);
return false;
}
}
return true;
}
[[nodiscard]] std::vector<const char*> Layers(bool enable_validation) {
std::vector<const char*> layers;
if (enable_validation) {
@@ -141,8 +138,7 @@ vk::Instance CreateInstance(const Common::DynamicLibrary& library, vk::InstanceD
LOG_ERROR(Render_Vulkan, "Failed to load Vulkan function pointers");
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
}
const std::vector<const char*> extensions =
RequiredExtensions(dld, window_type, enable_validation);
const std::vector<const char*> extensions = RequiredExtensions(window_type, enable_validation);
if (!AreExtensionsSupported(dld, extensions)) {
throw vk::Exception(VK_ERROR_EXTENSION_NOT_PRESENT);
}

View File

@@ -259,9 +259,7 @@ bool Load(VkInstance instance, InstanceDispatch& dld) noexcept {
// These functions may fail to load depending on the enabled extensions.
// Don't return a failure on these.
X(vkCreateDebugUtilsMessengerEXT);
X(vkCreateDebugReportCallbackEXT);
X(vkDestroyDebugUtilsMessengerEXT);
X(vkDestroyDebugReportCallbackEXT);
X(vkDestroySurfaceKHR);
X(vkGetPhysicalDeviceFeatures2);
X(vkGetPhysicalDeviceProperties2);
@@ -483,11 +481,6 @@ void Destroy(VkInstance instance, VkDebugUtilsMessengerEXT handle,
dld.vkDestroyDebugUtilsMessengerEXT(instance, handle, nullptr);
}
void Destroy(VkInstance instance, VkDebugReportCallbackEXT handle,
const InstanceDispatch& dld) noexcept {
dld.vkDestroyDebugReportCallbackEXT(instance, handle, nullptr);
}
void Destroy(VkInstance instance, VkSurfaceKHR handle, const InstanceDispatch& dld) noexcept {
dld.vkDestroySurfaceKHR(instance, handle, nullptr);
}
@@ -556,13 +549,6 @@ DebugUtilsMessenger Instance::CreateDebugUtilsMessenger(
return DebugUtilsMessenger(object, handle, *dld);
}
DebugReportCallback Instance::CreateDebugReportCallback(
const VkDebugReportCallbackCreateInfoEXT& create_info) const {
VkDebugReportCallbackEXT object;
Check(dld->vkCreateDebugReportCallbackEXT(handle, &create_info, nullptr, &object));
return DebugReportCallback(object, handle, *dld);
}
void Image::SetObjectNameEXT(const char* name) const {
SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_IMAGE, name);
}

View File

@@ -164,10 +164,8 @@ struct InstanceDispatch {
PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties{};
PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT{};
PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT{};
PFN_vkCreateDevice vkCreateDevice{};
PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT{};
PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT{};
PFN_vkDestroyDevice vkDestroyDevice{};
PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR{};
PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties{};
@@ -368,7 +366,6 @@ void Destroy(VkDevice, VkSwapchainKHR, const DeviceDispatch&) noexcept;
void Destroy(VkDevice, VkSemaphore, const DeviceDispatch&) noexcept;
void Destroy(VkDevice, VkShaderModule, const DeviceDispatch&) noexcept;
void Destroy(VkInstance, VkDebugUtilsMessengerEXT, const InstanceDispatch&) noexcept;
void Destroy(VkInstance, VkDebugReportCallbackEXT, const InstanceDispatch&) noexcept;
void Destroy(VkInstance, VkSurfaceKHR, const InstanceDispatch&) noexcept;
VkResult Free(VkDevice, VkDescriptorPool, Span<VkDescriptorSet>, const DeviceDispatch&) noexcept;
@@ -584,7 +581,6 @@ private:
};
using DebugUtilsMessenger = Handle<VkDebugUtilsMessengerEXT, VkInstance, InstanceDispatch>;
using DebugReportCallback = Handle<VkDebugReportCallbackEXT, VkInstance, InstanceDispatch>;
using DescriptorSetLayout = Handle<VkDescriptorSetLayout, VkDevice, DeviceDispatch>;
using DescriptorUpdateTemplate = Handle<VkDescriptorUpdateTemplate, VkDevice, DeviceDispatch>;
using Pipeline = Handle<VkPipeline, VkDevice, DeviceDispatch>;
@@ -617,11 +613,6 @@ public:
DebugUtilsMessenger CreateDebugUtilsMessenger(
const VkDebugUtilsMessengerCreateInfoEXT& create_info) const;
/// Creates a debug report callback.
/// @throw Exception on creation failure.
DebugReportCallback CreateDebugReportCallback(
const VkDebugReportCallbackCreateInfoEXT& create_info) const;
/// Returns dispatch table.
const InstanceDispatch& Dispatch() const noexcept {
return *dld;