summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assets/shaders/cube.frag12
-rw-r--r--assets/shaders/cube.vert7
-rw-r--r--examples/cube/ex_cube.c25
-rw-r--r--src/renderer/backends/backend_vulkan.c200
-rw-r--r--src/renderer/backends/backend_vulkan.h3
-rw-r--r--src/renderer/ral.h2
-rw-r--r--src/renderer/ral_types.h6
-rw-r--r--src/renderer/render.c3
-rw-r--r--xmake.lua1
9 files changed, 191 insertions, 68 deletions
diff --git a/assets/shaders/cube.frag b/assets/shaders/cube.frag
index e69de29..11f1efa 100644
--- a/assets/shaders/cube.frag
+++ b/assets/shaders/cube.frag
@@ -0,0 +1,12 @@
+#version 450
+
+layout(location = 0) in vec3 fragColor;
+layout(location = 1) in vec2 fragTexCoord;
+
+layout(binding = 1) uniform sampler2D texSampler;
+
+layout(location = 0) out vec4 outColor;
+
+void main() {
+ outColor = texture(texSampler, fragTexCoord); // vec4(fragTexCoord, 0.0);
+}
diff --git a/assets/shaders/cube.vert b/assets/shaders/cube.vert
index 1818c3c..fa9f85b 100644
--- a/assets/shaders/cube.vert
+++ b/assets/shaders/cube.vert
@@ -4,16 +4,17 @@ layout(binding = 0) uniform UniformBufferObject {
mat4 model;
mat4 view;
mat4 proj;
-}
-ubo;
+} ubo;
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inNormal;
-layout(location = 2) in vec3 inTexCoords;
+layout(location = 2) in vec2 inTexCoords;
layout(location = 0) out vec3 fragColor;
+layout(location = 1) out vec2 fragTexCoord;
void main() {
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 1.0);
fragColor = abs(inNormal);
+ fragTexCoord = inTexCoords;
}
diff --git a/examples/cube/ex_cube.c b/examples/cube/ex_cube.c
index 80a4e26..5d6cbbe 100644
--- a/examples/cube/ex_cube.c
+++ b/examples/cube/ex_cube.c
@@ -22,20 +22,30 @@ typedef struct mvp_uniforms {
mat4 view;
mat4 projection;
} mvp_uniforms;
+typedef struct my_shader_bind_group {
+ mvp_uniforms mvp;
+ texture_handle tex;
+} my_shader_bind_group;
// We also must create a function that knows how to return a `shader_data_layout`
shader_data_layout mvp_uniforms_layout(void* data) {
- mvp_uniforms* d = (mvp_uniforms*)data;
+ my_shader_bind_group* d = (my_shader_bind_group*)data;
bool has_data = data != NULL;
shader_binding b1 = { .label = "mvp_uniforms",
.type = SHADER_BINDING_BYTES,
.stores_data = has_data,
.data = { .bytes = { .size = sizeof(mvp_uniforms) } } };
+
+ shader_binding b2 = { .label = "texture_sampler",
+ .type = SHADER_BINDING_TEXTURE,
+ .stores_data = has_data
+ };
if (has_data) {
- b1.data.bytes.data = d;
+ b1.data.bytes.data = &d->mvp;
+ b2.data.texture.handle = d->tex;
}
- return (shader_data_layout){ .name = "global_ubo", .bindings = { b1 }, .bindings_count = 1 };
+ return (shader_data_layout){ .name = "global_ubo", .bindings = { b1, b2 }, .bindings_count = 2 };
}
int main() {
@@ -60,7 +70,7 @@ int main() {
gpu_renderpass* renderpass = gpu_renderpass_create(&pass_description);
str8 vert_path = str8lit("build/linux/x86_64/debug/cube.vert.spv");
- str8 frag_path = str8lit("build/linux/x86_64/debug/triangle.frag.spv");
+ str8 frag_path = str8lit("build/linux/x86_64/debug/cube.frag.spv");
str8_opt vertex_shader = str8_from_file(&scratch, vert_path);
str8_opt fragment_shader = str8_from_file(&scratch, frag_path);
if (!vertex_shader.has_value || !fragment_shader.has_value) {
@@ -93,6 +103,7 @@ int main() {
// Texture
texture_data tex_data = texture_data_load("assets/textures/texture.jpg", false);
texture_handle texture = texture_data_upload(tex_data, true);
+ printf("Texture %d", texture.raw);
// Main loop
while (!should_exit(&g_core)) {
@@ -118,7 +129,11 @@ int main() {
camera_view_projection(&cam, g_core.renderer.swapchain.extent.width,
g_core.renderer.swapchain.extent.height, &view, &proj);
mvp_uniforms mvp_data = { .model = model, .view = view, .projection = proj };
- mvp_uniforms_data.data = &mvp_data;
+ my_shader_bind_group shader_bind_data = {
+ .mvp = mvp_data,
+ .tex = texture
+ };
+ mvp_uniforms_data.data = &shader_bind_data;
encode_bind_shader_data(enc, 0, &mvp_uniforms_data);
// Record draw calls
diff --git a/src/renderer/backends/backend_vulkan.c b/src/renderer/backends/backend_vulkan.c
index 33e0860..e8b54d9 100644
--- a/src/renderer/backends/backend_vulkan.c
+++ b/src/renderer/backends/backend_vulkan.c
@@ -92,8 +92,12 @@ VkShaderModule create_shader_module(str8 spirv);
/** @brief Helper function for creating array of all extensions we want */
cstr_darray* get_all_extensions();
+void vulkan_transition_image_layout(gpu_texture* texture, VkFormat format, VkImageLayout old_layout,
+ VkImageLayout new_layout);
+
// --- Handy macros
#define BUFFER_GET(h) (buffer_pool_get(&context.resource_pools->buffers, h))
+#define TEXTURE_GET(h) (texture_pool_get(&context.resource_pools->textures, h))
bool gpu_backend_init(const char* window_name, GLFWwindow* window) {
memset(&context, 0, sizeof(vulkan_context));
@@ -571,24 +575,24 @@ gpu_pipeline* gpu_graphics_pipeline_create(struct graphics_pipeline_desc descrip
// assert(description.data_layouts_count == 1);
printf("data layouts %d\n", description.data_layouts_count);
- for (u32 i = 0; i < description.data_layouts_count; i++) {
- shader_data_layout sdl = description.data_layouts[i].shader_data_get_layout(NULL);
+ for (u32 layout_i = 0; layout_i < description.data_layouts_count; layout_i++) {
+ shader_data_layout sdl = description.data_layouts[layout_i].shader_data_get_layout(NULL);
+ TRACE("Got shader data layout %d's bindings! . found %d", layout_i, sdl.bindings_count);
- // NOTE: is using VLA generally ok?
- VkDescriptorSetLayoutBinding desc_set_bindings[description.data_layouts_count];
+ VkDescriptorSetLayoutBinding desc_set_bindings[sdl.bindings_count];
// Bindings
- assert(sdl.bindings_count == 1);
- for (u32 j = 0; j < sdl.bindings_count; j++) {
- desc_set_bindings[j].binding = j;
- desc_set_bindings[j].descriptorCount = 1;
- switch (sdl.bindings[j].type) {
+ assert(sdl.bindings_count == 2);
+ for (u32 binding_j = 0; binding_j < sdl.bindings_count; binding_j++) {
+ desc_set_bindings[binding_j].binding = binding_j;
+ desc_set_bindings[binding_j].descriptorCount = 1;
+ switch (sdl.bindings[binding_j].type) {
case SHADER_BINDING_BUFFER:
case SHADER_BINDING_BYTES:
- desc_set_bindings[j].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- desc_set_bindings[j].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; // FIXME: dont hardcode
+ desc_set_bindings[binding_j].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+ desc_set_bindings[binding_j].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; // FIXME: dont hardcode
- u64 buffer_size = sdl.bindings[j].data.bytes.size;
+ u64 buffer_size = sdl.bindings[binding_j].data.bytes.size;
VkDeviceSize uniform_buf_size = buffer_size;
// TODO: Create backing buffer
@@ -617,18 +621,24 @@ gpu_pipeline* gpu_graphics_pipeline_create(struct graphics_pipeline_desc descrip
sizeof(uniform_buf_mem_mappings));
uniform_data.size = buffer_size;
- pipeline->uniform_pointers[j] = uniform_data;
+ pipeline->uniform_pointers[binding_j] = uniform_data;
+
+ break;
+ case SHADER_BINDING_TEXTURE:
+ desc_set_bindings[binding_j].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+ desc_set_bindings[binding_j].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; // FIXME: dont hardcode
+ desc_set_bindings[binding_j].pImmutableSamplers = NULL;
break;
default:
ERROR_EXIT("Unimplemented binding type!! in backend_vulkan");
}
- switch (sdl.bindings[j].vis) {
+ switch (sdl.bindings[binding_j].vis) {
case VISIBILITY_VERTEX:
- desc_set_bindings[j].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
+ desc_set_bindings[binding_j].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
break;
case VISIBILITY_FRAGMENT:
- desc_set_bindings[j].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
+ desc_set_bindings[binding_j].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
break;
case VISIBILITY_COMPUTE:
WARN("Compute is not implemented yet");
@@ -643,7 +653,7 @@ gpu_pipeline* gpu_graphics_pipeline_create(struct graphics_pipeline_desc descrip
desc_set_layout_info.pBindings = desc_set_bindings;
VK_CHECK(vkCreateDescriptorSetLayout(context.device->logical_device, &desc_set_layout_info,
- context.allocator, &desc_set_layouts[i]));
+ context.allocator, &desc_set_layouts[layout_i]));
}
printf("Descriptor set layouts\n");
@@ -683,17 +693,15 @@ gpu_pipeline* gpu_graphics_pipeline_create(struct graphics_pipeline_desc descrip
pipeline_create_info.basePipelineHandle = VK_NULL_HANDLE;
pipeline_create_info.basePipelineIndex = -1;
- printf("Here\n");
+ printf("About to create graphics pipeline\n");
VkResult result =
vkCreateGraphicsPipelines(context.device->logical_device, VK_NULL_HANDLE, 1,
&pipeline_create_info, context.allocator, &pipeline->handle);
if (result != VK_SUCCESS) {
- printf("BAD\n");
FATAL("graphics pipeline creation failed. its fked mate");
ERROR_EXIT("Doomed");
}
- printf("Here2\n");
TRACE("Vulkan Graphics pipeline created");
// once the pipeline has been created we can destroy these
@@ -810,13 +818,17 @@ gpu_cmd_encoder gpu_cmd_encoder_create() {
VK_CHECK(vkAllocateCommandBuffers(context.device->logical_device, &allocate_info,
&encoder.cmd_buffer););
- VkDescriptorPoolSize uniform_pool_size;
- uniform_pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- uniform_pool_size.descriptorCount = MAX_FRAMES_IN_FLIGHT * MAX_DESCRIPTOR_SETS;
+ VkDescriptorPoolSize pool_sizes[2];
+ // Uniforms pool
+ pool_sizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+ pool_sizes[0].descriptorCount = MAX_FRAMES_IN_FLIGHT * MAX_DESCRIPTOR_SETS;
+ // Samplers pool
+ pool_sizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+ pool_sizes[1].descriptorCount = MAX_FRAMES_IN_FLIGHT * MAX_DESCRIPTOR_SETS;
VkDescriptorPoolCreateInfo pool_info = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO };
- pool_info.poolSizeCount = 1;
- pool_info.pPoolSizes = &uniform_pool_size;
+ pool_info.poolSizeCount = 2;
+ pool_info.pPoolSizes = pool_sizes;
pool_info.maxSets = 100;
VK_CHECK(vkCreateDescriptorPool(context.device->logical_device, &pool_info, context.allocator,
@@ -875,6 +887,8 @@ void encode_bind_pipeline(gpu_cmd_encoder* encoder, pipeline_kind kind, gpu_pipe
}
void encode_bind_shader_data(gpu_cmd_encoder* encoder, u32 group, shader_data* data) {
+ arena tmp = arena_create(malloc(1024), 1024);
+
assert(data->data != NULL);
// Update the local buffer
@@ -886,44 +900,62 @@ void encode_bind_shader_data(gpu_cmd_encoder* encoder, u32 group, shader_data* d
alloc_info.descriptorSetCount = 1;
alloc_info.pSetLayouts = &encoder->pipeline->desc_set_layouts[group];
- VkDescriptorSet sets[1];
+ shader_data_layout sdl = data->shader_data_get_layout(data->data);
+ size_t binding_count = sdl.bindings_count;
+ assert(binding_count == 2);
+
+ VkDescriptorSet sets[0];
VK_CHECK(vkAllocateDescriptorSets(context.device->logical_device, &alloc_info, sets));
+ // FIXME: hardcoded
VkDescriptorSet_darray_push(context.free_set_queue, sets[0]);
+ /* VkDescriptorSet_darray_push(context.free_set_queue, sets[1]); */
- shader_data_layout sdl = data->shader_data_get_layout(NULL);
- assert(sdl.bindings_count == 1);
-
- VkWriteDescriptorSet write_sets[1];
- memset(&write_sets, 0, sizeof(write_sets));
+ VkWriteDescriptorSet write_sets[binding_count];
+ memset(&write_sets, 0, binding_count * sizeof(VkWriteDescriptorSet));
- assert(sdl.bindings_count == 1);
for (u32 i = 0; i < sdl.bindings_count; i++) {
shader_binding binding = sdl.bindings[i];
if (binding.type == SHADER_BINDING_BUFFER || binding.type == SHADER_BINDING_BYTES) {
- VkDescriptorBufferInfo buffer_info;
- buffer_info.buffer = ubo.buffers[context.current_frame];
- buffer_info.offset = 0;
- buffer_info.range = binding.data.bytes.size;
-
- write_sets[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
- write_sets[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- write_sets[0].descriptorCount = 1;
- write_sets[0].dstSet = sets[0];
- write_sets[0].dstBinding = 0;
- write_sets[0].dstArrayElement = 0;
- write_sets[0].pBufferInfo = &buffer_info;
- } else {
+ VkDescriptorBufferInfo* buffer_info = arena_alloc(&tmp, sizeof(VkDescriptorBufferInfo));
+ buffer_info->buffer = ubo.buffers[context.current_frame];
+ buffer_info->offset = 0;
+ buffer_info->range = binding.data.bytes.size;
+
+ write_sets[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+ write_sets[i].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+ write_sets[i].descriptorCount = 1;
+ write_sets[i].dstSet = sets[0];
+ write_sets[i].dstBinding = i;
+ write_sets[i].dstArrayElement = 0;
+ write_sets[i].pBufferInfo = buffer_info;
+ } else if (binding.type == SHADER_BINDING_TEXTURE) {
+ gpu_texture* texture = TEXTURE_GET(binding.data.texture.handle);
+ VkDescriptorImageInfo* image_info = arena_alloc(&tmp, sizeof(VkDescriptorImageInfo));
+ image_info->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+ image_info->imageView = texture->view;
+ image_info->sampler = texture->sampler;
+
+ write_sets[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+ write_sets[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+ write_sets[i].descriptorCount = 1;
+ write_sets[i].dstSet = sets[0];
+ write_sets[i].dstBinding = i;
+ write_sets[i].dstArrayElement = 0;
+ write_sets[i].pImageInfo = image_info;
+ }else {
WARN("Unknown binding");
}
}
// Update
- vkUpdateDescriptorSets(context.device->logical_device, 1, write_sets, 0, NULL);
+ vkUpdateDescriptorSets(context.device->logical_device, binding_count, write_sets, 0, NULL);
// Bind
vkCmdBindDescriptorSets(encoder->cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
encoder->pipeline->layout_handle, 0, 1, sets, 0, NULL);
+
+ arena_free_storage(&tmp);
}
void encode_set_vertex_buffer(gpu_cmd_encoder* encoder, buffer_handle buf) {
@@ -1453,19 +1485,15 @@ void copy_buffer_to_image_oneshot(buffer_handle src, texture_handle dst) {
vulkan_command_buffer_finish_oneshot(temp_cmd_buffer);
}
-texture_handle gpu_texture_create(texture_desc desc, const void* data) {
+texture_handle gpu_texture_create(texture_desc desc, bool create_view, const void* data) {
VkDeviceSize image_size = desc.extents.x * desc.extents.y * 4;
- TRACE("Uploading pixel data to texture using staging buffer");
- // Create a staging buffer
- buffer_handle staging =
- gpu_buffer_create(image_size, CEL_BUFFER_DEFAULT, CEL_BUFFER_FLAG_CPU, NULL);
- // Copy data into it
- buffer_upload_bytes(staging, (bytebuffer){ .buf = (u8*)data, .size = image_size }, 0, image_size);
-
VkImage image;
VkDeviceMemory image_memory;
+ // FIXME: get from desc
+ VkFormat format = VK_FORMAT_R8G8B8A8_SRGB;
+
VkImageCreateInfo image_create_info = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
image_create_info.imageType = VK_IMAGE_TYPE_2D;
image_create_info.extent.width = desc.extents.x;
@@ -1473,7 +1501,7 @@ texture_handle gpu_texture_create(texture_desc desc, const void* data) {
image_create_info.extent.depth = 1;
image_create_info.mipLevels = 1;
image_create_info.arrayLayers = 1;
- image_create_info.format = VK_FORMAT_R8G8B8A8_SRGB;
+ image_create_info.format = format;
image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
@@ -1494,13 +1522,71 @@ texture_handle gpu_texture_create(texture_desc desc, const void* data) {
vkBindImageMemory(context.device->logical_device, image, image_memory, 0);
- gpu_buffer_destroy(staging);
-
texture_handle handle;
gpu_texture* texture = texture_pool_alloc(&context.resource_pools->textures, &handle);
+ DEBUG("Allocated texture with handle %d", handle.raw);
texture->handle = image;
+ texture->debug_label = "Test Texture";
+ texture->desc = desc;
texture->memory = image_memory;
texture->size = image_size;
+
+ if (data) {
+ TRACE("Uploading pixel data to texture using staging buffer");
+ // Create a staging buffer
+ buffer_handle staging =
+ gpu_buffer_create(image_size, CEL_BUFFER_DEFAULT, CEL_BUFFER_FLAG_CPU, NULL);
+ // Copy data into it
+ vulkan_transition_image_layout(texture, format, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
+ buffer_upload_bytes(staging, (bytebuffer){ .buf = (u8*)data, .size = image_size }, 0, image_size);
+ copy_buffer_to_image_oneshot(staging, handle);
+ vulkan_transition_image_layout(texture, format, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
+
+ gpu_buffer_destroy(staging);
+ }
+
+ // Texture View
+ if (create_view) {
+ VkImageViewCreateInfo view_create_info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO };
+ view_create_info.image = image;
+ view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
+ view_create_info.format = format;
+ view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+
+ view_create_info.subresourceRange.baseMipLevel = 0;
+ view_create_info.subresourceRange.levelCount = 1;
+ view_create_info.subresourceRange.baseArrayLayer = 0;
+ view_create_info.subresourceRange.layerCount = 1;
+
+ VK_CHECK(vkCreateImageView(context.device->logical_device, &view_create_info, context.allocator,
+ &texture->view));
+ }
+
+ // Sampler
+ VkSamplerCreateInfo sampler_info = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO };
+ sampler_info.magFilter = VK_FILTER_LINEAR;
+ sampler_info.minFilter = VK_FILTER_LINEAR;
+ sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
+ sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
+ sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
+ sampler_info.anisotropyEnable = VK_TRUE;
+ sampler_info.maxAnisotropy = 16;
+ sampler_info.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
+ sampler_info.unnormalizedCoordinates = VK_FALSE;
+ sampler_info.compareEnable = VK_FALSE;
+ sampler_info.compareOp = VK_COMPARE_OP_ALWAYS;
+ sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
+ sampler_info.mipLodBias = 0.0;
+ sampler_info.minLod = 0.0;
+ sampler_info.maxLod = 0.0;
+
+ VkResult res = vkCreateSampler(context.device->logical_device, &sampler_info, context.allocator,
+ &texture->sampler);
+ if (res != VK_SUCCESS) {
+ ERROR("Error creating texture sampler for image %s", texture->debug_label);
+ return;
+ }
+
return handle;
}
diff --git a/src/renderer/backends/backend_vulkan.h b/src/renderer/backends/backend_vulkan.h
index 1e36ca3..dc0f7bd 100644
--- a/src/renderer/backends/backend_vulkan.h
+++ b/src/renderer/backends/backend_vulkan.h
@@ -109,4 +109,7 @@ typedef struct gpu_texture {
VkDeviceMemory memory;
u64 size;
texture_desc desc;
+ VkImageView view;
+ VkSampler sampler;
+ char* debug_label;
} gpu_texture;
diff --git a/src/renderer/ral.h b/src/renderer/ral.h
index a82a2ba..3697ea5 100644
--- a/src/renderer/ral.h
+++ b/src/renderer/ral.h
@@ -147,7 +147,7 @@ void gpu_buffer_upload();
void gpu_buffer_bind(buffer_handle buffer);
// Textures
-texture_handle gpu_texture_create(texture_desc desc, const void* data);
+texture_handle gpu_texture_create(texture_desc desc, bool create_view, const void* data);
void gpu_texture_destroy();
void gpu_texture_upload();
diff --git a/src/renderer/ral_types.h b/src/renderer/ral_types.h
index 8339625..62a2f1d 100644
--- a/src/renderer/ral_types.h
+++ b/src/renderer/ral_types.h
@@ -139,6 +139,7 @@ typedef struct custom_vertex {
} custom_vertex;
// Vertex attributes
+/// @strip_prefix(ATTR_)
typedef enum vertex_attrib_type {
ATTR_F32,
ATTR_F32x2,
@@ -211,7 +212,10 @@ typedef struct shader_binding {
void* data;
size_t size;
} bytes;
- } data; /** @brief */
+ struct {
+ texture_handle handle;
+ } texture;
+ } data; /** @brief can store any kind of data that we can bind to a shader / descriptor set */
} shader_binding;
#define MAX_LAYOUT_BINDINGS 8
diff --git a/src/renderer/render.c b/src/renderer/render.c
index 9f9a97c..5723c9e 100644
--- a/src/renderer/render.c
+++ b/src/renderer/render.c
@@ -230,8 +230,9 @@ texture_data texture_data_load(const char* path, bool invert_y) {
}
texture_handle texture_data_upload(texture_data data, bool free_on_upload) {
- texture_handle handle = gpu_texture_create(data.description, data.image_data);
+ texture_handle handle = gpu_texture_create(data.description, true, data.image_data);
if (free_on_upload) {
+ TRACE("Freed stb_image data");
stbi_image_free(data.image_data);
}
return handle;
diff --git a/xmake.lua b/xmake.lua
index 9b06db0..40ef961 100644
--- a/xmake.lua
+++ b/xmake.lua
@@ -123,6 +123,7 @@ target("core_config")
add_files("assets/shaders/triangle.vert")
add_files("assets/shaders/triangle.frag")
add_files("assets/shaders/cube.vert")
+ add_files("assets/shaders/cube.frag")
-- add_files("assets/shaders/*.frag")
if is_plat("windows") then
add_includedirs("$(env VULKAN_SDK)/Include", {public = true})