Created HexContext, and initial hex region shader

main
noah metz 2024-11-01 15:46:27 -06:00
parent 07b0a46dfc
commit 5b1275ea83
7 changed files with 169 additions and 58 deletions

@ -3,12 +3,12 @@
#include "gpu.h" #include "gpu.h"
#include "ui.h" #include "ui.h"
#include "hex.h"
VkResult draw_frame( VkResult draw_frame(
RenderContext* context, RenderContext* context,
UIContext* ui, UIContext* ui,
GraphicsPipeline* hex_graphics, HexContext* hex,
VkDeviceAddress world,
double time); double time);
#endif #endif

@ -3,20 +3,59 @@
#include "gpu.h" #include "gpu.h"
typedef struct GPUHexContextStruct { #define REGION_SIZE 6
mat4 proj; #define REGION_HEX_COUNT 3*REGION_SIZE*(REGION_SIZE-1)+1
mat4 view;
} GPUHexContext;
typedef struct HexPushConstantStruct { typedef struct HexPushConstantStruct {
VkDeviceAddress context; VkDeviceAddress context;
double time; double time;
} HexPushConstant; } HexPushConstant;
VkResult create_hex_pipeline( typedef struct GPUHexContextStruct {
VkDevice device, mat4 proj;
VkRenderPass render_pass, mat4 view;
GraphicsPipeline* graphics, VkDeviceAddress regions;
ComputePipeline* compute); } GPUHexContext;
typedef struct HexContextStruct {
VkDeviceAddress address;
VkBuffer context;
VmaAllocation context_memory;
GraphicsPipeline graphics;
ComputePipeline compute;
GPUHexContext data;
} HexContext;
typedef struct GPUHexStruct {
float height[6];
uint32_t color[6];
} GPUHex;
typedef struct GPUHexRegionStruct {
uint32_t x;
uint32_t y;
GPUHex hexes[REGION_HEX_COUNT];
} GPUHexRegion;
typedef struct HexRegionStruct {
uint32_t x;
uint32_t y;
VkDeviceAddress address;
VkBuffer region;
VmaAllocation region_memory;
} HexRegion;
VkResult create_hex_context(
RenderContext* gpu,
HexContext* context);
VkResult create_hex_region(
uint32_t x, uint32_t y,
HexRegion* region,
RenderContext* gpu);
#endif #endif

