Code reorganization and cleanup.
This commit is contained in:
parent
ee7cd1b5f4
commit
047be0bd46
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -8,5 +8,7 @@ config/visual-studio/.vs/
|
||||||
config/visual-studio/vk_layer_settings.txt
|
config/visual-studio/vk_layer_settings.txt
|
||||||
config/visual-studio/vk_report
|
config/visual-studio/vk_report
|
||||||
config/visual-studio/*.log
|
config/visual-studio/*.log
|
||||||
|
config/visual-studio/*.psess
|
||||||
|
config/visual-studio/*.vspx
|
||||||
tools/bin2hex.exe
|
tools/bin2hex.exe
|
||||||
tools/bin2hex.obj
|
tools/bin2hex.obj
|
||||||
|
|
|
||||||
|
|
@ -943,9 +943,9 @@ const void *RB_DrawBuffer( const void *data ) {
|
||||||
begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||||
begin_info.pInheritanceInfo = nullptr;
|
begin_info.pInheritanceInfo = nullptr;
|
||||||
|
|
||||||
extern FILE* logfile;
|
extern FILE* vk_log_file;
|
||||||
fprintf(logfile, "begin\n");
|
if (r_logFile->integer)
|
||||||
fflush(logfile);
|
fprintf(vk_log_file, "begin\n");
|
||||||
|
|
||||||
result = vkBeginCommandBuffer(vk.command_buffer, &begin_info);
|
result = vkBeginCommandBuffer(vk.command_buffer, &begin_info);
|
||||||
check_vk_result(result, "vkBeginCommandBuffer");
|
check_vk_result(result, "vkBeginCommandBuffer");
|
||||||
|
|
@ -1061,14 +1061,14 @@ const void *RB_SwapBuffers( const void *data ) {
|
||||||
backEnd.projection2D = qfalse;
|
backEnd.projection2D = qfalse;
|
||||||
|
|
||||||
// VULKAN
|
// VULKAN
|
||||||
extern FILE* logfile;
|
extern FILE* vk_log_file;
|
||||||
|
|
||||||
vulkan_demo->end_frame();
|
vulkan_demo->end_frame();
|
||||||
VkResult result = vkEndCommandBuffer(vk.command_buffer);
|
VkResult result = vkEndCommandBuffer(vk.command_buffer);
|
||||||
check_vk_result(result, "vkEndCommandBuffer");
|
check_vk_result(result, "vkEndCommandBuffer");
|
||||||
|
|
||||||
fprintf(logfile, "present\n");
|
if (r_logFile->integer)
|
||||||
fflush(logfile);
|
fprintf(vk_log_file, "present\n");
|
||||||
|
|
||||||
VkPipelineStageFlags wait_dst_stage_mask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
VkPipelineStageFlags wait_dst_stage_mask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
VkSubmitInfo submit_info;
|
VkSubmitInfo submit_info;
|
||||||
|
|
|
||||||
|
|
@ -838,7 +838,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
||||||
}
|
}
|
||||||
|
|
||||||
// VULKAN
|
// VULKAN
|
||||||
vulkan_demo->render_tess(pStage->vk_pipeline, multitexture);
|
vk_draw(pStage->vk_pipeline, multitexture);
|
||||||
|
|
||||||
// allow skipping out to show just lightmaps during development
|
// allow skipping out to show just lightmaps during development
|
||||||
if ( r_lightmap->integer && ( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap ) )
|
if ( r_lightmap->integer && ( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap ) )
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,9 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
static const int VERTEX_BUFFER_SIZE = 4 * 1024 * 1024;
|
||||||
|
static const int INDEX_BUFFER_SIZE = 2 * 1024 * 1024;
|
||||||
|
|
||||||
static const std::vector<const char*> instance_extensions = {
|
static const std::vector<const char*> instance_extensions = {
|
||||||
VK_KHR_SURFACE_EXTENSION_NAME,
|
VK_KHR_SURFACE_EXTENSION_NAME,
|
||||||
VK_KHR_WIN32_SURFACE_EXTENSION_NAME
|
VK_KHR_WIN32_SURFACE_EXTENSION_NAME
|
||||||
|
|
@ -487,6 +490,46 @@ bool vk_initialize(HWND hwnd) {
|
||||||
check_vk_result(result, "vkCreatePipelineLayout");
|
check_vk_result(result, "vkCreatePipelineLayout");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create geometry buffers.
|
||||||
|
//
|
||||||
|
{
|
||||||
|
VkBufferCreateInfo desc;
|
||||||
|
desc.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||||
|
desc.pNext = nullptr;
|
||||||
|
desc.flags = 0;
|
||||||
|
desc.size = VERTEX_BUFFER_SIZE;
|
||||||
|
desc.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
|
||||||
|
desc.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
desc.queueFamilyIndexCount = 0;
|
||||||
|
desc.pQueueFamilyIndices = nullptr;
|
||||||
|
|
||||||
|
VkResult result = vkCreateBuffer(vk.device, &desc, nullptr, &vk.vertex_buffer);
|
||||||
|
check_vk_result(result, "vkCreateBuffer");
|
||||||
|
|
||||||
|
vk.vertex_buffer_memory = get_allocator()->allocate_staging_memory(vk.vertex_buffer);
|
||||||
|
result = vkBindBufferMemory(vk.device, vk.vertex_buffer, vk.vertex_buffer_memory, 0);
|
||||||
|
check_vk_result(result, "vkBindBufferMemory");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
VkBufferCreateInfo desc;
|
||||||
|
desc.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||||
|
desc.pNext = nullptr;
|
||||||
|
desc.flags = 0;
|
||||||
|
desc.size = INDEX_BUFFER_SIZE;
|
||||||
|
desc.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
|
||||||
|
desc.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
desc.queueFamilyIndexCount = 0;
|
||||||
|
desc.pQueueFamilyIndices = nullptr;
|
||||||
|
|
||||||
|
VkResult result = vkCreateBuffer(vk.device, &desc, nullptr, &vk.index_buffer);
|
||||||
|
check_vk_result(result, "vkCreateBuffer");
|
||||||
|
|
||||||
|
vk.index_buffer_memory = get_allocator()->allocate_staging_memory(vk.index_buffer);
|
||||||
|
result = vkBindBufferMemory(vk.device, vk.index_buffer, vk.index_buffer_memory, 0);
|
||||||
|
check_vk_result(result, "vkBindBufferMemory");
|
||||||
|
}
|
||||||
|
|
||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -518,6 +561,8 @@ void vk_deinitialize() {
|
||||||
vkDestroyDescriptorPool(vk.device, vk.descriptor_pool, nullptr);
|
vkDestroyDescriptorPool(vk.device, vk.descriptor_pool, nullptr);
|
||||||
vkDestroyDescriptorSetLayout(vk.device, vk.set_layout, nullptr);
|
vkDestroyDescriptorSetLayout(vk.device, vk.set_layout, nullptr);
|
||||||
vkDestroyPipelineLayout(vk.device, vk.pipeline_layout, nullptr);
|
vkDestroyPipelineLayout(vk.device, vk.pipeline_layout, nullptr);
|
||||||
|
vkDestroyBuffer(vk.device, vk.vertex_buffer, nullptr);
|
||||||
|
vkDestroyBuffer(vk.device, vk.index_buffer, nullptr);
|
||||||
|
|
||||||
vkDestroySwapchainKHR(g.device, g.swapchain, nullptr);
|
vkDestroySwapchainKHR(g.device, g.swapchain, nullptr);
|
||||||
vkDestroyDevice(g.device, nullptr);
|
vkDestroyDevice(g.device, nullptr);
|
||||||
|
|
@ -886,12 +931,12 @@ static float pipeline_create_time;
|
||||||
|
|
||||||
struct Timer {
|
struct Timer {
|
||||||
using Clock = std::chrono::high_resolution_clock;
|
using Clock = std::chrono::high_resolution_clock;
|
||||||
using Second = std::chrono::duration<float, std::ratio<1>>;
|
using Second = std::chrono::duration<double, std::ratio<1>>;
|
||||||
|
|
||||||
Clock::time_point start = Clock::now();
|
Clock::time_point start = Clock::now();
|
||||||
float Elapsed_Seconds() const {
|
double Elapsed_Seconds() const {
|
||||||
const auto duration = Clock::now() - start;
|
const auto duration = Clock::now() - start;
|
||||||
float seconds = std::chrono::duration_cast<Second>(duration).count();
|
double seconds = std::chrono::duration_cast<Second>(duration).count();
|
||||||
return seconds;
|
return seconds;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -965,6 +1010,9 @@ VkDescriptorSet vk_create_descriptor_set(VkImageView image_view) {
|
||||||
void vk_destroy_resources() {
|
void vk_destroy_resources() {
|
||||||
vkDeviceWaitIdle(vk.device);
|
vkDeviceWaitIdle(vk.device);
|
||||||
vk_destroy_pipelines();
|
vk_destroy_pipelines();
|
||||||
|
|
||||||
|
vk.vertex_buffer_offset = 0;
|
||||||
|
vk.index_buffer_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkRect2D vk_get_viewport_rect() {
|
VkRect2D vk_get_viewport_rect() {
|
||||||
|
|
@ -1026,3 +1074,95 @@ void vk_get_mvp_transform(float mvp[16]) {
|
||||||
myGlMultMatrix(backEnd.or.modelMatrix, proj, mvp);
|
myGlMultMatrix(backEnd.or.modelMatrix, proj, mvp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vk_draw(VkPipeline pipeline, bool multitexture) {
|
||||||
|
extern FILE* vk_log_file;
|
||||||
|
if (r_logFile->integer)
|
||||||
|
fprintf(vk_log_file, "render_tess (%s, vert %d, inds %d)\n", multitexture ? "M" : "S", tess.numVertexes, tess.numIndexes);
|
||||||
|
|
||||||
|
auto vertex_size = multitexture ? sizeof(Vk_Vertex2) : sizeof(Vk_Vertex);
|
||||||
|
|
||||||
|
// update vertex buffer
|
||||||
|
std::size_t vertexes_size = tess.numVertexes * vertex_size;
|
||||||
|
if (vk.vertex_buffer_offset + vertexes_size > VERTEX_BUFFER_SIZE)
|
||||||
|
ri.Error(ERR_DROP, "vk_draw: vertex buffer overflow\n");
|
||||||
|
|
||||||
|
void* data;
|
||||||
|
VkResult result = vkMapMemory(vk.device, vk.vertex_buffer_memory, vk.vertex_buffer_offset, vertexes_size, 0, &data);
|
||||||
|
check_vk_result(result, "vkMapMemory");
|
||||||
|
Timer t;
|
||||||
|
unsigned char* ptr = (unsigned char*)data;
|
||||||
|
for (int i = 0; i < tess.numVertexes; i++, ptr += vertex_size) {
|
||||||
|
Vk_Vertex* v = (Vk_Vertex*)ptr;
|
||||||
|
v->pos[0] = tess.xyz[i][0];
|
||||||
|
v->pos[1] = tess.xyz[i][1];
|
||||||
|
v->pos[2] = tess.xyz[i][2];
|
||||||
|
v->color[0] = tess.svars.colors[i][0];
|
||||||
|
v->color[1] = tess.svars.colors[i][1];
|
||||||
|
v->color[2] = tess.svars.colors[i][2];
|
||||||
|
v->color[3] = tess.svars.colors[i][3];
|
||||||
|
v->st[0] = tess.svars.texcoords[0][i][0];
|
||||||
|
v->st[1] = tess.svars.texcoords[0][i][1];
|
||||||
|
|
||||||
|
if (multitexture) {
|
||||||
|
auto v2 = (Vk_Vertex2*)ptr;
|
||||||
|
v2->st2[0] = tess.svars.texcoords[1][i][0];
|
||||||
|
v2->st2[1] = tess.svars.texcoords[1][i][1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vulkan_demo->vertex_copy_time += t.Elapsed_Seconds();
|
||||||
|
vkUnmapMemory(vk.device, vk.vertex_buffer_memory);
|
||||||
|
|
||||||
|
vkCmdBindVertexBuffers(vk.command_buffer, 0, 1, &vk.vertex_buffer, &vk.vertex_buffer_offset);
|
||||||
|
vk.vertex_buffer_offset += vertexes_size;
|
||||||
|
|
||||||
|
// update index buffer
|
||||||
|
std::size_t indexes_size = tess.numIndexes * sizeof(uint32_t);
|
||||||
|
if (vk.index_buffer_offset + indexes_size > INDEX_BUFFER_SIZE)
|
||||||
|
ri.Error(ERR_DROP, "vk_draw: index buffer overflow\n");
|
||||||
|
|
||||||
|
result = vkMapMemory(vk.device, vk.index_buffer_memory, vk.index_buffer_offset, indexes_size, 0, &data);
|
||||||
|
check_vk_result(result, "vkMapMemory");
|
||||||
|
uint32_t* ind = (uint32_t*)data;
|
||||||
|
for (int i = 0; i < tess.numIndexes; i++, ind++) {
|
||||||
|
*ind = tess.indexes[i];
|
||||||
|
}
|
||||||
|
vkUnmapMemory(vk.device, vk.index_buffer_memory);
|
||||||
|
|
||||||
|
vkCmdBindIndexBuffer(vk.command_buffer, vk.index_buffer, vk.index_buffer_offset, VK_INDEX_TYPE_UINT32);
|
||||||
|
vk.index_buffer_offset += indexes_size;
|
||||||
|
|
||||||
|
// update mvp transform
|
||||||
|
float mvp[16];
|
||||||
|
vk_get_mvp_transform(mvp);
|
||||||
|
vkCmdPushConstants(vk.command_buffer, vk.pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0, 64, mvp);
|
||||||
|
|
||||||
|
image_t* image = glState.vk_current_images[0];
|
||||||
|
image_t* image2 = glState.vk_current_images[1];
|
||||||
|
VkDescriptorSet sets[2] = { image->vk_descriptor_set, image2 ? image2->vk_descriptor_set : VkDescriptorSet() };
|
||||||
|
int set_count = multitexture ? 2 : 1;
|
||||||
|
vkCmdBindDescriptorSets(vk.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk.pipeline_layout, 0, set_count, sets, 0, nullptr);
|
||||||
|
|
||||||
|
vkCmdBindPipeline(vk.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||||
|
|
||||||
|
VkRect2D r = vk_get_viewport_rect();
|
||||||
|
vkCmdSetScissor(vk.command_buffer, 0, 1, &r);
|
||||||
|
|
||||||
|
VkViewport viewport;
|
||||||
|
viewport.x = (float)r.offset.x;
|
||||||
|
viewport.y = (float)r.offset.y;
|
||||||
|
viewport.width = (float)r.extent.width;
|
||||||
|
viewport.height = (float)r.extent.height;
|
||||||
|
viewport.minDepth = 0.0f;
|
||||||
|
viewport.maxDepth = 1.0f;
|
||||||
|
vkCmdSetViewport(vk.command_buffer, 0, 1, &viewport);
|
||||||
|
|
||||||
|
if (tess.shader->polygonOffset) {
|
||||||
|
vkCmdSetDepthBias(vk.command_buffer, r_offsetUnits->value, 0.0f, r_offsetFactor->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw primitives
|
||||||
|
vkCmdDrawIndexed(vk.command_buffer, tess.numIndexes, 1, 0, 0, 0);
|
||||||
|
|
||||||
|
glState.vk_dirty_attachments = true;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ void vk_destroy_resources();
|
||||||
VkRect2D vk_get_viewport_rect();
|
VkRect2D vk_get_viewport_rect();
|
||||||
void vk_get_mvp_transform(float mvp[16]);
|
void vk_get_mvp_transform(float mvp[16]);
|
||||||
|
|
||||||
|
void vk_draw(VkPipeline pipeline, bool multitexture);
|
||||||
|
|
||||||
struct Vk_Staging_Buffer {
|
struct Vk_Staging_Buffer {
|
||||||
VkBuffer handle = VK_NULL_HANDLE;
|
VkBuffer handle = VK_NULL_HANDLE;
|
||||||
VkDeviceMemory memory = VK_NULL_HANDLE; // memory associated with a buffer
|
VkDeviceMemory memory = VK_NULL_HANDLE; // memory associated with a buffer
|
||||||
|
|
@ -165,6 +167,14 @@ struct Vulkan_Instance {
|
||||||
VkDescriptorPool descriptor_pool = VK_NULL_HANDLE;
|
VkDescriptorPool descriptor_pool = VK_NULL_HANDLE;
|
||||||
VkDescriptorSetLayout set_layout = VK_NULL_HANDLE;
|
VkDescriptorSetLayout set_layout = VK_NULL_HANDLE;
|
||||||
VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
|
VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
VkBuffer vertex_buffer = VK_NULL_HANDLE;
|
||||||
|
VkDeviceMemory vertex_buffer_memory = VK_NULL_HANDLE;
|
||||||
|
VkDeviceSize vertex_buffer_offset = 0;
|
||||||
|
|
||||||
|
VkBuffer index_buffer = VK_NULL_HANDLE;
|
||||||
|
VkDeviceMemory index_buffer_memory = VK_NULL_HANDLE;
|
||||||
|
VkDeviceSize index_buffer_offset = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
const int MAX_VK_PIPELINES = 1024;
|
const int MAX_VK_PIPELINES = 1024;
|
||||||
|
|
|
||||||
|
|
@ -14,13 +14,13 @@
|
||||||
|
|
||||||
#include "tr_local.h"
|
#include "tr_local.h"
|
||||||
|
|
||||||
FILE* logfile;
|
FILE* vk_log_file;
|
||||||
|
|
||||||
Vulkan_Demo::Vulkan_Demo(int window_width, int window_height)
|
Vulkan_Demo::Vulkan_Demo(int window_width, int window_height)
|
||||||
: window_width(window_width)
|
: window_width(window_width)
|
||||||
, window_height(window_height)
|
, window_height(window_height)
|
||||||
{
|
{
|
||||||
logfile = fopen("vk_dev.log", "w");
|
vk_log_file = fopen("vk_dev.log", "w");
|
||||||
|
|
||||||
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();
|
||||||
|
|
@ -33,8 +33,6 @@ Vulkan_Demo::Vulkan_Demo(int window_width, int window_height)
|
||||||
check_vk_result(result, "vkCreateFence");
|
check_vk_result(result, "vkCreateFence");
|
||||||
|
|
||||||
create_texture_sampler();
|
create_texture_sampler();
|
||||||
|
|
||||||
upload_geometry();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VkImage Vulkan_Demo::create_texture(const uint8_t* pixels, int bytes_per_pixel, int image_width, int image_height, VkImageView& image_view) {
|
VkImage Vulkan_Demo::create_texture(const uint8_t* pixels, int bytes_per_pixel, int image_width, int image_height, VkImageView& image_view) {
|
||||||
|
|
@ -110,46 +108,9 @@ 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::upload_geometry() {
|
|
||||||
|
|
||||||
{
|
|
||||||
VkBufferCreateInfo desc;
|
|
||||||
desc.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
|
||||||
desc.pNext = nullptr;
|
|
||||||
desc.flags = 0;
|
|
||||||
desc.size = 16 * 1024 * 1024;
|
|
||||||
desc.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
|
|
||||||
desc.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
|
||||||
desc.queueFamilyIndexCount = 0;
|
|
||||||
desc.pQueueFamilyIndices = nullptr;
|
|
||||||
|
|
||||||
tess_vertex_buffer = get_resource_manager()->create_buffer(desc);
|
|
||||||
tess_vertex_buffer_memory = get_allocator()->allocate_staging_memory(tess_vertex_buffer);
|
|
||||||
VkResult result = vkBindBufferMemory(vk.device, tess_vertex_buffer, tess_vertex_buffer_memory, 0);
|
|
||||||
check_vk_result(result, "vkBindBufferMemory");
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
VkBufferCreateInfo desc;
|
|
||||||
desc.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
|
||||||
desc.pNext = nullptr;
|
|
||||||
desc.flags = 0;
|
|
||||||
desc.size = 16 * 1024 * 1024;
|
|
||||||
desc.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
|
|
||||||
desc.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
|
||||||
desc.queueFamilyIndexCount = 0;
|
|
||||||
desc.pQueueFamilyIndices = nullptr;
|
|
||||||
|
|
||||||
tess_index_buffer = get_resource_manager()->create_buffer(desc);
|
|
||||||
tess_index_buffer_memory = get_allocator()->allocate_staging_memory(tess_index_buffer);
|
|
||||||
VkResult result = vkBindBufferMemory(vk.device, tess_index_buffer, tess_index_buffer_memory, 0);
|
|
||||||
check_vk_result(result, "vkBindBufferMemory");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Vulkan_Demo::begin_frame() {
|
void Vulkan_Demo::begin_frame() {
|
||||||
fprintf(logfile, "begin_frame\n");
|
if (r_logFile->integer)
|
||||||
fflush(logfile);
|
fprintf(vk_log_file, "begin_frame\n");
|
||||||
|
|
||||||
std::array<VkClearValue, 2> clear_values;
|
std::array<VkClearValue, 2> clear_values;
|
||||||
clear_values[0].color = {1.0f, 0.3f, 0.3f, 0.0f};
|
clear_values[0].color = {1.0f, 0.3f, 0.3f, 0.0f};
|
||||||
|
|
@ -167,91 +128,15 @@ void Vulkan_Demo::begin_frame() {
|
||||||
|
|
||||||
vkCmdBeginRenderPass(vk.command_buffer, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE);
|
vkCmdBeginRenderPass(vk.command_buffer, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
|
|
||||||
tess_vertex_buffer_offset = 0;
|
vk.vertex_buffer_offset = 0;
|
||||||
tess_index_buffer_offset = 0;
|
vk.index_buffer_offset = 0;
|
||||||
|
|
||||||
glState.vk_dirty_attachments = false;
|
glState.vk_dirty_attachments = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vulkan_Demo::end_frame() {
|
void Vulkan_Demo::end_frame() {
|
||||||
fprintf(logfile, "end_frame (vb_size %d, ib_size %d)\n", (int)tess_vertex_buffer_offset, (int)tess_index_buffer_offset);
|
if (r_logFile->integer)
|
||||||
fflush(logfile);
|
fprintf(vk_log_file, "end_frame (vb_size %d, ib_size %d, copy_time %d)\n", (int)vk.vertex_buffer_offset, (int)vk.index_buffer_offset, int(vertex_copy_time * 1000000000));
|
||||||
|
vertex_copy_time = 0.0f;
|
||||||
vkCmdEndRenderPass(vk.command_buffer);
|
vkCmdEndRenderPass(vk.command_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vulkan_Demo::render_tess(VkPipeline pipeline, bool multitexture) {
|
|
||||||
fprintf(logfile, "render_tess (%s, vert %d, inds %d)\n", multitexture ? "M" : "S", tess.numVertexes, tess.numIndexes);
|
|
||||||
fflush(logfile);
|
|
||||||
|
|
||||||
auto vertex_size = multitexture ? sizeof(Vk_Vertex2) : sizeof(Vk_Vertex);
|
|
||||||
|
|
||||||
void* data;
|
|
||||||
VkResult result = vkMapMemory(vk.device, tess_vertex_buffer_memory, tess_vertex_buffer_offset, tess.numVertexes * vertex_size, 0, &data);
|
|
||||||
check_vk_result(result, "vkMapMemory");
|
|
||||||
|
|
||||||
unsigned char* ptr = (unsigned char*)data;
|
|
||||||
for (int i = 0; i < tess.numVertexes; i++, ptr += vertex_size) {
|
|
||||||
Vk_Vertex* v = (Vk_Vertex*)ptr;
|
|
||||||
v->pos[0] = tess.xyz[i][0];
|
|
||||||
v->pos[1] = tess.xyz[i][1];
|
|
||||||
v->pos[2] = tess.xyz[i][2];
|
|
||||||
v->color[0] = tess.svars.colors[i][0];
|
|
||||||
v->color[1] = tess.svars.colors[i][1];
|
|
||||||
v->color[2] = tess.svars.colors[i][2];
|
|
||||||
v->color[3] = tess.svars.colors[i][3];
|
|
||||||
v->st[0] = tess.svars.texcoords[0][i][0];
|
|
||||||
v->st[1] = tess.svars.texcoords[0][i][1];
|
|
||||||
|
|
||||||
if (multitexture) {
|
|
||||||
auto v2 = (Vk_Vertex2*)ptr;
|
|
||||||
v2->st2[0] = tess.svars.texcoords[1][i][0];
|
|
||||||
v2->st2[1] = tess.svars.texcoords[1][i][1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vkUnmapMemory(vk.device, tess_vertex_buffer_memory);
|
|
||||||
|
|
||||||
result = vkMapMemory(vk.device, tess_index_buffer_memory, tess_index_buffer_offset, tess.numIndexes * sizeof(uint32_t), 0, &data);
|
|
||||||
check_vk_result(result, "vkMapMemory");
|
|
||||||
uint32_t* ind = (uint32_t*)data;
|
|
||||||
for (int i = 0; i < tess.numIndexes; i++, ind++) {
|
|
||||||
*ind = tess.indexes[i];
|
|
||||||
}
|
|
||||||
vkUnmapMemory(vk.device, tess_index_buffer_memory);
|
|
||||||
|
|
||||||
vkCmdBindVertexBuffers(vk.command_buffer, 0, 1, &tess_vertex_buffer, &tess_vertex_buffer_offset);
|
|
||||||
vkCmdBindIndexBuffer(vk.command_buffer, tess_index_buffer, tess_index_buffer_offset, VK_INDEX_TYPE_UINT32);
|
|
||||||
|
|
||||||
float mvp[16];
|
|
||||||
vk_get_mvp_transform(mvp);
|
|
||||||
vkCmdPushConstants(vk.command_buffer, vk.pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0, 64, mvp);
|
|
||||||
|
|
||||||
image_t* image = glState.vk_current_images[0];
|
|
||||||
image_t* image2 = glState.vk_current_images[1];
|
|
||||||
VkDescriptorSet sets[2] = { image->vk_descriptor_set, image2 ? image2->vk_descriptor_set : VkDescriptorSet() };
|
|
||||||
int set_count = multitexture ? 2 : 1;
|
|
||||||
vkCmdBindDescriptorSets(vk.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk.pipeline_layout, 0, set_count, sets, 0, nullptr);
|
|
||||||
|
|
||||||
vkCmdBindPipeline(vk.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
|
||||||
|
|
||||||
VkRect2D r = vk_get_viewport_rect();
|
|
||||||
vkCmdSetScissor(vk.command_buffer, 0, 1, &r);
|
|
||||||
|
|
||||||
VkViewport viewport;
|
|
||||||
viewport.x = (float)r.offset.x;
|
|
||||||
viewport.y = (float)r.offset.y;
|
|
||||||
viewport.width = (float)r.extent.width;
|
|
||||||
viewport.height = (float)r.extent.height;
|
|
||||||
viewport.minDepth = 0.0f;
|
|
||||||
viewport.maxDepth = 1.0f;
|
|
||||||
vkCmdSetViewport(vk.command_buffer, 0, 1, &viewport);
|
|
||||||
|
|
||||||
if (tess.shader->polygonOffset) {
|
|
||||||
vkCmdSetDepthBias(vk.command_buffer, r_offsetUnits->value, 0.0f, r_offsetFactor->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
vkCmdDrawIndexed(vk.command_buffer, tess.numIndexes, 1, 0, 0, 0);
|
|
||||||
tess_vertex_buffer_offset += tess.numVertexes * vertex_size;
|
|
||||||
tess_index_buffer_offset += tess.numIndexes * sizeof(uint32_t);
|
|
||||||
|
|
||||||
glState.vk_dirty_attachments = true;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -14,14 +14,11 @@ public:
|
||||||
|
|
||||||
void begin_frame();
|
void begin_frame();
|
||||||
void end_frame();
|
void end_frame();
|
||||||
void render_tess(VkPipeline pipeline, bool multitexture);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
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 upload_geometry();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const int window_width = 0;
|
const int window_width = 0;
|
||||||
const int window_height = 0;
|
const int window_height = 0;
|
||||||
|
|
@ -32,11 +29,6 @@ public:
|
||||||
|
|
||||||
VkSampler texture_image_sampler = VK_NULL_HANDLE;
|
VkSampler texture_image_sampler = VK_NULL_HANDLE;
|
||||||
|
|
||||||
VkBuffer tess_vertex_buffer = VK_NULL_HANDLE;
|
|
||||||
VkDeviceMemory tess_vertex_buffer_memory = VK_NULL_HANDLE;
|
|
||||||
VkDeviceSize tess_vertex_buffer_offset = 0;
|
|
||||||
VkBuffer tess_index_buffer = VK_NULL_HANDLE;
|
|
||||||
VkDeviceMemory tess_index_buffer_memory = VK_NULL_HANDLE;
|
|
||||||
VkDeviceSize tess_index_buffer_offset = 0;
|
|
||||||
uint32_t swapchain_image_index = -1;
|
uint32_t swapchain_image_index = -1;
|
||||||
|
double vertex_copy_time = 0.0f;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,6 @@ void Resource_Manager::release_resources() {
|
||||||
}
|
}
|
||||||
semaphores.clear();
|
semaphores.clear();
|
||||||
|
|
||||||
for (auto buffer : buffers) {
|
|
||||||
vkDestroyBuffer(device, buffer, nullptr);
|
|
||||||
}
|
|
||||||
buffers.clear();
|
|
||||||
|
|
||||||
for (auto sampler : samplers) {
|
for (auto sampler : samplers) {
|
||||||
vkDestroySampler(device, sampler, nullptr);
|
vkDestroySampler(device, sampler, nullptr);
|
||||||
}
|
}
|
||||||
|
|
@ -40,14 +35,6 @@ VkSemaphore Resource_Manager::create_semaphore() {
|
||||||
return semaphore;
|
return semaphore;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkBuffer Resource_Manager::create_buffer(const VkBufferCreateInfo& desc) {
|
|
||||||
VkBuffer buffer;
|
|
||||||
VkResult result = vkCreateBuffer(device, &desc, nullptr, &buffer);
|
|
||||||
check_vk_result(result, "vkCreateBuffer");
|
|
||||||
buffers.push_back(buffer);
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,11 @@ public:
|
||||||
void release_resources();
|
void release_resources();
|
||||||
|
|
||||||
VkSemaphore create_semaphore();
|
VkSemaphore create_semaphore();
|
||||||
VkBuffer create_buffer(const VkBufferCreateInfo& desc);
|
|
||||||
VkSampler create_sampler(const VkSamplerCreateInfo& desc);
|
VkSampler create_sampler(const VkSamplerCreateInfo& desc);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VkDevice device = VK_NULL_HANDLE;
|
VkDevice device = VK_NULL_HANDLE;
|
||||||
std::vector<VkSemaphore> semaphores;
|
std::vector<VkSemaphore> semaphores;
|
||||||
std::vector<VkBuffer> buffers;
|
|
||||||
std::vector<VkSampler> samplers;
|
std::vector<VkSampler> samplers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@
|
||||||
|
|
||||||
#include "tr_local.h"
|
#include "tr_local.h"
|
||||||
|
|
||||||
void check_vk_result(VkResult result, const std::string& functionName) {
|
void check_vk_result(VkResult result, const char* functionName) {
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
error(functionName + " has returned error code with value " + std::to_string(result));
|
error(functionName + std::string(" has returned error code with value ") + std::to_string(result));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -277,22 +277,3 @@ VkImageView create_image_view(VkImage image, VkFormat format, VkImageAspectFlags
|
||||||
check_vk_result(result, "vkCreateImageView");
|
check_vk_result(result, "vkCreateImageView");
|
||||||
return image_view;
|
return image_view;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkBuffer create_buffer(VkDeviceSize size, VkBufferUsageFlags usage) {
|
|
||||||
VkBufferCreateInfo desc;
|
|
||||||
desc.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
|
||||||
desc.pNext = nullptr;
|
|
||||||
desc.flags = 0;
|
|
||||||
desc.size = size;
|
|
||||||
desc.usage = usage;
|
|
||||||
desc.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
|
||||||
desc.queueFamilyIndexCount = 0;
|
|
||||||
desc.pQueueFamilyIndices = nullptr;
|
|
||||||
|
|
||||||
VkBuffer buffer = get_resource_manager()->create_buffer(desc);
|
|
||||||
|
|
||||||
VkDeviceMemory memory = get_allocator()->allocate_memory(buffer);
|
|
||||||
VkResult result = vkBindBufferMemory(vk.device, buffer, memory, 0);
|
|
||||||
check_vk_result(result, "vkBindBufferMemory");
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ struct Shader_Module {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Errors
|
// Errors
|
||||||
void check_vk_result(VkResult result, const std::string& function_name);
|
void check_vk_result(VkResult result, const char* function_name);
|
||||||
void error(const std::string& message);
|
void error(const std::string& message);
|
||||||
|
|
||||||
// Command buffers
|
// Command buffers
|
||||||
|
|
@ -36,6 +36,3 @@ VkImage create_texture(int image_width, int image_height, VkFormat format);
|
||||||
VkImage create_staging_texture(int image_width, int image_height, VkFormat format, const uint8_t* pixels, int bytes_per_pixel);
|
VkImage create_staging_texture(int image_width, int image_height, VkFormat format, const uint8_t* pixels, int bytes_per_pixel);
|
||||||
VkImage create_depth_attachment_image(int image_width, int image_height, VkFormat format);
|
VkImage create_depth_attachment_image(int image_width, int image_height, VkFormat format);
|
||||||
VkImageView create_image_view(VkImage image, VkFormat format, VkImageAspectFlags aspect_flags);
|
VkImageView create_image_view(VkImage image, VkFormat format, VkImageAspectFlags aspect_flags);
|
||||||
|
|
||||||
// Buffers
|
|
||||||
VkBuffer create_buffer(VkDeviceSize size, VkBufferUsageFlags usage);
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user