mirror of
https://github.com/korenkonder/ReDIVA.git
synced 2026-10-06 21:58:09 +03:00
Experimental Vulkan support
This commit is contained in:
+1588
File diff suppressed because it is too large
Load Diff
Vendored
+195
@@ -0,0 +1,195 @@
|
||||
// dear imgui: Renderer Backend for Vulkan
|
||||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||
|
||||
// Implemented features:
|
||||
// [!] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// Important: on 32-bit systems, user texture binding is only supported if your imconfig file has '#define ImTextureID ImU64'.
|
||||
// See imgui_impl_vulkan.cpp file for details.
|
||||
|
||||
// The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification.
|
||||
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own engine/app.
|
||||
// - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h.
|
||||
// You will use those if you want to use this rendering backend in your engine/app.
|
||||
// - Helper ImGui_ImplVulkanH_XXX functions and structures are only used by this example (main.cpp) and by
|
||||
// the backend itself (imgui_impl_vulkan.cpp), but should PROBABLY NOT be used by your own engine/app code.
|
||||
// Read comments in imgui_impl_vulkan.h.
|
||||
|
||||
#pragma once
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
|
||||
// [Configuration] in order to use a custom Vulkan function loader:
|
||||
// (1) You'll need to disable default Vulkan function prototypes.
|
||||
// We provide a '#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES' convenience configuration flag.
|
||||
// In order to make sure this is visible from the imgui_impl_vulkan.cpp compilation unit:
|
||||
// - Add '#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES' in your imconfig.h file
|
||||
// - Or as a compilation flag in your build system
|
||||
// - Or uncomment here (not recommended because you'd be modifying imgui sources!)
|
||||
// - Do not simply add it in a .cpp file!
|
||||
// (2) Call ImGui_ImplVulkan_LoadFunctions() before ImGui_ImplVulkan_Init() with your custom function.
|
||||
// If you have no idea what this is, leave it alone!
|
||||
//#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES
|
||||
|
||||
// Convenience support for Volk
|
||||
// (you can also technically use IMGUI_IMPL_VULKAN_NO_PROTOTYPES + wrap Volk via ImGui_ImplVulkan_LoadFunctions().)
|
||||
#define IMGUI_IMPL_VULKAN_USE_VOLK
|
||||
|
||||
#if defined(IMGUI_IMPL_VULKAN_NO_PROTOTYPES) && !defined(VK_NO_PROTOTYPES)
|
||||
#define VK_NO_PROTOTYPES
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR) && !defined(NOMINMAX)
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
// Vulkan includes
|
||||
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
|
||||
#include <Volk/volk.h>
|
||||
#else
|
||||
#include <vulkan/vulkan.h>
|
||||
#endif
|
||||
#if defined(VK_VERSION_1_3) || defined(VK_KHR_dynamic_rendering)
|
||||
#define IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
#endif
|
||||
|
||||
// Initialization data, for ImGui_ImplVulkan_Init()
|
||||
// - VkDescriptorPool should be created with VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
|
||||
// and must contain a pool size large enough to hold an ImGui VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor.
|
||||
// - When using dynamic rendering, set UseDynamicRendering=true and fill PipelineRenderingCreateInfo structure.
|
||||
// [Please zero-clear before use!]
|
||||
struct ImGui_ImplVulkan_InitInfo
|
||||
{
|
||||
VkInstance Instance;
|
||||
VkPhysicalDevice PhysicalDevice;
|
||||
VkDevice Device;
|
||||
uint32_t QueueFamily;
|
||||
VkQueue Queue;
|
||||
VkDescriptorPool DescriptorPool; // See requirements in note above
|
||||
VkRenderPass RenderPass; // Ignored if using dynamic rendering
|
||||
uint32_t MinImageCount; // >= 2
|
||||
uint32_t ImageCount; // >= MinImageCount
|
||||
VkSampleCountFlagBits MSAASamples; // 0 defaults to VK_SAMPLE_COUNT_1_BIT
|
||||
|
||||
// (Optional)
|
||||
VkPipelineCache PipelineCache;
|
||||
uint32_t Subpass;
|
||||
|
||||
// (Optional) Dynamic Rendering
|
||||
// Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3.
|
||||
bool UseDynamicRendering;
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
VkPipelineRenderingCreateInfoKHR PipelineRenderingCreateInfo;
|
||||
#endif
|
||||
|
||||
// (Optional) Allocation, Debugging
|
||||
const VkAllocationCallbacks* Allocator;
|
||||
void (*CheckVkResultFn)(VkResult err);
|
||||
VkDeviceSize MinAllocationSize; // Minimum allocation size. Set to 1024*1024 to satisfy zealous best practices validation layer and waste a little memory.
|
||||
};
|
||||
|
||||
// Called by user code
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline = VK_NULL_HANDLE);
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateFontsTexture();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontsTexture();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated)
|
||||
|
||||
// Register a texture (VkDescriptorSet == ImTextureID)
|
||||
// FIXME: This is experimental in the sense that we are unsure how to best design/tackle this problem
|
||||
// Please post to https://github.com/ocornut/imgui/pull/914 if you have suggestions.
|
||||
IMGUI_IMPL_API VkDescriptorSet ImGui_ImplVulkan_AddTexture(VkSampler sampler, VkImageView image_view, VkImageLayout image_layout);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_RemoveTexture(VkDescriptorSet descriptor_set);
|
||||
|
||||
// Optional: load Vulkan functions with a custom function loader
|
||||
// This is only useful with IMGUI_IMPL_VULKAN_NO_PROTOTYPES / VK_NO_PROTOTYPES
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data = nullptr);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Internal / Miscellaneous Vulkan Helpers
|
||||
// (Used by example's main.cpp. Used by multi-viewport features. PROBABLY NOT used by your own engine/app.)
|
||||
//-------------------------------------------------------------------------
|
||||
// You probably do NOT need to use or care about those functions.
|
||||
// Those functions only exist because:
|
||||
// 1) they facilitate the readability and maintenance of the multiple main.cpp examples files.
|
||||
// 2) the multi-viewport / platform window implementation needs them internally.
|
||||
// Generally we avoid exposing any kind of superfluous high-level helpers in the bindings,
|
||||
// but it is too much code to duplicate everywhere so we exceptionally expose them.
|
||||
//
|
||||
// Your engine/app will likely _already_ have code to setup all that stuff (swap chain, render pass, frame buffers, etc.).
|
||||
// You may read this code to learn about Vulkan, but it is recommended you use you own custom tailored code to do equivalent work.
|
||||
// (The ImGui_ImplVulkanH_XXX functions do not interact with any of the state used by the regular ImGui_ImplVulkan_XXX functions)
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
struct ImGui_ImplVulkanH_Frame;
|
||||
struct ImGui_ImplVulkanH_Window;
|
||||
|
||||
// Helpers
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkanH_CreateOrResizeWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wnd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Window* wnd, const VkAllocationCallbacks* allocator);
|
||||
IMGUI_IMPL_API VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space);
|
||||
IMGUI_IMPL_API VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count);
|
||||
IMGUI_IMPL_API int ImGui_ImplVulkanH_GetMinImageCountFromPresentMode(VkPresentModeKHR present_mode);
|
||||
|
||||
// Helper structure to hold the data needed by one rendering frame
|
||||
// (Used by example's main.cpp. Used by multi-viewport features. Probably NOT used by your own engine/app.)
|
||||
// [Please zero-clear before use!]
|
||||
struct ImGui_ImplVulkanH_Frame
|
||||
{
|
||||
VkCommandPool CommandPool;
|
||||
VkCommandBuffer CommandBuffer;
|
||||
VkFence Fence;
|
||||
VkImage Backbuffer;
|
||||
VkImageView BackbufferView;
|
||||
VkFramebuffer Framebuffer;
|
||||
};
|
||||
|
||||
struct ImGui_ImplVulkanH_FrameSemaphores
|
||||
{
|
||||
VkSemaphore ImageAcquiredSemaphore;
|
||||
VkSemaphore RenderCompleteSemaphore;
|
||||
};
|
||||
|
||||
// Helper structure to hold the data needed by one rendering context into one OS window
|
||||
// (Used by example's main.cpp. Used by multi-viewport features. Probably NOT used by your own engine/app.)
|
||||
struct ImGui_ImplVulkanH_Window
|
||||
{
|
||||
int Width;
|
||||
int Height;
|
||||
VkSwapchainKHR Swapchain;
|
||||
VkSurfaceKHR Surface;
|
||||
VkSurfaceFormatKHR SurfaceFormat;
|
||||
VkPresentModeKHR PresentMode;
|
||||
VkRenderPass RenderPass;
|
||||
VkPipeline Pipeline; // The window pipeline may uses a different VkRenderPass than the one passed in ImGui_ImplVulkan_InitInfo
|
||||
bool UseDynamicRendering;
|
||||
bool ClearEnable;
|
||||
VkClearValue ClearValue;
|
||||
uint32_t FrameIndex; // Current frame being rendered to (0 <= FrameIndex < FrameInFlightCount)
|
||||
uint32_t ImageCount; // Number of simultaneous in-flight frames (returned by vkGetSwapchainImagesKHR, usually derived from min_image_count)
|
||||
uint32_t SemaphoreCount; // Number of simultaneous in-flight frames + 1, to be able to use it in vkAcquireNextImageKHR
|
||||
uint32_t SemaphoreIndex; // Current set of swapchain wait semaphores we're using (needs to be distinct from per frame data)
|
||||
ImGui_ImplVulkanH_Frame* Frames;
|
||||
ImGui_ImplVulkanH_FrameSemaphores* FrameSemaphores;
|
||||
|
||||
ImGui_ImplVulkanH_Window()
|
||||
{
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
PresentMode = (VkPresentModeKHR)~0; // Ensure we get an error if user doesn't set this.
|
||||
ClearEnable = true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
@@ -6,7 +6,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../KKdLib/default.hpp"
|
||||
#include <glad/glad.h>
|
||||
#include "../gl.hpp"
|
||||
|
||||
namespace GL {
|
||||
struct ArrayBuffer {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../KKdLib/default.hpp"
|
||||
#include <glad/glad.h>
|
||||
#include "../gl.hpp"
|
||||
|
||||
namespace GL {
|
||||
struct ElementArrayBuffer {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../KKdLib/default.hpp"
|
||||
#include <glad/glad.h>
|
||||
#include "../gl.hpp"
|
||||
|
||||
namespace GL {
|
||||
struct ShaderStorageBuffer {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../KKdLib/default.hpp"
|
||||
#include <glad/glad.h>
|
||||
#include "../gl.hpp"
|
||||
|
||||
namespace GL {
|
||||
struct UniformBuffer {
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#include "Buffer.hpp"
|
||||
#include "CommandBuffer.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
bool Buffer::Create(VmaAllocator allocator, VkDeviceSize size,
|
||||
VkBufferUsageFlags usage, VkSharingMode sharing_mode,
|
||||
VmaMemoryUsage memory_usage, VmaAllocationCreateFlags flags) {
|
||||
Destroy();
|
||||
|
||||
VkBufferCreateInfo buffer_create_info = {};
|
||||
buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
buffer_create_info.size = size;
|
||||
buffer_create_info.usage = usage;
|
||||
buffer_create_info.sharingMode = sharing_mode;
|
||||
|
||||
VmaAllocationCreateInfo allocation_create_info = {};
|
||||
allocation_create_info.usage = memory_usage;
|
||||
allocation_create_info.flags = flags;
|
||||
|
||||
if (vmaCreateBuffer(allocator, &buffer_create_info,
|
||||
&allocation_create_info, &data, &allocation, 0) != VK_SUCCESS) {
|
||||
this->allocator = 0;
|
||||
data = 0;
|
||||
offset = 0;
|
||||
this->size = 0;
|
||||
allocation = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
this->allocator = allocator;
|
||||
offset = 0;
|
||||
this->size = size;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Buffer::Destroy() {
|
||||
if (allocator)
|
||||
CommandBuffer::AddBuffer(Vulkan::current_command_buffer, *this);
|
||||
|
||||
allocator = 0;
|
||||
size = 0;
|
||||
offset = 0;
|
||||
data = 0;
|
||||
allocation = 0;
|
||||
}
|
||||
|
||||
void Buffer::Copy(VkCommandBuffer command_buffer, VkBuffer src_buffer, VkBuffer dst_buffer,
|
||||
VkDeviceSize src_offset, VkDeviceSize dst_offset, VkDeviceSize size) {
|
||||
Vulkan::end_render_pass(command_buffer);
|
||||
|
||||
VkBufferCopy copy_region = {};
|
||||
copy_region.srcOffset = src_offset;
|
||||
copy_region.dstOffset = dst_offset;
|
||||
copy_region.size = size;
|
||||
vkCmdCopyBuffer(command_buffer, src_buffer, dst_buffer, 1, ©_region);
|
||||
}
|
||||
|
||||
void Buffer::CopyToImage(VkCommandBuffer command_buffer,
|
||||
VkBuffer src_buffer, VkDeviceSize src_buffer_offset, VkImage dst_image,
|
||||
VkImageAspectFlags aspect_mask, uint32_t level, uint32_t layer,
|
||||
int32_t x_offset, int32_t y_offset, uint32_t width, uint32_t height) {
|
||||
Vulkan::end_render_pass(command_buffer);
|
||||
|
||||
VkBufferImageCopy region = {};
|
||||
region.bufferOffset = src_buffer_offset;
|
||||
region.bufferRowLength = 0;
|
||||
region.bufferImageHeight = 0;
|
||||
region.imageSubresource.aspectMask = aspect_mask;
|
||||
region.imageSubresource.mipLevel = level;
|
||||
region.imageSubresource.baseArrayLayer = layer;
|
||||
region.imageSubresource.layerCount = 1;
|
||||
region.imageOffset = { x_offset, y_offset, 0 };
|
||||
region.imageExtent = { width, height, 1 };
|
||||
|
||||
vkCmdCopyBufferToImage(command_buffer, src_buffer, dst_image,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
}
|
||||
|
||||
void Buffer::CopyFromImage(VkCommandBuffer command_buffer,
|
||||
VkImage src_image, VkBuffer dst_buffer, VkDeviceSize dst_buffer_offset,
|
||||
VkImageAspectFlags aspect_mask, uint32_t level, uint32_t layer,
|
||||
int32_t x_offset, int32_t y_offset, uint32_t width, uint32_t height) {
|
||||
Vulkan::end_render_pass(command_buffer);
|
||||
|
||||
VkBufferImageCopy region = {};
|
||||
region.bufferOffset = dst_buffer_offset;
|
||||
region.bufferRowLength = 0;
|
||||
region.bufferImageHeight = 0;
|
||||
region.imageSubresource.aspectMask = aspect_mask;
|
||||
region.imageSubresource.mipLevel = level;
|
||||
region.imageSubresource.baseArrayLayer = layer;
|
||||
region.imageSubresource.layerCount = 1;
|
||||
region.imageOffset = { x_offset, y_offset, 0 };
|
||||
region.imageExtent = { width, height, 1 };
|
||||
|
||||
vkCmdCopyImageToBuffer(command_buffer, src_image,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst_buffer, 1, ®ion);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
class Buffer {
|
||||
friend class CommandBuffer;
|
||||
protected:
|
||||
VmaAllocator allocator;
|
||||
VkBuffer data;
|
||||
VkDeviceSize offset;
|
||||
VkDeviceSize size;
|
||||
VmaAllocation allocation;
|
||||
|
||||
public:
|
||||
inline Buffer() : allocator(), data(), offset(), size(), allocation() {
|
||||
|
||||
}
|
||||
|
||||
bool Create(VmaAllocator allocator, VkDeviceSize size,
|
||||
VkBufferUsageFlags usage, VkSharingMode sharing_mode,
|
||||
VmaMemoryUsage memory_usage, VmaAllocationCreateFlags flags);
|
||||
void Destroy();
|
||||
|
||||
inline bool Create(VmaAllocator allocator, VkDeviceSize size,
|
||||
VkBufferUsageFlags usage, VmaMemoryUsage memory_usage, VmaAllocationCreateFlags flags) {
|
||||
return Create(allocator, size, usage, VK_SHARING_MODE_EXCLUSIVE, memory_usage, flags);
|
||||
}
|
||||
|
||||
inline bool IsNull() {
|
||||
return !data;
|
||||
}
|
||||
|
||||
inline VkDeviceSize GetOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
inline VkDeviceSize GetSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
inline void* MapMemory() {
|
||||
void* data;
|
||||
if (vmaMapMemory(allocator, allocation, &data) == VK_SUCCESS)
|
||||
return data;
|
||||
vmaUnmapMemory(allocator, allocation);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void* MapMemory(size_t offset, size_t length) {
|
||||
void* data;
|
||||
if (vmaMapMemory(allocator, allocation, &data) == VK_SUCCESS)
|
||||
return (void*)((size_t)data + offset);
|
||||
vmaUnmapMemory(allocator, allocation);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline bool NotNull() {
|
||||
return !!data;
|
||||
}
|
||||
|
||||
inline void ReadMemory(size_t offset, size_t size, void* data) {
|
||||
void* _data;
|
||||
if (vmaMapMemory(allocator, allocation, &_data) == VK_SUCCESS)
|
||||
memcpy(data, (void*)((size_t)_data + offset), size);
|
||||
vmaUnmapMemory(allocator, allocation);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void ReadMemory(T& data) {
|
||||
void* _data;
|
||||
if (vmaMapMemory(allocator, allocation, &_data) == VK_SUCCESS)
|
||||
memcpy(&data, _data, sizeof(T));
|
||||
vmaUnmapMemory(allocator, allocation);
|
||||
}
|
||||
|
||||
inline void SetOffset(VkDeviceSize offset) {
|
||||
this->offset = offset;
|
||||
}
|
||||
|
||||
inline void SetSize(VkDeviceSize size) {
|
||||
this->size = size;
|
||||
}
|
||||
|
||||
inline void UnmapMemory() {
|
||||
vmaUnmapMemory(allocator, allocation);
|
||||
}
|
||||
|
||||
inline void WriteMemory(size_t offset, size_t size, const void* data) {
|
||||
void* _data;
|
||||
if (vmaMapMemory(allocator, allocation, &_data) == VK_SUCCESS)
|
||||
memcpy((void*)((size_t)_data + offset), data, size);
|
||||
vmaUnmapMemory(allocator, allocation);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void WriteMemory(T& data) {
|
||||
void* _data;
|
||||
if (vmaMapMemory(allocator, allocation, &_data) == VK_SUCCESS)
|
||||
memcpy(_data, &data, sizeof(T));
|
||||
vmaUnmapMemory(allocator, allocation);
|
||||
}
|
||||
|
||||
static void Copy(VkCommandBuffer command_buffer, VkBuffer src_buffer, VkBuffer dst_buffer,
|
||||
VkDeviceSize src_offset, VkDeviceSize dst_offset, VkDeviceSize size);
|
||||
static void CopyToImage(VkCommandBuffer command_buffer,
|
||||
VkBuffer src_buffer, VkDeviceSize src_buffer_offset, VkImage dst_image,
|
||||
VkImageAspectFlags aspect_mask, uint32_t level, uint32_t layer,
|
||||
int32_t x_offset, int32_t y_offset, uint32_t width, uint32_t height);
|
||||
static void CopyFromImage(VkCommandBuffer command_buffer,
|
||||
VkImage src_image, VkBuffer dst_buffer, VkDeviceSize dst_buffer_offset,
|
||||
VkImageAspectFlags aspect_mask, uint32_t level, uint32_t layer,
|
||||
int32_t x_offset, int32_t y_offset, uint32_t width, uint32_t height);
|
||||
|
||||
inline operator VkBuffer() const {
|
||||
return data;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#include "CommandBuffer.hpp"
|
||||
#include <unordered_map>
|
||||
|
||||
namespace Vulkan {
|
||||
std::unordered_map<VkCommandBuffer, std::vector<Vulkan::Buffer>> buffers;
|
||||
std::unordered_map<VkCommandBuffer, std::vector<Vulkan::Image>> images;
|
||||
|
||||
bool CommandBuffer::Create(VkDevice device, VkCommandPool command_pool) {
|
||||
Destroy();
|
||||
|
||||
VkCommandBufferAllocateInfo alloc_info;
|
||||
alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
alloc_info.pNext = 0;
|
||||
alloc_info.commandPool = command_pool;
|
||||
alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||
alloc_info.commandBufferCount = 1;
|
||||
|
||||
this->device = device;
|
||||
this->command_pool = command_pool;
|
||||
began = false;
|
||||
if (vkAllocateCommandBuffers(device, &alloc_info, &data) == VK_SUCCESS)
|
||||
return true;
|
||||
|
||||
this->device = 0;
|
||||
this->command_pool = 0;
|
||||
data = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
void CommandBuffer::Destroy() {
|
||||
if (began) {
|
||||
End();
|
||||
began = false;
|
||||
}
|
||||
|
||||
if (data) {
|
||||
vkFreeCommandBuffers(device, command_pool, 1, &data);
|
||||
data = 0;
|
||||
}
|
||||
device = 0;
|
||||
command_pool = 0;
|
||||
}
|
||||
|
||||
bool CommandBuffer::BeginOneTimeSubmit() {
|
||||
if (began)
|
||||
return true;
|
||||
|
||||
VkCommandBufferBeginInfo begin_info;
|
||||
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
begin_info.pNext = 0;
|
||||
begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||
begin_info.pInheritanceInfo = 0;
|
||||
|
||||
if (vkBeginCommandBuffer(data, &begin_info) == VK_SUCCESS) {
|
||||
began = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
began = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
void CommandBuffer::CopyBuffer(Vulkan::Buffer& src_buffer, Vulkan::Buffer& dst_buffer,
|
||||
VkDeviceSize src_offset, VkDeviceSize dst_offset, VkDeviceSize size) {
|
||||
if (began)
|
||||
Vulkan::Buffer::Copy(data, src_buffer, dst_buffer, src_offset, dst_offset, size);
|
||||
}
|
||||
|
||||
void CommandBuffer::CopyBufferToImage(Vulkan::Buffer& src_buffer, VkDeviceSize src_buffer_offset,
|
||||
Vulkan::Image& dst_image, VkImageAspectFlags aspect_mask, uint32_t level, uint32_t layer,
|
||||
int32_t x_offset, int32_t y_offset, uint32_t width, uint32_t height) {
|
||||
if (began)
|
||||
Vulkan::Buffer::CopyToImage(data, src_buffer, src_buffer_offset, dst_image,
|
||||
aspect_mask, level, layer, x_offset, y_offset, width, height);
|
||||
}
|
||||
|
||||
void CommandBuffer::CopyImageToBuffer(Vulkan::Image& src_image, Vulkan::Buffer& dst_buffer,
|
||||
VkDeviceSize dst_buffer_offset, VkImageAspectFlags aspect_mask, uint32_t level, uint32_t layer,
|
||||
int32_t x_offset, int32_t y_offset, uint32_t width, uint32_t height) {
|
||||
if (began) {
|
||||
const VkImageLayout old_layout = src_image.GetImageLayout(level, layer);
|
||||
const VkImageLayout new_layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
|
||||
Vulkan::Image::PipelineBarrierSingle(data, src_image, aspect_mask, 0, 0, new_layout);
|
||||
Vulkan::Buffer::CopyFromImage(data, src_image, dst_buffer, dst_buffer_offset,
|
||||
aspect_mask, level, layer, x_offset, y_offset, width, height);
|
||||
Vulkan::Image::PipelineBarrierSingle(data, src_image, aspect_mask, 0, 0, old_layout);
|
||||
}
|
||||
}
|
||||
|
||||
bool CommandBuffer::End() {
|
||||
if (vkEndCommandBuffer(data) == VK_SUCCESS)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CommandBuffer::Sumbit(VkQueue queue, VkFence fence) {
|
||||
if (began) {
|
||||
End();
|
||||
began = false;
|
||||
}
|
||||
|
||||
VkSubmitInfo submit_info = {};
|
||||
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
submit_info.commandBufferCount = 1;
|
||||
submit_info.pCommandBuffers = &data;
|
||||
|
||||
bool ret = vkQueueSubmit(queue, 1, &submit_info, fence) == VK_SUCCESS;
|
||||
vkQueueWaitIdle(queue);
|
||||
|
||||
CommandBuffer::FreeData(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CommandBuffer::AddBuffer(VkCommandBuffer command_buffer, Vulkan::Buffer buffer) {
|
||||
if (!buffer.allocation)
|
||||
return;
|
||||
|
||||
auto elem = buffers.find(command_buffer);
|
||||
if (elem != buffers.end()) {
|
||||
elem->second.push_back(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
buffers.insert({ command_buffer, {} }).first->second.push_back(buffer);
|
||||
}
|
||||
|
||||
void CommandBuffer::AddImage(VkCommandBuffer command_buffer, Vulkan::Image image) {
|
||||
if (!image.allocation)
|
||||
return;
|
||||
|
||||
auto elem = images.find(command_buffer);
|
||||
if (elem != images.end()) {
|
||||
elem->second.push_back(image);
|
||||
return;
|
||||
}
|
||||
|
||||
images.insert({ command_buffer, {} }).first->second.push_back(image);
|
||||
}
|
||||
|
||||
void CommandBuffer::FreeData(VkCommandBuffer command_buffer) {
|
||||
auto elem_buffers = buffers.find(command_buffer);
|
||||
if (elem_buffers != buffers.end()) {
|
||||
for (Vulkan::Buffer& i : elem_buffers->second)
|
||||
vmaDestroyBuffer(i.allocator, i.data, i.allocation);
|
||||
buffers.erase(elem_buffers);
|
||||
}
|
||||
|
||||
auto elem_images = images.find(command_buffer);
|
||||
if (elem_images != images.end()) {
|
||||
for (Vulkan::Image& i : elem_images->second)
|
||||
vmaDestroyImage(i.allocator, i.data, i.allocation);
|
||||
images.erase(elem_images);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "Fence.hpp"
|
||||
#include "Image.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace Vulkan {
|
||||
class CommandBuffer {
|
||||
protected:
|
||||
VkDevice device;
|
||||
VkCommandPool command_pool;
|
||||
VkCommandBuffer data;
|
||||
bool began;
|
||||
|
||||
public:
|
||||
inline CommandBuffer() : device(), command_pool(), data(), began() {
|
||||
|
||||
}
|
||||
|
||||
inline CommandBuffer(VkDevice device, VkCommandPool command_pool, VkCommandBuffer data) {
|
||||
this->device = device;
|
||||
this->command_pool = command_pool;
|
||||
this->data = data;
|
||||
began = true;
|
||||
}
|
||||
|
||||
inline ~CommandBuffer() {
|
||||
|
||||
}
|
||||
|
||||
bool Create(VkDevice device, VkCommandPool command_pool);
|
||||
void Destroy();
|
||||
|
||||
bool BeginOneTimeSubmit();
|
||||
|
||||
void CopyBuffer(Vulkan::Buffer& src_buffer, Vulkan::Buffer& dst_buffer,
|
||||
VkDeviceSize src_offset, VkDeviceSize dst_offset, VkDeviceSize size);
|
||||
void CopyBufferToImage(Vulkan::Buffer& src_buffer, VkDeviceSize src_buffer_offset,
|
||||
Vulkan::Image& dst_image, VkImageAspectFlags aspect_mask, uint32_t level, uint32_t layer,
|
||||
int32_t x_offset, int32_t y_offset, uint32_t width, uint32_t height);
|
||||
void CopyImageToBuffer(Vulkan::Image& src_image, Vulkan::Buffer& dst_buffer,
|
||||
VkDeviceSize dst_buffer_offset, VkImageAspectFlags aspect_mask, uint32_t level, uint32_t layer,
|
||||
int32_t x_offset, int32_t y_offset, uint32_t width, uint32_t height);
|
||||
bool End();
|
||||
bool Sumbit(VkQueue queue, VkFence fence = 0);
|
||||
|
||||
static void AddBuffer(VkCommandBuffer command_buffer, Vulkan::Buffer buffer);
|
||||
static void AddImage(VkCommandBuffer command_buffer, Vulkan::Image image);
|
||||
static void FreeData(VkCommandBuffer command_buffer);
|
||||
|
||||
inline operator VkCommandBuffer() const {
|
||||
return data;
|
||||
}
|
||||
|
||||
inline operator const VkCommandBuffer* () const {
|
||||
return &data;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DataBuffer.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
bool DataBuffer::Create(VmaAllocator allocator, size_t size, bool uniform) {
|
||||
curr_size = 0;
|
||||
offset = 0;
|
||||
return Buffer::Create(allocator, size,
|
||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT
|
||||
| VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||
VMA_MEMORY_USAGE_AUTO,
|
||||
VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT
|
||||
| VMA_ALLOCATION_CREATE_MAPPED_BIT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Buffer.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
class DataBuffer : public Buffer {
|
||||
public:
|
||||
VkDeviceSize curr_size;
|
||||
VkDeviceSize offset;
|
||||
|
||||
inline DataBuffer() : curr_size(), offset() {
|
||||
|
||||
}
|
||||
|
||||
bool Create(VmaAllocator allocator, size_t size, bool uniform);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DescriptorPipeline.hpp"
|
||||
#include "../../KKdLib/hash.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
DescriptorPipeline::DescriptorSetCollection::DescriptorSetCollection()
|
||||
: data(), used(), count(), frame(), hash() {
|
||||
}
|
||||
|
||||
void DescriptorPipeline::DescriptorSetCollection::Destroy(VkDevice device, VkDescriptorPool descriptor_pool) {
|
||||
if (data[2]) {
|
||||
vkFreeDescriptorSets(device, descriptor_pool, 1, &data[2]);
|
||||
data[2] = 0;
|
||||
}
|
||||
|
||||
if (data[1]) {
|
||||
vkFreeDescriptorSets(device, descriptor_pool, 1, &data[1]);
|
||||
data[1] = 0;
|
||||
}
|
||||
|
||||
if (data[0]) {
|
||||
vkFreeDescriptorSets(device, descriptor_pool, 1, &data[0]);
|
||||
data[0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
DescriptorPipeline::DescriptorPipeline(VkDevice device, VkDescriptorPool descriptor_pool,
|
||||
uint32_t sampler_count, uint32_t uniform_count, uint32_t storage_count,
|
||||
const VkDescriptorSetLayoutBinding* bindings) {
|
||||
|
||||
this->device = device;
|
||||
this->descriptor_pool = descriptor_pool;
|
||||
|
||||
descriptor_set_layouts[0] = 0;
|
||||
descriptor_set_layouts[1] = 0;
|
||||
descriptor_set_layouts[2] = 0;
|
||||
descriptor_set_layout_indices[0] = -1;
|
||||
descriptor_set_layout_indices[1] = -1;
|
||||
descriptor_set_layout_indices[2] = -1;
|
||||
pipeline_layout = 0;
|
||||
|
||||
uint32_t set_layout_count = 0;
|
||||
if (sampler_count) {
|
||||
VkDescriptorSetLayoutCreateInfo descriptor_set_layout_create_info;
|
||||
descriptor_set_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||
descriptor_set_layout_create_info.pNext = 0;
|
||||
descriptor_set_layout_create_info.flags = 0;
|
||||
descriptor_set_layout_create_info.bindingCount = sampler_count;
|
||||
descriptor_set_layout_create_info.pBindings = bindings;
|
||||
|
||||
vkCreateDescriptorSetLayout(device, &descriptor_set_layout_create_info,
|
||||
0, &descriptor_set_layouts[set_layout_count]);
|
||||
descriptor_set_layout_indices[0] = set_layout_count++;
|
||||
}
|
||||
|
||||
if (uniform_count) {
|
||||
VkDescriptorSetLayoutCreateInfo descriptor_set_layout_create_info;
|
||||
descriptor_set_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||
descriptor_set_layout_create_info.pNext = 0;
|
||||
descriptor_set_layout_create_info.flags = 0;
|
||||
descriptor_set_layout_create_info.bindingCount = uniform_count;
|
||||
descriptor_set_layout_create_info.pBindings = bindings + sampler_count;
|
||||
|
||||
vkCreateDescriptorSetLayout(device, &descriptor_set_layout_create_info,
|
||||
0, &descriptor_set_layouts[set_layout_count]);
|
||||
descriptor_set_layout_indices[1] = set_layout_count++;
|
||||
}
|
||||
|
||||
if (storage_count) {
|
||||
VkDescriptorSetLayoutCreateInfo descriptor_set_layout_create_info;
|
||||
descriptor_set_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||
descriptor_set_layout_create_info.pNext = 0;
|
||||
descriptor_set_layout_create_info.flags = 0;
|
||||
descriptor_set_layout_create_info.bindingCount = storage_count;
|
||||
descriptor_set_layout_create_info.pBindings = bindings + sampler_count + uniform_count;
|
||||
|
||||
vkCreateDescriptorSetLayout(device, &descriptor_set_layout_create_info,
|
||||
0, &descriptor_set_layouts[set_layout_count]);
|
||||
descriptor_set_layout_indices[2] = set_layout_count++;
|
||||
}
|
||||
|
||||
if (set_layout_count) {
|
||||
VkPipelineLayoutCreateInfo pipeline_layout_create_info;
|
||||
pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||
pipeline_layout_create_info.pNext = 0;
|
||||
pipeline_layout_create_info.flags = 0;
|
||||
pipeline_layout_create_info.setLayoutCount = set_layout_count;
|
||||
pipeline_layout_create_info.pSetLayouts = descriptor_set_layouts;
|
||||
pipeline_layout_create_info.pushConstantRangeCount = 0;
|
||||
pipeline_layout_create_info.pPushConstantRanges = 0;
|
||||
|
||||
if (vkCreatePipelineLayout(device, &pipeline_layout_create_info, 0, &pipeline_layout) == VK_SUCCESS)
|
||||
return;
|
||||
}
|
||||
|
||||
if (pipeline_layout) {
|
||||
vkDestroyPipelineLayout(device, pipeline_layout, 0);
|
||||
pipeline_layout = 0;
|
||||
}
|
||||
|
||||
for (DescriptorPipeline::DescriptorSetCollection& i : descriptor_sets)
|
||||
i.Destroy(device, descriptor_pool);
|
||||
descriptor_sets.clear();
|
||||
|
||||
if (descriptor_set_layouts[2]) {
|
||||
vkDestroyDescriptorSetLayout(device, descriptor_set_layouts[2], 0);
|
||||
descriptor_set_layouts[2] = 0;
|
||||
}
|
||||
|
||||
if (descriptor_set_layouts[1]) {
|
||||
vkDestroyDescriptorSetLayout(device, descriptor_set_layouts[1], 0);
|
||||
descriptor_set_layouts[1] = 0;
|
||||
}
|
||||
|
||||
if (descriptor_set_layouts[0]) {
|
||||
vkDestroyDescriptorSetLayout(device, descriptor_set_layouts[0], 0);
|
||||
descriptor_set_layouts[0] = 0;
|
||||
}
|
||||
|
||||
descriptor_set_layout_indices[2] = -1;
|
||||
descriptor_set_layout_indices[1] = -1;
|
||||
descriptor_set_layout_indices[0] = -1;
|
||||
this->descriptor_pool = 0;
|
||||
this->device = 0;
|
||||
}
|
||||
|
||||
DescriptorPipeline::~DescriptorPipeline() {
|
||||
if (pipeline_layout) {
|
||||
vkDestroyPipelineLayout(device, pipeline_layout, 0);
|
||||
pipeline_layout = 0;
|
||||
}
|
||||
|
||||
for (DescriptorPipeline::DescriptorSetCollection& i : descriptor_sets)
|
||||
i.Destroy(device, descriptor_pool);
|
||||
descriptor_sets.clear();
|
||||
|
||||
if (descriptor_set_layouts[2]) {
|
||||
vkDestroyDescriptorSetLayout(device, descriptor_set_layouts[2], 0);
|
||||
descriptor_set_layouts[2] = 0;
|
||||
}
|
||||
|
||||
if (descriptor_set_layouts[1]) {
|
||||
vkDestroyDescriptorSetLayout(device, descriptor_set_layouts[1], 0);
|
||||
descriptor_set_layouts[1] = 0;
|
||||
}
|
||||
|
||||
if (descriptor_set_layouts[0]) {
|
||||
vkDestroyDescriptorSetLayout(device, descriptor_set_layouts[0], 0);
|
||||
descriptor_set_layouts[0] = 0;
|
||||
}
|
||||
|
||||
descriptor_set_layout_indices[2] = -1;
|
||||
descriptor_set_layout_indices[1] = -1;
|
||||
descriptor_set_layout_indices[0] = -1;
|
||||
descriptor_pool = 0;
|
||||
device = 0;
|
||||
}
|
||||
|
||||
DescriptorPipeline::DescriptorSetCollection*
|
||||
DescriptorPipeline::GetDescriptorSetCollection(uint32_t frame, uint64_t hash) {
|
||||
for (DescriptorPipeline::DescriptorSetCollection& i : descriptor_sets)
|
||||
if (i.used && i.frame == frame && i.hash == hash)
|
||||
return &i;
|
||||
|
||||
for (DescriptorPipeline::DescriptorSetCollection& i : descriptor_sets)
|
||||
if (!i.used && i.frame == frame) {
|
||||
i.hash = hash;
|
||||
return &i;
|
||||
}
|
||||
|
||||
descriptor_sets.push_back({});
|
||||
DescriptorPipeline::DescriptorSetCollection* set_collection = &descriptor_sets.back();
|
||||
set_collection->count = 0;
|
||||
set_collection->frame = frame;
|
||||
set_collection->hash = hash;
|
||||
|
||||
for (uint32_t i = 0; i < 3; i++)
|
||||
if (descriptor_set_layout_indices[i] != -1) {
|
||||
VkDescriptorSetAllocateInfo descriptor_set_allocate_info;
|
||||
descriptor_set_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||
descriptor_set_allocate_info.pNext = 0;
|
||||
descriptor_set_allocate_info.descriptorPool = descriptor_pool;
|
||||
descriptor_set_allocate_info.descriptorSetCount = 1;
|
||||
descriptor_set_allocate_info.pSetLayouts
|
||||
= &descriptor_set_layouts[descriptor_set_layout_indices[i]];
|
||||
|
||||
if (vkAllocateDescriptorSets(device, &descriptor_set_allocate_info,
|
||||
&set_collection->data[set_collection->count++]) != VK_SUCCESS)
|
||||
return 0;
|
||||
}
|
||||
return set_collection;
|
||||
}
|
||||
|
||||
VkPipelineLayout DescriptorPipeline::GetPipelineLayout() {
|
||||
return pipeline_layout;
|
||||
}
|
||||
|
||||
void DescriptorPipeline::ResetSetCollectionsState() {
|
||||
for (DescriptorPipeline::DescriptorSetCollection& i : descriptor_sets) {
|
||||
i.used = false;
|
||||
i.hash = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace Vulkan {
|
||||
class DescriptorPipeline {
|
||||
public:
|
||||
struct DescriptorSetCollection {
|
||||
VkDescriptorSet data[3];
|
||||
bool used;
|
||||
uint32_t count;
|
||||
uint32_t frame;
|
||||
uint64_t hash;
|
||||
|
||||
DescriptorSetCollection();
|
||||
|
||||
void Destroy(VkDevice device, VkDescriptorPool descriptor_pool);
|
||||
};
|
||||
|
||||
protected:
|
||||
VkDevice device;
|
||||
VkDescriptorPool descriptor_pool;
|
||||
VkDescriptorSetLayout descriptor_set_layouts[3];
|
||||
uint32_t descriptor_set_layout_indices[3];
|
||||
std::vector<DescriptorSetCollection> descriptor_sets;
|
||||
VkPipelineLayout pipeline_layout;
|
||||
|
||||
public:
|
||||
DescriptorPipeline(VkDevice device, VkDescriptorPool descriptor_pool,
|
||||
uint32_t sampler_count, uint32_t uniform_count, uint32_t storage_count,
|
||||
const VkDescriptorSetLayoutBinding* bindings);
|
||||
~DescriptorPipeline();
|
||||
|
||||
DescriptorSetCollection* GetDescriptorSetCollection(uint32_t frame, uint64_t hash);
|
||||
VkPipelineLayout GetPipelineLayout();
|
||||
void ResetSetCollectionsState();
|
||||
|
||||
DescriptorPipeline(const DescriptorPipeline&) = delete;
|
||||
DescriptorPipeline& operator=(const DescriptorPipeline&) = delete;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DynamicBuffer.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
bool DynamicBuffer::Create(VmaAllocator allocator, size_t size, VkBufferUsageFlags usage) {
|
||||
this->usage = usage;
|
||||
curr_size = 0;
|
||||
offset = 0;
|
||||
return Buffer::Create(allocator, size, usage
|
||||
| VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
|
||||
VMA_MEMORY_USAGE_AUTO,
|
||||
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT
|
||||
| VMA_ALLOCATION_CREATE_MAPPED_BIT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Buffer.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
class DynamicBuffer : public Buffer {
|
||||
public:
|
||||
VkBufferUsageFlags usage;
|
||||
VkDeviceSize curr_size;
|
||||
uint32_t empty_frame_count;
|
||||
|
||||
inline DynamicBuffer() : usage(), curr_size(), empty_frame_count() {
|
||||
|
||||
}
|
||||
|
||||
bool Create(VmaAllocator allocator, size_t size, VkBufferUsageFlags usage);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Fence.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
bool Fence::Create(VkDevice device, VkFenceCreateFlags flags) {
|
||||
Destroy();
|
||||
|
||||
VkFenceCreateInfo fence_create_info;
|
||||
fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
fence_create_info.pNext = 0;
|
||||
fence_create_info.flags = flags;
|
||||
|
||||
this->device = device;
|
||||
if (vkCreateFence(device, &fence_create_info, 0, &data) == VK_SUCCESS)
|
||||
return true;
|
||||
|
||||
this->device = 0;
|
||||
data = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Fence::Destroy() {
|
||||
if (data) {
|
||||
vkDestroyFence(device, data, 0);
|
||||
data = 0;
|
||||
}
|
||||
device = 0;
|
||||
}
|
||||
|
||||
void Fence::Reset() {
|
||||
vkResetFences(device, 1, &data);
|
||||
}
|
||||
|
||||
void Fence::WaitFor() {
|
||||
vkWaitForFences(device, 1, &data, VK_TRUE, UINT64_MAX);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
class Fence {
|
||||
protected:
|
||||
VkDevice device;
|
||||
VkFence data;
|
||||
|
||||
public:
|
||||
inline Fence() : device(), data() {
|
||||
|
||||
}
|
||||
|
||||
bool Create(VkDevice device, VkFenceCreateFlags flags);
|
||||
void Destroy();
|
||||
void Reset();
|
||||
void WaitFor();
|
||||
|
||||
inline operator VkFence() const {
|
||||
return data;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Framebuffer.hpp"
|
||||
#include "manager.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
bool Framebuffer::Create(VkDevice device, VkFramebufferCreateFlags flags, VkRenderPass render_pass,
|
||||
uint32_t attachment_count, const VkImageView* attachments, uint32_t width, uint32_t height) {
|
||||
Destroy();
|
||||
|
||||
VkFramebufferCreateInfo framebuffer_create_info;
|
||||
framebuffer_create_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||
framebuffer_create_info.pNext = 0;
|
||||
framebuffer_create_info.flags = 0;
|
||||
framebuffer_create_info.renderPass = render_pass;
|
||||
framebuffer_create_info.attachmentCount = attachment_count;
|
||||
framebuffer_create_info.pAttachments = attachments;
|
||||
framebuffer_create_info.width = width;
|
||||
framebuffer_create_info.height = height;
|
||||
framebuffer_create_info.layers = 1;
|
||||
|
||||
this->device = device;
|
||||
extent.width = width;
|
||||
extent.height = height;
|
||||
if (vkCreateFramebuffer(device, &framebuffer_create_info, 0, &data) == VK_SUCCESS)
|
||||
return true;
|
||||
|
||||
this->device = 0;
|
||||
data = 0;
|
||||
extent = {};
|
||||
return false;
|
||||
}
|
||||
|
||||
void Framebuffer::Destroy() {
|
||||
extent = {};
|
||||
if (data) {
|
||||
manager_free_framebuffer(device, data, 0);
|
||||
data = 0;
|
||||
}
|
||||
device = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
class Framebuffer {
|
||||
protected:
|
||||
VkDevice device;
|
||||
VkFramebuffer data;
|
||||
VkExtent2D extent;
|
||||
|
||||
public:
|
||||
inline Framebuffer() : device(), data(), extent() {
|
||||
|
||||
}
|
||||
|
||||
bool Create(VkDevice device, VkFramebufferCreateFlags flags, VkRenderPass render_pass,
|
||||
uint32_t attachment_count, const VkImageView* attachments, uint32_t width, uint32_t height);
|
||||
void Destroy();
|
||||
|
||||
inline VkExtent2D GetExtent() const {
|
||||
return extent;
|
||||
}
|
||||
|
||||
inline operator VkFramebuffer() const {
|
||||
return data;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Image.hpp"
|
||||
#include "CommandBuffer.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
bool Image::Create(VmaAllocator allocator, VkImageCreateFlags flags, uint32_t width, uint32_t height,
|
||||
uint32_t mip_levels, uint32_t array_layers, VkFormat format, VkImageTiling tiling,
|
||||
VkImageUsageFlags usage, VmaMemoryUsage memory_usage, VmaAllocationCreateFlags allocation_flags) {
|
||||
Destroy();
|
||||
|
||||
VkImageCreateInfo image_create_info = {};
|
||||
image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
image_create_info.flags = flags;
|
||||
image_create_info.imageType = VK_IMAGE_TYPE_2D;
|
||||
image_create_info.extent.width = width;
|
||||
image_create_info.extent.height = height;
|
||||
image_create_info.extent.depth = 1;
|
||||
image_create_info.mipLevels = mip_levels;
|
||||
image_create_info.arrayLayers = array_layers;
|
||||
image_create_info.format = format;
|
||||
image_create_info.tiling = tiling;
|
||||
image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
image_create_info.usage = usage;
|
||||
image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
|
||||
VmaAllocationCreateInfo allocation_create_info = {};
|
||||
allocation_create_info.usage = memory_usage;
|
||||
allocation_create_info.flags = allocation_flags;
|
||||
|
||||
if (vmaCreateImage(allocator, &image_create_info,
|
||||
&allocation_create_info, &data, &allocation, 0) != VK_SUCCESS) {
|
||||
this->allocator = 0;
|
||||
data = 0;
|
||||
image_layout = 0;
|
||||
allocation = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*(uint64_t*)&data == 0xf448ed0000001349)
|
||||
printf("");
|
||||
|
||||
this->allocator = allocator;
|
||||
this->mip_levels = mip_levels;
|
||||
this->array_layers = array_layers;
|
||||
|
||||
image_layout = force_malloc<VkImageLayout>((size_t)mip_levels * array_layers);
|
||||
for (uint32_t i = 0; i < mip_levels; i++)
|
||||
for (uint32_t j = 0; j < array_layers; j++)
|
||||
image_layout[array_layers * i + j] = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Image::Destroy() {
|
||||
free_def(image_layout);
|
||||
image_layout = 0;
|
||||
|
||||
CommandBuffer::AddImage(Vulkan::current_command_buffer, *this);
|
||||
|
||||
allocator = 0;
|
||||
data = 0;
|
||||
allocation = 0;
|
||||
}
|
||||
|
||||
VkImageLayout Image::GetImageLayout(uint32_t level, uint32_t layer) {
|
||||
return image_layout[array_layers * level + layer];
|
||||
}
|
||||
|
||||
void Image::SetImageLayout(VkImageLayout image_layout) {
|
||||
for (uint32_t i = 0; i < mip_levels; i++)
|
||||
for (uint32_t j = 0; j < array_layers; j++)
|
||||
this->image_layout[array_layers * i + j] = image_layout;
|
||||
}
|
||||
|
||||
void Image::SetImageLayout(VkImageLayout image_layout, uint32_t level, uint32_t layer) {
|
||||
this->image_layout[array_layers * level + layer] = image_layout;
|
||||
}
|
||||
|
||||
std::pair<VkAccessFlags, VkPipelineStageFlags> getVkPipelineStageFlagsVkAccessFlags(VkImageLayout image_layout) {
|
||||
switch (image_layout) {
|
||||
case VK_IMAGE_LAYOUT_UNDEFINED:
|
||||
return {
|
||||
0,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
|
||||
};
|
||||
case VK_IMAGE_LAYOUT_GENERAL:
|
||||
return {
|
||||
0,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
|
||||
};
|
||||
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
|
||||
return {
|
||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
|
||||
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
|
||||
};
|
||||
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
|
||||
return {
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
|
||||
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
|
||||
| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
|
||||
};
|
||||
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
|
||||
return {
|
||||
VK_ACCESS_SHADER_READ_BIT,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
|
||||
};
|
||||
case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
|
||||
return {
|
||||
VK_ACCESS_TRANSFER_READ_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT
|
||||
};
|
||||
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
|
||||
return {
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT
|
||||
};
|
||||
case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:
|
||||
return {
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT
|
||||
};
|
||||
}
|
||||
return { 0, 0 };
|
||||
}
|
||||
|
||||
bool Image::PipelineBarrier(VkCommandBuffer command_buffer, VkImage image,
|
||||
VkImageAspectFlags aspect_mask, uint32_t level_count, uint32_t layer_count,
|
||||
VkImageLayout old_layout, VkImageLayout new_layout) {
|
||||
if (old_layout == new_layout)
|
||||
return true;
|
||||
|
||||
VkImageMemoryBarrier barrier;
|
||||
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
barrier.pNext = 0;
|
||||
barrier.srcAccessMask = 0;
|
||||
barrier.dstAccessMask = 0;
|
||||
barrier.oldLayout = old_layout;
|
||||
barrier.newLayout = new_layout;
|
||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.image = image;
|
||||
barrier.subresourceRange.aspectMask = aspect_mask;
|
||||
barrier.subresourceRange.baseMipLevel = 0;
|
||||
barrier.subresourceRange.levelCount = level_count;
|
||||
barrier.subresourceRange.baseArrayLayer = 0;
|
||||
barrier.subresourceRange.layerCount = layer_count;
|
||||
|
||||
std::pair<VkAccessFlags, VkPipelineStageFlags> src = getVkPipelineStageFlagsVkAccessFlags(old_layout);
|
||||
std::pair<VkAccessFlags, VkPipelineStageFlags> dst = getVkPipelineStageFlagsVkAccessFlags(new_layout);
|
||||
if (!src.second || !dst.second)
|
||||
return false;
|
||||
|
||||
barrier.srcAccessMask = src.first;
|
||||
barrier.dstAccessMask = dst.first;
|
||||
|
||||
Vulkan::end_render_pass(command_buffer);
|
||||
|
||||
vkCmdPipelineBarrier(command_buffer, src.second, dst.second, 0, 0, 0, 0, 0, 1, &barrier);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Image::PipelineBarrier(VkCommandBuffer command_buffer, Vulkan::Image& image,
|
||||
VkImageAspectFlags aspect_mask, uint32_t level_count, uint32_t layer_count, VkImageLayout new_layout) {
|
||||
VkImageLayout old_layout = image.GetImageLayout(0, 0);
|
||||
if (old_layout == new_layout)
|
||||
return true;
|
||||
|
||||
VkImageMemoryBarrier barrier;
|
||||
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
barrier.pNext = 0;
|
||||
barrier.srcAccessMask = 0;
|
||||
barrier.dstAccessMask = 0;
|
||||
barrier.oldLayout = old_layout;
|
||||
barrier.newLayout = new_layout;
|
||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.image = image;
|
||||
barrier.subresourceRange.aspectMask = aspect_mask;
|
||||
barrier.subresourceRange.baseMipLevel = 0;
|
||||
barrier.subresourceRange.levelCount = level_count;
|
||||
barrier.subresourceRange.baseArrayLayer = 0;
|
||||
barrier.subresourceRange.layerCount = layer_count;
|
||||
|
||||
std::pair<VkAccessFlags, VkPipelineStageFlags> src = getVkPipelineStageFlagsVkAccessFlags(old_layout);
|
||||
std::pair<VkAccessFlags, VkPipelineStageFlags> dst = getVkPipelineStageFlagsVkAccessFlags(new_layout);
|
||||
if (!src.second || !dst.second)
|
||||
return false;
|
||||
|
||||
barrier.srcAccessMask = src.first;
|
||||
barrier.dstAccessMask = dst.first;
|
||||
|
||||
Vulkan::end_render_pass(command_buffer);
|
||||
|
||||
vkCmdPipelineBarrier(command_buffer, src.second, dst.second, 0, 0, 0, 0, 0, 1, &barrier);
|
||||
image.SetImageLayout(new_layout);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Image::PipelineBarrierSingle(VkCommandBuffer command_buffer, VkImage image,
|
||||
VkImageAspectFlags aspect_mask, uint32_t level, uint32_t layer,
|
||||
VkImageLayout old_layout, VkImageLayout new_layout) {
|
||||
if (old_layout == new_layout)
|
||||
return true;
|
||||
|
||||
VkImageMemoryBarrier barrier;
|
||||
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
barrier.pNext = 0;
|
||||
barrier.srcAccessMask = 0;
|
||||
barrier.dstAccessMask = 0;
|
||||
barrier.oldLayout = old_layout;
|
||||
barrier.newLayout = new_layout;
|
||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.image = image;
|
||||
barrier.subresourceRange.aspectMask = aspect_mask;
|
||||
barrier.subresourceRange.baseMipLevel = level;
|
||||
barrier.subresourceRange.levelCount = 1;
|
||||
barrier.subresourceRange.baseArrayLayer = layer;
|
||||
barrier.subresourceRange.layerCount = 1;
|
||||
|
||||
std::pair<VkAccessFlags, VkPipelineStageFlags> src = getVkPipelineStageFlagsVkAccessFlags(old_layout);
|
||||
std::pair<VkAccessFlags, VkPipelineStageFlags> dst = getVkPipelineStageFlagsVkAccessFlags(new_layout);
|
||||
if (!src.second || !dst.second)
|
||||
return false;
|
||||
|
||||
barrier.srcAccessMask = src.first;
|
||||
barrier.dstAccessMask = dst.first;
|
||||
|
||||
Vulkan::end_render_pass(command_buffer);
|
||||
|
||||
vkCmdPipelineBarrier(command_buffer, src.second, dst.second, 0, 0, 0, 0, 0, 1, &barrier);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Image::PipelineBarrierSingle(VkCommandBuffer command_buffer, Vulkan::Image& image,
|
||||
VkImageAspectFlags aspect_mask, uint32_t level, uint32_t layer, VkImageLayout new_layout) {
|
||||
VkImageLayout old_layout = image.GetImageLayout(level, layer);
|
||||
if (old_layout == new_layout)
|
||||
return true;
|
||||
|
||||
VkImageMemoryBarrier barrier;
|
||||
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
barrier.pNext = 0;
|
||||
barrier.srcAccessMask = 0;
|
||||
barrier.dstAccessMask = 0;
|
||||
barrier.oldLayout = old_layout;
|
||||
barrier.newLayout = new_layout;
|
||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.image = image;
|
||||
barrier.subresourceRange.aspectMask = aspect_mask;
|
||||
barrier.subresourceRange.baseMipLevel = level;
|
||||
barrier.subresourceRange.levelCount = 1;
|
||||
barrier.subresourceRange.baseArrayLayer = layer;
|
||||
barrier.subresourceRange.layerCount = 1;
|
||||
|
||||
std::pair<VkAccessFlags, VkPipelineStageFlags> src = getVkPipelineStageFlagsVkAccessFlags(old_layout);
|
||||
std::pair<VkAccessFlags, VkPipelineStageFlags> dst = getVkPipelineStageFlagsVkAccessFlags(new_layout);
|
||||
if (!src.second || !dst.second)
|
||||
return false;
|
||||
|
||||
barrier.srcAccessMask = src.first;
|
||||
barrier.dstAccessMask = dst.first;
|
||||
|
||||
Vulkan::end_render_pass(command_buffer);
|
||||
|
||||
vkCmdPipelineBarrier(command_buffer, src.second, dst.second, 0, 0, 0, 0, 0, 1, &barrier);
|
||||
image.SetImageLayout(new_layout, level, layer);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
class Image {
|
||||
friend class CommandBuffer;
|
||||
protected:
|
||||
VmaAllocator allocator;
|
||||
VkImage data;
|
||||
uint32_t mip_levels;
|
||||
uint32_t array_layers;
|
||||
VkImageLayout* image_layout;
|
||||
VmaAllocation allocation;
|
||||
|
||||
public:
|
||||
inline Image() : allocator(), data(), image_layout(), mip_levels(), array_layers(), allocation() {
|
||||
|
||||
}
|
||||
|
||||
bool Create(VmaAllocator allocator, VkImageCreateFlags flags, uint32_t width, uint32_t height,
|
||||
uint32_t mip_levels, uint32_t array_layers, VkFormat format, VkImageTiling tiling,
|
||||
VkImageUsageFlags usage, VmaMemoryUsage memory_usage, VmaAllocationCreateFlags allocation_flags);
|
||||
void Destroy();
|
||||
VkImageLayout GetImageLayout(uint32_t level, uint32_t layer);
|
||||
void SetImageLayout(VkImageLayout image_layout);
|
||||
void SetImageLayout(VkImageLayout image_layout, uint32_t level, uint32_t layer);
|
||||
|
||||
inline void* MapMemory() {
|
||||
void* data;
|
||||
if (vmaMapMemory(allocator, allocation, &data) == VK_SUCCESS)
|
||||
return data;
|
||||
vmaUnmapMemory(allocator, allocation);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void* MapMemory(size_t offset, size_t length) {
|
||||
void* data;
|
||||
if (vmaMapMemory(allocator, allocation, &data) == VK_SUCCESS)
|
||||
return (void*)((size_t)data + offset);
|
||||
vmaUnmapMemory(allocator, allocation);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline bool NotNull() {
|
||||
return !!data;
|
||||
}
|
||||
|
||||
inline void ReadMemory(size_t offset, size_t size, void* data) {
|
||||
void* _data;
|
||||
if (vmaMapMemory(allocator, allocation, &_data) == VK_SUCCESS)
|
||||
memcpy(data, (void*)((size_t)_data + offset), size);
|
||||
vmaUnmapMemory(allocator, allocation);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void ReadMemory(T& data) {
|
||||
void* _data;
|
||||
if (vmaMapMemory(allocator, allocation, &_data) == VK_SUCCESS)
|
||||
memcpy(&data, _data, sizeof(T));
|
||||
vmaUnmapMemory(allocator, allocation);
|
||||
}
|
||||
|
||||
inline void UnmapMemory() {
|
||||
vmaUnmapMemory(allocator, allocation);
|
||||
}
|
||||
|
||||
inline void WriteMemory(size_t offset, size_t size, const void* data) {
|
||||
void* _data;
|
||||
if (vmaMapMemory(allocator, allocation, &_data) == VK_SUCCESS)
|
||||
memcpy((void*)((size_t)_data + offset), data, size);
|
||||
vmaUnmapMemory(allocator, allocation);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void WriteMemory(T& data) {
|
||||
void* _data;
|
||||
if (vmaMapMemory(allocator, allocation, &_data) == VK_SUCCESS)
|
||||
memcpy(_data, &data, sizeof(T));
|
||||
vmaUnmapMemory(allocator, allocation);
|
||||
}
|
||||
|
||||
static bool PipelineBarrier(VkCommandBuffer command_buffer, VkImage image,
|
||||
VkImageAspectFlags aspect_mask, uint32_t level_count, uint32_t layer_count,
|
||||
VkImageLayout old_layout, VkImageLayout new_layout);
|
||||
static bool PipelineBarrier(VkCommandBuffer command_buffer, Vulkan::Image& image,
|
||||
VkImageAspectFlags aspect_mask, uint32_t level_count, uint32_t layer_count, VkImageLayout new_layout);
|
||||
static bool PipelineBarrierSingle(VkCommandBuffer command_buffer, VkImage image,
|
||||
VkImageAspectFlags aspect_mask, uint32_t level, uint32_t layer,
|
||||
VkImageLayout old_layout, VkImageLayout new_layout);
|
||||
static bool PipelineBarrierSingle(VkCommandBuffer command_buffer, Vulkan::Image& image,
|
||||
VkImageAspectFlags aspect_mask, uint32_t level, uint32_t layer, VkImageLayout new_layout);
|
||||
|
||||
inline operator VkImage() const {
|
||||
return data;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ImageView.hpp"
|
||||
#include "Manager.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
bool ImageView::Create(VkDevice device, VkImageViewCreateFlags flags, VkImage image,
|
||||
VkImageViewType view_type, VkFormat format, VkImageAspectFlags aspect_mask,
|
||||
uint32_t base_mip_level, uint32_t level_count, uint32_t base_array_layer, uint32_t layer_count,
|
||||
const VkComponentMapping& components) {
|
||||
if (data)
|
||||
Destroy();
|
||||
|
||||
VkImageViewCreateInfo image_view_create_info;
|
||||
image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
image_view_create_info.pNext = 0;
|
||||
image_view_create_info.flags = flags;
|
||||
image_view_create_info.image = image;
|
||||
image_view_create_info.viewType = view_type;
|
||||
image_view_create_info.format = format;
|
||||
image_view_create_info.components = components;
|
||||
image_view_create_info.subresourceRange.aspectMask = aspect_mask;
|
||||
image_view_create_info.subresourceRange.baseMipLevel = base_mip_level;
|
||||
image_view_create_info.subresourceRange.levelCount = level_count;
|
||||
image_view_create_info.subresourceRange.baseArrayLayer = base_array_layer;
|
||||
image_view_create_info.subresourceRange.layerCount = layer_count;
|
||||
|
||||
this->device = device;
|
||||
if (vkCreateImageView(device, &image_view_create_info, 0, &data) == VK_SUCCESS)
|
||||
return true;
|
||||
|
||||
this->device = 0;
|
||||
data = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
void ImageView::Destroy() {
|
||||
if (data) {
|
||||
Vulkan::manager_free_image_view(device, data, 0);
|
||||
data = 0;
|
||||
}
|
||||
device = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
class ImageView {
|
||||
protected:
|
||||
VkDevice device;
|
||||
VkImageView data;
|
||||
|
||||
public:
|
||||
inline ImageView() : device(), data() {
|
||||
|
||||
}
|
||||
|
||||
bool Create(VkDevice device, VkImageViewCreateFlags flags, VkImage image,
|
||||
VkImageViewType view_type, VkFormat format, VkImageAspectFlags aspect_mask,
|
||||
uint32_t base_mip_level, uint32_t level_count, uint32_t base_array_layer, uint32_t layer_count,
|
||||
const VkComponentMapping& components = {});
|
||||
void Destroy();
|
||||
|
||||
inline operator VkImageView() const {
|
||||
return data;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "IndexBuffer.hpp"
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Buffer.hpp"
|
||||
#include "CommandBuffer.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
class IndexBuffer : public Buffer {
|
||||
public:
|
||||
inline IndexBuffer() {
|
||||
|
||||
}
|
||||
|
||||
inline bool Create(VmaAllocator allocator, size_t size) {
|
||||
return Buffer::Create(allocator, size,
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT
|
||||
| VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
|
||||
VMA_MEMORY_USAGE_AUTO, 0);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Pipeline.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
Pipeline::Pipeline(VkDevice device, VkPipelineCreateFlags flags, uint32_t stage_count,
|
||||
const VkPipelineShaderStageCreateInfo* stages,
|
||||
uint32_t vertex_input_binding_description_count,
|
||||
const VkVertexInputBindingDescription* vertex_input_binding_descriptions,
|
||||
uint32_t vertex_input_attribute_description_count,
|
||||
const VkVertexInputAttributeDescription* vertex_input_attribute_descriptions,
|
||||
const VkPipelineInputAssemblyStateCreateInfo* input_assembly_state,
|
||||
const VkPipelineViewportStateCreateInfo* viewport_state,
|
||||
const VkPipelineRasterizationStateCreateInfo* rasterization_state,
|
||||
const VkPipelineDepthStencilStateCreateInfo* depth_stencil_state,
|
||||
uint32_t color_blend_attachment_count,
|
||||
const VkPipelineColorBlendAttachmentState* color_blend_attachments,
|
||||
VkPipelineLayout layout, VkRenderPass render_pass) {
|
||||
VkPipelineVertexInputStateCreateInfo vertex_input_state = {};
|
||||
vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||
vertex_input_state.vertexBindingDescriptionCount = vertex_input_binding_description_count;
|
||||
vertex_input_state.pVertexBindingDescriptions = vertex_input_binding_descriptions;
|
||||
vertex_input_state.vertexAttributeDescriptionCount = vertex_input_attribute_description_count;
|
||||
vertex_input_state.pVertexAttributeDescriptions = vertex_input_attribute_descriptions;
|
||||
|
||||
VkPipelineMultisampleStateCreateInfo multisample_state = {};
|
||||
multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||
multisample_state.sampleShadingEnable = VK_FALSE;
|
||||
multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
VkPipelineColorBlendStateCreateInfo color_blend_state = {};
|
||||
color_blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
||||
color_blend_state.logicOpEnable = VK_FALSE;
|
||||
color_blend_state.logicOp = VK_LOGIC_OP_COPY;
|
||||
color_blend_state.attachmentCount = color_blend_attachment_count;
|
||||
color_blend_state.pAttachments = color_blend_attachments;
|
||||
color_blend_state.blendConstants[0] = 0.0f;
|
||||
color_blend_state.blendConstants[1] = 0.0f;
|
||||
color_blend_state.blendConstants[2] = 0.0f;
|
||||
color_blend_state.blendConstants[3] = 0.0f;
|
||||
|
||||
VkGraphicsPipelineCreateInfo graphics_pipeline_create_info;
|
||||
graphics_pipeline_create_info.pNext = 0;
|
||||
graphics_pipeline_create_info.flags = flags;
|
||||
graphics_pipeline_create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
graphics_pipeline_create_info.stageCount = 2;
|
||||
graphics_pipeline_create_info.pStages = stages;
|
||||
graphics_pipeline_create_info.pVertexInputState = &vertex_input_state;
|
||||
graphics_pipeline_create_info.pInputAssemblyState = input_assembly_state;
|
||||
graphics_pipeline_create_info.pTessellationState = 0;
|
||||
graphics_pipeline_create_info.pViewportState = viewport_state;
|
||||
graphics_pipeline_create_info.pRasterizationState = rasterization_state;
|
||||
graphics_pipeline_create_info.pMultisampleState = &multisample_state;
|
||||
graphics_pipeline_create_info.pDepthStencilState = depth_stencil_state;
|
||||
graphics_pipeline_create_info.pColorBlendState = &color_blend_state;
|
||||
graphics_pipeline_create_info.pDynamicState = 0;
|
||||
graphics_pipeline_create_info.layout = layout;
|
||||
graphics_pipeline_create_info.renderPass = render_pass;
|
||||
graphics_pipeline_create_info.subpass = 0;
|
||||
graphics_pipeline_create_info.basePipelineHandle = 0;
|
||||
graphics_pipeline_create_info.basePipelineIndex = 0;
|
||||
|
||||
this->device = device;
|
||||
if (vkCreateGraphicsPipelines(device, 0, 1, &graphics_pipeline_create_info, 0, &data) == VK_SUCCESS)
|
||||
return;
|
||||
|
||||
this->device = 0;
|
||||
data = 0;
|
||||
}
|
||||
|
||||
Pipeline::~Pipeline() {
|
||||
if (data) {
|
||||
vkDestroyPipeline(device, data, 0);
|
||||
data = 0;
|
||||
}
|
||||
device = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
class Pipeline {
|
||||
protected:
|
||||
VkDevice device;
|
||||
VkPipeline data;
|
||||
|
||||
public:
|
||||
Pipeline(VkDevice device, VkPipelineCreateFlags flags, uint32_t stage_count,
|
||||
const VkPipelineShaderStageCreateInfo* stages,
|
||||
uint32_t vertex_input_binding_description_count,
|
||||
const VkVertexInputBindingDescription* vertex_input_binding_descriptions,
|
||||
uint32_t vertex_input_attribute_description_count,
|
||||
const VkVertexInputAttributeDescription* vertex_input_attribute_descriptions,
|
||||
const VkPipelineInputAssemblyStateCreateInfo* input_assembly_state,
|
||||
const VkPipelineViewportStateCreateInfo* viewport_state,
|
||||
const VkPipelineRasterizationStateCreateInfo* rasterization_state,
|
||||
const VkPipelineDepthStencilStateCreateInfo* depth_stencil_state,
|
||||
uint32_t color_blend_attachment_count,
|
||||
const VkPipelineColorBlendAttachmentState* color_blend_attachments,
|
||||
VkPipelineLayout layout, VkRenderPass render_pass);
|
||||
~Pipeline();
|
||||
|
||||
inline operator VkPipeline() const {
|
||||
return data;
|
||||
}
|
||||
|
||||
Pipeline(const Pipeline&) = delete;
|
||||
Pipeline& operator=(const Pipeline&) = delete;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Query.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
bool Query::Create(VkDevice device, VkQueryPoolCreateFlags flags, VkQueryType query_type) {
|
||||
VkQueryPoolCreateInfo query_pool_create_info;
|
||||
query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
|
||||
query_pool_create_info.pNext = 0;
|
||||
query_pool_create_info.flags = flags;
|
||||
query_pool_create_info.queryType = query_type;
|
||||
query_pool_create_info.queryCount = 1;
|
||||
query_pool_create_info.pipelineStatistics = 0;
|
||||
|
||||
this->device = device;
|
||||
began = false;
|
||||
needs_reset = true;
|
||||
if (vkCreateQueryPool(device, &query_pool_create_info, 0, &data) == VK_SUCCESS)
|
||||
return true;
|
||||
|
||||
this->device = 0;
|
||||
data = 0;
|
||||
needs_reset = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Query::Destroy() {
|
||||
if (data) {
|
||||
vkDestroyQueryPool(device, data, 0);
|
||||
data = 0;
|
||||
}
|
||||
device = 0;
|
||||
began = false;
|
||||
needs_reset = false;
|
||||
}
|
||||
|
||||
void Query::Begin(VkCommandBuffer command_buffer) {
|
||||
if (!began) {
|
||||
vkCmdBeginQuery(command_buffer, data, 0, 0);
|
||||
began = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Query::End(VkCommandBuffer command_buffer) {
|
||||
if (began) {
|
||||
vkCmdEndQuery(command_buffer, data, 0);
|
||||
began = false;
|
||||
needs_reset = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool Query::GetBegan() {
|
||||
return began;
|
||||
}
|
||||
|
||||
void Query::GetResult(size_t size, void* data, VkQueryResultFlags flags) {
|
||||
vkGetQueryPoolResults(device, this->data, 0, 1, size, data, size, flags);
|
||||
}
|
||||
|
||||
void Query::Reset(VkCommandBuffer command_buffer) {
|
||||
if (needs_reset) {
|
||||
vkCmdResetQueryPool(command_buffer, data, 0, 1);
|
||||
needs_reset = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
class Query {
|
||||
protected:
|
||||
VkDevice device;
|
||||
VkQueryPool data;
|
||||
bool began;
|
||||
bool needs_reset;
|
||||
|
||||
public:
|
||||
inline Query() : device(), data(), began(), needs_reset() {
|
||||
|
||||
}
|
||||
|
||||
bool Create(VkDevice device, VkQueryPoolCreateFlags flags, VkQueryType query_type);
|
||||
void Destroy();
|
||||
|
||||
void Begin(VkCommandBuffer command_buffer);
|
||||
void End(VkCommandBuffer command_buffer);
|
||||
bool GetBegan();
|
||||
void GetResult(size_t size, void* data, VkQueryResultFlags flags);
|
||||
void Reset(VkCommandBuffer command_buffer);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RenderPass.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
RenderPass::RenderPass(VkDevice device, VkRenderPassCreateFlags flags,
|
||||
uint32_t attachment_count, const VkAttachmentDescription* sttachments,
|
||||
uint32_t subpass_count, const VkSubpassDescription* subpasses,
|
||||
uint32_t dependency_count, const VkSubpassDependency* dependencies) {
|
||||
|
||||
VkRenderPassCreateInfo render_pass_create_info;
|
||||
render_pass_create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||
render_pass_create_info.pNext = 0;
|
||||
render_pass_create_info.flags = flags;
|
||||
render_pass_create_info.attachmentCount = attachment_count;
|
||||
render_pass_create_info.pAttachments = sttachments;
|
||||
render_pass_create_info.subpassCount = subpass_count;
|
||||
render_pass_create_info.pSubpasses = subpasses;
|
||||
render_pass_create_info.dependencyCount = dependency_count;
|
||||
render_pass_create_info.pDependencies = dependencies;
|
||||
|
||||
this->device = device;
|
||||
if (vkCreateRenderPass(device, &render_pass_create_info, 0, &data) == VK_SUCCESS)
|
||||
return;
|
||||
|
||||
this->device = 0;
|
||||
data = 0;
|
||||
}
|
||||
|
||||
RenderPass::~RenderPass() {
|
||||
if (data) {
|
||||
vkDestroyRenderPass(device, data, 0);
|
||||
data = 0;
|
||||
}
|
||||
device = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
class RenderPass {
|
||||
protected:
|
||||
VkDevice device;
|
||||
VkRenderPass data;
|
||||
|
||||
public:
|
||||
RenderPass(VkDevice device, VkRenderPassCreateFlags flags,
|
||||
uint32_t attachment_count, const VkAttachmentDescription* sttachments,
|
||||
uint32_t subpass_count, const VkSubpassDescription* subpasses,
|
||||
uint32_t dependency_count, const VkSubpassDependency* dependencies);
|
||||
~RenderPass();
|
||||
|
||||
inline operator VkRenderPass() const {
|
||||
return data;
|
||||
}
|
||||
|
||||
RenderPass(const RenderPass&) = delete;
|
||||
RenderPass& operator=(const RenderPass&) = delete;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Sampler.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
Sampler::Sampler(VkDevice device, VkSamplerCreateFlags flags,
|
||||
VkFilter mag_filter, VkFilter min_filter, VkSamplerMipmapMode mipmap_mode,
|
||||
VkSamplerAddressMode address_mode_u, VkSamplerAddressMode address_mode_v,
|
||||
VkSamplerAddressMode address_mode_w, float_t min_lod, float_t max_lod,
|
||||
float_t max_anisotropy, VkBorderColor border_color) {
|
||||
VkSamplerCreateInfo sampler_create_info = {};
|
||||
sampler_create_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
sampler_create_info.pNext = 0;
|
||||
sampler_create_info.flags = flags;
|
||||
sampler_create_info.magFilter = mag_filter;
|
||||
sampler_create_info.minFilter = min_filter;
|
||||
sampler_create_info.mipmapMode = mipmap_mode;
|
||||
sampler_create_info.addressModeU = address_mode_u;
|
||||
sampler_create_info.addressModeV = address_mode_v;
|
||||
sampler_create_info.addressModeW = address_mode_w;
|
||||
sampler_create_info.mipLodBias = 0.0f;
|
||||
sampler_create_info.anisotropyEnable = max_anisotropy > 0.0f;
|
||||
sampler_create_info.maxAnisotropy = min_def(max_anisotropy, 16.0f);
|
||||
sampler_create_info.compareEnable = VK_FALSE;
|
||||
sampler_create_info.compareOp = VK_COMPARE_OP_ALWAYS;
|
||||
sampler_create_info.minLod = min_lod;
|
||||
sampler_create_info.maxLod = max_lod;
|
||||
sampler_create_info.borderColor = border_color;
|
||||
sampler_create_info.unnormalizedCoordinates = VK_FALSE;
|
||||
|
||||
this->device = device;
|
||||
if (vkCreateSampler(device, &sampler_create_info, 0, &data) == VK_SUCCESS)
|
||||
return;
|
||||
|
||||
this->device = 0;
|
||||
data = 0;
|
||||
}
|
||||
|
||||
Sampler::~Sampler() {
|
||||
if (data) {
|
||||
vkDestroySampler(device, data, 0);
|
||||
data = 0;
|
||||
}
|
||||
device = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
class Sampler {
|
||||
protected:
|
||||
VkDevice device;
|
||||
VkSampler data;
|
||||
|
||||
public:
|
||||
Sampler(VkDevice device, VkSamplerCreateFlags flags,
|
||||
VkFilter mag_filter, VkFilter min_filter, VkSamplerMipmapMode mipmap_mode,
|
||||
VkSamplerAddressMode address_mode_u, VkSamplerAddressMode address_mode_v,
|
||||
VkSamplerAddressMode address_mode_w, float_t min_lod, float_t max_lod,
|
||||
float_t max_anisotropy, VkBorderColor border_color);
|
||||
~Sampler();
|
||||
|
||||
inline operator VkSampler() const {
|
||||
return data;
|
||||
}
|
||||
|
||||
Sampler(const Sampler&) = delete;
|
||||
Sampler& operator=(const Sampler&) = delete;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Semaphore.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
bool Semaphore::Create(VkDevice device, VkSemaphoreCreateFlags flags) {
|
||||
Destroy();
|
||||
|
||||
VkSemaphoreCreateInfo semaphore_create_info;
|
||||
semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
semaphore_create_info.pNext = 0;
|
||||
semaphore_create_info.flags = flags;
|
||||
|
||||
this->device = device;
|
||||
if (vkCreateSemaphore(device, &semaphore_create_info, 0, &data) == VK_SUCCESS)
|
||||
return true;
|
||||
|
||||
this->device = 0;
|
||||
data = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Semaphore::Destroy() {
|
||||
if (data) {
|
||||
vkDestroySemaphore(device, data, 0);
|
||||
data = 0;
|
||||
}
|
||||
device = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
class Semaphore {
|
||||
protected:
|
||||
VkDevice device;
|
||||
VkSemaphore data;
|
||||
|
||||
public:
|
||||
inline Semaphore() : device(), data() {
|
||||
|
||||
}
|
||||
|
||||
bool Create(VkDevice device, VkSemaphoreCreateFlags flags);
|
||||
void Destroy();
|
||||
|
||||
inline operator VkSemaphore() const {
|
||||
return data;
|
||||
}
|
||||
|
||||
inline operator const VkSemaphore* () const {
|
||||
return &data;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ShaderModule.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
ShaderModule::ShaderModule(VkDevice device, const void* data, size_t size) {
|
||||
VkShaderModuleCreateInfo shader_module_create_info;
|
||||
shader_module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
shader_module_create_info.pNext = 0;
|
||||
shader_module_create_info.flags = 0;
|
||||
shader_module_create_info.codeSize = size;
|
||||
shader_module_create_info.pCode = (const uint32_t*)data;
|
||||
|
||||
this->device = device;
|
||||
if (vkCreateShaderModule(device, &shader_module_create_info, 0, &this->data) == VK_SUCCESS)
|
||||
return;
|
||||
|
||||
this->device = 0;
|
||||
this->data = 0;
|
||||
}
|
||||
|
||||
ShaderModule::~ShaderModule() {
|
||||
if (data) {
|
||||
vkDestroyShaderModule(device, data, 0);
|
||||
data = 0;
|
||||
}
|
||||
device = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
class ShaderModule {
|
||||
protected:
|
||||
VkDevice device;
|
||||
VkShaderModule data;
|
||||
|
||||
public:
|
||||
ShaderModule(VkDevice device, const void* data, size_t size);
|
||||
~ShaderModule();
|
||||
|
||||
inline operator VkShaderModule() const {
|
||||
return data;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "StagingBuffer.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
bool StagingBuffer::Create(VmaAllocator allocator, size_t size) {
|
||||
curr_size = 0;
|
||||
offset = 0;
|
||||
return Buffer::Create(allocator, size,
|
||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT
|
||||
| VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||
VMA_MEMORY_USAGE_AUTO,
|
||||
VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT
|
||||
| VMA_ALLOCATION_CREATE_MAPPED_BIT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Buffer.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
class StagingBuffer : public Buffer {
|
||||
public:
|
||||
VkDeviceSize curr_size;
|
||||
uint32_t empty_frame_count;
|
||||
|
||||
inline StagingBuffer() : curr_size(), empty_frame_count() {
|
||||
|
||||
}
|
||||
|
||||
bool Create(VmaAllocator allocator, size_t size);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "StorageBuffer.hpp"
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Buffer.hpp"
|
||||
#include "CommandBuffer.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
class StorageBuffer : public Buffer {
|
||||
public:
|
||||
inline StorageBuffer() {
|
||||
|
||||
}
|
||||
|
||||
inline bool Create(VmaAllocator allocator, size_t size) {
|
||||
return Buffer::Create(allocator, size,
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT
|
||||
| VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
||||
VMA_MEMORY_USAGE_AUTO, 0);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "UniformBuffer.hpp"
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Buffer.hpp"
|
||||
#include "CommandBuffer.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
class UniformBuffer : public Buffer {
|
||||
public:
|
||||
inline UniformBuffer() {
|
||||
|
||||
}
|
||||
|
||||
inline bool Create(VmaAllocator allocator, size_t size) {
|
||||
return Buffer::Create(allocator, size,
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT
|
||||
| VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
||||
VMA_MEMORY_USAGE_AUTO, 0);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "VertexBuffer.hpp"
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Buffer.hpp"
|
||||
#include "CommandBuffer.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
class VertexBuffer : public Buffer {
|
||||
public:
|
||||
inline VertexBuffer() {
|
||||
|
||||
}
|
||||
|
||||
inline bool Create(VmaAllocator allocator, size_t size) {
|
||||
return Buffer::Create(allocator, size,
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT
|
||||
| VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
||||
VMA_MEMORY_USAGE_AUTO, 0);
|
||||
}
|
||||
};
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../KKdLib/default.hpp"
|
||||
#include "../../KKdLib/prj/shared_ptr.hpp"
|
||||
#include "../../KKdLib/vec.hpp"
|
||||
#include "../gl.hpp"
|
||||
#include "shared.hpp"
|
||||
#include "Framebuffer.hpp"
|
||||
#include "Image.hpp"
|
||||
#include "ImageView.hpp"
|
||||
#include "IndexBuffer.hpp"
|
||||
#include "Query.hpp"
|
||||
#include "RenderPass.hpp"
|
||||
#include "Sampler.hpp"
|
||||
#include "ShaderModule.hpp"
|
||||
#include "StorageBuffer.hpp"
|
||||
#include "UniformBuffer.hpp"
|
||||
#include "VertexBuffer.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
constexpr uint32_t MAX_COLOR_ATTACHMENTS = 8;
|
||||
constexpr uint32_t MAX_DRAW_BUFFERS = 8;
|
||||
constexpr uint32_t MAX_VERTEX_ATTRIB_COUNT = 16;
|
||||
|
||||
struct gl_framebuffer {
|
||||
Vulkan::Framebuffer framebuffer;
|
||||
prj::shared_ptr<Vulkan::RenderPass> render_pass;
|
||||
|
||||
GLuint color_attachments[Vulkan::MAX_COLOR_ATTACHMENTS];
|
||||
GLint color_attachment_levels[Vulkan::MAX_COLOR_ATTACHMENTS];
|
||||
Vulkan::ImageView color_attachment_image_views[Vulkan::MAX_COLOR_ATTACHMENTS];
|
||||
GLuint depth_attachment;
|
||||
GLint depth_attachment_level;
|
||||
Vulkan::ImageView depth_attachment_image_view;
|
||||
GLenum draw_buffers[Vulkan::MAX_DRAW_BUFFERS];
|
||||
GLenum read_buffer;
|
||||
bool update_color_attachment;
|
||||
bool update_depth_attachment;
|
||||
bool update_framebuffer;
|
||||
|
||||
gl_framebuffer();
|
||||
|
||||
GLuint get_draw_buffer_texture(uint32_t index = 0);
|
||||
GLuint get_read_buffer_texture();
|
||||
void release();
|
||||
|
||||
static gl_framebuffer* get(GLuint framebuffer, bool update_data = true);
|
||||
};
|
||||
|
||||
struct gl_index_buffer {
|
||||
Vulkan::IndexBuffer index_buffer;
|
||||
bool copy_working_buffer;
|
||||
Vulkan::Buffer working_buffer;
|
||||
|
||||
gl_index_buffer();
|
||||
|
||||
static gl_index_buffer* get(GLuint buffer);
|
||||
};
|
||||
|
||||
struct gl_program {
|
||||
prj::shared_ptr<Vulkan::ShaderModule> vertex_shader_module;
|
||||
prj::shared_ptr<Vulkan::ShaderModule> fragment_shader_module;
|
||||
|
||||
gl_program();
|
||||
|
||||
static gl_program* get(GLuint program);
|
||||
};
|
||||
|
||||
struct gl_query {
|
||||
GLenum target;
|
||||
Vulkan::Query query;
|
||||
|
||||
gl_query();
|
||||
|
||||
static gl_query* get(GLuint query);
|
||||
};
|
||||
|
||||
struct gl_sampler {
|
||||
GLenum min_filter;
|
||||
GLenum mag_filter;
|
||||
GLenum wrap_s;
|
||||
GLenum wrap_t;
|
||||
GLenum wrap_r;
|
||||
vec4 border_color;
|
||||
float_t max_anisotropy;
|
||||
|
||||
gl_sampler();
|
||||
gl_sampler(GLenum min_filter, GLenum mag_filter,
|
||||
GLenum wrap_s, GLenum wrap_t, GLenum wrap_r,
|
||||
const vec4& border_color, float_t max_anisotropy);
|
||||
|
||||
static gl_sampler* get(GLuint program);
|
||||
};
|
||||
|
||||
struct gl_storage_buffer {
|
||||
Vulkan::StorageBuffer storage_buffer;
|
||||
bool copy_working_buffer;
|
||||
Vulkan::Buffer working_buffer;
|
||||
|
||||
gl_storage_buffer();
|
||||
|
||||
static gl_storage_buffer* get(GLuint buffer);
|
||||
};
|
||||
|
||||
struct gl_texture {
|
||||
GLenum target;
|
||||
GLint max_mipmap_level;
|
||||
GLenum internal_format;
|
||||
GLsizei width;
|
||||
GLsizei height;
|
||||
Vulkan::Image image;
|
||||
Vulkan::ImageView image_view;
|
||||
Vulkan::ImageView sample_image_view;
|
||||
VkComponentMapping components;
|
||||
gl_sampler sampler_data;
|
||||
|
||||
gl_texture();
|
||||
|
||||
VkImageView get_image_view();
|
||||
|
||||
static gl_texture* get(GLuint texture, bool update_data = true);
|
||||
};
|
||||
|
||||
struct gl_uniform_buffer {
|
||||
Vulkan::UniformBuffer uniform_buffer;
|
||||
bool copy_working_buffer;
|
||||
Vulkan::Buffer working_buffer;
|
||||
|
||||
gl_uniform_buffer();
|
||||
|
||||
static gl_uniform_buffer* get(GLuint buffer);
|
||||
};
|
||||
|
||||
struct gl_vertex_buffer_binding_data {
|
||||
GLuint buffer;
|
||||
uint32_t offset;
|
||||
uint32_t stride;
|
||||
|
||||
gl_vertex_buffer_binding_data();
|
||||
};
|
||||
|
||||
constexpr bool operator==(const gl_vertex_buffer_binding_data& left,
|
||||
const gl_vertex_buffer_binding_data& right) {
|
||||
return left.buffer == right.buffer
|
||||
&& left.offset == right.offset && left.stride == right.stride;
|
||||
}
|
||||
|
||||
struct gl_index_buffer_binding_data {
|
||||
GLuint buffer;
|
||||
|
||||
gl_index_buffer_binding_data();
|
||||
};
|
||||
|
||||
struct gl_vertex_array_vertex_attrib {
|
||||
uint32_t binding;
|
||||
VkFormat format;
|
||||
uint32_t offset;
|
||||
bool enabled;
|
||||
vec4 generic_value;
|
||||
|
||||
gl_vertex_array_vertex_attrib();
|
||||
};
|
||||
|
||||
struct gl_vertex_array {
|
||||
gl_vertex_buffer_binding_data vertex_buffer_bindings[Vulkan::MAX_VERTEX_ATTRIB_COUNT];
|
||||
gl_index_buffer_binding_data index_buffer_binding;
|
||||
|
||||
gl_vertex_array_vertex_attrib vertex_attribs[Vulkan::MAX_VERTEX_ATTRIB_COUNT];
|
||||
|
||||
gl_vertex_array();
|
||||
|
||||
void set_vertex_attrib(uint32_t index, VkFormat format, uint32_t stride, uint32_t offset);
|
||||
void reset_vertex_attrib(uint32_t index);
|
||||
|
||||
public:
|
||||
static gl_vertex_array* get(GLuint array);
|
||||
};
|
||||
|
||||
struct gl_vertex_buffer {
|
||||
Vulkan::VertexBuffer vertex_buffer;
|
||||
bool copy_working_buffer;
|
||||
Vulkan::Buffer working_buffer;
|
||||
|
||||
gl_vertex_buffer();
|
||||
|
||||
static gl_vertex_buffer* get(GLuint buffer);
|
||||
};
|
||||
|
||||
extern void gl_wrap_manager_init(Vulkan::CommandBuffer& command_buffer);
|
||||
extern VkBuffer gl_wrap_manager_get_dummy_vertex_buffer();
|
||||
extern GLuint gl_wrap_manager_get_query_samples_passed();
|
||||
extern void gl_wrap_manager_update_buffers();
|
||||
extern void gl_wrap_manager_load_funcs();
|
||||
extern void gl_wrap_manager_free();
|
||||
|
||||
extern VkImageAspectFlags get_aspect_mask(GLenum internal_format);
|
||||
extern VkBlendFactor get_blend_factor(GLenum factor);
|
||||
extern VkBlendOp get_blend_op(GLenum mode);
|
||||
extern VkCompareOp get_compare_op(GLenum func);
|
||||
extern VkComponentSwizzle get_component_swizzle(GLenum swizzle, GLenum comp);
|
||||
extern VkCullModeFlags get_cull_mode_flags(GLenum mode);
|
||||
extern VkFormat get_format(GLenum internal_format);
|
||||
extern VkImageViewType get_image_view_type(GLenum target);
|
||||
extern VkPolygonMode get_polygon_mode(GLenum mode);
|
||||
}
|
||||
@@ -0,0 +1,761 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "manager.hpp"
|
||||
#include "../../KKdLib/prj/shared_ptr.hpp"
|
||||
#include "../../KKdLib/hash.hpp"
|
||||
#include "../static_var.hpp"
|
||||
#include "DescriptorPipeline.hpp"
|
||||
#include "Pipeline.hpp"
|
||||
#include "RenderPass.hpp"
|
||||
#include "Sampler.hpp"
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
struct descriptor_pipeline_data {
|
||||
uint64_t vp_desc_hash;
|
||||
uint64_t fp_desc_hash;
|
||||
uint64_t unival_hash;
|
||||
|
||||
inline descriptor_pipeline_data() : vp_desc_hash(), fp_desc_hash(), unival_hash() {
|
||||
|
||||
}
|
||||
|
||||
inline descriptor_pipeline_data(uint64_t vp_desc_hash, uint64_t fp_desc_hash, uint64_t unival_hash) {
|
||||
this->vp_desc_hash = vp_desc_hash;
|
||||
this->fp_desc_hash = fp_desc_hash;
|
||||
this->unival_hash = unival_hash;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class std::hash<descriptor_pipeline_data> {
|
||||
public:
|
||||
size_t operator()(const descriptor_pipeline_data& format) const {
|
||||
return (size_t)hash_xxh3_64bits(&format, sizeof(format));
|
||||
}
|
||||
};
|
||||
|
||||
constexpr bool operator==(const descriptor_pipeline_data& left, const descriptor_pipeline_data& right) {
|
||||
return left.vp_desc_hash == right.vp_desc_hash && left.fp_desc_hash == right.fp_desc_hash
|
||||
&& left.unival_hash == right.unival_hash;
|
||||
}
|
||||
|
||||
struct pipeline_data {
|
||||
uint64_t stages_hash;
|
||||
uint64_t vertex_input_info_binding_hash;
|
||||
uint64_t vertex_input_info_attribute_hash;
|
||||
uint64_t input_assembly_state_hash;
|
||||
uint64_t viewport_state_hash;
|
||||
uint64_t rasterization_state_hash;
|
||||
uint64_t depth_stencil_state_hash;
|
||||
uint64_t color_blend_attachmen_hash;
|
||||
VkPipelineLayout layout;
|
||||
VkRenderPass render_pass;
|
||||
|
||||
inline pipeline_data() : stages_hash(), vertex_input_info_binding_hash(),
|
||||
vertex_input_info_attribute_hash(), input_assembly_state_hash(),
|
||||
viewport_state_hash(), rasterization_state_hash(), depth_stencil_state_hash(),
|
||||
color_blend_attachmen_hash(), layout(), render_pass() {
|
||||
|
||||
}
|
||||
|
||||
inline pipeline_data(uint64_t stages_hash,
|
||||
uint64_t vertex_input_info_binding_hash, uint64_t vertex_input_info_attribute_hash,
|
||||
uint64_t input_assembly_state_hash, uint64_t viewport_state_hash,
|
||||
uint64_t rasterization_state_hash, uint64_t depth_stencil_state_hash, uint64_t color_blend_attachmen_hash,
|
||||
VkPipelineLayout layout, VkRenderPass render_pass) {
|
||||
this->stages_hash = stages_hash;
|
||||
this->vertex_input_info_binding_hash = vertex_input_info_binding_hash;
|
||||
this->vertex_input_info_attribute_hash = vertex_input_info_attribute_hash;
|
||||
this->input_assembly_state_hash = input_assembly_state_hash;
|
||||
this->viewport_state_hash = viewport_state_hash;
|
||||
this->rasterization_state_hash = rasterization_state_hash;
|
||||
this->depth_stencil_state_hash = depth_stencil_state_hash;
|
||||
this->color_blend_attachmen_hash = color_blend_attachmen_hash;
|
||||
this->layout = layout;
|
||||
this->render_pass = render_pass;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class std::hash<pipeline_data> {
|
||||
public:
|
||||
size_t operator()(const pipeline_data& format) const {
|
||||
return (size_t)hash_xxh3_64bits(&format, sizeof(format));
|
||||
}
|
||||
};
|
||||
|
||||
constexpr bool operator==(const pipeline_data& left, const pipeline_data& right) {
|
||||
return left.stages_hash == right.stages_hash
|
||||
&& left.vertex_input_info_binding_hash == right.vertex_input_info_binding_hash
|
||||
&& left.vertex_input_info_attribute_hash == right.vertex_input_info_attribute_hash
|
||||
&& left.input_assembly_state_hash == right.input_assembly_state_hash
|
||||
&& left.viewport_state_hash == right.viewport_state_hash
|
||||
&& left.rasterization_state_hash == right.rasterization_state_hash
|
||||
&& left.depth_stencil_state_hash == right.depth_stencil_state_hash
|
||||
&& left.color_blend_attachmen_hash == right.color_blend_attachmen_hash
|
||||
&& left.layout == right.layout && left.render_pass == right.render_pass;
|
||||
}
|
||||
|
||||
struct render_pass_data {
|
||||
uint64_t color_formats_hash;
|
||||
GLenum depth_format;
|
||||
bool stencil;
|
||||
uint8_t pad[3];
|
||||
|
||||
inline render_pass_data() : color_formats_hash(), depth_format(), stencil(), pad() {
|
||||
|
||||
}
|
||||
|
||||
inline render_pass_data(uint64_t color_formats_hash, GLenum depth_format, bool stencil) : pad() {
|
||||
this->color_formats_hash = color_formats_hash;
|
||||
this->depth_format = depth_format;
|
||||
this->stencil = stencil;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class std::hash<render_pass_data> {
|
||||
public:
|
||||
size_t operator()(const render_pass_data& format) const {
|
||||
return (size_t)hash_xxh3_64bits(&format, sizeof(format));
|
||||
}
|
||||
};
|
||||
|
||||
constexpr bool operator==(const render_pass_data& left, const render_pass_data& right) {
|
||||
return left.color_formats_hash == right.color_formats_hash
|
||||
&& left.depth_format == right.depth_format && left.stencil == right.stencil;
|
||||
}
|
||||
|
||||
namespace Vulkan {
|
||||
struct manager {
|
||||
struct free_framebuffer_data {
|
||||
VkDevice device;
|
||||
VkFramebuffer framebuffer;
|
||||
const VkAllocationCallbacks* allocator;
|
||||
|
||||
inline free_framebuffer_data() : device(), framebuffer(), allocator() {
|
||||
|
||||
}
|
||||
|
||||
inline free_framebuffer_data(VkDevice device,
|
||||
VkFramebuffer framebuffer, const VkAllocationCallbacks* allocator) {
|
||||
this->device = device;
|
||||
this->framebuffer = framebuffer;
|
||||
this->allocator = allocator;
|
||||
}
|
||||
};
|
||||
|
||||
struct free_image_view_data {
|
||||
VkDevice device;
|
||||
VkImageView image_view;
|
||||
const VkAllocationCallbacks* allocator;
|
||||
|
||||
inline free_image_view_data() : device(), image_view(), allocator() {
|
||||
|
||||
}
|
||||
|
||||
inline free_image_view_data(VkDevice device,
|
||||
VkImageView image_view, const VkAllocationCallbacks* allocator) {
|
||||
this->device = device;
|
||||
this->image_view = image_view;
|
||||
this->allocator = allocator;
|
||||
}
|
||||
};
|
||||
|
||||
struct frame_data {
|
||||
std::vector<free_framebuffer_data> free_framebuffers;
|
||||
std::vector<free_image_view_data> free_image_views;
|
||||
std::vector<Vulkan::DynamicBuffer> dynamic_buffers;
|
||||
std::vector<Vulkan::StagingBuffer> staging_buffers;
|
||||
|
||||
frame_data();
|
||||
~frame_data();
|
||||
|
||||
void ctrl();
|
||||
};
|
||||
|
||||
std::vector<frame_data> frames_data;
|
||||
uint32_t frame;
|
||||
|
||||
std::unordered_map<descriptor_pipeline_data,
|
||||
prj::shared_ptr<Vulkan::DescriptorPipeline>> descriptor_pipelines;
|
||||
std::unordered_map<pipeline_data, prj::shared_ptr<Vulkan::Pipeline>> pipelines;
|
||||
std::unordered_map<render_pass_data, prj::shared_ptr<Vulkan::RenderPass>> render_passes;
|
||||
std::unordered_map<uint64_t, prj::shared_ptr<Vulkan::Sampler>> samplers;
|
||||
|
||||
manager(uint32_t max_frames);
|
||||
~manager();
|
||||
|
||||
void free_framebuffer(VkDevice device,
|
||||
VkFramebuffer framebuffer, const VkAllocationCallbacks* allocator);
|
||||
void free_image_view(VkDevice device,
|
||||
VkImageView image_view, const VkAllocationCallbacks* allocator);
|
||||
prj::shared_ptr<Vulkan::DescriptorPipeline> get_descriptor_pipeline(
|
||||
uint64_t vp_desc_hash, uint64_t fp_desc_hash, uint64_t unival_hash);
|
||||
prj::shared_ptr<Vulkan::DescriptorPipeline> get_descriptor_pipeline(
|
||||
uint64_t vp_desc_hash, uint64_t fp_desc_hash, uint64_t unival_hash,
|
||||
uint32_t sampler_count, uint32_t uniform_count, uint32_t storage_count,
|
||||
const VkDescriptorSetLayoutBinding* bindings);
|
||||
frame_data& get_frame_data();
|
||||
prj::shared_ptr<Vulkan::Pipeline> get_pipeline(uint32_t stage_count,
|
||||
const VkPipelineShaderStageCreateInfo* stages,
|
||||
uint32_t vertex_input_binding_description_count,
|
||||
const VkVertexInputBindingDescription* vertex_input_binding_descriptions,
|
||||
uint32_t vertex_input_attribute_description_count,
|
||||
const VkVertexInputAttributeDescription* vertex_input_attribute_descriptions,
|
||||
const VkPipelineInputAssemblyStateCreateInfo* input_assembly_state,
|
||||
const VkRect2D viewport_scissor_rect[2],
|
||||
const VkPipelineRasterizationStateCreateInfo* rasterization_state,
|
||||
const VkPipelineDepthStencilStateCreateInfo* depth_stencil_state,
|
||||
uint32_t color_blend_attachment_count,
|
||||
const VkPipelineColorBlendAttachmentState* color_blend_attachments,
|
||||
VkPipelineLayout layout, VkRenderPass render_pass);
|
||||
prj::shared_ptr<Vulkan::RenderPass> get_render_pass(GLenum* color_formats,
|
||||
uint32_t color_format_count, GLenum depth_format, bool stencil);
|
||||
prj::shared_ptr<Vulkan::Sampler> get_sampler(const gl_sampler& sampler_data);
|
||||
Vulkan::Buffer get_dynamic_buffer(VkDeviceSize size, VkDeviceSize alignment, bool uniform);
|
||||
Vulkan::Buffer get_staging_buffer(VkDeviceSize size, VkDeviceSize alignment);
|
||||
void next_frame(uint32_t frame);
|
||||
void reset_descriptor_pipelines_descriptor_set_collections();
|
||||
};
|
||||
|
||||
manager* manager_ptr;
|
||||
|
||||
void manager_init(uint32_t max_frames) {
|
||||
manager_ptr = new manager(max_frames);
|
||||
}
|
||||
|
||||
void manager_free_descriptor_pipelines() {
|
||||
manager_ptr->descriptor_pipelines.clear();
|
||||
}
|
||||
|
||||
void manager_free_framebuffer(VkDevice device,
|
||||
VkFramebuffer framebuffer, const VkAllocationCallbacks* allocator) {
|
||||
manager_ptr->free_framebuffer(device, framebuffer, allocator);
|
||||
}
|
||||
|
||||
void manager_free_image_view(VkDevice device,
|
||||
VkImageView image_view, const VkAllocationCallbacks* allocator) {
|
||||
manager_ptr->free_image_view(device, image_view, allocator);
|
||||
}
|
||||
|
||||
void manager_free_pipelines() {
|
||||
manager_ptr->pipelines.clear();
|
||||
}
|
||||
|
||||
void manager_free_render_passes() {
|
||||
manager_ptr->render_passes.clear();
|
||||
}
|
||||
|
||||
void manager_free_samplers() {
|
||||
manager_ptr->samplers.clear();
|
||||
}
|
||||
|
||||
prj::shared_ptr<Vulkan::DescriptorPipeline> manager_get_descriptor_pipeline(
|
||||
uint64_t vp_desc_hash, uint64_t fp_desc_hash, uint64_t unival_hash) {
|
||||
return manager_ptr->get_descriptor_pipeline(vp_desc_hash, fp_desc_hash, unival_hash);
|
||||
}
|
||||
|
||||
prj::shared_ptr<Vulkan::DescriptorPipeline> manager_get_descriptor_pipeline(
|
||||
uint64_t vp_desc_hash, uint64_t fp_desc_hash, uint64_t unival_hash,
|
||||
uint32_t sampler_count, uint32_t uniform_count, uint32_t storage_count,
|
||||
const VkDescriptorSetLayoutBinding* bindings) {
|
||||
return manager_ptr->get_descriptor_pipeline(vp_desc_hash, fp_desc_hash, unival_hash,
|
||||
sampler_count, uniform_count, storage_count, bindings);
|
||||
}
|
||||
|
||||
uint32_t manager_get_frame() {
|
||||
return manager_ptr->frame;
|
||||
}
|
||||
|
||||
prj::shared_ptr<Vulkan::Pipeline> manager_get_pipeline(uint32_t stage_count,
|
||||
const VkPipelineShaderStageCreateInfo* stages,
|
||||
uint32_t vertex_input_binding_description_count,
|
||||
const VkVertexInputBindingDescription* vertex_input_binding_descriptions,
|
||||
uint32_t vertex_input_attribute_description_count,
|
||||
const VkVertexInputAttributeDescription* vertex_input_attribute_descriptions,
|
||||
const VkPipelineInputAssemblyStateCreateInfo* input_assembly_state,
|
||||
const VkRect2D viewport_scissor_rect[2],
|
||||
const VkPipelineRasterizationStateCreateInfo* rasterization_state,
|
||||
const VkPipelineDepthStencilStateCreateInfo* depth_stencil_state,
|
||||
uint32_t color_blend_attachment_count,
|
||||
const VkPipelineColorBlendAttachmentState* color_blend_attachments,
|
||||
VkPipelineLayout layout, VkRenderPass render_pass) {
|
||||
return manager_ptr->get_pipeline(stage_count, stages,
|
||||
vertex_input_binding_description_count, vertex_input_binding_descriptions,
|
||||
vertex_input_attribute_description_count, vertex_input_attribute_descriptions,
|
||||
input_assembly_state, viewport_scissor_rect, rasterization_state, depth_stencil_state,
|
||||
color_blend_attachment_count, color_blend_attachments, layout, render_pass);
|
||||
}
|
||||
|
||||
prj::shared_ptr<Vulkan::RenderPass> manager_get_render_pass(
|
||||
GLenum* color_formats, uint32_t color_format_count, GLenum depth_format, bool stencil) {
|
||||
return manager_ptr->get_render_pass(color_formats,
|
||||
color_format_count, depth_format, stencil);
|
||||
}
|
||||
|
||||
prj::shared_ptr<Vulkan::Sampler> manager_get_sampler(const gl_sampler& sampler_data) {
|
||||
return manager_ptr->get_sampler(sampler_data);
|
||||
}
|
||||
|
||||
Vulkan::Buffer manager_get_dynamic_buffer(VkDeviceSize size, VkDeviceSize alignment) {
|
||||
return manager_ptr->get_dynamic_buffer(size, alignment, false);
|
||||
}
|
||||
|
||||
Vulkan::Buffer manager_get_dynamic_uniform_buffer(VkDeviceSize size, VkDeviceSize alignment) {
|
||||
return manager_ptr->get_dynamic_buffer(size, alignment, true);
|
||||
}
|
||||
|
||||
Vulkan::Buffer manager_get_staging_buffer(VkDeviceSize size, VkDeviceSize alignment) {
|
||||
return manager_ptr->get_staging_buffer(size, alignment);
|
||||
}
|
||||
|
||||
void manager_next_frame(uint32_t frame) {
|
||||
manager_ptr->next_frame(frame);
|
||||
}
|
||||
|
||||
void manager_reset_descriptor_pipelines_descriptor_set_collections() {
|
||||
manager_ptr->reset_descriptor_pipelines_descriptor_set_collections();
|
||||
}
|
||||
|
||||
void manager_free() {
|
||||
delete manager_ptr;
|
||||
}
|
||||
|
||||
manager::frame_data::frame_data() {
|
||||
|
||||
}
|
||||
|
||||
manager::frame_data::~frame_data() {
|
||||
ctrl();
|
||||
|
||||
for (Vulkan::StagingBuffer& i : staging_buffers)
|
||||
i.Destroy();
|
||||
for (Vulkan::DynamicBuffer& i : dynamic_buffers)
|
||||
i.Destroy();
|
||||
}
|
||||
|
||||
void manager::frame_data::ctrl() {
|
||||
for (free_framebuffer_data& i : free_framebuffers)
|
||||
vkDestroyFramebuffer(i.device, i.framebuffer, i.allocator);
|
||||
free_framebuffers.clear();
|
||||
|
||||
for (free_image_view_data& i : free_image_views)
|
||||
vkDestroyImageView(i.device, i.image_view, i.allocator);
|
||||
free_image_views.clear();
|
||||
|
||||
for (Vulkan::DynamicBuffer& i : dynamic_buffers) {
|
||||
if (!i.curr_size)
|
||||
i.empty_frame_count++;
|
||||
}
|
||||
|
||||
auto i_dyn_begin = dynamic_buffers.begin();
|
||||
auto i_dyn_end = dynamic_buffers.end();
|
||||
for (auto i = i_dyn_end; i != i_dyn_begin; ) {
|
||||
i--;
|
||||
|
||||
if (!i->curr_size) {
|
||||
i->empty_frame_count++;
|
||||
|
||||
if (i->empty_frame_count >= 60) {
|
||||
i->Destroy();
|
||||
dynamic_buffers.erase(i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
i->empty_frame_count = 0;
|
||||
|
||||
i->curr_size = 0;
|
||||
}
|
||||
|
||||
auto i_stg_begin = staging_buffers.begin();
|
||||
auto i_stg_end = staging_buffers.end();
|
||||
for (auto i = i_stg_end; i != i_stg_begin; ) {
|
||||
i--;
|
||||
|
||||
if (!i->curr_size) {
|
||||
i->empty_frame_count++;
|
||||
|
||||
if (i->empty_frame_count >= 60) {
|
||||
i->Destroy();
|
||||
staging_buffers.erase(i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
i->empty_frame_count = 0;
|
||||
|
||||
i->curr_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
manager::manager(uint32_t max_frames) : frame() {
|
||||
frames_data.resize(max_frames);
|
||||
}
|
||||
|
||||
manager::~manager() {
|
||||
|
||||
}
|
||||
|
||||
void manager::free_framebuffer(VkDevice device,
|
||||
VkFramebuffer framebuffer, const VkAllocationCallbacks* allocator) {
|
||||
if (framebuffer) {
|
||||
frame_data& frame_data = get_frame_data();
|
||||
frame_data.free_framebuffers.push_back({ device, framebuffer, allocator });
|
||||
}
|
||||
}
|
||||
|
||||
void manager::free_image_view(VkDevice device,
|
||||
VkImageView image_view, const VkAllocationCallbacks* allocator) {
|
||||
if (image_view) {
|
||||
frame_data& frame_data = get_frame_data();
|
||||
frame_data.free_image_views.push_back({ device, image_view, allocator });
|
||||
}
|
||||
}
|
||||
|
||||
prj::shared_ptr<Vulkan::DescriptorPipeline> manager::get_descriptor_pipeline(
|
||||
uint64_t vp_desc_hash, uint64_t fp_desc_hash, uint64_t unival_hash) {
|
||||
auto elem = descriptor_pipelines.find({ vp_desc_hash, fp_desc_hash, unival_hash });
|
||||
if (elem != descriptor_pipelines.end())
|
||||
return elem->second;
|
||||
return {};
|
||||
}
|
||||
|
||||
prj::shared_ptr<Vulkan::DescriptorPipeline> manager::get_descriptor_pipeline(
|
||||
uint64_t vp_desc_hash, uint64_t fp_desc_hash, uint64_t unival_hash,
|
||||
uint32_t sampler_count, uint32_t uniform_count, uint32_t storage_count,
|
||||
const VkDescriptorSetLayoutBinding* bindings) {
|
||||
auto elem = descriptor_pipelines.find({ vp_desc_hash, fp_desc_hash, unival_hash });
|
||||
if (elem != descriptor_pipelines.end())
|
||||
return elem->second;
|
||||
|
||||
prj::shared_ptr<Vulkan::DescriptorPipeline> descriptor_pipeline(
|
||||
new Vulkan::DescriptorPipeline(Vulkan::current_device, Vulkan::current_descriptor_pool,
|
||||
sampler_count, uniform_count, storage_count, bindings));
|
||||
descriptor_pipelines.insert({ { vp_desc_hash, fp_desc_hash, unival_hash }, descriptor_pipeline });
|
||||
return descriptor_pipeline;
|
||||
}
|
||||
|
||||
manager::frame_data& manager::get_frame_data() {
|
||||
return frames_data.data()[frame];
|
||||
}
|
||||
|
||||
prj::shared_ptr<Vulkan::Pipeline> manager::get_pipeline(uint32_t stage_count,
|
||||
const VkPipelineShaderStageCreateInfo* stages,
|
||||
uint32_t vertex_input_binding_description_count,
|
||||
const VkVertexInputBindingDescription* vertex_input_binding_descriptions,
|
||||
uint32_t vertex_input_attribute_description_count,
|
||||
const VkVertexInputAttributeDescription* vertex_input_attribute_descriptions,
|
||||
const VkPipelineInputAssemblyStateCreateInfo* input_assembly_state,
|
||||
const VkRect2D viewport_scissor_rect[2],
|
||||
const VkPipelineRasterizationStateCreateInfo* rasterization_state,
|
||||
const VkPipelineDepthStencilStateCreateInfo* depth_stencil_state,
|
||||
uint32_t color_blend_attachment_count,
|
||||
const VkPipelineColorBlendAttachmentState* color_blend_attachments,
|
||||
VkPipelineLayout layout, VkRenderPass render_pass) {
|
||||
uint64_t stages_hash = hash_xxh3_64bits(stages,
|
||||
sizeof(VkPipelineShaderStageCreateInfo) * stage_count);
|
||||
uint64_t vertex_input_info_binding_hash = hash_xxh3_64bits(vertex_input_binding_descriptions,
|
||||
sizeof(VkVertexInputBindingDescription) * vertex_input_binding_description_count);
|
||||
uint64_t vertex_input_info_attribute_hash = hash_xxh3_64bits(vertex_input_attribute_descriptions,
|
||||
sizeof(VkVertexInputBindingDescription) * vertex_input_attribute_description_count);
|
||||
uint64_t input_assembly_state_hash = hash_xxh3_64bits(input_assembly_state,
|
||||
sizeof(VkPipelineInputAssemblyStateCreateInfo));
|
||||
uint64_t viewport_state_hash = hash_xxh3_64bits(viewport_scissor_rect,
|
||||
sizeof(VkRect2D) * 2);
|
||||
uint64_t rasterization_state_hash = hash_xxh3_64bits(rasterization_state,
|
||||
sizeof(VkPipelineRasterizationStateCreateInfo));
|
||||
uint64_t depth_stencil_state_hash = hash_xxh3_64bits(depth_stencil_state,
|
||||
sizeof(VkPipelineDepthStencilStateCreateInfo));
|
||||
uint64_t color_blend_attachmen_hash = hash_xxh3_64bits(color_blend_attachments,
|
||||
sizeof(VkPipelineColorBlendAttachmentState) * color_blend_attachment_count);
|
||||
|
||||
auto elem = pipelines.find({ stages_hash, vertex_input_info_binding_hash, vertex_input_info_attribute_hash,
|
||||
input_assembly_state_hash, viewport_state_hash, rasterization_state_hash,
|
||||
depth_stencil_state_hash, color_blend_attachmen_hash, layout, render_pass });
|
||||
if (elem != pipelines.end())
|
||||
return elem->second;
|
||||
|
||||
VkViewport viewport;
|
||||
viewport.x = (float_t)viewport_scissor_rect[0].offset.x;
|
||||
viewport.y = (float_t)viewport_scissor_rect[0].offset.y;
|
||||
viewport.width = (float_t)viewport_scissor_rect[0].extent.width;
|
||||
viewport.height = (float_t)viewport_scissor_rect[0].extent.height;
|
||||
viewport.minDepth = 0.0f;
|
||||
viewport.maxDepth = 1.0f;
|
||||
|
||||
VkRect2D scissor = viewport_scissor_rect[1];
|
||||
|
||||
VkPipelineViewportStateCreateInfo viewport_state = {};
|
||||
viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
||||
viewport_state.viewportCount = 1;
|
||||
viewport_state.pViewports = &viewport;
|
||||
viewport_state.scissorCount = 1;
|
||||
viewport_state.pScissors = &scissor;
|
||||
|
||||
prj::shared_ptr<Vulkan::Pipeline> pipeline(new Vulkan::Pipeline(Vulkan::current_device, 0,
|
||||
stage_count, stages, vertex_input_binding_description_count, vertex_input_binding_descriptions,
|
||||
vertex_input_attribute_description_count, vertex_input_attribute_descriptions,
|
||||
input_assembly_state, &viewport_state, rasterization_state, depth_stencil_state,
|
||||
color_blend_attachment_count, color_blend_attachments, layout, render_pass));
|
||||
pipelines.insert({ { stages_hash, vertex_input_info_binding_hash, vertex_input_info_attribute_hash,
|
||||
input_assembly_state_hash, viewport_state_hash, rasterization_state_hash,
|
||||
depth_stencil_state_hash, color_blend_attachmen_hash, layout, render_pass }, pipeline });
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
prj::shared_ptr<Vulkan::RenderPass> manager::get_render_pass(GLenum* color_formats,
|
||||
uint32_t color_format_count, GLenum depth_format, bool stencil) {
|
||||
uint64_t color_formats_hash = hash_xxh3_64bits(color_formats,
|
||||
sizeof(GLenum) * color_format_count);
|
||||
|
||||
auto elem = render_passes.find({ color_formats_hash, depth_format, stencil });
|
||||
if (elem != render_passes.end())
|
||||
return elem->second;
|
||||
|
||||
VkAttachmentReference* color_attachment_reference = force_malloc<VkAttachmentReference>(color_format_count);
|
||||
VkAttachmentReference depth_attachment_reference = {};
|
||||
|
||||
VkSubpassDescription subpass_description = {};
|
||||
subpass_description.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
if (color_format_count) {
|
||||
for (uint32_t i = 0; i < color_format_count; i++) {
|
||||
color_attachment_reference[i].attachment = i;
|
||||
color_attachment_reference[i].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
}
|
||||
|
||||
subpass_description.colorAttachmentCount = color_format_count;
|
||||
subpass_description.pColorAttachments = color_attachment_reference;
|
||||
}
|
||||
else
|
||||
subpass_description.colorAttachmentCount = 0;
|
||||
|
||||
if (depth_format) {
|
||||
depth_attachment_reference.attachment = 1;
|
||||
depth_attachment_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
|
||||
subpass_description.pDepthStencilAttachment = &depth_attachment_reference;
|
||||
}
|
||||
|
||||
VkSubpassDependency subpass_dependency = {};
|
||||
subpass_dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||
subpass_dependency.dstSubpass = 0;
|
||||
subpass_dependency.srcStageMask = 0;
|
||||
subpass_dependency.srcAccessMask = 0;
|
||||
subpass_dependency.dstStageMask = 0;
|
||||
subpass_dependency.dstAccessMask = 0;
|
||||
|
||||
if (color_format_count) {
|
||||
subpass_dependency.srcStageMask |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
subpass_dependency.dstStageMask |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
subpass_dependency.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
}
|
||||
|
||||
if (depth_format) {
|
||||
subpass_dependency.srcStageMask |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
|
||||
subpass_dependency.dstStageMask |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
|
||||
subpass_dependency.dstAccessMask |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
}
|
||||
|
||||
int32_t attachment_count = 0;
|
||||
|
||||
VkAttachmentDescription* attachments
|
||||
= force_malloc<VkAttachmentDescription>((size_t)color_format_count + 1);
|
||||
if (color_format_count)
|
||||
for (uint32_t i = 0; i < color_format_count; i++) {
|
||||
VkAttachmentDescription& color_attachment = attachments[attachment_count];
|
||||
color_attachment.flags = 0;
|
||||
color_attachment.format = Vulkan::get_format(color_formats[i]);
|
||||
color_attachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
color_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
color_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
color_attachment.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
color_attachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
attachment_count++;
|
||||
}
|
||||
|
||||
if (depth_format) {
|
||||
VkAttachmentDescription& depth_attachment = attachments[attachment_count];
|
||||
depth_attachment.flags = 0;
|
||||
depth_attachment.format = Vulkan::get_format(depth_format);
|
||||
depth_attachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
depth_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
depth_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
depth_attachment.stencilLoadOp = stencil
|
||||
? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
depth_attachment.stencilStoreOp = stencil
|
||||
? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
depth_attachment.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
depth_attachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
|
||||
attachment_count++;
|
||||
}
|
||||
|
||||
prj::shared_ptr<Vulkan::RenderPass> render_pass(new Vulkan::RenderPass(Vulkan::current_device, 0,
|
||||
attachment_count, attachments, 1, &subpass_description, 1, &subpass_dependency));
|
||||
render_passes.insert({ { color_formats_hash, depth_format, stencil }, render_pass });
|
||||
|
||||
free_def(attachments);
|
||||
free_def(color_attachment_reference);
|
||||
return render_pass;
|
||||
}
|
||||
|
||||
static VkSamplerAddressMode get_sampler_address_mode(GLenum wrap) {
|
||||
switch (wrap) {
|
||||
case GL_REPEAT:
|
||||
default:
|
||||
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
case GL_CLAMP_TO_BORDER:
|
||||
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
||||
case GL_CLAMP_TO_EDGE:
|
||||
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
case GL_MIRRORED_REPEAT:
|
||||
return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
|
||||
case GL_MIRROR_CLAMP_TO_EDGE:
|
||||
return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
|
||||
}
|
||||
}
|
||||
|
||||
prj::shared_ptr<Vulkan::Sampler> manager::get_sampler(const gl_sampler& sampler_data) {
|
||||
uint64_t sampler_hash = hash_xxh3_64bits(&sampler_data, sizeof(gl_sampler));
|
||||
|
||||
auto elem = samplers.find(sampler_hash);
|
||||
if (elem != samplers.end())
|
||||
return elem->second;
|
||||
|
||||
VkFilter vk_mag_filter = sampler_data.mag_filter != GL_NEAREST ? VK_FILTER_LINEAR : VK_FILTER_NEAREST;
|
||||
VkFilter vk_min_filter;
|
||||
VkSamplerMipmapMode vk_mipmap_mode;
|
||||
switch (sampler_data.min_filter) {
|
||||
case GL_NEAREST:
|
||||
case GL_NEAREST_MIPMAP_NEAREST:
|
||||
vk_min_filter = VK_FILTER_NEAREST;
|
||||
vk_mipmap_mode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||
break;
|
||||
case GL_LINEAR:
|
||||
case GL_LINEAR_MIPMAP_NEAREST:
|
||||
default:
|
||||
vk_min_filter = VK_FILTER_LINEAR;
|
||||
vk_mipmap_mode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||
break;
|
||||
case GL_NEAREST_MIPMAP_LINEAR:
|
||||
vk_min_filter = VK_FILTER_NEAREST;
|
||||
vk_mipmap_mode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
break;
|
||||
case GL_LINEAR_MIPMAP_LINEAR:
|
||||
vk_min_filter = VK_FILTER_LINEAR;
|
||||
vk_mipmap_mode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
break;
|
||||
}
|
||||
|
||||
VkBorderColor vk_border_color;
|
||||
if (sampler_data.border_color == 0.0f)
|
||||
vk_border_color = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
|
||||
else if (sampler_data.border_color == vec4(0.0f, 0.0f, 0.0f, 1.0f))
|
||||
vk_border_color = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
|
||||
else if (sampler_data.border_color == 1.0f)
|
||||
vk_border_color = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
|
||||
else
|
||||
vk_border_color = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
|
||||
|
||||
prj::shared_ptr<Vulkan::Sampler> sampler(new Vulkan::Sampler(Vulkan::current_device, 0,
|
||||
vk_mag_filter, vk_min_filter, vk_mipmap_mode,
|
||||
get_sampler_address_mode(sampler_data.wrap_s),
|
||||
get_sampler_address_mode(sampler_data.wrap_t),
|
||||
get_sampler_address_mode(sampler_data.wrap_r),
|
||||
-1000.0f, 1000.0f, sampler_data.max_anisotropy, vk_border_color));
|
||||
samplers.insert({ sampler_hash, sampler });
|
||||
return sampler;
|
||||
}
|
||||
|
||||
Vulkan::Buffer manager::get_dynamic_buffer(VkDeviceSize size, VkDeviceSize alignment, bool uniform) {
|
||||
frame_data& frame_data = get_frame_data();
|
||||
|
||||
VkBufferUsageFlags usage = 0;
|
||||
if (uniform)
|
||||
usage |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
|
||||
else {
|
||||
usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||
usage |= VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
|
||||
usage |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
|
||||
}
|
||||
|
||||
for (Vulkan::DynamicBuffer& i : frame_data.dynamic_buffers)
|
||||
if ((i.usage & usage) == usage
|
||||
&& align_val(i.curr_size, alignment) + align_val(size, alignment) <= i.GetSize()) {
|
||||
i.curr_size = align_val(i.curr_size, alignment);
|
||||
|
||||
Vulkan::Buffer buffer = (Vulkan::Buffer)i;
|
||||
buffer.SetOffset(i.curr_size);
|
||||
buffer.SetSize(size);
|
||||
i.curr_size += align_val(size, alignment);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
VkDeviceSize buffer_size = sv_max_uniform_buffer_size;
|
||||
if (!uniform) {
|
||||
buffer_size = 0x1000000;
|
||||
while (buffer_size <= size)
|
||||
buffer_size *= 2;
|
||||
}
|
||||
|
||||
frame_data.dynamic_buffers.push_back({});
|
||||
Vulkan::DynamicBuffer& dynamic_buffer = frame_data.dynamic_buffers.back();
|
||||
dynamic_buffer.Create(Vulkan::current_allocator, buffer_size, usage);
|
||||
|
||||
Vulkan::Buffer buffer = (Vulkan::Buffer)dynamic_buffer;
|
||||
buffer.SetOffset(0);
|
||||
buffer.SetSize(size);
|
||||
dynamic_buffer.curr_size = align_val(size, alignment);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
Vulkan::Buffer manager::get_staging_buffer(VkDeviceSize size, VkDeviceSize alignment) {
|
||||
frame_data& frame_data = get_frame_data();
|
||||
|
||||
for (Vulkan::StagingBuffer& i : frame_data.staging_buffers)
|
||||
if (align_val(i.curr_size, alignment) + align_val(size, alignment) <= i.GetSize()) {
|
||||
i.curr_size = align_val(i.curr_size, alignment);
|
||||
|
||||
Vulkan::Buffer buffer = (Vulkan::Buffer)i;
|
||||
buffer.SetOffset(i.curr_size);
|
||||
buffer.SetSize(size);
|
||||
i.curr_size += align_val(size, alignment);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
VkDeviceSize buffer_size = 0x1000000;
|
||||
while (buffer_size <= size)
|
||||
buffer_size *= 2;
|
||||
|
||||
frame_data.staging_buffers.push_back({});
|
||||
Vulkan::StagingBuffer& staging_buffer = frame_data.staging_buffers.back();
|
||||
staging_buffer.Create(Vulkan::current_allocator, buffer_size);
|
||||
|
||||
Vulkan::Buffer buffer = (Vulkan::Buffer)staging_buffer;
|
||||
buffer.SetOffset(0);
|
||||
buffer.SetSize(size);
|
||||
staging_buffer.curr_size = align_val(size, alignment);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void manager::next_frame(uint32_t frame) {
|
||||
this->frame = frame;
|
||||
get_frame_data().ctrl();
|
||||
}
|
||||
|
||||
void manager::reset_descriptor_pipelines_descriptor_set_collections() {
|
||||
for (auto& i : descriptor_pipelines)
|
||||
i.second.get()->ResetSetCollectionsState();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared.hpp"
|
||||
#include "gl_wrap.hpp"
|
||||
#include "DescriptorPipeline.hpp"
|
||||
#include "DynamicBuffer.hpp"
|
||||
#include "Pipeline.hpp"
|
||||
#include "StagingBuffer.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
extern void manager_init(uint32_t max_frames);
|
||||
extern void manager_free_descriptor_pipelines();
|
||||
extern void manager_free_framebuffer(VkDevice device,
|
||||
VkFramebuffer framebuffer, const VkAllocationCallbacks* allocator);
|
||||
extern void manager_free_image_view(VkDevice device,
|
||||
VkImageView image_view, const VkAllocationCallbacks* allocator);
|
||||
extern void manager_free_pipelines();
|
||||
extern void manager_free_render_passes();
|
||||
extern void manager_free_samplers();
|
||||
extern prj::shared_ptr<Vulkan::DescriptorPipeline> manager_get_descriptor_pipeline(
|
||||
uint64_t vp_desc_hash, uint64_t fp_desc_hash, uint64_t unival_hash);
|
||||
extern prj::shared_ptr<Vulkan::DescriptorPipeline> manager_get_descriptor_pipeline(
|
||||
uint64_t vp_desc_hash, uint64_t fp_desc_hash, uint64_t unival_hash,
|
||||
uint32_t sampler_count, uint32_t uniform_count, uint32_t storage_count,
|
||||
const VkDescriptorSetLayoutBinding* bindings);
|
||||
extern uint32_t manager_get_frame();
|
||||
extern prj::shared_ptr<Vulkan::Pipeline> manager_get_pipeline(uint32_t stage_count,
|
||||
const VkPipelineShaderStageCreateInfo* stages,
|
||||
uint32_t vertex_input_binding_descriptions_count,
|
||||
const VkVertexInputBindingDescription* vertex_input_binding_descriptions,
|
||||
uint32_t vertex_input_attribute_description_count,
|
||||
const VkVertexInputAttributeDescription* vertex_input_attribute_descriptions,
|
||||
const VkPipelineInputAssemblyStateCreateInfo* input_assembly_state,
|
||||
const VkRect2D viewport_scissor_rect[2],
|
||||
const VkPipelineRasterizationStateCreateInfo* rasterization_state,
|
||||
const VkPipelineDepthStencilStateCreateInfo* depth_stencil_state,
|
||||
uint32_t color_blend_attachment_count,
|
||||
const VkPipelineColorBlendAttachmentState* color_blend_attachments,
|
||||
VkPipelineLayout layout, VkRenderPass render_pass);
|
||||
extern prj::shared_ptr<Vulkan::RenderPass> manager_get_render_pass(
|
||||
GLenum* color_formats, uint32_t color_format_count, GLenum depth_format, bool stencil = false);
|
||||
extern prj::shared_ptr<Vulkan::Sampler> manager_get_sampler(const gl_sampler& sampler_data);
|
||||
Vulkan::Buffer manager_get_dynamic_buffer(VkDeviceSize size, VkDeviceSize alignment = 0x10);
|
||||
Vulkan::Buffer manager_get_dynamic_uniform_buffer(VkDeviceSize size, VkDeviceSize alignment = 0x10);
|
||||
Vulkan::Buffer manager_get_staging_buffer(VkDeviceSize size, VkDeviceSize alignment = 0x10);
|
||||
extern void manager_next_frame(uint32_t frame);
|
||||
extern void manager_reset_descriptor_pipelines_descriptor_set_collections();
|
||||
extern void manager_free();
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define VOLK_IMPLEMENTATION
|
||||
#define VMA_IMPLEMENTATION
|
||||
#define VMA_VULKAN_VERSION 1000000
|
||||
#include "shared.hpp"
|
||||
#include "gl_wrap.hpp"
|
||||
|
||||
namespace Vulkan {
|
||||
bool use;
|
||||
|
||||
VkDevice current_device;
|
||||
|
||||
VkQueue current_graphics_queue;
|
||||
VkQueue current_present_queue;
|
||||
|
||||
VmaAllocator current_allocator;
|
||||
|
||||
VkCommandPool current_command_pool;
|
||||
|
||||
VkCommandBuffer current_command_buffer;
|
||||
|
||||
VkDescriptorPool current_descriptor_pool;
|
||||
|
||||
VkFramebuffer current_framebuffer;
|
||||
VkRenderPass current_render_pass;
|
||||
|
||||
VkImage current_swapchain_image;
|
||||
|
||||
const char* get_error_string(VkResult error_code) {
|
||||
switch (error_code) {
|
||||
#define ERROR_STRING(r) case VK_##r: return "VK_"#r
|
||||
ERROR_STRING(NOT_READY);
|
||||
ERROR_STRING(TIMEOUT);
|
||||
ERROR_STRING(EVENT_SET);
|
||||
ERROR_STRING(EVENT_RESET);
|
||||
ERROR_STRING(INCOMPLETE);
|
||||
ERROR_STRING(ERROR_OUT_OF_HOST_MEMORY);
|
||||
ERROR_STRING(ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
ERROR_STRING(ERROR_INITIALIZATION_FAILED);
|
||||
ERROR_STRING(ERROR_DEVICE_LOST);
|
||||
ERROR_STRING(ERROR_MEMORY_MAP_FAILED);
|
||||
ERROR_STRING(ERROR_LAYER_NOT_PRESENT);
|
||||
ERROR_STRING(ERROR_EXTENSION_NOT_PRESENT);
|
||||
ERROR_STRING(ERROR_FEATURE_NOT_PRESENT);
|
||||
ERROR_STRING(ERROR_INCOMPATIBLE_DRIVER);
|
||||
ERROR_STRING(ERROR_TOO_MANY_OBJECTS);
|
||||
ERROR_STRING(ERROR_FORMAT_NOT_SUPPORTED);
|
||||
ERROR_STRING(ERROR_SURFACE_LOST_KHR);
|
||||
ERROR_STRING(ERROR_NATIVE_WINDOW_IN_USE_KHR);
|
||||
ERROR_STRING(SUBOPTIMAL_KHR);
|
||||
ERROR_STRING(ERROR_OUT_OF_DATE_KHR);
|
||||
ERROR_STRING(ERROR_INCOMPATIBLE_DISPLAY_KHR);
|
||||
ERROR_STRING(ERROR_VALIDATION_FAILED_EXT);
|
||||
ERROR_STRING(ERROR_INVALID_SHADER_NV);
|
||||
ERROR_STRING(ERROR_INCOMPATIBLE_SHADER_BINARY_EXT);
|
||||
#undef ERROR_STRING
|
||||
default:
|
||||
return "VK_UNKNOWN_ERROR";
|
||||
}
|
||||
}
|
||||
|
||||
void end_render_pass(VkCommandBuffer command_buffer) {
|
||||
GLuint query = Vulkan::gl_wrap_manager_get_query_samples_passed();
|
||||
if (query && Vulkan::gl_query::get(query)->query.GetBegan())
|
||||
glEndQuery(GL_SAMPLES_PASSED);
|
||||
|
||||
if (Vulkan::current_render_pass) {
|
||||
vkCmdEndRenderPass(command_buffer);
|
||||
Vulkan::current_render_pass = 0;
|
||||
}
|
||||
|
||||
Vulkan::current_framebuffer = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../KKdLib/default.hpp"
|
||||
#include <Volk/volk.h>
|
||||
#define VMA_VULKAN_VERSION 1000000
|
||||
#include <vma/vk_mem_alloc.h>
|
||||
|
||||
namespace Vulkan {
|
||||
extern bool use;
|
||||
|
||||
extern VkDevice current_device;
|
||||
|
||||
extern VkQueue current_graphics_queue;
|
||||
extern VkQueue current_present_queue;
|
||||
|
||||
extern VmaAllocator current_allocator;
|
||||
|
||||
extern VkCommandPool current_command_pool;
|
||||
|
||||
extern VkCommandBuffer current_command_buffer;
|
||||
|
||||
extern VkDescriptorPool current_descriptor_pool;
|
||||
|
||||
extern VkFramebuffer current_framebuffer;
|
||||
extern VkRenderPass current_render_pass;
|
||||
|
||||
extern VkImage current_swapchain_image;
|
||||
|
||||
extern const char* get_error_string(VkResult error_code);
|
||||
extern void end_render_pass(VkCommandBuffer command_buffer);
|
||||
}
|
||||
|
||||
#define VK_CHECK_RESULT(f) { \
|
||||
VkResult res = (f); \
|
||||
if (res != VK_SUCCESS) { \
|
||||
const char* error_string = Vulkan::get_error_string(res); \
|
||||
printf("Fatal error: VkResult is \"%s\" in \"%s\" at line \"%s\"\n", error_string, __FILE__, __LINE__); \
|
||||
assert(res == VK_SUCCESS); \
|
||||
} \
|
||||
}
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#include "gl.hpp"
|
||||
|
||||
#ifndef USE_OPENGL
|
||||
int GLAD_GL_VERSION_1_0;
|
||||
int GLAD_GL_VERSION_1_1;
|
||||
int GLAD_GL_VERSION_1_2;
|
||||
int GLAD_GL_VERSION_1_3;
|
||||
int GLAD_GL_VERSION_1_4;
|
||||
int GLAD_GL_VERSION_1_5;
|
||||
int GLAD_GL_VERSION_2_0;
|
||||
int GLAD_GL_VERSION_2_1;
|
||||
int GLAD_GL_VERSION_3_0;
|
||||
int GLAD_GL_VERSION_3_1;
|
||||
int GLAD_GL_VERSION_3_2;
|
||||
int GLAD_GL_VERSION_3_3;
|
||||
int GLAD_GL_VERSION_4_0;
|
||||
int GLAD_GL_VERSION_4_1;
|
||||
int GLAD_GL_VERSION_4_2;
|
||||
int GLAD_GL_VERSION_4_3;
|
||||
int GLAD_GL_VERSION_4_4;
|
||||
int GLAD_GL_VERSION_4_5;
|
||||
int GLAD_GL_VERSION_4_6;
|
||||
|
||||
PFNGLBEGINQUERYPROC glad_glBeginQuery;
|
||||
PFNGLBINDBUFFERPROC glad_glBindBuffer;
|
||||
PFNGLBINDTEXTUREPROC glad_glBindTexture;
|
||||
PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer;
|
||||
PFNGLBLITNAMEDFRAMEBUFFERPROC glad_glBlitNamedFramebuffer;
|
||||
PFNGLBUFFERDATAPROC glad_glBufferData;
|
||||
PFNGLBUFFERSTORAGEPROC glad_glBufferStorage;
|
||||
PFNGLBUFFERSUBDATAPROC glad_glBufferSubData;
|
||||
PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus;
|
||||
PFNGLCLEARPROC glad_glClear;
|
||||
PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv;
|
||||
PFNGLCLEARCOLORPROC glad_glClearColor;
|
||||
PFNGLCLEARDEPTHFPROC glad_glClearDepthf;
|
||||
PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D;
|
||||
PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D;
|
||||
PFNGLCOPYIMAGESUBDATAPROC glad_glCopyImageSubData;
|
||||
PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D;
|
||||
PFNGLCREATEBUFFERSPROC glad_glCreateBuffers;
|
||||
PFNGLCREATEPROGRAMPROC glad_glCreateProgram;
|
||||
PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers;
|
||||
PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers;
|
||||
PFNGLDELETEPROGRAMPROC glad_glDeleteProgram;
|
||||
PFNGLDELETEQUERIESPROC glad_glDeleteQueries;
|
||||
PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers;
|
||||
PFNGLDELETETEXTURESPROC glad_glDeleteTextures;
|
||||
PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays;
|
||||
PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray;
|
||||
PFNGLDRAWBUFFERPROC glad_glDrawBuffer;
|
||||
PFNGLDRAWBUFFERSPROC glad_glDrawBuffers;
|
||||
PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray;
|
||||
PFNGLENDQUERYPROC glad_glEndQuery;
|
||||
PFNGLFINISHPROC glad_glFinish;
|
||||
PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture;
|
||||
PFNGLGENBUFFERSPROC glad_glGenBuffers;
|
||||
PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers;
|
||||
PFNGLGENQUERIESPROC glad_glGenQueries;
|
||||
PFNGLGENSAMPLERSPROC glad_glGenSamplers;
|
||||
PFNGLGENTEXTURESPROC glad_glGenTextures;
|
||||
PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays;
|
||||
PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap;
|
||||
PFNGLGENERATETEXTUREMIPMAPPROC glad_glGenerateTextureMipmap;
|
||||
PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage;
|
||||
PFNGLGETERRORPROC glad_glGetError;
|
||||
PFNGLGETFLOATVPROC glad_glGetFloatv;
|
||||
PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv;
|
||||
PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv;
|
||||
PFNGLGETTEXIMAGEPROC glad_glGetTexImage;
|
||||
PFNGLMAPBUFFERPROC glad_glMapBuffer;
|
||||
PFNGLMAPNAMEDBUFFERPROC glad_glMapNamedBuffer;
|
||||
PFNGLNAMEDBUFFERDATAPROC glad_glNamedBufferData;
|
||||
PFNGLNAMEDBUFFERSTORAGEPROC glad_glNamedBufferStorage;
|
||||
PFNGLNAMEDBUFFERSUBDATAPROC glad_glNamedBufferSubData;
|
||||
PFNGLPIXELSTOREIPROC glad_glPixelStorei;
|
||||
PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup;
|
||||
PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup;
|
||||
PFNGLREADBUFFERPROC glad_glReadBuffer;
|
||||
PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf;
|
||||
PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv;
|
||||
PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri;
|
||||
PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv;
|
||||
PFNGLTEXIMAGE2DPROC glad_glTexImage2D;
|
||||
PFNGLTEXPARAMETERFPROC glad_glTexParameterf;
|
||||
PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv;
|
||||
PFNGLTEXPARAMETERIPROC glad_glTexParameteri;
|
||||
PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv;
|
||||
PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D;
|
||||
PFNGLTEXTUREPARAMETERFPROC glad_glTextureParameterf;
|
||||
PFNGLTEXTUREPARAMETERFVPROC glad_glTextureParameterfv;
|
||||
PFNGLTEXTUREPARAMETERIPROC glad_glTextureParameteri;
|
||||
PFNGLTEXTUREPARAMETERIVPROC glad_glTextureParameteriv;
|
||||
PFNGLTEXTURESUBIMAGE2DPROC glad_glTextureSubImage2D;
|
||||
PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer;
|
||||
PFNGLUNMAPNAMEDBUFFERPROC glad_glUnmapNamedBuffer;
|
||||
PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f;
|
||||
PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer;
|
||||
PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer;
|
||||
#endif
|
||||
+2235
File diff suppressed because it is too large
Load Diff
+188
-47
@@ -10,7 +10,10 @@ gl_state_struct gl_state;
|
||||
void gl_state_active_bind_texture_2d(int32_t index, GLuint texture, bool force) {
|
||||
if (force || gl_state.texture_binding_2d[index] != texture) {
|
||||
if (force || gl_state.active_texture_index != index) {
|
||||
glActiveTexture((GLenum)(GL_TEXTURE0 + index));
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glActiveTexture((GLenum)(GL_TEXTURE0 + index));
|
||||
#endif
|
||||
gl_state.active_texture = (GLenum)(GL_TEXTURE0 + index);
|
||||
gl_state.active_texture_index = (GLuint)index;
|
||||
}
|
||||
@@ -22,7 +25,10 @@ void gl_state_active_bind_texture_2d(int32_t index, GLuint texture, bool force)
|
||||
void gl_state_active_bind_texture_cube_map(int32_t index, GLuint texture, bool force) {
|
||||
if (force || gl_state.texture_binding_cube_map[index] != texture) {
|
||||
if (force || gl_state.active_texture_index != index) {
|
||||
glActiveTexture((GLenum)(GL_TEXTURE0 + index));
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glActiveTexture((GLenum)(GL_TEXTURE0 + index));
|
||||
#endif
|
||||
gl_state.active_texture = (GLenum)(GL_TEXTURE0 + index);
|
||||
gl_state.active_texture_index = (GLuint)index;
|
||||
}
|
||||
@@ -33,16 +39,22 @@ void gl_state_active_bind_texture_cube_map(int32_t index, GLuint texture, bool f
|
||||
|
||||
void gl_state_active_texture(size_t index, bool force) {
|
||||
if (force || gl_state.active_texture_index != index) {
|
||||
glActiveTexture((GLenum)(GL_TEXTURE0 + index));
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glActiveTexture((GLenum)(GL_TEXTURE0 + index));
|
||||
#endif
|
||||
gl_state.active_texture = (GLenum)(GL_TEXTURE0 + index);
|
||||
gl_state.active_texture_index = (GLuint)index;
|
||||
}
|
||||
}
|
||||
|
||||
void gl_state_bind_framebuffer(GLuint framebuffer, bool force) {
|
||||
if (force || gl_state.read_framebuffer_binding != framebuffer
|
||||
|| gl_state.draw_framebuffer_binding != framebuffer) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
if (force || gl_state.framebuffer_binding != framebuffer) {
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
#endif
|
||||
gl_state.framebuffer_binding = framebuffer;
|
||||
gl_state.read_framebuffer_binding = framebuffer;
|
||||
gl_state.draw_framebuffer_binding = framebuffer;
|
||||
}
|
||||
@@ -50,21 +62,30 @@ void gl_state_bind_framebuffer(GLuint framebuffer, bool force) {
|
||||
|
||||
void gl_state_bind_read_framebuffer(GLuint framebuffer, bool force) {
|
||||
if (force || gl_state.read_framebuffer_binding != framebuffer) {
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
|
||||
#endif
|
||||
gl_state.read_framebuffer_binding = framebuffer;
|
||||
}
|
||||
}
|
||||
|
||||
void gl_state_bind_draw_framebuffer(GLuint framebuffer, bool force) {
|
||||
if (force || gl_state.draw_framebuffer_binding != framebuffer) {
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
|
||||
#endif
|
||||
gl_state.draw_framebuffer_binding = framebuffer;
|
||||
}
|
||||
}
|
||||
|
||||
void gl_state_bind_vertex_array(GLuint array, bool force) {
|
||||
if (force || gl_state.vertex_array_binding != array) {
|
||||
glBindVertexArray(array);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glBindVertexArray(array);
|
||||
#endif
|
||||
gl_state.vertex_array_binding = array;
|
||||
}
|
||||
}
|
||||
@@ -92,7 +113,10 @@ void gl_state_bind_uniform_buffer(GLuint buffer, bool force) {
|
||||
|
||||
void gl_state_bind_uniform_buffer_base(GLuint index, GLuint buffer, bool force) {
|
||||
if (force || gl_state.uniform_buffer_bindings[index] != buffer) {
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, index, buffer);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, index, buffer);
|
||||
#endif
|
||||
gl_state.uniform_buffer_bindings[index] = buffer;
|
||||
gl_state.uniform_buffer_offsets[index] = 0;
|
||||
gl_state.uniform_buffer_sizes[index] = -1;
|
||||
@@ -104,7 +128,10 @@ void gl_state_bind_uniform_buffer_range(GLuint index,
|
||||
if (force || gl_state.uniform_buffer_bindings[index] != buffer
|
||||
|| gl_state.uniform_buffer_offsets[index] != offset
|
||||
|| gl_state.uniform_buffer_sizes[index] != size) {
|
||||
glBindBufferRange(GL_UNIFORM_BUFFER, index, buffer, offset, size);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glBindBufferRange(GL_UNIFORM_BUFFER, index, buffer, offset, size);
|
||||
#endif
|
||||
gl_state.uniform_buffer_bindings[index] = buffer;
|
||||
gl_state.uniform_buffer_offsets[index] = offset;
|
||||
gl_state.uniform_buffer_sizes[index] = size;
|
||||
@@ -120,7 +147,10 @@ void gl_state_bind_shader_storage_buffer(GLuint buffer, bool force) {
|
||||
|
||||
void gl_state_bind_shader_storage_buffer_base(GLuint index, GLuint buffer, bool force) {
|
||||
if (force || gl_state.shader_storage_buffer_bindings[index] != buffer) {
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index, buffer);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index, buffer);
|
||||
#endif
|
||||
gl_state.shader_storage_buffer_bindings[index] = buffer;
|
||||
gl_state.shader_storage_buffer_offsets[index] = 0;
|
||||
gl_state.shader_storage_buffer_sizes[index] = -1;
|
||||
@@ -132,7 +162,10 @@ void gl_state_bind_shader_storage_buffer_range(GLuint index,
|
||||
if (force || gl_state.shader_storage_buffer_bindings[index] != buffer
|
||||
|| gl_state.shader_storage_buffer_offsets[index] != offset
|
||||
|| gl_state.shader_storage_buffer_sizes[index] != size) {
|
||||
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, index, buffer, offset, size);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, index, buffer, offset, size);
|
||||
#endif
|
||||
gl_state.shader_storage_buffer_bindings[index] = buffer;
|
||||
gl_state.shader_storage_buffer_offsets[index] = offset;
|
||||
gl_state.shader_storage_buffer_sizes[index] = size;
|
||||
@@ -155,7 +188,10 @@ void gl_state_bind_texture_cube_map(GLuint texture, bool force) {
|
||||
|
||||
void gl_state_bind_sampler(int32_t index, GLuint sampler, bool force) {
|
||||
if (force || gl_state.sampler_binding[index] != sampler) {
|
||||
glBindSampler(index, sampler);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glBindSampler(index, sampler);
|
||||
#endif
|
||||
gl_state.sampler_binding[index] = sampler;
|
||||
}
|
||||
}
|
||||
@@ -190,103 +226,149 @@ bool gl_state_check_sampler_binding(int32_t index, GLuint sampler) {
|
||||
|
||||
void gl_state_disable_blend(bool force) {
|
||||
if (force || gl_state.blend) {
|
||||
glDisable(GL_BLEND);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glDisable(GL_BLEND);
|
||||
#endif
|
||||
gl_state.blend = GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void gl_state_disable_cull_face(bool force) {
|
||||
if (force || gl_state.cull_face) {
|
||||
glDisable(GL_CULL_FACE);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glDisable(GL_CULL_FACE);
|
||||
#endif
|
||||
gl_state.cull_face = GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void gl_state_disable_depth_test(bool force) {
|
||||
if (force || gl_state.depth_test) {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
#endif
|
||||
gl_state.depth_test = GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void gl_state_disable_multisample(bool force) {
|
||||
if (force || gl_state.multisample) {
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
#endif
|
||||
gl_state.multisample = GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void gl_state_disable_primitive_restart(bool force) {
|
||||
if (force || gl_state.primitive_restart) {
|
||||
glDisable(GL_PRIMITIVE_RESTART);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glDisable(GL_PRIMITIVE_RESTART);
|
||||
#endif
|
||||
gl_state.primitive_restart = GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void gl_state_disable_scissor_test(bool force) {
|
||||
if (force || gl_state.scissor_test) {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
#endif
|
||||
gl_state.scissor_test = GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void gl_state_disable_stencil_test(bool force) {
|
||||
if (force || gl_state.stencil_test) {
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
#endif
|
||||
gl_state.stencil_test = GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void gl_state_enable_blend(bool force) {
|
||||
if (force || !gl_state.blend) {
|
||||
glEnable(GL_BLEND);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glEnable(GL_BLEND);
|
||||
#endif
|
||||
gl_state.blend = GL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void gl_state_enable_cull_face(bool force) {
|
||||
if (force || !gl_state.cull_face) {
|
||||
glEnable(GL_CULL_FACE);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glEnable(GL_CULL_FACE);
|
||||
#endif
|
||||
gl_state.cull_face = GL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void gl_state_enable_depth_test(bool force) {
|
||||
if (force || !gl_state.depth_test) {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
#endif
|
||||
gl_state.depth_test = GL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void gl_state_enable_multisample(bool force) {
|
||||
if (force || !gl_state.multisample) {
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
#endif
|
||||
gl_state.multisample = GL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void gl_state_enable_primitive_restart(bool force) {
|
||||
if (force || !gl_state.primitive_restart) {
|
||||
glEnable(GL_PRIMITIVE_RESTART);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glEnable(GL_PRIMITIVE_RESTART);
|
||||
#endif
|
||||
gl_state.primitive_restart = GL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void gl_state_enable_scissor_test(bool force) {
|
||||
if (force || !gl_state.scissor_test) {
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
#endif
|
||||
gl_state.scissor_test = GL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void gl_state_enable_stencil_test(bool force) {
|
||||
if (force || !gl_state.stencil_test) {
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
#endif
|
||||
gl_state.stencil_test = GL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void gl_state_get() {
|
||||
#ifdef USE_OPENGL
|
||||
if (Vulkan::use)
|
||||
return;
|
||||
|
||||
glGetIntegerv(GL_CURRENT_PROGRAM, &gl_state.program);
|
||||
glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&gl_state.active_texture);
|
||||
gl_state.active_texture_index = gl_state.active_texture - GL_TEXTURE0;
|
||||
@@ -306,6 +388,7 @@ void gl_state_get() {
|
||||
glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint*)&gl_state.blend_mode_rgb);
|
||||
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint*)&gl_state.blend_mode_alpha);
|
||||
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*)&gl_state.framebuffer_binding);
|
||||
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, (GLint*)&gl_state.read_framebuffer_binding);
|
||||
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&gl_state.draw_framebuffer_binding);
|
||||
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, (GLint*)&gl_state.vertex_array_binding);
|
||||
@@ -344,6 +427,7 @@ void gl_state_get() {
|
||||
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
gl_state.polygon_mode = GL_FILL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void gl_state_get_all_gl_errors() {
|
||||
@@ -388,7 +472,10 @@ void gl_state_get_viewport(GLint& x, GLint& y, GLsizei& width, GLsizei& height)
|
||||
void gl_state_set_blend_func(GLenum src, GLenum dst, bool force) {
|
||||
if (force || gl_state.blend_src_rgb != src || gl_state.blend_dst_rgb != dst
|
||||
|| gl_state.blend_src_alpha != GL_ONE || gl_state.blend_dst_alpha != GL_ONE_MINUS_SRC_ALPHA) {
|
||||
glBlendFuncSeparate(src, dst, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glBlendFuncSeparate(src, dst, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
#endif
|
||||
gl_state.blend_src_rgb = src;
|
||||
gl_state.blend_dst_rgb = dst;
|
||||
gl_state.blend_src_alpha = GL_ONE;
|
||||
@@ -400,7 +487,10 @@ void gl_state_set_blend_func_separate(GLenum src_rgb, GLenum dst_rgb,
|
||||
GLenum src_alpha, GLenum dst_alpha, bool force) {
|
||||
if (force || gl_state.blend_src_rgb != src_rgb || gl_state.blend_dst_rgb != dst_rgb
|
||||
|| gl_state.blend_src_alpha != src_alpha || gl_state.blend_dst_alpha != dst_alpha) {
|
||||
glBlendFuncSeparate(src_rgb, dst_rgb, src_alpha, dst_alpha);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glBlendFuncSeparate(src_rgb, dst_rgb, src_alpha, dst_alpha);
|
||||
#endif
|
||||
gl_state.blend_src_rgb = src_rgb;
|
||||
gl_state.blend_dst_rgb = dst_rgb;
|
||||
gl_state.blend_src_alpha = src_alpha;
|
||||
@@ -410,7 +500,10 @@ void gl_state_set_blend_func_separate(GLenum src_rgb, GLenum dst_rgb,
|
||||
|
||||
void gl_state_set_blend_equation(GLenum mode, bool force) {
|
||||
if (force || gl_state.blend_mode_rgb != mode || gl_state.blend_mode_alpha != mode) {
|
||||
glBlendEquationSeparate(mode, mode);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glBlendEquationSeparate(mode, mode);
|
||||
#endif
|
||||
gl_state.blend_mode_rgb = mode;
|
||||
gl_state.blend_mode_alpha = mode;
|
||||
}
|
||||
@@ -418,7 +511,10 @@ void gl_state_set_blend_equation(GLenum mode, bool force) {
|
||||
|
||||
void gl_state_set_blend_equation_separate(GLenum mode_rgb, GLenum mode_alpha, bool force) {
|
||||
if (force || gl_state.blend_mode_rgb != mode_rgb || gl_state.blend_mode_alpha != mode_alpha) {
|
||||
glBlendEquationSeparate(mode_rgb, mode_alpha);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glBlendEquationSeparate(mode_rgb, mode_alpha);
|
||||
#endif
|
||||
gl_state.blend_mode_rgb = mode_rgb;
|
||||
gl_state.blend_mode_alpha = mode_alpha;
|
||||
}
|
||||
@@ -428,7 +524,10 @@ void gl_state_set_color_mask(GLboolean red, GLboolean green,
|
||||
GLboolean blue, GLboolean alpha, bool force) {
|
||||
if (force || gl_state.color_mask[0] != red || gl_state.color_mask[1] != green
|
||||
|| gl_state.color_mask[2] != blue || gl_state.color_mask[3] != alpha) {
|
||||
glColorMask(red, green, blue, alpha);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glColorMask(red, green, blue, alpha);
|
||||
#endif
|
||||
gl_state.color_mask[0] = red;
|
||||
gl_state.color_mask[1] = green;
|
||||
gl_state.color_mask[2] = blue;
|
||||
@@ -438,28 +537,40 @@ void gl_state_set_color_mask(GLboolean red, GLboolean green,
|
||||
|
||||
void gl_state_set_cull_face_mode(GLenum mode, bool force) {
|
||||
if (force || gl_state.cull_face_mode != mode) {
|
||||
glCullFace(mode);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glCullFace(mode);
|
||||
#endif
|
||||
gl_state.cull_face_mode = mode;
|
||||
}
|
||||
}
|
||||
|
||||
void gl_state_set_depth_func(GLenum func, bool force) {
|
||||
if (force || gl_state.depth_func != func) {
|
||||
glDepthFunc(func);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glDepthFunc(func);
|
||||
#endif
|
||||
gl_state.depth_func = func;
|
||||
}
|
||||
}
|
||||
|
||||
void gl_state_set_depth_mask(GLboolean flag, bool force) {
|
||||
if (force || gl_state.depth_mask != flag) {
|
||||
glDepthMask(flag);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glDepthMask(flag);
|
||||
#endif
|
||||
gl_state.depth_mask = flag;
|
||||
}
|
||||
}
|
||||
|
||||
void gl_state_set_line_width(GLfloat width, bool force) {
|
||||
if (force || gl_state.line_width != width) {
|
||||
glLineWidth(width);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glLineWidth(width);
|
||||
#endif
|
||||
gl_state.line_width = width;
|
||||
}
|
||||
}
|
||||
@@ -468,19 +579,28 @@ void gl_state_set_polygon_mode(GLenum face, GLenum mode, bool force) {
|
||||
switch (face) {
|
||||
case GL_FRONT:
|
||||
if (force || gl_state.polygon_mode != mode) {
|
||||
glPolygonMode(GL_FRONT, mode);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glPolygonMode(GL_FRONT, mode);
|
||||
#endif
|
||||
gl_state.polygon_mode = mode;
|
||||
}
|
||||
break;
|
||||
case GL_BACK:
|
||||
if (force || gl_state.polygon_mode != mode) {
|
||||
glPolygonMode(GL_BACK, mode);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glPolygonMode(GL_BACK, mode);
|
||||
#endif
|
||||
gl_state.polygon_mode = mode;
|
||||
}
|
||||
break;
|
||||
case GL_FRONT_AND_BACK:
|
||||
if (force || gl_state.polygon_mode != mode) {
|
||||
glPolygonMode(GL_FRONT_AND_BACK, mode);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, mode);
|
||||
#endif
|
||||
gl_state.polygon_mode = mode;
|
||||
}
|
||||
break;
|
||||
@@ -489,7 +609,10 @@ void gl_state_set_polygon_mode(GLenum face, GLenum mode, bool force) {
|
||||
|
||||
void gl_state_set_primitive_restart_index(GLuint index, bool force) {
|
||||
if (force || gl_state.primitive_restart_index != index) {
|
||||
glPrimitiveRestartIndex(index);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glPrimitiveRestartIndex(index);
|
||||
#endif
|
||||
gl_state.primitive_restart_index = index;
|
||||
}
|
||||
}
|
||||
@@ -497,7 +620,10 @@ void gl_state_set_primitive_restart_index(GLuint index, bool force) {
|
||||
void gl_state_set_scissor(const gl_state_rect& rect, bool force) {
|
||||
if (force || gl_state.scissor_box.x != rect.x || gl_state.scissor_box.y != rect.y
|
||||
|| gl_state.scissor_box.width != rect.width || gl_state.scissor_box.height != rect.height) {
|
||||
glScissor(rect.x, rect.y, rect.width, rect.height);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glScissor(rect.x, rect.y, rect.width, rect.height);
|
||||
#endif
|
||||
gl_state.scissor_box = rect;
|
||||
}
|
||||
}
|
||||
@@ -505,7 +631,10 @@ void gl_state_set_scissor(const gl_state_rect& rect, bool force) {
|
||||
void gl_state_set_scissor(GLint x, GLint y, GLsizei width, GLsizei height, bool force) {
|
||||
if (force || gl_state.scissor_box.x != x || gl_state.scissor_box.y != y
|
||||
|| gl_state.scissor_box.width != width || gl_state.scissor_box.height != height) {
|
||||
glScissor(x, y, width, height);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glScissor(x, y, width, height);
|
||||
#endif
|
||||
gl_state.scissor_box.x = x;
|
||||
gl_state.scissor_box.y = y;
|
||||
gl_state.scissor_box.width = width;
|
||||
@@ -515,7 +644,10 @@ void gl_state_set_scissor(GLint x, GLint y, GLsizei width, GLsizei height, bool
|
||||
|
||||
void gl_state_set_stencil_mask(GLuint mask, bool force) {
|
||||
if (force || gl_state.stencil_mask != mask) {
|
||||
glStencilMask(mask);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glStencilMask(mask);
|
||||
#endif
|
||||
gl_state.stencil_mask = mask;
|
||||
}
|
||||
}
|
||||
@@ -523,7 +655,10 @@ void gl_state_set_stencil_mask(GLuint mask, bool force) {
|
||||
void gl_state_set_viewport(const gl_state_rect& rect, bool force) {
|
||||
if (force || gl_state.viewport.x != rect.x || gl_state.viewport.y != rect.y
|
||||
|| gl_state.viewport.width != rect.width || gl_state.viewport.height != rect.height) {
|
||||
glViewport(rect.x, rect.y, rect.width, rect.height);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glViewport(rect.x, rect.y, rect.width, rect.height);
|
||||
#endif
|
||||
gl_state.viewport = rect;
|
||||
}
|
||||
}
|
||||
@@ -531,7 +666,10 @@ void gl_state_set_viewport(const gl_state_rect& rect, bool force) {
|
||||
void gl_state_set_viewport(GLint x, GLint y, GLsizei width, GLsizei height, bool force) {
|
||||
if (force || gl_state.viewport.x != x || gl_state.viewport.y != y
|
||||
|| gl_state.viewport.width != width || gl_state.viewport.height != height) {
|
||||
glViewport(x, y, width, height);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glViewport(x, y, width, height);
|
||||
#endif
|
||||
gl_state.viewport.x = x;
|
||||
gl_state.viewport.y = y;
|
||||
gl_state.viewport.width = width;
|
||||
@@ -541,7 +679,10 @@ void gl_state_set_viewport(GLint x, GLint y, GLsizei width, GLsizei height, bool
|
||||
|
||||
void gl_state_use_program(GLuint program, bool force) {
|
||||
if (force || gl_state.program != program) {
|
||||
glUseProgram(program);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use)
|
||||
glUseProgram(program);
|
||||
#endif
|
||||
gl_state.program = program;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../KKdLib/default.hpp"
|
||||
#include <glad/glad.h>
|
||||
#include "gl.hpp"
|
||||
|
||||
struct gl_state_rect {
|
||||
GLint x;
|
||||
@@ -29,6 +29,7 @@ struct gl_state_struct {
|
||||
GLenum blend_dst_alpha;
|
||||
GLenum blend_mode_rgb;
|
||||
GLenum blend_mode_alpha;
|
||||
GLuint framebuffer_binding;
|
||||
GLuint read_framebuffer_binding;
|
||||
GLuint draw_framebuffer_binding;
|
||||
GLuint vertex_array_binding;
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "config.hpp"
|
||||
#include "data.hpp"
|
||||
#include "file_handler.hpp"
|
||||
#include <glad/glad.h>
|
||||
#include "gl.hpp"
|
||||
|
||||
enum light_param_data_storage_flags {
|
||||
LIGHT_PARAM_DATA_STORAGE_LIGHT = 0x01,
|
||||
|
||||
+38
-22
@@ -9,6 +9,7 @@
|
||||
#include "light_param/fog.hpp"
|
||||
#include "light_param/light.hpp"
|
||||
#include "rob/rob.hpp"
|
||||
#include "Vulkan/gl_wrap.hpp"
|
||||
#include "clear_color.hpp"
|
||||
#include "effect.hpp"
|
||||
#include "gl_state.hpp"
|
||||
@@ -192,20 +193,24 @@ namespace rndr {
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
|
||||
if (!multisample_framebuffer)
|
||||
glGenFramebuffers(1, &multisample_framebuffer);
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use) {
|
||||
if (!multisample_framebuffer)
|
||||
glGenFramebuffers(1, &multisample_framebuffer);
|
||||
|
||||
if (!multisample_renderbuffer)
|
||||
glGenRenderbuffers(1, &multisample_renderbuffer);
|
||||
if (!multisample_renderbuffer)
|
||||
glGenRenderbuffers(1, &multisample_renderbuffer);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, multisample_framebuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, multisample_renderbuffer);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_RGBA8, width, height);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, multisample_renderbuffer);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, multisample_framebuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, multisample_renderbuffer);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_RGBA8, width, height);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, multisample_renderbuffer);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void RenderManager::set_clear(bool value) {
|
||||
@@ -1017,7 +1022,8 @@ namespace rndr {
|
||||
rndr::Render* rend = render;
|
||||
gl_state_set_viewport(0, 0, width, height);
|
||||
|
||||
if (multisample && multisample_framebuffer) {
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use && multisample && multisample_framebuffer) {
|
||||
gl_state_bind_framebuffer(multisample_framebuffer);
|
||||
gl_state_enable_multisample();
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
@@ -1025,6 +1031,7 @@ namespace rndr {
|
||||
}
|
||||
else
|
||||
rctx->screen_buffer.Bind();
|
||||
#endif
|
||||
|
||||
gl_state_disable_depth_test();
|
||||
gl_state_enable_blend();
|
||||
@@ -1036,7 +1043,8 @@ namespace rndr {
|
||||
gl_state_disable_blend();
|
||||
gl_state_enable_depth_test();
|
||||
|
||||
if (multisample && multisample_framebuffer) {
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use && multisample && multisample_framebuffer) {
|
||||
gl_state_bind_framebuffer(rctx->screen_buffer.fbos[0]);
|
||||
gl_state_disable_multisample();
|
||||
gl_state_bind_read_framebuffer(multisample_framebuffer);
|
||||
@@ -1044,6 +1052,7 @@ namespace rndr {
|
||||
0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
gl_state_bind_read_framebuffer(0);
|
||||
}
|
||||
#endif
|
||||
gl_state_get_error();
|
||||
gl_state_bind_framebuffer(0);
|
||||
gl_state_end_event();
|
||||
@@ -1807,15 +1816,20 @@ static void blur_filter_apply(render_context* rctx, RenderTexture* dst, RenderTe
|
||||
static void render_manager_free_render_textures() {
|
||||
rndr::RenderManager& render_manager = *rctx_ptr->render_manager;
|
||||
|
||||
if (render_manager.multisample_renderbuffer) {
|
||||
glDeleteRenderbuffers(1, &render_manager.multisample_renderbuffer);
|
||||
render_manager.multisample_renderbuffer = 0;
|
||||
}
|
||||
|
||||
if (render_manager.multisample_framebuffer) {
|
||||
glDeleteFramebuffers(1, &render_manager.multisample_framebuffer);
|
||||
render_manager.multisample_framebuffer = 0;
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use) {
|
||||
if (render_manager.multisample_renderbuffer) {
|
||||
glDeleteRenderbuffers(1, &render_manager.multisample_renderbuffer);
|
||||
render_manager.multisample_renderbuffer = 0;
|
||||
}
|
||||
|
||||
if (render_manager.multisample_framebuffer) {
|
||||
glDeleteFramebuffers(1, &render_manager.multisample_framebuffer);
|
||||
render_manager.multisample_framebuffer = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (RenderTexture& i : render_manager.render_textures)
|
||||
i.Free();
|
||||
@@ -1824,7 +1838,8 @@ static void render_manager_free_render_textures() {
|
||||
static void render_manager_init_render_textures(int32_t multisample) {
|
||||
rndr::RenderManager& render_manager = *rctx_ptr->render_manager;
|
||||
|
||||
if (multisample) {
|
||||
#ifdef USE_OPENGL
|
||||
if (!Vulkan::use && multisample) {
|
||||
glGenFramebuffers(1, &render_manager.multisample_framebuffer);
|
||||
glGenRenderbuffers(1, &render_manager.multisample_renderbuffer);
|
||||
|
||||
@@ -1846,6 +1861,7 @@ static void render_manager_init_render_textures(int32_t multisample) {
|
||||
render_manager.multisample_framebuffer = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (int32_t i = 0; i < 9; i++) {
|
||||
const rndr::RenderTextureData* tex_data = &rndr::render_manager_render_texture_data_array[i];
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
|
||||
#include "../KKdLib/default.hpp"
|
||||
#include "../KKdLib/vec.hpp"
|
||||
#include "gl.hpp"
|
||||
#include "render.hpp"
|
||||
#include "shadow.hpp"
|
||||
#include <glad/glad.h>
|
||||
#include <list>
|
||||
|
||||
enum reflect_refract_resolution_mode {
|
||||
|
||||
+1530
-314
File diff suppressed because it is too large
Load Diff
@@ -13,12 +13,32 @@
|
||||
#include "../KKdLib/vec.hpp"
|
||||
#include "static_var.hpp"
|
||||
|
||||
enum shader_description_type {
|
||||
SHADER_DESCRIPTION_NONE = 0,
|
||||
SHADER_DESCRIPTION_VERTEX_INPUT,
|
||||
SHADER_DESCRIPTION_SAMPLER,
|
||||
SHADER_DESCRIPTION_UNIFORM,
|
||||
SHADER_DESCRIPTION_STORAGE,
|
||||
SHADER_DESCRIPTION_FRAGMENT_OUTPUT,
|
||||
SHADER_DESCRIPTION_MAX,
|
||||
SHADER_DESCRIPTION_END = -1,
|
||||
};
|
||||
|
||||
struct shader_description {
|
||||
shader_description_type type;
|
||||
int32_t binding;
|
||||
int32_t data;
|
||||
uniform_name use_uniform;
|
||||
};
|
||||
|
||||
struct shader_sub_table {
|
||||
uint32_t sub_index;
|
||||
const int32_t* vp_unival_max;
|
||||
const int32_t* fp_unival_max;
|
||||
const char* vp;
|
||||
const char* fp;
|
||||
const shader_description* vp_desc;
|
||||
const shader_description* fp_desc;
|
||||
};
|
||||
|
||||
struct shader_table {
|
||||
@@ -48,6 +68,8 @@ struct shader_sub {
|
||||
const int32_t* vp_unival_max;
|
||||
const int32_t* fp_unival_max;
|
||||
GLuint* programs;
|
||||
const shader_description* fp_desc;
|
||||
const shader_description* vp_desc;
|
||||
};
|
||||
|
||||
struct shader {
|
||||
@@ -78,6 +100,10 @@ struct shader_set_data {
|
||||
PFNSHADERGETINDEXFUNCPROC get_index_by_name_func;
|
||||
PFNSHADERGETNAMEFUNCPROC get_name_by_index_func;
|
||||
|
||||
const shader_description* vp_desc;
|
||||
const shader_description* fp_desc;
|
||||
uint64_t unival_hash;
|
||||
|
||||
shader_set_data();
|
||||
|
||||
void disable_primitive_restart();
|
||||
|
||||
@@ -27,6 +27,44 @@ static const int32_t cubemap_display_fpt_unival_max[] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#pragma region Shader Description
|
||||
#define SHADER_DESCRIPTION_EFFECT_TEXTURE_SAMPLER \
|
||||
{ SHADER_DESCRIPTION_SAMPLER, 14, 0, U_INVALID, }
|
||||
|
||||
#define SHADER_DESCRIPTION_COMMON_SCENE \
|
||||
{ SHADER_DESCRIPTION_UNIFORM, 0, sizeof(obj_shader_shader_data), U_INVALID, }, \
|
||||
{ SHADER_DESCRIPTION_UNIFORM, 1, sizeof(obj_scene_shader_data), U_INVALID, }, \
|
||||
{ SHADER_DESCRIPTION_UNIFORM, 2, sizeof(obj_batch_shader_data), U_INVALID, }
|
||||
|
||||
#define SHADER_DESCRIPTION_COMMON_SKINNING \
|
||||
{ SHADER_DESCRIPTION_VERTEX_INPUT, 1, 4, U_SKINNING, }, \
|
||||
{ SHADER_DESCRIPTION_VERTEX_INPUT, 15, 4, U_SKINNING, }, \
|
||||
{ SHADER_DESCRIPTION_STORAGE, 0, sizeof(obj_skinning_shader_data), U_SKINNING, }
|
||||
|
||||
#define SHADER_DESCRIPTION_COMMON_QUAD \
|
||||
{ SHADER_DESCRIPTION_UNIFORM, 0, sizeof(quad_shader_data), U_INVALID, }
|
||||
|
||||
#if DISPLAY_IBL
|
||||
static const shader_description cubemap_display_vpt_desc[] = {
|
||||
{ SHADER_DESCRIPTION_VERTEX_INPUT, 0, 3, U_INVALID, },
|
||||
{ SHADER_DESCRIPTION_UNIFORM, 3, sizeof(vec4) * 5, U_INVALID, },
|
||||
{ SHADER_DESCRIPTION_END, -1, -1, U_INVALID, },
|
||||
};
|
||||
|
||||
static const shader_description cubemap_display_fpt_desc[] = {
|
||||
{ SHADER_DESCRIPTION_SAMPLER, 0, 0, U_INVALID, },
|
||||
{ SHADER_DESCRIPTION_UNIFORM, 3, sizeof(vec4) * 5, U_INVALID, },
|
||||
{ SHADER_DESCRIPTION_FRAGMENT_OUTPUT, 0, 4, U_INVALID, },
|
||||
{ SHADER_DESCRIPTION_END, -1, -1, U_INVALID, },
|
||||
};
|
||||
#endif
|
||||
|
||||
#undef SHADER_DESCRIPTION_COMMON_QUAD
|
||||
#undef SHADER_DESCRIPTION_COMMON_SKINNING
|
||||
#undef SHADER_DESCRIPTION_COMMON_SCENE
|
||||
#undef SHADER_DESCRIPTION_EFFECT_TEXTURE_SAMPLER
|
||||
#pragma endregion
|
||||
|
||||
#if DISPLAY_IBL
|
||||
static const uniform_name CUBEMAP_DISPLAY_uniform[] = {
|
||||
U_INVALID,
|
||||
@@ -40,6 +78,8 @@ static const uniform_name CUBEMAP_DISPLAY_uniform[] = {
|
||||
fp##_fpt_unival_max, \
|
||||
#vp, \
|
||||
#fp, \
|
||||
vp##_vpt_desc, \
|
||||
fp##_fpt_desc, \
|
||||
}
|
||||
|
||||
#if DISPLAY_IBL
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -11,9 +11,9 @@
|
||||
#include "GL/element_array_buffer.hpp"
|
||||
#include "data.hpp"
|
||||
#include "file_handler.hpp"
|
||||
#include "gl.hpp"
|
||||
#include "shader_ft.hpp"
|
||||
#include "texture.hpp"
|
||||
#include <glad/glad.h>
|
||||
|
||||
class SprSet {
|
||||
public:
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
|
||||
#include "static_var.hpp"
|
||||
|
||||
int32_t sv_max_texture_buffer_size = 0x100000;
|
||||
int32_t sv_max_texture_size = 2048;
|
||||
int32_t sv_max_texture_max_anisotropy = 1;
|
||||
int32_t sv_max_uniform_buffer_size = 0x10000;
|
||||
int32_t sv_min_uniform_buffer_alignment = 0x40;
|
||||
|
||||
bool sv_anisotropy_changed = false;
|
||||
int32_t sv_old_anisotropy = 1;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "../KKdLib/light_param/light.hpp"
|
||||
#include "../KKdLib/mat.hpp"
|
||||
#include "../KKdLib/vec.hpp"
|
||||
#include <glad/glad.h>
|
||||
#include "gl.hpp"
|
||||
|
||||
enum blur_filter_mode {
|
||||
BLUR_FILTER_4 = 0,
|
||||
@@ -105,9 +105,10 @@ enum uniform_name {
|
||||
U_DOF_STAGE = U_TEX_1_TYPE,
|
||||
};
|
||||
|
||||
extern int32_t sv_max_texture_buffer_size;
|
||||
extern int32_t sv_max_texture_size;
|
||||
extern int32_t sv_max_texture_max_anisotropy;
|
||||
extern int32_t sv_max_uniform_buffer_size;
|
||||
extern int32_t sv_min_uniform_buffer_alignment;
|
||||
|
||||
extern bool sv_anisotropy_changed;
|
||||
extern int32_t sv_anisotropy;
|
||||
|
||||
@@ -317,7 +317,6 @@ void texture_get_format_type_by_internal_format(GLenum internal_format, GLenum*
|
||||
break;
|
||||
case GL_DEPTH_COMPONENT16:
|
||||
case GL_DEPTH_COMPONENT24:
|
||||
case GL_DEPTH_COMPONENT32:
|
||||
case GL_DEPTH_COMPONENT32F:
|
||||
_format = GL_DEPTH_COMPONENT;
|
||||
_type = GL_FLOAT;
|
||||
@@ -410,7 +409,6 @@ int32_t texture_get_size(GLenum internal_format, int32_t width, int32_t height)
|
||||
case GL_RGB8:
|
||||
case GL_RGBA8:
|
||||
case GL_DEPTH_COMPONENT24:
|
||||
case GL_DEPTH_COMPONENT32:
|
||||
case GL_R32F:
|
||||
case GL_RG16F:
|
||||
case GL_DEPTH24_STENCIL8:
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@
|
||||
#include "../KKdLib/default.hpp"
|
||||
#include "../KKdLib/image.hpp"
|
||||
#include "../KKdLib/txp.hpp"
|
||||
#include <glad/glad.h>
|
||||
#include "gl.hpp"
|
||||
#include <map>
|
||||
|
||||
enum texture_flags {
|
||||
|
||||
+1360
-39
File diff suppressed because it is too large
Load Diff
+8
-2
@@ -29,14 +29,20 @@ enum render_scale {
|
||||
struct app_init_struct {
|
||||
vec2i res;
|
||||
int32_t scale_index;
|
||||
bool vulkan;
|
||||
|
||||
inline app_init_struct() : scale_index() {
|
||||
inline app_init_struct() : scale_index(), vulkan() {
|
||||
|
||||
}
|
||||
|
||||
inline app_init_struct(vec2i res, int32_t scale_index) {
|
||||
inline app_init_struct(bool vulkan) : scale_index() {
|
||||
this->vulkan = vulkan;
|
||||
}
|
||||
|
||||
inline app_init_struct(vec2i res, int32_t scale_index, bool vulkan) {
|
||||
this->res = res;
|
||||
this->scale_index = scale_index;
|
||||
this->vulkan = vulkan;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+5
-1
@@ -1270,6 +1270,10 @@ int32_t wmain(int32_t argc, wchar_t** argv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool vulkan = false;
|
||||
if (argc >= 2 && !wcscmp(argv[1], L"--vulkan"))
|
||||
vulkan = true;
|
||||
|
||||
/*process_edit_dsc();
|
||||
return 0;*/
|
||||
|
||||
@@ -1292,7 +1296,7 @@ int32_t wmain(int32_t argc, wchar_t** argv) {
|
||||
|
||||
//a3da_to_dft_dsc(269);
|
||||
|
||||
app_main({});
|
||||
app_main({ vulkan });
|
||||
|
||||
timeEndPeriod(1);
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user