160 lines
5.0 KiB
C
160 lines
5.0 KiB
C
#pragma once
|
|
|
|
#ifdef _WIN32
|
|
#define VK_USE_PLATFORM_WIN32_KHR
|
|
#define NOMINMAX
|
|
#endif
|
|
|
|
#include "vulkan/vulkan.h"
|
|
|
|
const int MAX_SWAPCHAIN_IMAGES = 8;
|
|
const int MAX_VK_PIPELINES = 1024;
|
|
const int MAX_VK_IMAGES = 2048; // should be the same as MAX_DRAWIMAGES
|
|
|
|
const int IMAGE_CHUNK_SIZE = 32 * 1024 * 1024;
|
|
const int MAX_IMAGE_CHUNKS = 16;
|
|
|
|
#define VK_CHECK(function_call) { \
|
|
VkResult result = function_call; \
|
|
if (result < 0) \
|
|
ri.Error(ERR_FATAL, "Vulkan error: function %s, error code %d", function_call, result); \
|
|
}
|
|
|
|
enum class Vk_Shader_Type {
|
|
single_texture,
|
|
multi_texture_mul,
|
|
multi_texture_add
|
|
};
|
|
|
|
struct Vk_Pipeline_Desc {
|
|
Vk_Shader_Type shader_type = Vk_Shader_Type::single_texture;
|
|
unsigned int state_bits = 0; // GLS_XXX flags
|
|
int face_culling = 0;// cullType_t
|
|
bool polygon_offset = false;
|
|
|
|
bool operator==(const Vk_Pipeline_Desc& other) const {
|
|
return
|
|
shader_type == other.shader_type &&
|
|
state_bits == other.state_bits &&
|
|
face_culling == other.face_culling &&
|
|
polygon_offset == other.polygon_offset;
|
|
}
|
|
};
|
|
|
|
struct Vk_Image {
|
|
VkImage image = VK_NULL_HANDLE;
|
|
VkImageView image_view = VK_NULL_HANDLE;
|
|
|
|
// One to one correspondence between images and descriptor sets.
|
|
// We update descriptor set during image initialization and then never touch it again (except for cinematic images).
|
|
VkDescriptorSet descriptor_set;
|
|
};
|
|
|
|
|
|
//
|
|
// Initialization.
|
|
//
|
|
void vk_create_instance(HWND hwnd); // initializes VK_Instance
|
|
void vk_destroy_instance(); // destroys Vk_Instance resources
|
|
void vk_destroy_resources(); // destroys Vk_Resources resources
|
|
|
|
//
|
|
// Resources allocation.
|
|
//
|
|
VkImage vk_create_image(int width, int height, VkImageView& image_view);
|
|
void vk_upload_image_data(VkImage image, int width, int height, const uint8_t* rgba_pixels);
|
|
VkPipeline vk_find_pipeline(const Vk_Pipeline_Desc& desc);
|
|
VkDescriptorSet vk_create_descriptor_set(VkImageView image_view);
|
|
|
|
//
|
|
// Rendering setup.
|
|
//
|
|
VkRect2D vk_get_viewport_rect();
|
|
void vk_get_mvp_transform(float mvp[16]);
|
|
|
|
void vk_bind_resources_shared_between_stages();
|
|
void vk_bind_stage_specific_resources(VkPipeline pipeline, bool multitexture, bool sky);
|
|
|
|
void vk_begin_frame();
|
|
void vk_end_frame();
|
|
|
|
// Vulkan specific structures used by the engine.
|
|
struct Vk_Instance {
|
|
VkInstance instance = VK_NULL_HANDLE;
|
|
VkPhysicalDevice physical_device = VK_NULL_HANDLE;
|
|
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
|
VkSurfaceFormatKHR surface_format = {};
|
|
|
|
uint32_t queue_family_index = 0;
|
|
VkDevice device = VK_NULL_HANDLE;
|
|
VkQueue queue = VK_NULL_HANDLE;
|
|
|
|
VkSwapchainKHR swapchain = VK_NULL_HANDLE;
|
|
uint32_t swapchain_image_count = 0;
|
|
VkImage swapchain_images[MAX_SWAPCHAIN_IMAGES];
|
|
VkImageView swapchain_image_views[MAX_SWAPCHAIN_IMAGES];
|
|
|
|
VkCommandPool command_pool = VK_NULL_HANDLE;
|
|
VkCommandBuffer command_buffer = VK_NULL_HANDLE;
|
|
|
|
VkImage depth_image = VK_NULL_HANDLE;
|
|
VkDeviceMemory depth_image_memory = VK_NULL_HANDLE;
|
|
VkImageView depth_image_view = VK_NULL_HANDLE;
|
|
|
|
VkRenderPass render_pass = VK_NULL_HANDLE;
|
|
VkFramebuffer framebuffers[MAX_SWAPCHAIN_IMAGES];
|
|
|
|
VkDescriptorPool descriptor_pool = VK_NULL_HANDLE;
|
|
VkDescriptorSetLayout set_layout = VK_NULL_HANDLE;
|
|
VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
|
|
|
|
VkBuffer vertex_buffer = VK_NULL_HANDLE;
|
|
byte* vertex_buffer_ptr = nullptr; // pointer to mapped vertex buffer
|
|
int xyz_elements = 0;
|
|
int color_st_elements = 0;
|
|
|
|
VkBuffer index_buffer = VK_NULL_HANDLE;
|
|
byte* index_buffer_ptr = nullptr; // pointer to mapped index buffer
|
|
VkDeviceSize index_buffer_offset = 0;
|
|
|
|
// host visible memory that holds both vertex and index data
|
|
VkDeviceMemory geometry_buffer_memory = VK_NULL_HANDLE;
|
|
|
|
VkSemaphore image_acquired = VK_NULL_HANDLE;
|
|
uint32_t swapchain_image_index = -1;
|
|
|
|
VkSemaphore rendering_finished = VK_NULL_HANDLE;
|
|
VkFence rendering_finished_fence = VK_NULL_HANDLE;
|
|
|
|
VkShaderModule single_texture_vs = VK_NULL_HANDLE;
|
|
VkShaderModule single_texture_fs = VK_NULL_HANDLE;
|
|
VkShaderModule multi_texture_vs = VK_NULL_HANDLE;
|
|
VkShaderModule multi_texture_mul_fs = VK_NULL_HANDLE;
|
|
VkShaderModule multi_texture_add_fs = VK_NULL_HANDLE;
|
|
|
|
VkSampler sampler = VK_NULL_HANDLE;
|
|
VkPipeline skybox_pipeline = VK_NULL_HANDLE;
|
|
};
|
|
|
|
struct Vk_Resources {
|
|
int num_pipelines = 0;
|
|
Vk_Pipeline_Desc pipeline_desc[MAX_VK_PIPELINES];
|
|
VkPipeline pipelines[MAX_VK_PIPELINES];
|
|
|
|
Vk_Image images[MAX_VK_IMAGES];
|
|
|
|
struct Chunk {
|
|
VkDeviceMemory memory = VK_NULL_HANDLE;
|
|
VkDeviceSize used = 0;
|
|
};
|
|
|
|
int num_image_chunks = 0;
|
|
Chunk image_chunks[MAX_IMAGE_CHUNKS];
|
|
|
|
// Host visible memory used to copy image data to device local memory.
|
|
VkBuffer staging_buffer = VK_NULL_HANDLE;
|
|
VkDeviceMemory staging_buffer_memory = VK_NULL_HANDLE;
|
|
VkDeviceSize staging_buffer_size = 0;
|
|
byte* staging_buffer_ptr = nullptr; // pointer to mapped staging buffer
|
|
};
|