@ -4,9 +4,11 @@
#include "hex_common.glsl" #include "hex_common.glsl"
#define PI 3.1415926535897932384626433832795 #define PI 3.1415926535897932384626433832795
float w = 0.5; const float w = 0.5;
const float x = 0.75;
const float z = sqrt(3.0)/4.0;
vec4 vertices[] = { const vec4 vertices[] = {
vec4(0, 0, 0, 1), vec4(0, 0, 0, 1),
vec4(w*cos(0*PI/3), 0, w*sin(0*PI/3), 1), vec4(w*cos(0*PI/3), 0, w*sin(0*PI/3), 1),
vec4(w*cos(1*PI/3), 0, w*sin(1*PI/3), 1), vec4(w*cos(1*PI/3), 0, w*sin(1*PI/3), 1),
@ -16,7 +18,7 @@ vec4 vertices[] = {
vec4(w*cos(5*PI/3), 0, w*sin(5*PI/3), 1), vec4(w*cos(5*PI/3), 0, w*sin(5*PI/3), 1),
}; };
uint indices[] = { const uint indices[] = {
0, 2, 1, 0, 2, 1,
0, 3, 2, 0, 3, 2,
0, 4, 3, 0, 4, 3,
@ -25,6 +27,38 @@ uint indices[] = {
0, 1, 6, 0, 1, 6,
}; };
const vec4 starts[] = {
vec4( 0, 0, 2*z, 0),
vec4(-x, 0, z, 0),
vec4(-x, 0, -z, 0),
vec4( 0, 0, -2*z, 0),
vec4( x, 0, -z, 0),
vec4( x, 0, z, 0),
};
const vec4 direction[] = {
vec4(-x, 0, -z, 0),
vec4( 0, 0, -2*z, 0),
vec4( x, 0, -z, 0),
vec4( x, 0, z, 0),
vec4( 0, 0, 2*z, 0),
vec4(-x, 0, z, 0),
};
void main() { void main() {
gl_Position = pc.context.proj * pc.context.view * vertices[indices[gl_VertexIndex]]; uint radius = 0;
uint ring = 0;
uint side = 0;
uint hex = 0;
if(gl_InstanceIndex != 0) {
radius = uint(floor(0.5 + sqrt(12*gl_InstanceIndex-3)/6));
ring = gl_InstanceIndex - (3*radius*radius - 3*radius + 1);
side = uint(floor(ring/(radius)));
hex = ring - (radius*side);
}
// Calculate position based on radius/ring/side/hex
vec4 position = vertices[indices[gl_VertexIndex]] + (starts[side]*radius) + (direction[side]*hex);
gl_Position = pc.context.proj * pc.context.view * position;
} }

@ -1,6 +1,26 @@
struct Hex {
float heights[6];
uint colors[6];
};
layout(std430, buffer_reference) readonly buffer HexList {
Hex h[];
};
struct Region {
uint x;
uint y;
HexList hexes;
};
layout(std430, buffer_reference) readonly buffer RegionList {
Region r[];
};
layout(std430, buffer_reference) readonly buffer HexContext { layout(std430, buffer_reference) readonly buffer HexContext {
mat4 proj; mat4 proj;
mat4 view; mat4 view;
RegionList regions;
}; };
layout(std430, push_constant) uniform PushConstant { layout(std430, push_constant) uniform PushConstant {

@ -1,6 +1,4 @@
#include "draw.h" #include "draw.h"
#include "gpu.h"
#include "hex.h"
#include "vulkan/vulkan_core.h" #include "vulkan/vulkan_core.h"
void record_ui_draw(VkCommandBuffer command_buffer, UIContext* ui_context, double time, uint32_t frame) { void record_ui_draw(VkCommandBuffer command_buffer, UIContext* ui_context, double time, uint32_t frame) {
@ -24,14 +22,14 @@ void record_ui_draw(VkCommandBuffer command_buffer, UIContext* ui_context, doubl
} }
} }
void record_hex_draw(VkCommandBuffer command_buffer, GraphicsPipeline* graphics, VkDeviceAddress context, double time) { void record_hex_draw(VkCommandBuffer command_buffer, HexContext* hex, double time, uint32_t frame) {
HexPushConstant push = { HexPushConstant push = {
.context = context, .context = hex->address,
.time = time, .time = time,
}; };
vkCmdPushConstants(command_buffer, graphics->layout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(HexPushConstant), &push); vkCmdPushConstants(command_buffer, hex->graphics.layout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(HexPushConstant), &push);
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphics->pipeline); vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, hex->graphics.pipeline);
vkCmdDraw(command_buffer, 18, 1, 0, 0); vkCmdDraw(command_buffer, 18, REGION_HEX_COUNT, 0, 0);
} }
void record_ui_compute(VkCommandBuffer command_buffer, UIContext* ui, uint32_t frame) { void record_ui_compute(VkCommandBuffer command_buffer, UIContext* ui, uint32_t frame) {
@ -65,8 +63,7 @@ void record_ui_compute(VkCommandBuffer command_buffer, UIContext* ui, uint32_t f
VkResult draw_frame( VkResult draw_frame(
RenderContext* context, RenderContext* context,
UIContext* ui, UIContext* ui,
GraphicsPipeline* hex_graphics, HexContext* hex,
VkDeviceAddress hex_context,
double time) { double time) {
VkResult result; VkResult result;
@ -186,7 +183,7 @@ VkResult draw_frame(
}; };
vkCmdBeginRenderPass(command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE); vkCmdBeginRenderPass(command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE);
record_hex_draw(command_buffer, hex_graphics, hex_context, time); record_hex_draw(command_buffer, hex, time, context->current_frame);
vkCmdNextSubpass(command_buffer, VK_SUBPASS_CONTENTS_INLINE); vkCmdNextSubpass(command_buffer, VK_SUBPASS_CONTENTS_INLINE);
record_ui_draw(command_buffer, ui, time, context->current_frame); record_ui_draw(command_buffer, ui, time, context->current_frame);
vkCmdEndRenderPass(command_buffer); vkCmdEndRenderPass(command_buffer);

@ -2,16 +2,14 @@
#include "gpu.h" #include "gpu.h"
#include "vulkan/vulkan_core.h" #include "vulkan/vulkan_core.h"
VkResult create_hex_pipeline( VkResult create_hex_context(
VkDevice device, RenderContext* gpu,
VkRenderPass render_pass, HexContext* context) {
GraphicsPipeline* graphics,
ComputePipeline* compute) {
VkResult result; VkResult result;
// Compute Pipeline // Compute Pipeline
VkShaderModule compute_shader = load_shader_file("shader/hex.comp.spv", device); VkShaderModule compute_shader = load_shader_file("shader/hex.comp.spv", gpu->device);
if(compute_shader == VK_NULL_HANDLE) { if(compute_shader == VK_NULL_HANDLE) {
return VK_ERROR_UNKNOWN; return VK_ERROR_UNKNOWN;
} }
@ -35,20 +33,20 @@ VkResult create_hex_pipeline(
.pushConstantRangeCount = 1, .pushConstantRangeCount = 1,
}; };
VK_RESULT(vkCreatePipelineLayout(device, &compute_layout_info, NULL, &compute->layout)); VK_RESULT(vkCreatePipelineLayout(gpu->device, &compute_layout_info, NULL, &context->compute.layout));
VkComputePipelineCreateInfo compute_pipeline_info = { VkComputePipelineCreateInfo compute_pipeline_info = {
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
.stage = compute_shader_stage, .stage = compute_shader_stage,
.layout = compute->layout, .layout = context->compute.layout,
}; };
VK_RESULT(vkCreateComputePipelines(device, VK_NULL_HANDLE, 1, &compute_pipeline_info, NULL, &compute->pipeline)); VK_RESULT(vkCreateComputePipelines(gpu->device, VK_NULL_HANDLE, 1, &compute_pipeline_info, NULL, &context->compute.pipeline));
// Graphics Pipeline // Graphics Pipeline
VkShaderModule vert_shader = load_shader_file("shader/hex.vert.spv", device); VkShaderModule vert_shader = load_shader_file("shader/hex.vert.spv", gpu->device);
VkShaderModule frag_shader = load_shader_file("shader/hex.frag.spv", device); VkShaderModule frag_shader = load_shader_file("shader/hex.frag.spv", gpu->device);
VkPipelineShaderStageCreateInfo graphics_stages[] = { VkPipelineShaderStageCreateInfo graphics_stages[] = {
{ {
@ -77,7 +75,7 @@ VkResult create_hex_pipeline(
.pushConstantRangeCount = 1, .pushConstantRangeCount = 1,
}; };
VK_RESULT(vkCreatePipelineLayout(device, &graphics_layout_info, NULL, &graphics->layout)); VK_RESULT(vkCreatePipelineLayout(gpu->device, &graphics_layout_info, NULL, &context->graphics.layout));
VkPipelineVertexInputStateCreateInfo vertex_info = { VkPipelineVertexInputStateCreateInfo vertex_info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
@ -180,7 +178,7 @@ VkResult create_hex_pipeline(
VkGraphicsPipelineCreateInfo graphics_pipeline_info = { VkGraphicsPipelineCreateInfo graphics_pipeline_info = {
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.layout = graphics->layout, .layout = context->graphics.layout,
.stageCount = sizeof(graphics_stages)/sizeof(VkPipelineShaderStageCreateInfo), .stageCount = sizeof(graphics_stages)/sizeof(VkPipelineShaderStageCreateInfo),
.pStages = graphics_stages, .pStages = graphics_stages,
.pVertexInputState = &vertex_info, .pVertexInputState = &vertex_info,
@ -191,13 +189,42 @@ VkResult create_hex_pipeline(
.pDynamicState = &dynamic_info, .pDynamicState = &dynamic_info,
.pMultisampleState = &multisample_info, .pMultisampleState = &multisample_info,
.pDepthStencilState = &depth_info, .pDepthStencilState = &depth_info,
.renderPass = render_pass, .renderPass = gpu->render_pass,
.subpass = 0, .subpass = 0,
.basePipelineHandle = VK_NULL_HANDLE, .basePipelineHandle = VK_NULL_HANDLE,
.basePipelineIndex = -1, .basePipelineIndex = -1,
}; };
VK_RESULT(vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &graphics_pipeline_info, NULL, &graphics->pipeline)); VK_RESULT(vkCreateGraphicsPipelines(gpu->device, VK_NULL_HANDLE, 1, &graphics_pipeline_info, NULL, &context->graphics.pipeline));
glm_perspective(30.0, (float)gpu->swapchain_extent.width/(float)gpu->swapchain_extent.height, 0.01, 99.9, context->data.proj);
glm_mat4_identity(context->data.view);
VK_RESULT(create_storage_buffer(
gpu->allocator,
0,
sizeof(GPUHexContext),
&context->context,
&context->context_memory));
context->address = buffer_address(gpu->device, context->context);
VK_RESULT(add_transfer(&context->data, context->context, 0, sizeof(GPUHexContext), gpu->current_frame, gpu));
return VK_SUCCESS;
}
VkResult create_hex_region(uint32_t x, uint32_t y, HexRegion* region, RenderContext* gpu) {
VkResult result;
region->x = x;
region->y = y;
VK_RESULT(create_storage_buffer(
gpu->allocator,
0,
sizeof(GPUHexRegion),
&region->region,
&region->region_memory));
VK_RESULT(add_transfer(&region->x, region->region, offsetof(GPUHexRegion, x), sizeof(uint32_t)*2, 0, gpu));
region->address = buffer_address(gpu->device, region->region);
return VK_SUCCESS; return VK_SUCCESS;
} }

@ -17,6 +17,7 @@ typedef struct ClientContextStruct {
GLFWwindow* window; GLFWwindow* window;
RenderContext render; RenderContext render;
UIContext ui; UIContext ui;
HexContext hex;
uint32_t clicked_container; uint32_t clicked_container;
uint32_t clicked_element; uint32_t clicked_element;
@ -51,9 +52,6 @@ vec3 up = {0, 1, 0};
VkResult main_thread(ClientContext* context) { VkResult main_thread(ClientContext* context) {
VkResult result; VkResult result;
GraphicsPipeline graphics;
ComputePipeline compute;
VK_RESULT(create_hex_pipeline(context->render.device, context->render.render_pass, &graphics, &compute));
GPUString strings[] = { GPUString strings[] = {
{ {
@ -124,17 +122,13 @@ VkResult main_thread(ClientContext* context) {
4*sizeof(uint32_t), 4*sizeof(uint32_t),
&context->render)); &context->render));
VkBuffer hex_context; HexRegion region;
VmaAllocation hex_context_memory; VK_RESULT(create_hex_region(0, 0, &region, &context->render));
GPUHexContext hex;
VK_RESULT(create_storage_buffer(context->render.allocator, 0, sizeof(GPUHexContext), &hex_context, &hex_context_memory));
VkDeviceAddress hex_context_address = buffer_address(context->render.device, hex_context);
glm_perspective(30.0, (float)context->render.swapchain_extent.width/(float)context->render.swapchain_extent.height, 0.01, 99.9, hex.proj);
context->position[0] = 0; context->position[0] = 0;
context->position[1] = 0; context->position[1] = 0;
context->position[2] = 0; context->position[2] = 0;
context->rotation[0] = 0; context->rotation[0] = 3*M_PI/2;
context->rotation[1] = 0; context->rotation[1] = 0;
context->cur_spin[0] = 0; context->cur_spin[0] = 0;
context->cur_spin[1] = 0; context->cur_spin[1] = 0;
@ -143,7 +137,7 @@ VkResult main_thread(ClientContext* context) {
context->key_spin[1] = 0; context->key_spin[1] = 0;
context->cur_spin[0] = 0; context->cur_spin[0] = 0;
context->cur_spin[1] = 0; context->cur_spin[1] = 0;
context->distance = 1; context->distance = 10;
context->zoom = 0; context->zoom = 0;
context->camera_mode = false; context->camera_mode = false;
context->key_spin_speed = 1.0; context->key_spin_speed = 1.0;
@ -154,7 +148,6 @@ VkResult main_thread(ClientContext* context) {
uint32_t* mapped_codes = context->ui.containers[0].layers[0].codes_buffer; uint32_t* mapped_codes = context->ui.containers[0].layers[0].codes_buffer;
GPUString* mapped_string = context->ui.containers[0].layers[0].strings_buffer; GPUString* mapped_string = context->ui.containers[0].layers[0].strings_buffer;
char str[21]; char str[21];
//
double last_frame_time = glfwGetTime(); double last_frame_time = glfwGetTime();
while(glfwWindowShouldClose(context->window) == 0) { while(glfwWindowShouldClose(context->window) == 0) {
@ -183,8 +176,8 @@ VkResult main_thread(ClientContext* context) {
context->rotation[1] += (float)context->key_spin[1]*delta_time*context->key_spin_speed; context->rotation[1] += (float)context->key_spin[1]*delta_time*context->key_spin_speed;
context->rotation[1] += (float)context->cur_spin[1]*delta_time*context->cur_spin_speed; context->rotation[1] += (float)context->cur_spin[1]*delta_time*context->cur_spin_speed;
if(context->rotation[1] > M_PI/2) { if(context->rotation[1] > (M_PI/2 - 0.1)) {
context->rotation[1] = M_PI/2; context->rotation[1] = (M_PI/2 - 0.1);
} else if(context->rotation[1] < 0) { } else if(context->rotation[1] < 0) {
context->rotation[1] = 0; context->rotation[1] = 0;
} }
@ -198,9 +191,9 @@ VkResult main_thread(ClientContext* context) {
camera[0] = context->position[0] + context->distance*cos(context->rotation[1])*cos(context->rotation[0]); camera[0] = context->position[0] + context->distance*cos(context->rotation[1])*cos(context->rotation[0]);
camera[1] = context->position[1] + context->distance*sin(context->rotation[1]); camera[1] = context->position[1] + context->distance*sin(context->rotation[1]);
camera[2] = context->position[2] + context->distance*cos(context->rotation[1])*sin(context->rotation[0]); camera[2] = context->position[2] + context->distance*cos(context->rotation[1])*sin(context->rotation[0]);
glm_lookat(camera, context->position, up, hex.view); glm_lookat(camera, context->position, up, context->hex.data.view);
add_transfer(&context->hex.data, context->hex.context, 0, sizeof(GPUHexContext), 0, &context->render);
add_transfer(&hex, hex_context, 0, sizeof(GPUHexContext), (context->render.current_frame + 1) % MAX_FRAMES_IN_FLIGHT, &context->render); add_transfer(&context->hex.data, context->hex.context, 0, sizeof(GPUHexContext), 1, &context->render);
} }
if(context->clicked_container != 0) { if(context->clicked_container != 0) {
@ -223,7 +216,7 @@ VkResult main_thread(ClientContext* context) {
} }
// //
VkResult result = draw_frame(&context->render, &context->ui, &graphics, hex_context_address, frame_time); VkResult result = draw_frame(&context->render, &context->ui, &context->hex, frame_time);
if(result != VK_SUCCESS) { if(result != VK_SUCCESS) {
fprintf(stderr, "draw_frame error: %s\n", string_VkResult(result)); fprintf(stderr, "draw_frame error: %s\n", string_VkResult(result));
glfwDestroyWindow(context->window); glfwDestroyWindow(context->window);
@ -365,6 +358,7 @@ int main() {
// TODO: make # of fonts/textures/containers scaling, recreate GPU buffers as necessary // TODO: make # of fonts/textures/containers scaling, recreate GPU buffers as necessary
VK_RESULT(create_ui_context(10, 10, 10, &context.render, &context.ui)); VK_RESULT(create_ui_context(10, 10, 10, &context.render, &context.ui));
VK_RESULT(create_hex_context(&context.render, &context.hex));
pthread_t network_thread_handle; pthread_t network_thread_handle;