Cinematic images update.

This commit is contained in:
Artem Kharytoniuk 2017-03-27 17:20:21 +03:00
parent 35363cb05d
commit 54ab26edb3
6 changed files with 106 additions and 8 deletions

1
.gitignore vendored
View File

@ -7,3 +7,4 @@ bin/
config/visual-studio/.vs/
config/visual-studio/vk_layer_settings.txt
config/visual-studio/vk_report
config/visual-studio/*.log

View File

@ -739,8 +739,10 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *
// VULKAN
vkDestroyImage(get_device(), tr.scratchImage[client]->vk_image, nullptr);
vkDestroyImageView(get_device(), tr.scratchImage[client]->vk_image_view, nullptr);
tr.scratchImage[client]->vk_image = vulkan_demo->create_texture(data, 4, cols, rows, tr.scratchImage[client]->vk_image_view);
tr.scratchImage[client]->vk_image = vk_create_cinematic_image(cols, rows, tr.scratchImage[client]->vk_staging_buffer);
tr.scratchImage[client]->vk_image_view = create_image_view(tr.scratchImage[client]->vk_image, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT);
vulkan_demo->cinematic_image_view = tr.scratchImage[client]->vk_image_view;
vk_update_cinematic_image(tr.scratchImage[client]->vk_image, tr.scratchImage[client]->vk_staging_buffer, cols, rows, data);
} else {
if (dirty) {
// otherwise, just subimage upload it so that drivers can tell we are going to be changing
@ -748,10 +750,7 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *
qglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data );
// VULKAN
vkDestroyImage(get_device(), tr.scratchImage[client]->vk_image, nullptr);
vkDestroyImageView(get_device(), tr.scratchImage[client]->vk_image_view, nullptr);
tr.scratchImage[client]->vk_image = vulkan_demo->create_texture(data, 4, cols, rows, tr.scratchImage[client]->vk_image_view);
vulkan_demo->cinematic_image_view = tr.scratchImage[client]->vk_image_view;
vk_update_cinematic_image(tr.scratchImage[client]->vk_image, tr.scratchImage[client]->vk_staging_buffer, cols, rows, data);
}
}

View File

@ -110,6 +110,7 @@ typedef struct image_s {
// VULKAN
VkImage vk_image = VK_NULL_HANDLE;
VkImageView vk_image_view = VK_NULL_HANDLE;
Vk_Staging_Buffer vk_staging_buffer; // for cinematic images
struct image_s* next;
} image_t;

View File

@ -1,5 +1,8 @@
#include "vk.h"
#include "vk_utils.h"
#include "vk_allocator.h"
#include "tr_local.h"
#include "vk_demo.h"
#define SDL_MAIN_HANDLED
#include "sdl/SDL_syswm.h"
@ -331,3 +334,87 @@ VkFormat get_swapchain_image_format() {
const std::vector<VkImageView>& get_swapchain_image_views() {
return vulkan_globals.swapchain_image_views;
}
VkImage vk_create_cinematic_image(int width, int height, Vk_Staging_Buffer& staging_buffer) {
VkBufferCreateInfo buffer_desc;
buffer_desc.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
buffer_desc.pNext = nullptr;
buffer_desc.flags = 0;
buffer_desc.size = width * height * 4;
buffer_desc.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
buffer_desc.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
buffer_desc.queueFamilyIndexCount = 0;
buffer_desc.pQueueFamilyIndices = nullptr;
VkBuffer buffer;
VkResult result = vkCreateBuffer(get_device(), &buffer_desc, nullptr, &buffer);
check_vk_result(result, "vkCreateBuffer");
VkDeviceMemory buffer_memory = get_allocator()->allocate_staging_memory(buffer);
result = vkBindBufferMemory(get_device(), buffer, buffer_memory, 0);
check_vk_result(result, "vkBindBufferMemory");
VkImageCreateInfo image_desc;
image_desc.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
image_desc.pNext = nullptr;
image_desc.flags = 0;
image_desc.imageType = VK_IMAGE_TYPE_2D;
image_desc.format = VK_FORMAT_R8G8B8A8_UNORM;
image_desc.extent.width = width;
image_desc.extent.height = height;
image_desc.extent.depth = 1;
image_desc.mipLevels = 1;
image_desc.arrayLayers = 1;
image_desc.samples = VK_SAMPLE_COUNT_1_BIT;
image_desc.tiling = VK_IMAGE_TILING_OPTIMAL;
image_desc.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
image_desc.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
image_desc.queueFamilyIndexCount = 0;
image_desc.pQueueFamilyIndices = nullptr;
image_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
VkImage image;
result = vkCreateImage(get_device(), &image_desc, nullptr, &image);
check_vk_result(result, "vkCreateImage");
VkDeviceMemory image_memory = get_allocator()->allocate_memory(image);
result = vkBindImageMemory(get_device(), image, image_memory, 0);
check_vk_result(result, "vkBindImageMemory");
staging_buffer.handle = buffer;
staging_buffer.memory = buffer_memory;
staging_buffer.offset = 0;
staging_buffer.size = width * height * 4;
return image;
}
void vk_update_cinematic_image(VkImage image, const Vk_Staging_Buffer& staging_buffer, int width, int height, const uint8_t* rgba_pixels) {
void* buffer_data;
VkResult result = vkMapMemory(get_device(), staging_buffer.memory, staging_buffer.offset, staging_buffer.size, 0, &buffer_data);
check_vk_result(result, "vkMapMemory");
memcpy(buffer_data, rgba_pixels, staging_buffer.size);
vkUnmapMemory(get_device(), staging_buffer.memory);
record_and_run_commands(vulkan_demo->command_pool, get_queue(),
[&image, &staging_buffer, &width, &height](VkCommandBuffer command_buffer) {
record_image_layout_transition(command_buffer, image, VK_FORMAT_R8G8B8A8_UNORM,
0, VK_IMAGE_LAYOUT_UNDEFINED, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VkBufferImageCopy region;
region.bufferOffset = 0;
region.bufferRowLength = 0;
region.bufferImageHeight = 0;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageSubresource.mipLevel = 0;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1;
region.imageOffset = VkOffset3D{ 0, 0, 0 };
region.imageExtent = VkExtent3D{ (uint32_t)width, (uint32_t)height, 1 };
vkCmdCopyBufferToImage(command_buffer, staging_buffer.handle, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
record_image_layout_transition(command_buffer, image, VK_FORMAT_R8G8B8A8_UNORM,
VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
});
}

View File

@ -21,3 +21,13 @@ VkQueue get_queue();
VkSwapchainKHR get_swapchain();
VkFormat get_swapchain_image_format();
const std::vector<VkImageView>& get_swapchain_image_views();
struct Vk_Staging_Buffer {
VkBuffer handle = VK_NULL_HANDLE;
VkDeviceMemory memory = VK_NULL_HANDLE; // memory associated with a buffer
VkDeviceSize offset = -1;
VkDeviceSize size = 0;
};
VkImage vk_create_cinematic_image(int width, int height, Vk_Staging_Buffer& staging_buffer);
void vk_update_cinematic_image(VkImage image, const Vk_Staging_Buffer& staging_buffer, int width, int height, const uint8_t* rgba_pixels);

View File

@ -107,13 +107,13 @@ Vulkan_Demo::Vulkan_Demo(int window_width, int window_height, const SDL_SysWMinf
: window_width(window_width)
, window_height(window_height)
{
logfile = fopen("vk_dev.log", "w");
initialize_vulkan(window_sys_info);
get_allocator()->initialize(get_physical_device(), get_device());
get_resource_manager()->initialize(get_device());
create_command_pool();
logfile = fopen("debuglog.txt", "w");
image_acquired = get_resource_manager()->create_semaphore();
rendering_finished = get_resource_manager()->create_semaphore();
@ -204,7 +204,7 @@ VkImage Vulkan_Demo::create_texture(const uint8_t* pixels, int bytes_per_pixel,
Defer_Action destroy_staging_image([this, &staging_image]() {
vkDestroyImage(get_device(), staging_image, nullptr);
});
VkImage texture_image = ::create_texture(image_width, image_height,
bytes_per_pixel == 3 ? VK_FORMAT_R8G8B8_UNORM : VK_FORMAT_R8G8B8A8_UNORM);