Clean up: moved render pass/framebuffer handles to Vulkan_Instance.
Demo code removal.
This commit is contained in:
parent
6afd32f4d2
commit
0d29be174f
|
|
@ -1845,8 +1845,17 @@ R_DeleteTextures
|
||||||
void R_DeleteTextures( void ) {
|
void R_DeleteTextures( void ) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
// VULKAN
|
||||||
|
vkDeviceWaitIdle(vk_instance.device);
|
||||||
|
|
||||||
for ( i=0; i<tr.numImages ; i++ ) {
|
for ( i=0; i<tr.numImages ; i++ ) {
|
||||||
qglDeleteTextures( 1, &tr.images[i]->texnum );
|
qglDeleteTextures( 1, &tr.images[i]->texnum );
|
||||||
|
|
||||||
|
// VULKAN
|
||||||
|
vkDestroyImage(vk_instance.device, tr.images[i]->vk_image, nullptr);
|
||||||
|
vkDestroyImageView(vk_instance.device, tr.images[i]->vk_image_view, nullptr);
|
||||||
|
if (tr.images[i]->vk_staging_buffer.handle != VK_NULL_HANDLE)
|
||||||
|
vkDestroyBuffer(vk_instance.device, tr.images[i]->vk_staging_buffer.handle, nullptr);
|
||||||
}
|
}
|
||||||
Com_Memset( tr.images, 0, sizeof( tr.images ) );
|
Com_Memset( tr.images, 0, sizeof( tr.images ) );
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "vk.h"
|
#include "vk.h"
|
||||||
#include "vk_utils.h"
|
#include "vk_utils.h"
|
||||||
#include "vk_allocator.h"
|
#include "vk_allocator.h"
|
||||||
|
#include "vk_resource_manager.h"
|
||||||
#include "tr_local.h"
|
#include "tr_local.h"
|
||||||
#include "vk_demo.h"
|
#include "vk_demo.h"
|
||||||
|
|
||||||
|
|
@ -28,6 +29,25 @@ static bool is_extension_available(const std::vector<VkExtensionProperties>& pro
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VkFormat find_format_with_features(VkPhysicalDevice physical_device, const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features) {
|
||||||
|
for (VkFormat format : candidates) {
|
||||||
|
VkFormatProperties properties;
|
||||||
|
vkGetPhysicalDeviceFormatProperties(physical_device, format, &properties);
|
||||||
|
|
||||||
|
if (tiling == VK_IMAGE_TILING_LINEAR && (properties.linearTilingFeatures & features) == features)
|
||||||
|
return format;
|
||||||
|
if (tiling == VK_IMAGE_TILING_OPTIMAL && (properties.optimalTilingFeatures & features) == features)
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
error("failed to find format with requested features");
|
||||||
|
return VK_FORMAT_UNDEFINED; // never get here
|
||||||
|
}
|
||||||
|
|
||||||
|
VkFormat find_depth_format(VkPhysicalDevice physical_device) {
|
||||||
|
return find_format_with_features(physical_device, {VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT},
|
||||||
|
VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t select_queue_family(VkPhysicalDevice physical_device, VkSurfaceKHR surface) {
|
static uint32_t select_queue_family(VkPhysicalDevice physical_device, VkSurfaceKHR surface) {
|
||||||
uint32_t queue_family_count;
|
uint32_t queue_family_count;
|
||||||
vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, nullptr);
|
vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, nullptr);
|
||||||
|
|
@ -234,6 +254,68 @@ static VkSwapchainKHR create_swapchain(VkPhysicalDevice physical_device, VkDevic
|
||||||
return swapchain;
|
return swapchain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: pass device, color format, depth format. Physical device is not needed.
|
||||||
|
static VkRenderPass create_render_pass(VkPhysicalDevice physical_device, VkDevice device) {
|
||||||
|
VkAttachmentDescription color_attachment;
|
||||||
|
color_attachment.flags = 0;
|
||||||
|
color_attachment.format = vk_instance.surface_format.format;
|
||||||
|
color_attachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
|
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_UNDEFINED;
|
||||||
|
color_attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||||
|
|
||||||
|
VkAttachmentDescription depth_attachment;
|
||||||
|
depth_attachment.flags = 0;
|
||||||
|
depth_attachment.format = find_depth_format(physical_device);
|
||||||
|
depth_attachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
depth_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
|
depth_attachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
depth_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
depth_attachment.stencilStoreOp = 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;
|
||||||
|
|
||||||
|
VkAttachmentReference color_attachment_ref;
|
||||||
|
color_attachment_ref.attachment = 0;
|
||||||
|
color_attachment_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
VkAttachmentReference depth_attachment_ref;
|
||||||
|
depth_attachment_ref.attachment = 1;
|
||||||
|
depth_attachment_ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
VkSubpassDescription subpass;
|
||||||
|
subpass.flags = 0;
|
||||||
|
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||||
|
subpass.inputAttachmentCount = 0;
|
||||||
|
subpass.pInputAttachments = nullptr;
|
||||||
|
subpass.colorAttachmentCount = 1;
|
||||||
|
subpass.pColorAttachments = &color_attachment_ref;
|
||||||
|
subpass.pResolveAttachments = nullptr;
|
||||||
|
subpass.pDepthStencilAttachment = &depth_attachment_ref;
|
||||||
|
subpass.preserveAttachmentCount = 0;
|
||||||
|
subpass.pPreserveAttachments = nullptr;
|
||||||
|
|
||||||
|
std::array<VkAttachmentDescription, 2> attachments{color_attachment, depth_attachment};
|
||||||
|
VkRenderPassCreateInfo desc;
|
||||||
|
desc.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||||
|
desc.pNext = nullptr;
|
||||||
|
desc.flags = 0;
|
||||||
|
desc.attachmentCount = static_cast<uint32_t>(attachments.size());
|
||||||
|
desc.pAttachments = attachments.data();
|
||||||
|
desc.subpassCount = 1;
|
||||||
|
desc.pSubpasses = &subpass;
|
||||||
|
desc.dependencyCount = 0;
|
||||||
|
desc.pDependencies = nullptr;
|
||||||
|
|
||||||
|
VkRenderPass render_pass;
|
||||||
|
VkResult result = vkCreateRenderPass(device, &desc, nullptr, &render_pass);
|
||||||
|
check_vk_result(result, "vkCreateRenderPass");
|
||||||
|
return render_pass;
|
||||||
|
}
|
||||||
|
|
||||||
bool vk_initialize(HWND hwnd) {
|
bool vk_initialize(HWND hwnd) {
|
||||||
try {
|
try {
|
||||||
auto& g = vk_instance;
|
auto& g = vk_instance;
|
||||||
|
|
@ -300,6 +382,44 @@ bool vk_initialize(HWND hwnd) {
|
||||||
result = vkAllocateCommandBuffers(vk_instance.device, &alloc_info, &g.command_buffer);
|
result = vkAllocateCommandBuffers(vk_instance.device, &alloc_info, &g.command_buffer);
|
||||||
check_vk_result(result, "vkAllocateCommandBuffers");
|
check_vk_result(result, "vkAllocateCommandBuffers");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get_allocator()->initialize(vk_instance.physical_device, vk_instance.device);
|
||||||
|
get_resource_manager()->initialize(vk_instance.device);
|
||||||
|
|
||||||
|
{
|
||||||
|
VkFormat depth_format = find_depth_format(vk_instance.physical_device);
|
||||||
|
vk_instance.depth_image = create_depth_attachment_image(glConfig.vidWidth, glConfig.vidHeight, depth_format);
|
||||||
|
vk_instance.depth_image_view = create_image_view(vk_instance.depth_image, depth_format, VK_IMAGE_ASPECT_DEPTH_BIT);
|
||||||
|
|
||||||
|
record_and_run_commands(vk_instance.command_pool, vk_instance.queue, [&depth_format](VkCommandBuffer command_buffer) {
|
||||||
|
record_image_layout_transition(command_buffer, vk_instance.depth_image, depth_format, 0, VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
g.render_pass = create_render_pass(g.physical_device, g.device);
|
||||||
|
|
||||||
|
{
|
||||||
|
std::array<VkImageView, 2> attachments = {VK_NULL_HANDLE, vk_instance.depth_image_view};
|
||||||
|
|
||||||
|
VkFramebufferCreateInfo desc;
|
||||||
|
desc.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||||
|
desc.pNext = nullptr;
|
||||||
|
desc.flags = 0;
|
||||||
|
desc.renderPass = vk_instance.render_pass;
|
||||||
|
desc.attachmentCount = static_cast<uint32_t>(attachments.size());
|
||||||
|
desc.pAttachments = attachments.data();
|
||||||
|
desc.width = glConfig.vidWidth;
|
||||||
|
desc.height = glConfig.vidHeight;
|
||||||
|
desc.layers = 1;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < vk_instance.swapchain_image_count; i++) {
|
||||||
|
attachments[0] = vk_instance.swapchain_image_views[i]; // set color attachment
|
||||||
|
VkResult result = vkCreateFramebuffer(vk_instance.device, &desc, nullptr, &vk_instance.framebuffers[i]);
|
||||||
|
check_vk_result(result, "vkCreateFramebuffer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -309,9 +429,22 @@ bool vk_initialize(HWND hwnd) {
|
||||||
void vk_deinitialize() {
|
void vk_deinitialize() {
|
||||||
auto& g = vk_instance;
|
auto& g = vk_instance;
|
||||||
|
|
||||||
|
get_resource_manager()->release_resources();
|
||||||
|
get_allocator()->deallocate_all();
|
||||||
|
|
||||||
|
vkDestroyFence(vk_instance.device, vulkan_demo->rendering_finished_fence, nullptr);
|
||||||
|
vkDestroyImage(vk_instance.device, vk_instance.depth_image, nullptr);
|
||||||
|
vkDestroyImageView(vk_instance.device, vk_instance.depth_image_view, nullptr);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < vk_instance.swapchain_image_count; i++) {
|
||||||
|
vkDestroyFramebuffer(vk_instance.device, vk_instance.framebuffers[i], nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
vkDestroyRenderPass(vk_instance.device, vk_instance.render_pass, nullptr);
|
||||||
|
|
||||||
vkDestroyCommandPool(g.device, g.command_pool, nullptr);
|
vkDestroyCommandPool(g.device, g.command_pool, nullptr);
|
||||||
|
|
||||||
for (int i = 0; i < g.swapchain_image_count; i++) {
|
for (uint32_t i = 0; i < g.swapchain_image_count; i++) {
|
||||||
vkDestroyImageView(g.device, g.swapchain_image_views[i], nullptr);
|
vkDestroyImageView(g.device, g.swapchain_image_views[i], nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -665,7 +798,7 @@ static VkPipeline create_pipeline(const Vk_Pipeline_Desc& desc) {
|
||||||
create_info.pColorBlendState = &blend_state;
|
create_info.pColorBlendState = &blend_state;
|
||||||
create_info.pDynamicState = &dynamic_state;
|
create_info.pDynamicState = &dynamic_state;
|
||||||
create_info.layout = vulkan_demo->pipeline_layout;
|
create_info.layout = vulkan_demo->pipeline_layout;
|
||||||
create_info.renderPass = vulkan_demo->render_pass;
|
create_info.renderPass = vk_instance.render_pass;
|
||||||
create_info.subpass = 0;
|
create_info.subpass = 0;
|
||||||
create_info.basePipelineHandle = VK_NULL_HANDLE;
|
create_info.basePipelineHandle = VK_NULL_HANDLE;
|
||||||
create_info.basePipelineIndex = -1;
|
create_info.basePipelineIndex = -1;
|
||||||
|
|
@ -712,14 +845,11 @@ VkPipeline vk_find_pipeline(const Vk_Pipeline_Desc& desc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vk_destroy_pipelines() {
|
static void vk_destroy_pipelines() {
|
||||||
vkDeviceWaitIdle(vk_instance.device);
|
|
||||||
|
|
||||||
for (int i = 0; i < tr.vk.num_pipelines; i++) {
|
for (int i = 0; i < tr.vk.num_pipelines; i++) {
|
||||||
vkDestroyPipeline(vk_instance.device, tr.vk.pipelines[i], nullptr);
|
vkDestroyPipeline(vk_instance.device, tr.vk.pipelines[i], nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.vk.num_pipelines = 0;
|
tr.vk.num_pipelines = 0;
|
||||||
|
|
||||||
Com_Memset(tr.vk.pipelines, 0, sizeof(tr.vk.pipelines));
|
Com_Memset(tr.vk.pipelines, 0, sizeof(tr.vk.pipelines));
|
||||||
Com_Memset(tr.vk.pipeline_desc, 0, sizeof(tr.vk.pipeline_desc));
|
Com_Memset(tr.vk.pipeline_desc, 0, sizeof(tr.vk.pipeline_desc));
|
||||||
|
|
||||||
|
|
@ -727,5 +857,6 @@ static void vk_destroy_pipelines() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void vk_destroy_resources() {
|
void vk_destroy_resources() {
|
||||||
|
vkDeviceWaitIdle(vk_instance.device);
|
||||||
vk_destroy_pipelines();
|
vk_destroy_pipelines();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,12 @@ struct Vulkan_Instance {
|
||||||
|
|
||||||
VkCommandPool command_pool = VK_NULL_HANDLE;
|
VkCommandPool command_pool = VK_NULL_HANDLE;
|
||||||
VkCommandBuffer command_buffer = VK_NULL_HANDLE;
|
VkCommandBuffer command_buffer = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
VkImage depth_image = VK_NULL_HANDLE;
|
||||||
|
VkImageView depth_image_view = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
VkRenderPass render_pass = VK_NULL_HANDLE;
|
||||||
|
VkFramebuffer framebuffers[MAX_SWAPCHAIN_IMAGES];
|
||||||
};
|
};
|
||||||
|
|
||||||
const int MAX_VK_PIPELINES = 1024;
|
const int MAX_VK_PIPELINES = 1024;
|
||||||
|
|
|
||||||
|
|
@ -18,25 +18,6 @@ struct Uniform_Buffer_Object {
|
||||||
float mvp[16];
|
float mvp[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
static VkFormat find_format_with_features(VkPhysicalDevice physical_device, const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features) {
|
|
||||||
for (VkFormat format : candidates) {
|
|
||||||
VkFormatProperties properties;
|
|
||||||
vkGetPhysicalDeviceFormatProperties(physical_device, format, &properties);
|
|
||||||
|
|
||||||
if (tiling == VK_IMAGE_TILING_LINEAR && (properties.linearTilingFeatures & features) == features)
|
|
||||||
return format;
|
|
||||||
if (tiling == VK_IMAGE_TILING_OPTIMAL && (properties.optimalTilingFeatures & features) == features)
|
|
||||||
return format;
|
|
||||||
}
|
|
||||||
error("failed to find format with requested features");
|
|
||||||
return VK_FORMAT_UNDEFINED; // never get here
|
|
||||||
}
|
|
||||||
|
|
||||||
static VkFormat find_depth_format(VkPhysicalDevice physical_device) {
|
|
||||||
return find_format_with_features(physical_device, {VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT},
|
|
||||||
VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE* logfile;
|
FILE* logfile;
|
||||||
|
|
||||||
Vulkan_Demo::Vulkan_Demo(int window_width, int window_height)
|
Vulkan_Demo::Vulkan_Demo(int window_width, int window_height)
|
||||||
|
|
@ -44,8 +25,6 @@ Vulkan_Demo::Vulkan_Demo(int window_width, int window_height)
|
||||||
, window_height(window_height)
|
, window_height(window_height)
|
||||||
{
|
{
|
||||||
logfile = fopen("vk_dev.log", "w");
|
logfile = fopen("vk_dev.log", "w");
|
||||||
get_allocator()->initialize(vk_instance.physical_device, vk_instance.device);
|
|
||||||
get_resource_manager()->initialize(vk_instance.device);
|
|
||||||
|
|
||||||
image_acquired = get_resource_manager()->create_semaphore();
|
image_acquired = get_resource_manager()->create_semaphore();
|
||||||
rendering_finished = get_resource_manager()->create_semaphore();
|
rendering_finished = get_resource_manager()->create_semaphore();
|
||||||
|
|
@ -62,25 +41,13 @@ Vulkan_Demo::Vulkan_Demo(int window_width, int window_height)
|
||||||
create_uniform_buffer();
|
create_uniform_buffer();
|
||||||
|
|
||||||
create_texture_sampler();
|
create_texture_sampler();
|
||||||
create_depth_buffer_resources();
|
|
||||||
|
|
||||||
create_descriptor_set_layout();
|
create_descriptor_set_layout();
|
||||||
create_render_pass();
|
|
||||||
create_framebuffers();
|
|
||||||
create_pipeline_layout();
|
create_pipeline_layout();
|
||||||
|
|
||||||
upload_geometry();
|
upload_geometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vulkan_Demo::~Vulkan_Demo() {
|
|
||||||
VkResult result = vkDeviceWaitIdle(vk_instance.device);
|
|
||||||
if (result < 0)
|
|
||||||
std::cerr << "vkDeviceWaitIdle returned an error code: " + result;
|
|
||||||
|
|
||||||
get_resource_manager()->release_resources();
|
|
||||||
get_allocator()->deallocate_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Vulkan_Demo::create_descriptor_pool() {
|
void Vulkan_Demo::create_descriptor_pool() {
|
||||||
std::array<VkDescriptorPoolSize, 2> pool_sizes;
|
std::array<VkDescriptorPoolSize, 2> pool_sizes;
|
||||||
pool_sizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
|
pool_sizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
|
||||||
|
|
@ -182,17 +149,6 @@ void Vulkan_Demo::create_texture_sampler() {
|
||||||
texture_image_sampler = get_resource_manager()->create_sampler(desc);
|
texture_image_sampler = get_resource_manager()->create_sampler(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vulkan_Demo::create_depth_buffer_resources() {
|
|
||||||
VkFormat depth_format = find_depth_format(vk_instance.physical_device);
|
|
||||||
depth_image = create_depth_attachment_image(window_width, window_height, depth_format);
|
|
||||||
depth_image_view = create_image_view(depth_image, depth_format, VK_IMAGE_ASPECT_DEPTH_BIT);
|
|
||||||
|
|
||||||
record_and_run_commands(vk_instance.command_pool, vk_instance.queue, [&depth_format, this](VkCommandBuffer command_buffer) {
|
|
||||||
record_image_layout_transition(command_buffer, depth_image, depth_format, 0, VK_IMAGE_LAYOUT_UNDEFINED,
|
|
||||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void Vulkan_Demo::create_descriptor_set_layout() {
|
void Vulkan_Demo::create_descriptor_set_layout() {
|
||||||
std::array<VkDescriptorSetLayoutBinding, 3> descriptor_bindings;
|
std::array<VkDescriptorSetLayoutBinding, 3> descriptor_bindings;
|
||||||
descriptor_bindings[0].binding = 0;
|
descriptor_bindings[0].binding = 0;
|
||||||
|
|
@ -311,85 +267,6 @@ void Vulkan_Demo::create_multitexture_descriptor_set(const image_t* image, const
|
||||||
multitexture_descriptor_sets[images] = set;
|
multitexture_descriptor_sets[images] = set;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vulkan_Demo::create_render_pass() {
|
|
||||||
VkAttachmentDescription color_attachment;
|
|
||||||
color_attachment.flags = 0;
|
|
||||||
color_attachment.format = vk_instance.surface_format.format;
|
|
||||||
color_attachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
|
||||||
color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
|
||||||
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_UNDEFINED;
|
|
||||||
color_attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
|
||||||
|
|
||||||
VkAttachmentDescription depth_attachment;
|
|
||||||
depth_attachment.flags = 0;
|
|
||||||
depth_attachment.format = find_depth_format(vk_instance.physical_device);
|
|
||||||
depth_attachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
|
||||||
depth_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
|
||||||
depth_attachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
|
||||||
depth_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
|
||||||
depth_attachment.stencilStoreOp = 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;
|
|
||||||
|
|
||||||
VkAttachmentReference color_attachment_ref;
|
|
||||||
color_attachment_ref.attachment = 0;
|
|
||||||
color_attachment_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
|
||||||
|
|
||||||
VkAttachmentReference depth_attachment_ref;
|
|
||||||
depth_attachment_ref.attachment = 1;
|
|
||||||
depth_attachment_ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
|
||||||
|
|
||||||
VkSubpassDescription subpass;
|
|
||||||
subpass.flags = 0;
|
|
||||||
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
|
||||||
subpass.inputAttachmentCount = 0;
|
|
||||||
subpass.pInputAttachments = nullptr;
|
|
||||||
subpass.colorAttachmentCount = 1;
|
|
||||||
subpass.pColorAttachments = &color_attachment_ref;
|
|
||||||
subpass.pResolveAttachments = nullptr;
|
|
||||||
subpass.pDepthStencilAttachment = &depth_attachment_ref;
|
|
||||||
subpass.preserveAttachmentCount = 0;
|
|
||||||
subpass.pPreserveAttachments = nullptr;
|
|
||||||
|
|
||||||
std::array<VkAttachmentDescription, 2> attachments{color_attachment, depth_attachment};
|
|
||||||
VkRenderPassCreateInfo desc;
|
|
||||||
desc.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
|
||||||
desc.pNext = nullptr;
|
|
||||||
desc.flags = 0;
|
|
||||||
desc.attachmentCount = static_cast<uint32_t>(attachments.size());
|
|
||||||
desc.pAttachments = attachments.data();
|
|
||||||
desc.subpassCount = 1;
|
|
||||||
desc.pSubpasses = &subpass;
|
|
||||||
desc.dependencyCount = 0;
|
|
||||||
desc.pDependencies = nullptr;
|
|
||||||
|
|
||||||
render_pass = get_resource_manager()->create_render_pass(desc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Vulkan_Demo::create_framebuffers() {
|
|
||||||
std::array<VkImageView, 2> attachments = {VK_NULL_HANDLE, depth_image_view};
|
|
||||||
|
|
||||||
VkFramebufferCreateInfo desc;
|
|
||||||
desc.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
|
||||||
desc.pNext = nullptr;
|
|
||||||
desc.flags = 0;
|
|
||||||
desc.renderPass = render_pass;
|
|
||||||
desc.attachmentCount = static_cast<uint32_t>(attachments.size());
|
|
||||||
desc.pAttachments = attachments.data();
|
|
||||||
desc.width = window_width;
|
|
||||||
desc.height = window_height;
|
|
||||||
desc.layers = 1;
|
|
||||||
|
|
||||||
framebuffers.resize(vk_instance.swapchain_image_count);
|
|
||||||
for (std::size_t i = 0; i < framebuffers.size(); i++) {
|
|
||||||
attachments[0] = vk_instance.swapchain_image_views[i]; // set color attachment
|
|
||||||
framebuffers[i] = get_resource_manager()->create_framebuffer(desc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Vulkan_Demo::create_pipeline_layout() {
|
void Vulkan_Demo::create_pipeline_layout() {
|
||||||
VkPipelineLayoutCreateInfo desc;
|
VkPipelineLayoutCreateInfo desc;
|
||||||
desc.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
desc.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||||
|
|
@ -532,8 +409,8 @@ void Vulkan_Demo::begin_frame() {
|
||||||
VkRenderPassBeginInfo render_pass_begin_info;
|
VkRenderPassBeginInfo render_pass_begin_info;
|
||||||
render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||||
render_pass_begin_info.pNext = nullptr;
|
render_pass_begin_info.pNext = nullptr;
|
||||||
render_pass_begin_info.renderPass = render_pass;
|
render_pass_begin_info.renderPass = vk_instance.render_pass;
|
||||||
render_pass_begin_info.framebuffer = framebuffers[swapchain_image_index];
|
render_pass_begin_info.framebuffer = vk_instance.framebuffers[swapchain_image_index];
|
||||||
render_pass_begin_info.renderArea.offset = {0, 0};
|
render_pass_begin_info.renderArea.offset = {0, 0};
|
||||||
render_pass_begin_info.renderArea.extent = {(uint32_t)window_width, (uint32_t)window_height};
|
render_pass_begin_info.renderArea.extent = {(uint32_t)window_width, (uint32_t)window_height};
|
||||||
render_pass_begin_info.clearValueCount = static_cast<uint32_t>(clear_values.size());
|
render_pass_begin_info.clearValueCount = static_cast<uint32_t>(clear_values.size());
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@
|
||||||
class Vulkan_Demo {
|
class Vulkan_Demo {
|
||||||
public:
|
public:
|
||||||
Vulkan_Demo(int window_width, int window_height);
|
Vulkan_Demo(int window_width, int window_height);
|
||||||
~Vulkan_Demo();
|
|
||||||
|
|
||||||
void begin_frame();
|
void begin_frame();
|
||||||
void end_frame();
|
void end_frame();
|
||||||
|
|
@ -24,13 +23,10 @@ public:
|
||||||
void create_uniform_buffer();
|
void create_uniform_buffer();
|
||||||
VkImage create_texture(const uint8_t* pixels, int bytes_per_pixel, int width, int height, VkImageView& image_view);
|
VkImage create_texture(const uint8_t* pixels, int bytes_per_pixel, int width, int height, VkImageView& image_view);
|
||||||
void create_texture_sampler();
|
void create_texture_sampler();
|
||||||
void create_depth_buffer_resources();
|
|
||||||
|
|
||||||
void create_descriptor_set_layout();
|
void create_descriptor_set_layout();
|
||||||
void create_image_descriptor_set(const image_t* image);
|
void create_image_descriptor_set(const image_t* image);
|
||||||
void create_multitexture_descriptor_set(const image_t* image, const image_t* image2);
|
void create_multitexture_descriptor_set(const image_t* image, const image_t* image2);
|
||||||
void create_render_pass();
|
|
||||||
void create_framebuffers();
|
|
||||||
void create_pipeline_layout();
|
void create_pipeline_layout();
|
||||||
|
|
||||||
void upload_geometry();
|
void upload_geometry();
|
||||||
|
|
@ -52,12 +48,8 @@ public:
|
||||||
VkBuffer uniform_buffer = VK_NULL_HANDLE;
|
VkBuffer uniform_buffer = VK_NULL_HANDLE;
|
||||||
|
|
||||||
VkSampler texture_image_sampler = VK_NULL_HANDLE;
|
VkSampler texture_image_sampler = VK_NULL_HANDLE;
|
||||||
VkImage depth_image = VK_NULL_HANDLE;
|
|
||||||
VkImageView depth_image_view = VK_NULL_HANDLE;
|
|
||||||
|
|
||||||
VkDescriptorSetLayout descriptor_set_layout = VK_NULL_HANDLE;
|
VkDescriptorSetLayout descriptor_set_layout = VK_NULL_HANDLE;
|
||||||
VkRenderPass render_pass = VK_NULL_HANDLE;
|
|
||||||
std::vector<VkFramebuffer> framebuffers;
|
|
||||||
VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
|
VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
|
||||||
|
|
||||||
VkBuffer tess_vertex_buffer = VK_NULL_HANDLE;
|
VkBuffer tess_vertex_buffer = VK_NULL_HANDLE;
|
||||||
|
|
|
||||||
|
|
@ -26,31 +26,11 @@ void Resource_Manager::release_resources() {
|
||||||
}
|
}
|
||||||
buffers.clear();
|
buffers.clear();
|
||||||
|
|
||||||
for (auto image : images) {
|
|
||||||
vkDestroyImage(device, image, nullptr);
|
|
||||||
}
|
|
||||||
images.clear();
|
|
||||||
|
|
||||||
for (auto image_view : image_views) {
|
|
||||||
vkDestroyImageView(device, image_view, nullptr);
|
|
||||||
}
|
|
||||||
image_views.clear();
|
|
||||||
|
|
||||||
for (auto sampler : samplers) {
|
for (auto sampler : samplers) {
|
||||||
vkDestroySampler(device, sampler, nullptr);
|
vkDestroySampler(device, sampler, nullptr);
|
||||||
}
|
}
|
||||||
samplers.clear();
|
samplers.clear();
|
||||||
|
|
||||||
for (auto render_pass : render_passes) {
|
|
||||||
vkDestroyRenderPass(device, render_pass, nullptr);
|
|
||||||
}
|
|
||||||
render_passes.clear();
|
|
||||||
|
|
||||||
for (auto framebuffer : framebuffers) {
|
|
||||||
vkDestroyFramebuffer(device, framebuffer, nullptr);
|
|
||||||
}
|
|
||||||
framebuffers.clear();
|
|
||||||
|
|
||||||
for (auto descriptor_set_layout : descriptor_set_layouts) {
|
for (auto descriptor_set_layout : descriptor_set_layouts) {
|
||||||
vkDestroyDescriptorSetLayout(device, descriptor_set_layout, nullptr);
|
vkDestroyDescriptorSetLayout(device, descriptor_set_layout, nullptr);
|
||||||
}
|
}
|
||||||
|
|
@ -60,11 +40,6 @@ void Resource_Manager::release_resources() {
|
||||||
vkDestroyPipelineLayout(device, pipeline_layout, nullptr);
|
vkDestroyPipelineLayout(device, pipeline_layout, nullptr);
|
||||||
}
|
}
|
||||||
pipeline_layouts.clear();
|
pipeline_layouts.clear();
|
||||||
|
|
||||||
for (auto pipeline : graphics_pipelines) {
|
|
||||||
vkDestroyPipeline(device, pipeline, nullptr);
|
|
||||||
}
|
|
||||||
graphics_pipelines.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VkSemaphore Resource_Manager::create_semaphore() {
|
VkSemaphore Resource_Manager::create_semaphore() {
|
||||||
|
|
@ -96,22 +71,6 @@ VkBuffer Resource_Manager::create_buffer(const VkBufferCreateInfo& desc) {
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkImage Resource_Manager::create_image(const VkImageCreateInfo& desc) {
|
|
||||||
VkImage image;
|
|
||||||
VkResult result = vkCreateImage(device, &desc, nullptr, &image);
|
|
||||||
check_vk_result(result, "vkCreateImage");
|
|
||||||
images.push_back(image);
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkImageView Resource_Manager::create_image_view(const VkImageViewCreateInfo& desc) {
|
|
||||||
VkImageView image_view;
|
|
||||||
VkResult result = vkCreateImageView(device, &desc, nullptr, &image_view);
|
|
||||||
check_vk_result(result, "vkCreateImageView");
|
|
||||||
image_views.push_back(image_view);
|
|
||||||
return image_view;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkSampler Resource_Manager::create_sampler(const VkSamplerCreateInfo& desc) {
|
VkSampler Resource_Manager::create_sampler(const VkSamplerCreateInfo& desc) {
|
||||||
VkSampler sampler;
|
VkSampler sampler;
|
||||||
VkResult result = vkCreateSampler(device, &desc, nullptr, &sampler);
|
VkResult result = vkCreateSampler(device, &desc, nullptr, &sampler);
|
||||||
|
|
@ -120,22 +79,6 @@ VkSampler Resource_Manager::create_sampler(const VkSamplerCreateInfo& desc) {
|
||||||
return sampler;
|
return sampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkRenderPass Resource_Manager::create_render_pass(const VkRenderPassCreateInfo& desc) {
|
|
||||||
VkRenderPass render_pass;
|
|
||||||
VkResult result = vkCreateRenderPass(device, &desc, nullptr, &render_pass);
|
|
||||||
check_vk_result(result, "vkCreateRenderPass");
|
|
||||||
render_passes.push_back(render_pass);
|
|
||||||
return render_pass;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkFramebuffer Resource_Manager::create_framebuffer(const VkFramebufferCreateInfo& desc) {
|
|
||||||
VkFramebuffer framebuffer;
|
|
||||||
VkResult result = vkCreateFramebuffer(device, &desc, nullptr, &framebuffer);
|
|
||||||
check_vk_result(result, "vkCreateFramebuffer");
|
|
||||||
framebuffers.push_back(framebuffer);
|
|
||||||
return framebuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkDescriptorSetLayout Resource_Manager::create_descriptor_set_layout(const VkDescriptorSetLayoutCreateInfo& desc) {
|
VkDescriptorSetLayout Resource_Manager::create_descriptor_set_layout(const VkDescriptorSetLayoutCreateInfo& desc) {
|
||||||
VkDescriptorSetLayout descriptor_set_layout;
|
VkDescriptorSetLayout descriptor_set_layout;
|
||||||
VkResult result = vkCreateDescriptorSetLayout(device, &desc, nullptr, &descriptor_set_layout);
|
VkResult result = vkCreateDescriptorSetLayout(device, &desc, nullptr, &descriptor_set_layout);
|
||||||
|
|
@ -151,11 +94,3 @@ VkPipelineLayout Resource_Manager::create_pipeline_layout(const VkPipelineLayout
|
||||||
pipeline_layouts.push_back(pipeline_layout);
|
pipeline_layouts.push_back(pipeline_layout);
|
||||||
return pipeline_layout;
|
return pipeline_layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkPipeline Resource_Manager::create_graphics_pipeline(const VkGraphicsPipelineCreateInfo& desc) {
|
|
||||||
VkPipeline pipeline;
|
|
||||||
VkResult result = vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &desc, nullptr, &pipeline);
|
|
||||||
check_vk_result(result, "vkCreateGraphicsPipelines");
|
|
||||||
graphics_pipelines.push_back(pipeline);
|
|
||||||
return pipeline;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -11,28 +11,18 @@ public:
|
||||||
VkSemaphore create_semaphore();
|
VkSemaphore create_semaphore();
|
||||||
VkDescriptorPool create_descriptor_pool(const VkDescriptorPoolCreateInfo& desc);
|
VkDescriptorPool create_descriptor_pool(const VkDescriptorPoolCreateInfo& desc);
|
||||||
VkBuffer create_buffer(const VkBufferCreateInfo& desc);
|
VkBuffer create_buffer(const VkBufferCreateInfo& desc);
|
||||||
VkImage create_image(const VkImageCreateInfo& desc);
|
|
||||||
VkImageView create_image_view(const VkImageViewCreateInfo& desc);
|
|
||||||
VkSampler create_sampler(const VkSamplerCreateInfo& desc);
|
VkSampler create_sampler(const VkSamplerCreateInfo& desc);
|
||||||
VkRenderPass create_render_pass(const VkRenderPassCreateInfo& desc);
|
|
||||||
VkFramebuffer create_framebuffer(const VkFramebufferCreateInfo& desc);
|
|
||||||
VkDescriptorSetLayout create_descriptor_set_layout(const VkDescriptorSetLayoutCreateInfo& desc);
|
VkDescriptorSetLayout create_descriptor_set_layout(const VkDescriptorSetLayoutCreateInfo& desc);
|
||||||
VkPipelineLayout create_pipeline_layout(const VkPipelineLayoutCreateInfo& desc);
|
VkPipelineLayout create_pipeline_layout(const VkPipelineLayoutCreateInfo& desc);
|
||||||
VkPipeline create_graphics_pipeline(const VkGraphicsPipelineCreateInfo& desc);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VkDevice device = VK_NULL_HANDLE;
|
VkDevice device = VK_NULL_HANDLE;
|
||||||
std::vector<VkSemaphore> semaphores;
|
std::vector<VkSemaphore> semaphores;
|
||||||
std::vector<VkDescriptorPool> descriptor_pools;
|
std::vector<VkDescriptorPool> descriptor_pools;
|
||||||
std::vector<VkBuffer> buffers;
|
std::vector<VkBuffer> buffers;
|
||||||
std::vector<VkImage> images;
|
|
||||||
std::vector<VkImageView> image_views;
|
|
||||||
std::vector<VkSampler> samplers;
|
std::vector<VkSampler> samplers;
|
||||||
std::vector<VkDescriptorSetLayout> descriptor_set_layouts;
|
std::vector<VkDescriptorSetLayout> descriptor_set_layouts;
|
||||||
std::vector<VkRenderPass> render_passes;
|
|
||||||
std::vector<VkFramebuffer> framebuffers;
|
|
||||||
std::vector<VkPipelineLayout> pipeline_layouts;
|
std::vector<VkPipelineLayout> pipeline_layouts;
|
||||||
std::vector<VkPipeline> graphics_pipelines;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Resource_Manager* get_resource_manager();
|
Resource_Manager* get_resource_manager();
|
||||||
|
|
|
||||||
|
|
@ -161,10 +161,12 @@ VkImage create_texture(int image_width, int image_height, VkFormat format) {
|
||||||
desc.pQueueFamilyIndices = nullptr;
|
desc.pQueueFamilyIndices = nullptr;
|
||||||
desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
|
||||||
VkImage image = get_resource_manager()->create_image(desc);
|
VkImage image;
|
||||||
|
VkResult result = vkCreateImage(vk_instance.device, &desc, nullptr, &image);
|
||||||
|
check_vk_result(result, "vkCreateImage");
|
||||||
|
|
||||||
VkDeviceMemory memory = get_allocator()->allocate_memory(image);
|
VkDeviceMemory memory = get_allocator()->allocate_memory(image);
|
||||||
VkResult result = vkBindImageMemory(vk_instance.device, image, memory, 0);
|
result = vkBindImageMemory(vk_instance.device, image, memory, 0);
|
||||||
check_vk_result(result, "vkBindImageMemory");
|
check_vk_result(result, "vkBindImageMemory");
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
@ -242,10 +244,12 @@ VkImage create_depth_attachment_image(int image_width, int image_height, VkForma
|
||||||
desc.pQueueFamilyIndices = nullptr;
|
desc.pQueueFamilyIndices = nullptr;
|
||||||
desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
|
||||||
VkImage image = get_resource_manager()->create_image(desc);
|
VkImage image;
|
||||||
|
VkResult result = vkCreateImage(vk_instance.device, &desc, nullptr, &image);
|
||||||
|
check_vk_result(result, "vkCreateImage");
|
||||||
|
|
||||||
VkDeviceMemory memory = get_allocator()->allocate_memory(image);
|
VkDeviceMemory memory = get_allocator()->allocate_memory(image);
|
||||||
VkResult result = vkBindImageMemory(vk_instance.device, image, memory, 0);
|
result = vkBindImageMemory(vk_instance.device, image, memory, 0);
|
||||||
check_vk_result(result, "vkBindImageMemory");
|
check_vk_result(result, "vkBindImageMemory");
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
@ -268,7 +272,10 @@ VkImageView create_image_view(VkImage image, VkFormat format, VkImageAspectFlags
|
||||||
desc.subresourceRange.baseArrayLayer = 0;
|
desc.subresourceRange.baseArrayLayer = 0;
|
||||||
desc.subresourceRange.layerCount = 1;
|
desc.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
return get_resource_manager()->create_image_view(desc);
|
VkImageView image_view;
|
||||||
|
VkResult result = vkCreateImageView(vk_instance.device, &desc, nullptr, &image_view);
|
||||||
|
check_vk_result(result, "vkCreateImageView");
|
||||||
|
return image_view;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkBuffer create_buffer(VkDeviceSize size, VkBufferUsageFlags usage) {
|
VkBuffer create_buffer(VkDeviceSize size, VkBufferUsageFlags usage) {
|
||||||
|
|
@ -290,34 +297,6 @@ VkBuffer create_buffer(VkDeviceSize size, VkBufferUsageFlags usage) {
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkBuffer create_staging_buffer(VkDeviceSize size, const void* data) {
|
|
||||||
VkBufferCreateInfo desc;
|
|
||||||
desc.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
|
||||||
desc.pNext = nullptr;
|
|
||||||
desc.flags = 0;
|
|
||||||
desc.size = size;
|
|
||||||
desc.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
|
||||||
desc.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
|
||||||
desc.queueFamilyIndexCount = 0;
|
|
||||||
desc.pQueueFamilyIndices = nullptr;
|
|
||||||
|
|
||||||
VkBuffer buffer;
|
|
||||||
VkResult result = vkCreateBuffer(vk_instance.device, &desc, nullptr, &buffer);
|
|
||||||
check_vk_result(result, "vkCreateBuffer");
|
|
||||||
|
|
||||||
get_allocator()->get_shared_staging_memory().ensure_allocation_for_object(buffer);
|
|
||||||
VkDeviceMemory memory = get_allocator()->get_shared_staging_memory().get_handle();
|
|
||||||
result = vkBindBufferMemory(vk_instance.device, buffer, memory, 0);
|
|
||||||
check_vk_result(result, "vkBindBufferMemory");
|
|
||||||
|
|
||||||
void* buffer_data;
|
|
||||||
result = vkMapMemory(vk_instance.device, memory, 0, size, 0, &buffer_data);
|
|
||||||
check_vk_result(result, "vkMapMemory");
|
|
||||||
memcpy(buffer_data, data, size);
|
|
||||||
vkUnmapMemory(vk_instance.device, memory);
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkBuffer create_permanent_staging_buffer(VkDeviceSize size, VkDeviceMemory& memory) {
|
VkBuffer create_permanent_staging_buffer(VkDeviceSize size, VkDeviceMemory& memory) {
|
||||||
VkBufferCreateInfo desc;
|
VkBufferCreateInfo desc;
|
||||||
desc.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
desc.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||||
|
|
|
||||||
|
|
@ -39,5 +39,4 @@ VkImageView create_image_view(VkImage image, VkFormat format, VkImageAspectFlags
|
||||||
|
|
||||||
// Buffers
|
// Buffers
|
||||||
VkBuffer create_buffer(VkDeviceSize size, VkBufferUsageFlags usage);
|
VkBuffer create_buffer(VkDeviceSize size, VkBufferUsageFlags usage);
|
||||||
VkBuffer create_staging_buffer(VkDeviceSize size, const void* data);
|
|
||||||
VkBuffer create_permanent_staging_buffer(VkDeviceSize size, VkDeviceMemory& memory);
|
VkBuffer create_permanent_staging_buffer(VkDeviceSize size, VkDeviceMemory& memory);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user