renderer_vulkan: Drop VK prefix
* All the classes are in the Vulkan namespace, thus making it superfluous
This commit is contained in:
@@ -238,7 +238,7 @@ void RendererVulkan::CreateVulkanObjects() {
|
||||
//ReloadSampler();
|
||||
|
||||
// Generate VBO handle for drawing
|
||||
VKBuffer::Info vertex_info{
|
||||
Buffer::Info vertex_info{
|
||||
.size = sizeof(ScreenRectVertex) * 10,
|
||||
.properties = vk::MemoryPropertyFlagBits::eDeviceLocal,
|
||||
.usage = vk::BufferUsageFlagBits::eVertexBuffer |
|
||||
@@ -250,7 +250,7 @@ void RendererVulkan::CreateVulkanObjects() {
|
||||
void RendererVulkan::ConfigureFramebufferTexture(ScreenInfo& screen, const GPU::Regs::FramebufferConfig& framebuffer) {
|
||||
screen.format = framebuffer.color_format;
|
||||
|
||||
VKTexture::Info texture_info{
|
||||
Texture::Info texture_info{
|
||||
.width = framebuffer.width,
|
||||
.height = framebuffer.height,
|
||||
.type = vk::ImageType::e2D,
|
||||
@@ -582,13 +582,13 @@ VideoCore::ResultStatus RendererVulkan::Init() {
|
||||
|
||||
// Create global instance
|
||||
auto surface = CreateSurface(instance, render_window);
|
||||
g_vk_instace = std::make_unique<VKInstance>();
|
||||
g_vk_task_scheduler = std::make_unique<VKTaskScheduler>();
|
||||
g_vk_instace = std::make_unique<Instance>();
|
||||
g_vk_task_scheduler = std::make_unique<TaskScheduler>();
|
||||
g_vk_instace->Create(instance, physical_devices[1], surface, true);
|
||||
g_vk_task_scheduler->Create();
|
||||
|
||||
//auto& layout = render_window.GetFramebufferLayout();
|
||||
swapchain = std::make_shared<VKSwapChain>(surface);
|
||||
swapchain = std::make_shared<Swapchain>(surface);
|
||||
//swapchain->Create(layout.width, layout.height, false);
|
||||
|
||||
// Create Vulkan state
|
||||
|
@@ -20,9 +20,9 @@ namespace Vulkan {
|
||||
|
||||
/// Structure used for storing information about the display target for each 3DS screen
|
||||
struct ScreenInfo {
|
||||
VKTexture* display_texture;
|
||||
Texture* display_texture;
|
||||
Common::Rectangle<float> display_texcoords;
|
||||
VKTexture texture;
|
||||
Texture texture;
|
||||
GPU::Regs::PixelFormat format;
|
||||
};
|
||||
|
||||
@@ -68,7 +68,7 @@ private:
|
||||
|
||||
/// Display information for top and bottom screens respectively
|
||||
std::array<ScreenInfo, 3> screen_infos;
|
||||
std::shared_ptr<VKSwapChain> swapchain;
|
||||
std::shared_ptr<Swapchain> swapchain;
|
||||
};
|
||||
|
||||
} // namespace OpenGL
|
||||
|
@@ -12,11 +12,11 @@
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
VKBuffer::~VKBuffer() {
|
||||
Buffer::~Buffer() {
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void VKBuffer::Create(const VKBuffer::Info& info) {
|
||||
void Buffer::Create(const Buffer::Info& info) {
|
||||
auto device = g_vk_instace->GetDevice();
|
||||
buffer_info = info;
|
||||
|
||||
@@ -43,12 +43,12 @@ void VKBuffer::Create(const VKBuffer::Info& info) {
|
||||
}
|
||||
}
|
||||
|
||||
void VKBuffer::Recreate() {
|
||||
void Buffer::Recreate() {
|
||||
Destroy();
|
||||
Create(buffer_info);
|
||||
}
|
||||
|
||||
void VKBuffer::Destroy() {
|
||||
void Buffer::Destroy() {
|
||||
if (buffer) {
|
||||
if (host_ptr != nullptr) {
|
||||
g_vk_instace->GetDevice().unmapMemory(memory);
|
||||
@@ -71,7 +71,7 @@ void VKBuffer::Destroy() {
|
||||
}
|
||||
}
|
||||
|
||||
u32 VKBuffer::FindMemoryType(u32 type_filter, vk::MemoryPropertyFlags properties) {
|
||||
u32 Buffer::FindMemoryType(u32 type_filter, vk::MemoryPropertyFlags properties) {
|
||||
vk::PhysicalDeviceMemoryProperties mem_properties = g_vk_instace->GetPhysicalDevice().getMemoryProperties();
|
||||
|
||||
for (uint32_t i = 0; i < mem_properties.memoryTypeCount; i++)
|
||||
@@ -85,7 +85,7 @@ u32 VKBuffer::FindMemoryType(u32 type_filter, vk::MemoryPropertyFlags properties
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
void VKBuffer::Upload(std::span<const std::byte> data, u32 offset,
|
||||
void Buffer::Upload(std::span<const std::byte> data, u32 offset,
|
||||
vk::AccessFlags access_to_block,
|
||||
vk::PipelineStageFlags stage_to_block) {
|
||||
auto cmdbuffer = g_vk_task_scheduler->GetUploadCommandBuffer();
|
||||
|
@@ -17,7 +17,7 @@ constexpr u32 MAX_BUFFER_VIEWS = 5;
|
||||
constexpr u32 MAX_COMMIT_CHUNKS = 6;
|
||||
|
||||
/// Generic Vulkan buffer object used by almost every resource
|
||||
class VKBuffer : public NonCopyable {
|
||||
class Buffer : public NonCopyable {
|
||||
public:
|
||||
struct Info {
|
||||
u32 size;
|
||||
@@ -26,12 +26,12 @@ public:
|
||||
std::array<vk::Format, MAX_BUFFER_VIEWS> view_formats{};
|
||||
};
|
||||
|
||||
VKBuffer() = default;
|
||||
~VKBuffer();
|
||||
Buffer() = default;
|
||||
~Buffer();
|
||||
|
||||
/// Enable move operations
|
||||
VKBuffer(VKBuffer&&) = default;
|
||||
VKBuffer& operator=(VKBuffer&&) = default;
|
||||
Buffer(Buffer&&) = default;
|
||||
Buffer& operator=(Buffer&&) = default;
|
||||
|
||||
/// Create a new Vulkan buffer object
|
||||
void Create(const Info& info);
|
||||
@@ -60,7 +60,7 @@ protected:
|
||||
u32 view_count{};
|
||||
};
|
||||
|
||||
class StreamBuffer : public VKBuffer {
|
||||
class StreamBuffer : public Buffer {
|
||||
public:
|
||||
/*
|
||||
* Allocates a linear chunk of memory in the GPU buffer with at least "size" bytes
|
||||
|
@@ -9,16 +9,16 @@
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
std::unique_ptr<VKInstance> g_vk_instace;
|
||||
std::unique_ptr<Instance> g_vk_instace;
|
||||
|
||||
VKInstance::~VKInstance() {
|
||||
Instance::~Instance() {
|
||||
device.waitIdle();
|
||||
|
||||
device.destroy();
|
||||
instance.destroy();
|
||||
}
|
||||
|
||||
bool VKInstance::Create(vk::Instance new_instance, vk::PhysicalDevice gpu,
|
||||
bool Instance::Create(vk::Instance new_instance, vk::PhysicalDevice gpu,
|
||||
vk::SurfaceKHR surface, bool enable_validation_layer) {
|
||||
instance = new_instance;
|
||||
physical_device = gpu;
|
||||
@@ -34,7 +34,7 @@ bool VKInstance::Create(vk::Instance new_instance, vk::PhysicalDevice gpu,
|
||||
return CreateDevice(surface, enable_validation_layer);
|
||||
}
|
||||
|
||||
bool VKInstance::CreateDevice(vk::SurfaceKHR surface, bool validation_enabled) {
|
||||
bool Instance::CreateDevice(vk::SurfaceKHR surface, bool validation_enabled) {
|
||||
// Can't create an instance without a valid surface
|
||||
if (!surface) {
|
||||
LOG_CRITICAL(Render_Vulkan, "Invalid surface provided during instance creation!");
|
||||
@@ -106,7 +106,7 @@ bool VKInstance::CreateDevice(vk::SurfaceKHR surface, bool validation_enabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VKInstance::FindFeatures() {
|
||||
bool Instance::FindFeatures() {
|
||||
auto available = physical_device.getFeatures();
|
||||
|
||||
// Not having geometry shaders or wide lines will cause issues with rendering.
|
||||
@@ -146,7 +146,7 @@ bool VKInstance::FindFeatures() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VKInstance::FindExtensions() {
|
||||
bool Instance::FindExtensions() {
|
||||
auto available = physical_device.enumerateDeviceExtensionProperties();
|
||||
if (available.empty()) {
|
||||
LOG_CRITICAL(Render_Vulkan, "No extensions supported by device.");
|
||||
|
@@ -13,10 +13,10 @@
|
||||
namespace Vulkan {
|
||||
|
||||
/// The global Vulkan instance
|
||||
class VKInstance {
|
||||
class Instance {
|
||||
public:
|
||||
VKInstance() = default;
|
||||
~VKInstance();
|
||||
Instance() = default;
|
||||
~Instance();
|
||||
|
||||
/// Construct global Vulkan context
|
||||
bool Create(vk::Instance instance, vk::PhysicalDevice gpu,
|
||||
@@ -65,6 +65,6 @@ public:
|
||||
vk::PhysicalDeviceColorWriteEnableFeaturesEXT color_write_features{};
|
||||
};
|
||||
|
||||
extern std::unique_ptr<VKInstance> g_vk_instace;
|
||||
extern std::unique_ptr<Instance> g_vk_instace;
|
||||
|
||||
} // namespace Vulkan
|
||||
|
@@ -66,7 +66,7 @@ RasterizerVulkan::RasterizerVulkan(Frontend::EmuWindow& emu_window) {
|
||||
uniform_size_aligned_fs = Common::AlignUp<std::size_t>(sizeof(UniformData),
|
||||
uniform_buffer_alignment);
|
||||
// Allocate texture buffer LUTs
|
||||
VKBuffer::Info texel_buffer_info = {
|
||||
Buffer::Info texel_buffer_info = {
|
||||
.size = TEXTURE_BUFFER_SIZE,
|
||||
.properties = vk::MemoryPropertyFlagBits::eDeviceLocal,
|
||||
.usage = vk::BufferUsageFlagBits::eUniformTexelBuffer |
|
||||
@@ -80,7 +80,7 @@ RasterizerVulkan::RasterizerVulkan(Frontend::EmuWindow& emu_window) {
|
||||
texture_buffer_lut.Create(texel_buffer_info);
|
||||
|
||||
// Create and bind uniform buffers
|
||||
VKBuffer::Info uniform_info = {
|
||||
Buffer::Info uniform_info = {
|
||||
.size = UNIFORM_BUFFER_SIZE,
|
||||
.properties = vk::MemoryPropertyFlagBits::eDeviceLocal,
|
||||
.usage = vk::BufferUsageFlagBits::eUniformBuffer |
|
||||
@@ -98,14 +98,14 @@ RasterizerVulkan::RasterizerVulkan(Frontend::EmuWindow& emu_window) {
|
||||
state.SetTexelBuffer(2, 0, TEXTURE_BUFFER_SIZE, texture_buffer_lut, 1);
|
||||
|
||||
// Create vertex and index buffers
|
||||
VKBuffer::Info vertex_info = {
|
||||
Buffer::Info vertex_info = {
|
||||
.size = VERTEX_BUFFER_SIZE,
|
||||
.properties = vk::MemoryPropertyFlagBits::eDeviceLocal,
|
||||
.usage = vk::BufferUsageFlagBits::eVertexBuffer |
|
||||
vk::BufferUsageFlagBits::eTransferDst
|
||||
};
|
||||
|
||||
VKBuffer::Info index_info = {
|
||||
Buffer::Info index_info = {
|
||||
.size = INDEX_BUFFER_SIZE,
|
||||
.properties = vk::MemoryPropertyFlagBits::eDeviceLocal,
|
||||
.usage = vk::BufferUsageFlagBits::eIndexBuffer |
|
||||
@@ -328,7 +328,7 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) {
|
||||
}
|
||||
|
||||
// Sync and bind the texture surfaces
|
||||
VKTexture temp_tex;
|
||||
Texture temp_tex;
|
||||
const auto pica_textures = regs.texturing.GetTextures();
|
||||
for (unsigned texture_index = 0; texture_index < pica_textures.size(); ++texture_index) {
|
||||
const auto& texture = pica_textures[texture_index];
|
||||
|
@@ -276,7 +276,7 @@ private:
|
||||
static constexpr std::size_t UNIFORM_BUFFER_SIZE = 2 * 1024 * 1024;
|
||||
static constexpr std::size_t TEXTURE_BUFFER_SIZE = 1 * 1024 * 1024;
|
||||
|
||||
VKBuffer vertex_buffer, index_buffer;
|
||||
Buffer vertex_buffer, index_buffer;
|
||||
StreamBuffer uniform_buffer, texture_buffer_lut_lf, texture_buffer_lut;
|
||||
|
||||
u32 uniform_buffer_alignment;
|
||||
|
@@ -374,7 +374,7 @@ static vk::Rect2D FromRect(Common::Rectangle<u32> rect) {
|
||||
}
|
||||
|
||||
// Allocate an uninitialized texture of appropriate size and format for the surface
|
||||
void RasterizerCacheVulkan::AllocateTexture(VKTexture& target, SurfaceType type, vk::Format format,
|
||||
void RasterizerCacheVulkan::AllocateTexture(Texture& target, SurfaceType type, vk::Format format,
|
||||
u32 width, u32 height) {
|
||||
// First check if the texture can be recycled
|
||||
auto recycled_tex = host_texture_recycler.find({format, width, height});
|
||||
@@ -408,7 +408,7 @@ void RasterizerCacheVulkan::AllocateTexture(VKTexture& target, SurfaceType type,
|
||||
|
||||
// Otherwise create a brand new texture
|
||||
u32 levels = std::log2(std::max(width, height)) + 1;
|
||||
VKTexture::Info texture_info{
|
||||
Texture::Info texture_info{
|
||||
.width = width,
|
||||
.height = height,
|
||||
.format = format,
|
||||
|
@@ -176,7 +176,7 @@ struct CachedSurface : SurfaceParams, std::enable_shared_from_this<CachedSurface
|
||||
u32 fill_size = 0; /// Number of bytes to read from fill_data
|
||||
std::array<u8, 4> fill_data;
|
||||
|
||||
VKTexture texture;
|
||||
Texture texture;
|
||||
|
||||
/// max mipmap level that has been attached to the texture
|
||||
u32 max_level = 0;
|
||||
@@ -234,7 +234,7 @@ private:
|
||||
};
|
||||
|
||||
struct CachedTextureCube {
|
||||
VKTexture texture;
|
||||
Texture texture;
|
||||
u16 res_scale = 1;
|
||||
std::shared_ptr<SurfaceWatcher> px;
|
||||
std::shared_ptr<SurfaceWatcher> nx;
|
||||
@@ -298,7 +298,7 @@ public:
|
||||
// in the driver
|
||||
// this must be placed above the surface_cache to ensure all cached surfaces are destroyed
|
||||
// before destroying the recycler
|
||||
std::unordered_multimap<HostTextureTag, VKTexture> host_texture_recycler;
|
||||
std::unordered_multimap<HostTextureTag, Texture> host_texture_recycler;
|
||||
|
||||
private:
|
||||
void DuplicateSurface(const Surface& src_surface, const Surface& dest_surface);
|
||||
@@ -342,7 +342,7 @@ private:
|
||||
std::recursive_mutex mutex;
|
||||
|
||||
public:
|
||||
void AllocateTexture(VKTexture& target, SurfaceParams::SurfaceType type, vk::Format format,
|
||||
void AllocateTexture(Texture& target, SurfaceParams::SurfaceType type, vk::Format format,
|
||||
u32 width, u32 height);
|
||||
std::unique_ptr<FormatReinterpreterVulkan> format_reinterpreter;
|
||||
};
|
||||
|
@@ -78,9 +78,9 @@ void DescriptorUpdater::PushBufferUpdate(vk::DescriptorSet set, u32 binding,
|
||||
view ? &view : nullptr};
|
||||
}
|
||||
|
||||
VulkanState::VulkanState(const std::shared_ptr<VKSwapChain>& swapchain) : swapchain(swapchain) {
|
||||
VulkanState::VulkanState(const std::shared_ptr<Swapchain>& swapchain) : swapchain(swapchain) {
|
||||
// Create a placeholder texture which can be used in place of a real binding.
|
||||
VKTexture::Info info{
|
||||
Texture::Info info{
|
||||
.width = 1,
|
||||
.height = 1,
|
||||
.format = vk::Format::eR8G8B8A8Unorm,
|
||||
@@ -158,7 +158,7 @@ VulkanState::~VulkanState() {
|
||||
device.destroyPipeline(present_pipeline);
|
||||
}
|
||||
|
||||
void VulkanState::Create(const std::shared_ptr<VKSwapChain>& swapchain) {
|
||||
void VulkanState::Create(const std::shared_ptr<Swapchain>& swapchain) {
|
||||
if (!s_vulkan_state) {
|
||||
s_vulkan_state = std::make_unique<VulkanState>(swapchain);
|
||||
}
|
||||
@@ -169,12 +169,12 @@ VulkanState& VulkanState::Get() {
|
||||
return *s_vulkan_state;
|
||||
}
|
||||
|
||||
void VulkanState::SetVertexBuffer(const VKBuffer& buffer, vk::DeviceSize offset) {
|
||||
void VulkanState::SetVertexBuffer(const Buffer& buffer, vk::DeviceSize offset) {
|
||||
auto cmdbuffer = g_vk_task_scheduler->GetRenderCommandBuffer();
|
||||
cmdbuffer.bindVertexBuffers(0, buffer.GetBuffer(), offset);
|
||||
}
|
||||
|
||||
void VulkanState::SetUniformBuffer(u32 binding, u32 offset, u32 size, const VKBuffer& buffer) {
|
||||
void VulkanState::SetUniformBuffer(u32 binding, u32 offset, u32 size, const Buffer& buffer) {
|
||||
auto& set = descriptor_sets[0];
|
||||
updater.PushBufferUpdate(set, binding,
|
||||
vk::DescriptorType::eUniformBuffer,
|
||||
@@ -182,14 +182,14 @@ void VulkanState::SetUniformBuffer(u32 binding, u32 offset, u32 size, const VKBu
|
||||
descriptors_dirty = true;
|
||||
}
|
||||
|
||||
void VulkanState::SetTexture(u32 binding, const VKTexture& image) {
|
||||
void VulkanState::SetTexture(u32 binding, const Texture& image) {
|
||||
auto& set = descriptor_sets[1];
|
||||
updater.PushCombinedImageSamplerUpdate(set, binding, render_sampler, image.GetView());
|
||||
render_views[binding] = image.GetView();
|
||||
descriptors_dirty = true;
|
||||
}
|
||||
|
||||
void VulkanState::SetTexelBuffer(u32 binding, u32 offset, u32 size, const VKBuffer& buffer, u32 view_index) {
|
||||
void VulkanState::SetTexelBuffer(u32 binding, u32 offset, u32 size, const Buffer& buffer, u32 view_index) {
|
||||
auto& set = descriptor_sets[2];
|
||||
updater.PushBufferUpdate(set, binding,
|
||||
vk::DescriptorType::eUniformTexelBuffer,
|
||||
@@ -218,7 +218,7 @@ void VulkanState::SetPlaceholderColor(u8 red, u8 green, u8 blue, u8 alpha) {
|
||||
placeholder.Upload(0, 0, 1, placeholder.GetArea(), color);
|
||||
}
|
||||
|
||||
void VulkanState::UnbindTexture(const VKTexture& image) {
|
||||
void VulkanState::UnbindTexture(const Texture& image) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (render_views[i] == image.GetView()) {
|
||||
render_views[i] = placeholder.GetView();
|
||||
@@ -243,7 +243,7 @@ void VulkanState::UnbindTexture(u32 unit) {
|
||||
descriptors_dirty = true;
|
||||
}
|
||||
|
||||
void VulkanState::BeginRendering(VKTexture* color, VKTexture* depth, bool update_pipeline_formats,
|
||||
void VulkanState::BeginRendering(Texture* color, Texture* depth, bool update_pipeline_formats,
|
||||
vk::ClearColorValue color_clear, vk::AttachmentLoadOp color_load_op,
|
||||
vk::AttachmentStoreOp color_store_op, vk::ClearDepthStencilValue depth_clear,
|
||||
vk::AttachmentLoadOp depth_load_op, vk::AttachmentStoreOp depth_store_op,
|
||||
|
@@ -54,16 +54,16 @@ private:
|
||||
u32 image_count{0}, buffer_count{0}, write_count{0};
|
||||
};
|
||||
|
||||
class VKSwapChain;
|
||||
class Swapchain;
|
||||
|
||||
/// Tracks global Vulkan state
|
||||
class VulkanState {
|
||||
public:
|
||||
VulkanState(const std::shared_ptr<VKSwapChain>& swapchain);
|
||||
VulkanState(const std::shared_ptr<Swapchain>& swapchain);
|
||||
~VulkanState();
|
||||
|
||||
/// Initialize object to its initial state
|
||||
static void Create(const std::shared_ptr<VKSwapChain>& swapchain);
|
||||
static void Create(const std::shared_ptr<Swapchain>& swapchain);
|
||||
static VulkanState& Get();
|
||||
|
||||
/// Query state
|
||||
@@ -71,7 +71,7 @@ public:
|
||||
bool StencilTestEnabled() const { return stencil_enabled && stencil_writes; }
|
||||
|
||||
/// Configure drawing state
|
||||
void SetVertexBuffer(const VKBuffer& buffer, vk::DeviceSize offset);
|
||||
void SetVertexBuffer(const Buffer& buffer, vk::DeviceSize offset);
|
||||
void SetViewport(vk::Viewport viewport);
|
||||
void SetScissor(vk::Rect2D scissor);
|
||||
void SetCullMode(vk::CullModeFlags flags);
|
||||
@@ -90,7 +90,7 @@ public:
|
||||
vk::BlendFactor src_alpha, vk::BlendFactor dst_alpha);
|
||||
|
||||
/// Rendering
|
||||
void BeginRendering(VKTexture* color, VKTexture* depth, bool update_pipeline_formats = false,
|
||||
void BeginRendering(Texture* color, Texture* depth, bool update_pipeline_formats = false,
|
||||
vk::ClearColorValue color_clear = {},
|
||||
vk::AttachmentLoadOp color_load_op = vk::AttachmentLoadOp::eLoad,
|
||||
vk::AttachmentStoreOp color_store_op = vk::AttachmentStoreOp::eStore,
|
||||
@@ -102,13 +102,13 @@ public:
|
||||
void EndRendering();
|
||||
|
||||
/// Configure shader resources
|
||||
void SetUniformBuffer(u32 binding, u32 offset, u32 size, const VKBuffer& buffer);
|
||||
void SetTexture(u32 binding, const VKTexture& texture);
|
||||
void SetTexelBuffer(u32 binding, u32 offset, u32 size, const VKBuffer& buffer, u32 view_index);
|
||||
void SetUniformBuffer(u32 binding, u32 offset, u32 size, const Buffer& buffer);
|
||||
void SetTexture(u32 binding, const Texture& texture);
|
||||
void SetTexelBuffer(u32 binding, u32 offset, u32 size, const Buffer& buffer, u32 view_index);
|
||||
void SetPresentTextures(vk::ImageView view0, vk::ImageView view1, vk::ImageView view2);
|
||||
void SetPresentData(DrawInfo data);
|
||||
void SetPlaceholderColor(u8 red, u8 green, u8 blue, u8 alpha);
|
||||
void UnbindTexture(const VKTexture& image);
|
||||
void UnbindTexture(const Texture& image);
|
||||
void UnbindTexture(u32 unit);
|
||||
|
||||
/// Apply all dirty state to the current Vulkan command buffer
|
||||
@@ -124,12 +124,12 @@ private:
|
||||
|
||||
private:
|
||||
// Render targets
|
||||
std::shared_ptr<VKSwapChain> swapchain;
|
||||
std::shared_ptr<Swapchain> swapchain;
|
||||
bool rendering{false};
|
||||
vk::ImageView present_view;
|
||||
std::array<vk::ImageView, 4> render_views;
|
||||
vk::Sampler render_sampler, present_sampler;
|
||||
VKTexture placeholder;
|
||||
Texture placeholder;
|
||||
|
||||
// Render state
|
||||
bool descriptors_dirty{};
|
||||
|
@@ -13,11 +13,11 @@
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
VKSwapChain::VKSwapChain(vk::SurfaceKHR surface_) : surface(surface_) {
|
||||
Swapchain::Swapchain(vk::SurfaceKHR surface_) : surface(surface_) {
|
||||
|
||||
}
|
||||
|
||||
VKSwapChain::~VKSwapChain() {
|
||||
Swapchain::~Swapchain() {
|
||||
auto device = g_vk_instace->GetDevice();
|
||||
auto instance = g_vk_instace->GetInstance();
|
||||
device.waitIdle();
|
||||
@@ -28,7 +28,7 @@ VKSwapChain::~VKSwapChain() {
|
||||
instance.destroySurfaceKHR(surface);
|
||||
}
|
||||
|
||||
bool VKSwapChain::Create(u32 width, u32 height, bool vsync_enabled) {
|
||||
bool Swapchain::Create(u32 width, u32 height, bool vsync_enabled) {
|
||||
is_outdated = false;
|
||||
is_suboptimal = false;
|
||||
|
||||
@@ -80,7 +80,7 @@ bool VKSwapChain::Create(u32 width, u32 height, bool vsync_enabled) {
|
||||
// Wait for maximum of 1 second
|
||||
constexpr u64 ACQUIRE_TIMEOUT = 1000000000;
|
||||
|
||||
void VKSwapChain::AcquireNextImage() {
|
||||
void Swapchain::AcquireNextImage() {
|
||||
auto result = g_vk_instace->GetDevice().acquireNextImageKHR(swapchain, ACQUIRE_TIMEOUT,
|
||||
image_available, VK_NULL_HANDLE,
|
||||
&image_index);
|
||||
@@ -99,7 +99,7 @@ void VKSwapChain::AcquireNextImage() {
|
||||
}
|
||||
}
|
||||
|
||||
void VKSwapChain::Present() {
|
||||
void Swapchain::Present() {
|
||||
const auto present_queue = g_vk_instace->GetPresentQueue();
|
||||
|
||||
vk::PresentInfoKHR present_info(render_finished, swapchain, image_index);
|
||||
@@ -122,7 +122,7 @@ void VKSwapChain::Present() {
|
||||
frame_index = (frame_index + 1) % swapchain_images.size();
|
||||
}
|
||||
|
||||
void VKSwapChain::PopulateSwapchainDetails(vk::SurfaceKHR surface, u32 width, u32 height) {
|
||||
void Swapchain::PopulateSwapchainDetails(vk::SurfaceKHR surface, u32 width, u32 height) {
|
||||
auto gpu = g_vk_instace->GetPhysicalDevice();
|
||||
|
||||
// Choose surface format
|
||||
@@ -184,12 +184,12 @@ void VKSwapChain::PopulateSwapchainDetails(vk::SurfaceKHR surface, u32 width, u3
|
||||
}
|
||||
}
|
||||
|
||||
void VKSwapChain::SetupImages() {
|
||||
void Swapchain::SetupImages() {
|
||||
// Get the swap chain images
|
||||
auto device = g_vk_instace->GetDevice();
|
||||
auto images = device.getSwapchainImagesKHR(swapchain);
|
||||
|
||||
VKTexture::Info image_info{
|
||||
Texture::Info image_info{
|
||||
.width = details.extent.width,
|
||||
.height = details.extent.height,
|
||||
.format = details.format.format,
|
||||
@@ -201,7 +201,7 @@ void VKSwapChain::SetupImages() {
|
||||
// Create the swapchain buffers containing the image and imageview
|
||||
swapchain_images.resize(images.size());
|
||||
for (int i = 0; i < swapchain_images.size(); i++) {
|
||||
// Wrap swapchain images with VKTexture
|
||||
// Wrap swapchain images with Texture
|
||||
swapchain_images[i].Adopt(image_info, images[i]);
|
||||
}
|
||||
}
|
||||
|
@@ -18,10 +18,10 @@ struct SwapChainDetails {
|
||||
u32 image_count;
|
||||
};
|
||||
|
||||
class VKSwapChain {
|
||||
class Swapchain {
|
||||
public:
|
||||
VKSwapChain(vk::SurfaceKHR surface);
|
||||
~VKSwapChain();
|
||||
Swapchain(vk::SurfaceKHR surface);
|
||||
~Swapchain();
|
||||
|
||||
/// Creates (or recreates) the swapchain with a given size.
|
||||
bool Create(u32 width, u32 height, bool vsync_enabled);
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
vk::SwapchainKHR GetSwapChain() const { return swapchain; }
|
||||
const vk::Semaphore& GetAvailableSemaphore() const { return image_available; }
|
||||
const vk::Semaphore& GetRenderSemaphore() const { return render_finished; }
|
||||
VKTexture& GetCurrentImage() { return swapchain_images[image_index]; }
|
||||
Texture& GetCurrentImage() { return swapchain_images[image_index]; }
|
||||
|
||||
private:
|
||||
void PopulateSwapchainDetails(vk::SurfaceKHR surface, u32 width, u32 height);
|
||||
@@ -57,7 +57,7 @@ private:
|
||||
bool vsync_enabled{false}, is_outdated{true}, is_suboptimal{true};
|
||||
|
||||
vk::SwapchainKHR swapchain{VK_NULL_HANDLE};
|
||||
std::vector<VKTexture> swapchain_images;
|
||||
std::vector<Texture> swapchain_images;
|
||||
u32 image_index{0}, frame_index{0};
|
||||
};
|
||||
|
||||
|
@@ -10,7 +10,7 @@
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
VKTaskScheduler::~VKTaskScheduler() {
|
||||
TaskScheduler::~TaskScheduler() {
|
||||
// Destroy Vulkan resources
|
||||
auto device = g_vk_instace->GetDevice();
|
||||
device.waitIdle();
|
||||
@@ -25,7 +25,7 @@ VKTaskScheduler::~VKTaskScheduler() {
|
||||
device.destroySemaphore(timeline);
|
||||
}
|
||||
|
||||
std::tuple<u8*, u32> VKTaskScheduler::RequestStaging(u32 size) {
|
||||
std::tuple<u8*, u32> TaskScheduler::RequestStaging(u32 size) {
|
||||
auto& task = tasks[current_task];
|
||||
if (size > STAGING_BUFFER_SIZE - task.current_offset) {
|
||||
// If we run out of space, allocate a new buffer.
|
||||
@@ -43,11 +43,11 @@ std::tuple<u8*, u32> VKTaskScheduler::RequestStaging(u32 size) {
|
||||
return std::make_tuple(ptr, task.current_offset - size);
|
||||
}
|
||||
|
||||
VKBuffer& VKTaskScheduler::GetStaging() {
|
||||
Buffer& TaskScheduler::GetStaging() {
|
||||
return tasks[current_task].staging;
|
||||
}
|
||||
|
||||
bool VKTaskScheduler::Create() {
|
||||
bool TaskScheduler::Create() {
|
||||
auto device = g_vk_instace->GetDevice();
|
||||
|
||||
// Create command pool
|
||||
@@ -61,7 +61,7 @@ bool VKTaskScheduler::Create() {
|
||||
|
||||
timeline = device.createSemaphore(semaphore_info);
|
||||
|
||||
VKBuffer::Info staging_info{
|
||||
Buffer::Info staging_info{
|
||||
.size = STAGING_BUFFER_SIZE,
|
||||
.properties = vk::MemoryPropertyFlagBits::eHostVisible |
|
||||
vk::MemoryPropertyFlagBits::eHostCoherent,
|
||||
@@ -89,12 +89,12 @@ bool VKTaskScheduler::Create() {
|
||||
return true;
|
||||
}
|
||||
|
||||
vk::CommandBuffer VKTaskScheduler::GetRenderCommandBuffer() const {
|
||||
vk::CommandBuffer TaskScheduler::GetRenderCommandBuffer() const {
|
||||
const auto& task = tasks[current_task];
|
||||
return task.command_buffers[1];
|
||||
}
|
||||
|
||||
vk::CommandBuffer VKTaskScheduler::GetUploadCommandBuffer() {
|
||||
vk::CommandBuffer TaskScheduler::GetUploadCommandBuffer() {
|
||||
auto& task = tasks[current_task];
|
||||
if (!task.use_upload_buffer) {
|
||||
auto& cmdbuffer = task.command_buffers[0];
|
||||
@@ -105,12 +105,12 @@ vk::CommandBuffer VKTaskScheduler::GetUploadCommandBuffer() {
|
||||
return task.command_buffers[0];
|
||||
}
|
||||
|
||||
vk::DescriptorPool VKTaskScheduler::GetDescriptorPool() const {
|
||||
vk::DescriptorPool TaskScheduler::GetDescriptorPool() const {
|
||||
const auto& task = tasks[current_task];
|
||||
return task.pool;
|
||||
}
|
||||
|
||||
void VKTaskScheduler::SyncToGPU(u64 task_index) {
|
||||
void TaskScheduler::SyncToGPU(u64 task_index) {
|
||||
// No need to sync if the GPU already has finished the task
|
||||
auto tick = GetGPUTick();
|
||||
if (tasks[task_index].task_id <= tick) {
|
||||
@@ -140,20 +140,20 @@ void VKTaskScheduler::SyncToGPU(u64 task_index) {
|
||||
}
|
||||
}
|
||||
|
||||
void VKTaskScheduler::SyncToGPU() {
|
||||
void TaskScheduler::SyncToGPU() {
|
||||
SyncToGPU(current_task);
|
||||
}
|
||||
|
||||
u64 VKTaskScheduler::GetCPUTick() const {
|
||||
u64 TaskScheduler::GetCPUTick() const {
|
||||
return current_task_id;
|
||||
}
|
||||
|
||||
u64 VKTaskScheduler::GetGPUTick() const {
|
||||
u64 TaskScheduler::GetGPUTick() const {
|
||||
auto device = g_vk_instace->GetDevice();
|
||||
return device.getSemaphoreCounterValue(timeline);
|
||||
}
|
||||
|
||||
void VKTaskScheduler::Submit(bool wait_completion, bool present, VKSwapChain* swapchain) {
|
||||
void TaskScheduler::Submit(bool wait_completion, bool present, Swapchain* swapchain) {
|
||||
// End the current task recording.
|
||||
auto& task = tasks[current_task];
|
||||
|
||||
@@ -209,12 +209,12 @@ void VKTaskScheduler::Submit(bool wait_completion, bool present, VKSwapChain* sw
|
||||
BeginTask();
|
||||
}
|
||||
|
||||
void VKTaskScheduler::Schedule(std::function<void()> func) {
|
||||
void TaskScheduler::Schedule(std::function<void()> func) {
|
||||
auto& task = tasks[current_task];
|
||||
task.cleanups.push_back(func);
|
||||
}
|
||||
|
||||
void VKTaskScheduler::BeginTask() {
|
||||
void TaskScheduler::BeginTask() {
|
||||
u32 next_task_index = (current_task + 1) % TASK_COUNT;
|
||||
auto& task = tasks[next_task_index];
|
||||
auto device = g_vk_instace->GetDevice();
|
||||
@@ -234,6 +234,6 @@ void VKTaskScheduler::BeginTask() {
|
||||
state.InitDescriptorSets();
|
||||
}
|
||||
|
||||
std::unique_ptr<VKTaskScheduler> g_vk_task_scheduler;
|
||||
std::unique_ptr<TaskScheduler> g_vk_task_scheduler;
|
||||
|
||||
} // namespace Vulkan
|
||||
|
@@ -23,17 +23,17 @@ namespace Vulkan {
|
||||
constexpr u32 TASK_COUNT = 5;
|
||||
constexpr u32 STAGING_BUFFER_SIZE = 16 * 1024 * 1024;
|
||||
|
||||
class VKSwapChain;
|
||||
class Swapchain;
|
||||
|
||||
/// Wrapper class around command buffer execution. Handles an arbitrary
|
||||
/// number of tasks that can be submitted concurrently. This allows the host
|
||||
/// to start recording the next frame while the GPU is working on the
|
||||
/// current one. Larger values can be used with caution, as they can cause
|
||||
/// frame latency if the CPU is too far ahead of the GPU
|
||||
class VKTaskScheduler {
|
||||
class TaskScheduler {
|
||||
public:
|
||||
VKTaskScheduler() = default;
|
||||
~VKTaskScheduler();
|
||||
TaskScheduler() = default;
|
||||
~TaskScheduler();
|
||||
|
||||
/// Create and initialize the work scheduler
|
||||
bool Create();
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
|
||||
/// Access the staging buffer of the current task
|
||||
std::tuple<u8*, u32> RequestStaging(u32 size);
|
||||
VKBuffer& GetStaging();
|
||||
Buffer& GetStaging();
|
||||
|
||||
/// Query and/or synchronization CPU and GPU
|
||||
u64 GetCPUTick() const;
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
void SyncToGPU(u64 task_index);
|
||||
|
||||
void Schedule(std::function<void()> func);
|
||||
void Submit(bool wait_completion = false, bool present = false, VKSwapChain* swapchain = nullptr);
|
||||
void Submit(bool wait_completion = false, bool present = false, Swapchain* swapchain = nullptr);
|
||||
|
||||
void BeginTask();
|
||||
|
||||
@@ -65,7 +65,7 @@ private:
|
||||
std::array<vk::CommandBuffer, 2> command_buffers;
|
||||
std::vector<std::function<void()>> cleanups;
|
||||
vk::DescriptorPool pool;
|
||||
VKBuffer staging;
|
||||
Buffer staging;
|
||||
};
|
||||
|
||||
vk::Semaphore timeline;
|
||||
@@ -77,6 +77,6 @@ private:
|
||||
u64 current_task = TASK_COUNT - 1;
|
||||
};
|
||||
|
||||
extern std::unique_ptr<VKTaskScheduler> g_vk_task_scheduler;
|
||||
extern std::unique_ptr<TaskScheduler> g_vk_task_scheduler;
|
||||
|
||||
} // namespace Vulkan
|
||||
|
@@ -54,11 +54,11 @@ vk::ImageAspectFlags GetImageAspect(vk::Format format) {
|
||||
return flags;
|
||||
}
|
||||
|
||||
VKTexture::~VKTexture() {
|
||||
Texture::~Texture() {
|
||||
Destroy();
|
||||
}
|
||||
|
||||
VKTexture::VKTexture(VKTexture&& other) noexcept {
|
||||
Texture::Texture(Texture&& other) noexcept {
|
||||
info = std::exchange(other.info, Info{});
|
||||
texture = std::exchange(other.texture, VK_NULL_HANDLE);
|
||||
aspect = std::exchange(other.aspect, vk::ImageAspectFlagBits::eNone);
|
||||
@@ -70,7 +70,7 @@ VKTexture::VKTexture(VKTexture&& other) noexcept {
|
||||
is_d24s8 = std::exchange(other.is_d24s8, false);
|
||||
}
|
||||
|
||||
VKTexture& VKTexture::operator=(VKTexture&& other) noexcept {
|
||||
Texture& Texture::operator=(Texture&& other) noexcept {
|
||||
Destroy();
|
||||
info = std::exchange(other.info, Info{});
|
||||
texture = std::exchange(other.texture, VK_NULL_HANDLE);
|
||||
@@ -84,7 +84,7 @@ VKTexture& VKTexture::operator=(VKTexture&& other) noexcept {
|
||||
return *this;
|
||||
}
|
||||
|
||||
void VKTexture::Create(const Info& create_info) {
|
||||
void Texture::Create(const Info& create_info) {
|
||||
auto device = g_vk_instace->GetDevice();
|
||||
info = create_info;
|
||||
|
||||
@@ -121,7 +121,7 @@ void VKTexture::Create(const Info& create_info) {
|
||||
|
||||
// Create texture memory
|
||||
auto requirements = device.getImageMemoryRequirements(texture);
|
||||
auto memory_index = VKBuffer::FindMemoryType(requirements.memoryTypeBits,
|
||||
auto memory_index = Buffer::FindMemoryType(requirements.memoryTypeBits,
|
||||
vk::MemoryPropertyFlagBits::eDeviceLocal);
|
||||
vk::MemoryAllocateInfo alloc_info(requirements.size, memory_index);
|
||||
|
||||
@@ -137,7 +137,7 @@ void VKTexture::Create(const Info& create_info) {
|
||||
view = device.createImageView(view_info);
|
||||
}
|
||||
|
||||
void VKTexture::Create(VKTexture& other) {
|
||||
void Texture::Create(Texture& other) {
|
||||
auto info = other.info;
|
||||
Create(info);
|
||||
|
||||
@@ -167,7 +167,7 @@ void VKTexture::Create(VKTexture& other) {
|
||||
other.Transition(cmdbuffer, old_layout);
|
||||
}
|
||||
|
||||
void VKTexture::Adopt(const Info& create_info, vk::Image image) {
|
||||
void Texture::Adopt(const Info& create_info, vk::Image image) {
|
||||
info = create_info;
|
||||
image_size = info.width * info.height * BytesPerPixel(info.format);
|
||||
aspect = GetImageAspect(info.format);
|
||||
@@ -184,7 +184,7 @@ void VKTexture::Adopt(const Info& create_info, vk::Image image) {
|
||||
adopted = true;
|
||||
}
|
||||
|
||||
void VKTexture::Destroy() {
|
||||
void Texture::Destroy() {
|
||||
if (texture && !adopted) {
|
||||
// Make sure to unbind the texture before destroying it
|
||||
auto& state = VulkanState::Get();
|
||||
@@ -216,11 +216,11 @@ void VKTexture::Destroy() {
|
||||
}
|
||||
}
|
||||
|
||||
void VKTexture::Transition(vk::CommandBuffer cmdbuffer, vk::ImageLayout new_layout) {
|
||||
void Texture::Transition(vk::CommandBuffer cmdbuffer, vk::ImageLayout new_layout) {
|
||||
Transition(cmdbuffer, new_layout, 0, info.levels, 0, info.layers);
|
||||
}
|
||||
|
||||
void VKTexture::Transition(vk::CommandBuffer cmdbuffer, vk::ImageLayout new_layout,
|
||||
void Texture::Transition(vk::CommandBuffer cmdbuffer, vk::ImageLayout new_layout,
|
||||
u32 start_level, u32 level_count, u32 start_layer, u32 layer_count) {
|
||||
if (new_layout == layout) {
|
||||
return;
|
||||
@@ -305,11 +305,11 @@ void VKTexture::Transition(vk::CommandBuffer cmdbuffer, vk::ImageLayout new_layo
|
||||
layout = new_layout;
|
||||
}
|
||||
|
||||
void VKTexture::OverrideImageLayout(vk::ImageLayout new_layout) {
|
||||
void Texture::OverrideImageLayout(vk::ImageLayout new_layout) {
|
||||
layout = new_layout;
|
||||
}
|
||||
|
||||
void VKTexture::Upload(u32 level, u32 layer, u32 row_length, vk::Rect2D region, std::span<u8> pixels) {
|
||||
void Texture::Upload(u32 level, u32 layer, u32 row_length, vk::Rect2D region, std::span<u8> pixels) {
|
||||
u32 request_size = is_rgb ? (pixels.size() / 3) * 4 :
|
||||
(is_d24s8 ? (pixels.size() / 4) * 5 : pixels.size());
|
||||
auto [buffer, offset] = g_vk_task_scheduler->RequestStaging(request_size);
|
||||
@@ -367,7 +367,7 @@ void VKTexture::Upload(u32 level, u32 layer, u32 row_length, vk::Rect2D region,
|
||||
Transition(cmdbuffer, vk::ImageLayout::eShaderReadOnlyOptimal);
|
||||
}
|
||||
|
||||
void VKTexture::Download(u32 level, u32 layer, u32 row_length, vk::Rect2D region, std::span<u8> memory) {
|
||||
void Texture::Download(u32 level, u32 layer, u32 row_length, vk::Rect2D region, std::span<u8> memory) {
|
||||
u32 request_size = is_rgb ? (memory.size() / 3) * 4 :
|
||||
(is_d24s8 ? (memory.size() / 4) * 8 : memory.size());
|
||||
auto [buffer, offset] = g_vk_task_scheduler->RequestStaging(request_size);
|
||||
@@ -434,7 +434,7 @@ std::span<Out> SpanCast(std::span<In> span) {
|
||||
return std::span(reinterpret_cast<Out*>(span.data()), span.size_bytes() / sizeof(Out));
|
||||
}
|
||||
|
||||
std::vector<u8> VKTexture::RGBToRGBA(std::span<u8> data) {
|
||||
std::vector<u8> Texture::RGBToRGBA(std::span<u8> data) {
|
||||
ASSERT(data.size() % 3 == 0);
|
||||
|
||||
u32 new_size = (data.size() / 3) * 4;
|
||||
@@ -450,7 +450,7 @@ std::vector<u8> VKTexture::RGBToRGBA(std::span<u8> data) {
|
||||
return rgba;
|
||||
}
|
||||
|
||||
std::vector<u64> VKTexture::D24S8ToD32S8(std::span<u8> data) {
|
||||
std::vector<u64> Texture::D24S8ToD32S8(std::span<u8> data) {
|
||||
ASSERT(data.size() % 4 == 0);
|
||||
|
||||
std::vector<u64> d32s8;
|
||||
@@ -471,7 +471,7 @@ std::vector<u64> VKTexture::D24S8ToD32S8(std::span<u8> data) {
|
||||
return d32s8;
|
||||
}
|
||||
|
||||
std::vector<u8> VKTexture::RGBAToRGB(std::span<u8> data) {
|
||||
std::vector<u8> Texture::RGBAToRGB(std::span<u8> data) {
|
||||
ASSERT(data.size() % 4 == 0);
|
||||
|
||||
u32 new_size = (data.size() / 4) * 3;
|
||||
@@ -486,7 +486,7 @@ std::vector<u8> VKTexture::RGBAToRGB(std::span<u8> data) {
|
||||
return rgb;
|
||||
}
|
||||
|
||||
std::vector<u32> VKTexture::D32S8ToD24S8(std::span<u8> data) {
|
||||
std::vector<u32> Texture::D32S8ToD24S8(std::span<u8> data) {
|
||||
ASSERT(data.size() % 8 == 0);
|
||||
|
||||
std::vector<u32> d24s8;
|
||||
|
@@ -15,7 +15,7 @@
|
||||
namespace Vulkan {
|
||||
|
||||
/// Vulkan texture object
|
||||
class VKTexture final : public NonCopyable {
|
||||
class Texture final : public NonCopyable {
|
||||
public:
|
||||
/// Information for the creation of the target texture
|
||||
struct Info {
|
||||
@@ -28,16 +28,16 @@ public:
|
||||
u32 levels = 1, layers = 1;
|
||||
};
|
||||
|
||||
VKTexture() = default;
|
||||
~VKTexture();
|
||||
Texture() = default;
|
||||
~Texture();
|
||||
|
||||
/// Enable move operations
|
||||
VKTexture(VKTexture&& other) noexcept;
|
||||
VKTexture& operator=(VKTexture&& other) noexcept;
|
||||
Texture(Texture&& other) noexcept;
|
||||
Texture& operator=(Texture&& other) noexcept;
|
||||
|
||||
/// Create a new Vulkan texture object
|
||||
void Create(const Info& info);
|
||||
void Create(VKTexture& texture);
|
||||
void Create(Texture& texture);
|
||||
void Adopt(const Info& info, vk::Image image);
|
||||
void Destroy();
|
||||
|
||||
@@ -69,7 +69,7 @@ private:
|
||||
std::vector<u32> D32S8ToD24S8(std::span<u8> data);
|
||||
|
||||
private:
|
||||
VKTexture::Info info{};
|
||||
Texture::Info info{};
|
||||
vk::ImageLayout layout{};
|
||||
vk::ImageAspectFlags aspect{};
|
||||
vk::Image texture;
|
||||
|
Reference in New Issue
Block a user