+++ /dev/null
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-
-#define VK_PROTOTYPES
-#include <vulkan/vulkan.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdarg.h>
-#include <poll.h>
-#include <libpng16/png.h>
-
-#include "vk-spirv.h"
-
-#define for_each_bit(b, dword) \
- for (uint32_t __dword = (dword); \
- (b) = __builtin_ffs(__dword) - 1, __dword; \
- __dword &= ~(1 << (b)))
-
-static inline uint32_t
-align_u32(uint32_t value, uint32_t alignment)
-{
- return (value + alignment - 1) & ~(alignment - 1);
-}
-
-static void
-fail_if(int cond, const char *format, ...)
-{
- va_list args;
-
- if (!cond)
- return;
-
- va_start(args, format);
- vfprintf(stderr, format, args);
- va_end(args);
-
- exit(1);
-}
-
-static void
-write_png(char *path, int32_t width, int32_t height, int32_t stride, void *pixels)
-{
- FILE *f = NULL;
- png_structp png_writer = NULL;
- png_infop png_info = NULL;
-
- uint8_t *rows[height];
-
- for (int32_t y = 0; y < height; y++)
- rows[y] = pixels + y * stride;
-
- f = fopen(path, "wb");
- fail_if(!f, "failed to open file for writing: %s", path);
-
- png_writer = png_create_write_struct(PNG_LIBPNG_VER_STRING,
- NULL, NULL, NULL);
- fail_if (!png_writer, "failed to create png writer");
-
- png_info = png_create_info_struct(png_writer);
- fail_if(!png_info, "failed to create png writer info");
-
- png_init_io(png_writer, f);
- png_set_IHDR(png_writer, png_info,
- width, height,
- 8, PNG_COLOR_TYPE_RGBA,
- PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
- PNG_FILTER_TYPE_DEFAULT);
- png_write_info(png_writer, png_info);
- png_set_rows(png_writer, png_info, rows);
- png_write_png(png_writer, png_info, PNG_TRANSFORM_IDENTITY, NULL);
-
- png_destroy_write_struct(&png_writer, &png_info);
-
- fclose(f);
-}
-
-static void *
-test_alloc(void* pUserData,
- size_t size,
- size_t alignment,
- VkSystemAllocType allocType)
-{
- return malloc(size);
-}
-
-static void
-test_free(void* pUserData,
- void* pMem)
-{
- free(pMem);
-}
-
-#define GLSL(src) "#version 330\n" #src
-
-static void
-create_pipeline(VkDevice device, VkPipeline *pipeline,
- VkPipelineLayout pipeline_layout)
-{
- VkPipelineIaStateCreateInfo ia_create_info = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO,
- .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
- .disableVertexReuse = false,
- .primitiveRestartEnable = false,
- .primitiveRestartIndex = 0
- };
-
- VkShader vs = GLSL_VK_SHADER(device, VERTEX,
- layout(location = 0) in vec4 a_position;
- layout(location = 1) in vec4 a_color;
- layout(set = 0, binding = 0) uniform block1 {
- vec4 color;
- } u1;
- layout(set = 0, binding = 1) uniform block2 {
- vec4 color;
- } u2;
- layout(set = 1, binding = 0) uniform block3 {
- vec4 color;
- } u3;
- out vec4 v_color;
- void main()
- {
- gl_Position = a_position;
- v_color = a_color + u1.color + u2.color + u3.color;
- }
- );
-
- VkShader fs = GLSL_VK_SHADER(device, FRAGMENT,
- out vec4 f_color;
- in vec4 v_color;
- layout(set = 0, binding = 0) uniform sampler2D tex;
- void main()
- {
- f_color = v_color + texture(tex, vec2(0.1, 0.1));
- }
- );
-
- VkPipelineShaderStageCreateInfo vs_create_info = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
- .pNext = &ia_create_info,
- .shader = {
- .stage = VK_SHADER_STAGE_VERTEX,
- .shader = vs,
- .linkConstBufferCount = 0,
- .pLinkConstBufferInfo = NULL,
- .pSpecializationInfo = NULL
- }
- };
-
- VkPipelineShaderStageCreateInfo fs_create_info = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
- .pNext = &vs_create_info,
- .shader = {
- .stage = VK_SHADER_STAGE_FRAGMENT,
- .shader = fs,
- .linkConstBufferCount = 0,
- .pLinkConstBufferInfo = NULL,
- .pSpecializationInfo = NULL
- }
- };
-
- VkPipelineVertexInputCreateInfo vi_create_info = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO,
- .pNext = &fs_create_info,
- .bindingCount = 2,
- .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
- {
- .binding = 0,
- .strideInBytes = 16,
- .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
- },
- {
- .binding = 1,
- .strideInBytes = 0,
- .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
- }
- },
- .attributeCount = 2,
- .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
- {
- .location = 0,
- .binding = 0,
- .format = VK_FORMAT_R32G32B32A32_SFLOAT,
- .offsetInBytes = 0
- },
- {
- .location = 1,
- .binding = 1,
- .format = VK_FORMAT_R32G32B32A32_SFLOAT,
- .offsetInBytes = 0
- }
- }
- };
-
- VkPipelineRsStateCreateInfo rs_create_info = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO,
- .pNext = &vi_create_info,
-
- .depthClipEnable = true,
- .rasterizerDiscardEnable = false,
- .fillMode = VK_FILL_MODE_SOLID,
- .cullMode = VK_CULL_MODE_NONE,
- .frontFace = VK_FRONT_FACE_CCW
- };
-
- VkPipelineCbStateCreateInfo cb_create_info = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO,
- .pNext = &rs_create_info,
- .attachmentCount = 1,
- .pAttachments = (VkPipelineCbAttachmentState []) {
- { .channelWriteMask = VK_CHANNEL_A_BIT |
- VK_CHANNEL_R_BIT | VK_CHANNEL_G_BIT | VK_CHANNEL_B_BIT },
- }
- };
-
- vkCreateGraphicsPipeline(device,
- &(VkGraphicsPipelineCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
- .pNext = &cb_create_info,
- .flags = 0,
- .layout = pipeline_layout
- },
- pipeline);
-
-
- vkDestroyObject(device, VK_OBJECT_TYPE_SHADER, fs);
- vkDestroyObject(device, VK_OBJECT_TYPE_SHADER, vs);
-}
-
-static void
-test_timestamp(VkDevice device, VkQueue queue)
-{
- VkBuffer buffer;
- vkCreateBuffer(device,
- &(VkBufferCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
- .size = 1024,
- .usage = VK_BUFFER_USAGE_GENERAL,
- .flags = 0
- },
- &buffer);
-
- VkMemoryRequirements buffer_requirements;
- size_t size = sizeof(buffer_requirements);
- vkGetObjectInfo(device, VK_OBJECT_TYPE_BUFFER, buffer,
- VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
- &size, &buffer_requirements);
-
- VkDeviceMemory mem;
- vkAllocMemory(device,
- &(VkMemoryAllocInfo) {
- .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
- .allocationSize = buffer_requirements.size,
- .memProps = VK_MEMORY_PROPERTY_HOST_DEVICE_COHERENT_BIT,
- .memPriority = VK_MEMORY_PRIORITY_NORMAL
- },
- &mem);
-
- void *map;
- vkMapMemory(device, mem, 0, buffer_requirements.size, 0, &map);
- memset(map, 0x11, buffer_requirements.size);
-
- vkQueueBindObjectMemory(queue, VK_OBJECT_TYPE_BUFFER,
- buffer,
- 0, /* allocation index; for objects which need to bind to multiple mems */
- mem, 0);
-
- VkCmdBuffer cmdBuffer;
- vkCreateCommandBuffer(device,
- &(VkCmdBufferCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO,
- .queueNodeIndex = 0,
- .flags = 0
- },
- &cmdBuffer);
-
- vkBeginCommandBuffer(cmdBuffer,
- &(VkCmdBufferBeginInfo) {
- .sType = VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO,
- .flags = 0
- });
-
- vkCmdWriteTimestamp(cmdBuffer, VK_TIMESTAMP_TYPE_TOP, buffer, 0);
- vkCmdWriteTimestamp(cmdBuffer, VK_TIMESTAMP_TYPE_BOTTOM, buffer, 8);
-
- vkEndCommandBuffer(cmdBuffer);
-
- vkQueueSubmit(queue, 1, &cmdBuffer, 0);
-
- vkQueueWaitIdle(queue);
-
- vkDestroyObject(device, VK_OBJECT_TYPE_BUFFER, buffer);
- vkDestroyObject(device, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer);
-
- uint64_t *results = map;
- printf("top timestamp: %20ld (%016lx)\n", results[0], results[0]);
- printf("bottom timestamp: %20ld (%016lx)\n", results[1], results[1]);
-
- vkUnmapMemory(device, mem);
- vkFreeMemory(device, mem);
-}
-
-static void
-test_buffer_copy(VkDevice device, VkQueue queue)
-{
- /* We'll test copying 1000k buffers */
- const int buffer_size = 1024000;
-
- VkBufferCreateInfo buffer_info = {
- .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
- .size = buffer_size,
- .usage = VK_BUFFER_USAGE_GENERAL,
- .flags = 0
- };
-
- VkBuffer buffer1, buffer2;
- vkCreateBuffer(device, &buffer_info, &buffer1);
- vkCreateBuffer(device, &buffer_info, &buffer2);
-
- VkMemoryRequirements buffer_requirements;
- size_t size = sizeof(buffer_requirements);
- vkGetObjectInfo(device, VK_OBJECT_TYPE_BUFFER, buffer1,
- VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
- &size, &buffer_requirements);
-
- const int memory_size = buffer_requirements.size * 2;
-
- VkDeviceMemory mem;
- vkAllocMemory(device,
- &(VkMemoryAllocInfo) {
- .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
- .allocationSize = memory_size,
- .memProps = VK_MEMORY_PROPERTY_HOST_DEVICE_COHERENT_BIT,
- .memPriority = VK_MEMORY_PRIORITY_NORMAL
- }, &mem);
-
- void *map;
- vkMapMemory(device, mem, 0, buffer_requirements.size * 2, 0, &map);
-
- /* Fill the first buffer_size of the memory with a pattern */
- uint32_t *map32 = map;
- for (unsigned i = 0; i < buffer_size / sizeof(*map32); i++)
- map32[i] = i;
-
- /* Fill the rest with 0 */
- memset((char *)map + buffer_size, 0, memory_size - buffer_size);
-
- vkQueueBindObjectMemory(queue, VK_OBJECT_TYPE_BUFFER,
- buffer1,
- 0, /* allocation index; for objects which need to bind to multiple mems */
- mem, 0);
-
- vkQueueBindObjectMemory(queue, VK_OBJECT_TYPE_BUFFER,
- buffer2,
- 0, /* allocation index; for objects which need to bind to multiple mems */
- mem, buffer_requirements.size);
-
- VkCmdBuffer cmdBuffer;
- vkCreateCommandBuffer(device,
- &(VkCmdBufferCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO,
- .queueNodeIndex = 0,
- .flags = 0
- }, &cmdBuffer);
-
- vkBeginCommandBuffer(cmdBuffer,
- &(VkCmdBufferBeginInfo) {
- .sType = VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO,
- .flags = 0
- });
-
- vkCmdCopyBuffer(cmdBuffer, buffer1, buffer2, 1,
- &(VkBufferCopy) {
- .srcOffset = 0,
- .destOffset = 0,
- .copySize = buffer_size,
- });
-
- vkEndCommandBuffer(cmdBuffer);
-
- vkQueueSubmit(queue, 1, &cmdBuffer, 0);
-
- vkQueueWaitIdle(queue);
-
- vkDestroyObject(device, VK_OBJECT_TYPE_BUFFER, buffer1);
- vkDestroyObject(device, VK_OBJECT_TYPE_BUFFER, buffer2);
- vkDestroyObject(device, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer);
-
- uint32_t *map32_2 = map + buffer_requirements.size;
- for (unsigned i = 0; i < buffer_size / sizeof(*map32); i++) {
- if (map32[i] != map32_2[i]) {
- printf("buffer mismatch at dword %d: found 0x%x, expected 0x%x\n",
- i, map32_2[i], map32[i]);
- }
- }
-
- vkUnmapMemory(device, mem);
- vkFreeMemory(device, mem);
-}
-
-static void
-test_formats(VkDevice device, VkQueue queue)
-{
- VkFormatProperties properties;
- size_t size = sizeof(properties);
- uint32_t f;
-
- static const char *features[] = {
- "sampled_image",
- "storage_image",
- "storage_image_atomic",
- "uniform_texel_buffer",
- "storage_texel_buffer",
- "storage_texel_buffer_atomic",
- "vertex_buffer",
- "color_attachment",
- "color_attachment_blend",
- "depth_stencil_attachment",
- "conversion"
- };
-
- VkFormat format = VK_FORMAT_R32G32B32A32_SFLOAT;
- vkGetFormatInfo(device, format,
- VK_FORMAT_INFO_TYPE_PROPERTIES,
- &size, &properties);
-
- printf("format 0x%x:\n", format);
-
- printf(" linear tiling features (0x%x):", properties.linearTilingFeatures);
- for_each_bit(f, properties.linearTilingFeatures)
- printf(" %s", features[f]);
-
- printf("\n optimal tiling features (0x%x):", properties.optimalTilingFeatures);
- for_each_bit(f, properties.optimalTilingFeatures)
- printf(" %s", features[f]);
- printf("\n");
-}
-
-#define TEST_DEPTH_FLAG 0x01
-
-struct test_context {
- uint32_t width, height;
- VkDevice device;
- VkQueue queue;
- VkCmdBuffer cmdBuffer;
- VkPipeline pipeline;
- VkImage rt;
- VkImage ds;
- VkBuffer vertex_buffer;
- VkBuffer image_buffer;
- VkDeviceMemory mem;
- void *map;
- void *rt_map;
- void *vertex_map;
- void *image_map;
- VkDynamicVpState vp_state;
- VkDynamicRsState rs_state;
- VkDynamicDsState ds_state;
- VkDynamicCbState cb_state;
- VkColorAttachmentView rt_view;
- VkDepthStencilView ds_view;
- uint32_t rt_size;
- VkFramebuffer framebuffer;
- VkRenderPass pass;
-};
-
-static void
-test_prepare(struct test_context *ctx, VkDevice device, VkQueue queue, uint32_t flags)
-{
- ctx->device = device;
- ctx->queue = queue;
-
- vkCreateCommandBuffer(ctx->device,
- &(VkCmdBufferCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO,
- .queueNodeIndex = 0,
- .flags = 0
- },
- &ctx->cmdBuffer);
-
- vkCreateBuffer(ctx->device,
- &(VkBufferCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
- .size = 4096,
- .usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
- .flags = 0
- },
- &ctx->vertex_buffer);
-
- VkMemoryRequirements vb_requirements;
- size_t size = sizeof(vb_requirements);
- vkGetObjectInfo(ctx->device, VK_OBJECT_TYPE_BUFFER, ctx->vertex_buffer,
- VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
- &size, &vb_requirements);
-
- vkCreateImage(ctx->device,
- &(VkImageCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
- .imageType = VK_IMAGE_TYPE_2D,
- .format = VK_FORMAT_R8G8B8A8_UNORM,
- .extent = { .width = ctx->width, .height = ctx->height, .depth = 1 },
- .mipLevels = 1,
- .arraySize = 1,
- .samples = 1,
- .tiling = VK_IMAGE_TILING_OPTIMAL,
- .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
- .flags = 0,
- },
- &ctx->rt);
-
- VkMemoryRequirements rt_requirements;
- size = sizeof(rt_requirements);
- vkGetObjectInfo(ctx->device, VK_OBJECT_TYPE_IMAGE, ctx->rt,
- VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
- &size, &rt_requirements);
- ctx->rt_size = rt_requirements.size;
-
- VkDepthStencilBindInfo *ds_attachment;
- VkDepthStencilBindInfo ds_bind_info;
- VkMemoryRequirements ds_requirements;
-
- if (flags & TEST_DEPTH_FLAG) {
- vkCreateImage(ctx->device,
- &(VkImageCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
- .imageType = VK_IMAGE_TYPE_2D,
- .format = VK_FORMAT_D24_UNORM,
- .extent = { .width = ctx->width, .height = ctx->height, .depth = 1 },
- .mipLevels = 1,
- .arraySize = 1,
- .samples = 1,
- .tiling = VK_IMAGE_TILING_OPTIMAL,
- .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_BIT,
- .flags = 0,
- },
- &ctx->ds);
-
- size = sizeof(ds_requirements);
- vkGetObjectInfo(ctx->device, VK_OBJECT_TYPE_IMAGE, ctx->ds,
- VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
- &size, &ds_requirements);
- } else {
- ds_requirements.size = 0;
- }
-
- vkCreateBuffer(ctx->device,
- &(VkBufferCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
- .size = ctx->width * ctx->height * 4,
- .usage = VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT,
- .flags = 0
- },
- &ctx->image_buffer);
-
- VkMemoryRequirements ib_requirements;
- size = sizeof(ib_requirements);
- vkGetObjectInfo(ctx->device, VK_OBJECT_TYPE_BUFFER, ctx->image_buffer,
- VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
- &size, &ib_requirements);
-
- size_t mem_size =
- align_u32(vb_requirements.size, 4096) +
- align_u32(rt_requirements.size, 4096) +
- align_u32(ds_requirements.size, 4096) +
- align_u32(ib_requirements.size, 4096);
-
- printf("mem size %ld\n", mem_size);
-
- vkAllocMemory(ctx->device,
- &(VkMemoryAllocInfo) {
- .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
- .allocationSize = mem_size,
- .memProps = VK_MEMORY_PROPERTY_HOST_DEVICE_COHERENT_BIT,
- .memPriority = VK_MEMORY_PRIORITY_NORMAL
- },
- &ctx->mem);
-
- vkMapMemory(ctx->device, ctx->mem, 0, mem_size, 0, &ctx->map);
- memset(ctx->map, 0, mem_size);
-
- uint32_t offset = 0;
- printf("vb: %ldb at %d\n", vb_requirements.size, offset);
- vkQueueBindObjectMemory(ctx->queue, VK_OBJECT_TYPE_BUFFER,
- ctx->vertex_buffer, 0, ctx->mem, offset);
- ctx->vertex_map = ctx->map + offset;
- offset = align_u32(offset + vb_requirements.size, 4096);
-
- printf("rt: %ldb at %d\n", rt_requirements.size, offset);
- vkQueueBindObjectMemory(ctx->queue, VK_OBJECT_TYPE_IMAGE,
- ctx->rt, 0, ctx->mem, offset);
- ctx->rt_map = ctx->map + offset;
- offset = align_u32(offset + rt_requirements.size, 4096);
-
- if (flags & TEST_DEPTH_FLAG) {
- printf("ds: %ldb at %d\n", ds_requirements.size, offset);
- vkQueueBindObjectMemory(ctx->queue, VK_OBJECT_TYPE_IMAGE,
- ctx->ds, 0, ctx->mem, offset);
- offset = align_u32(offset + ds_requirements.size, 4096);
- }
-
- printf("ib: %ldb at %d\n", ib_requirements.size, offset);
- vkQueueBindObjectMemory(ctx->queue, VK_OBJECT_TYPE_BUFFER,
- ctx->image_buffer, 0, ctx->mem, offset);
- ctx->image_map = ctx->map + offset;
- offset = align_u32(offset + ib_requirements.size, 4096);
-
- vkCreateDynamicViewportState(ctx->device,
- &(VkDynamicVpStateCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO,
- .viewportAndScissorCount = 1,
- .pViewports = (VkViewport[]) {
- {
- .originX = 0,
- .originY = 0,
- .width = ctx->width,
- .height = ctx->height,
- .minDepth = -1,
- .maxDepth = 1
- },
- },
- .pScissors = (VkRect[]) {
- { { 0, 0 }, { ctx->width, ctx->height } },
- }
- },
- &ctx->vp_state);
-
- vkCreateDynamicRasterState(ctx->device,
- &(VkDynamicRsStateCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO,
- },
- &ctx->rs_state);
-
- vkCreateDynamicDepthStencilState(ctx->device,
- &(VkDynamicDsStateCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_DYNAMIC_DS_STATE_CREATE_INFO,
- },
- &ctx->ds_state);
-
- vkCreateDynamicColorBlendState(ctx->device,
- &(VkDynamicCbStateCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_DYNAMIC_CB_STATE_CREATE_INFO
- },
- &ctx->cb_state);
-
- vkCreateColorAttachmentView(ctx->device,
- &(VkColorAttachmentViewCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO,
- .image = ctx->rt,
- .format = VK_FORMAT_R8G8B8A8_UNORM,
- .mipLevel = 0,
- .baseArraySlice = 0,
- .arraySize = 1,
- .msaaResolveImage = 0,
- .msaaResolveSubResource = { 0, }
- },
- &ctx->rt_view);
-
- if (flags & TEST_DEPTH_FLAG) {
- vkCreateDepthStencilView(ctx->device,
- &(VkDepthStencilViewCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO,
- .image = ctx->ds,
- .mipLevel = 0,
- .baseArraySlice = 0,
- .arraySize = 1,
- .msaaResolveImage = 0,
- .msaaResolveSubResource = { 0, }
- },
- &ctx->ds_view);
- ds_bind_info.view = ctx->ds_view;
- ds_bind_info.layout = 0;
- ds_attachment = &ds_bind_info;
- } else {
- ds_attachment = NULL;
- }
-
- vkCreateFramebuffer(ctx->device,
- &(VkFramebufferCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
- .colorAttachmentCount = 1,
- .pColorAttachments = (VkColorAttachmentBindInfo[]) {
- {
- .view = ctx->rt_view,
- .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
- }
- },
- .pDepthStencilAttachment = ds_attachment,
- .sampleCount = 1,
- .width = ctx->width,
- .height = ctx->height,
- .layers = 1
- },
- &ctx->framebuffer);
-
- vkCreateRenderPass(ctx->device,
- &(VkRenderPassCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
- .renderArea = { { 0, 0 }, { ctx->width, ctx->height } },
- .colorAttachmentCount = 1,
- .extent = { },
- .sampleCount = 1,
- .layers = 1,
- .pColorFormats = (VkFormat[]) { VK_FORMAT_R8G8B8A8_UNORM },
- .pColorLayouts = (VkImageLayout[]) { VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL },
- .pColorLoadOps = (VkAttachmentLoadOp[]) { VK_ATTACHMENT_LOAD_OP_CLEAR },
- .pColorStoreOps = (VkAttachmentStoreOp[]) { VK_ATTACHMENT_STORE_OP_STORE },
- .pColorLoadClearValues = (VkClearColor[]) {
- { .color = { .floatColor = { 0.2, 0.2, 0.2, 1.0 } }, .useRawValue = false }
- },
- .depthStencilFormat = VK_FORMAT_D24_UNORM,
- .depthStencilLayout = 0,
- .depthLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
- .depthLoadClearValue = 0.5,
- .depthStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
- },
- &ctx->pass);
-
- vkBeginCommandBuffer(ctx->cmdBuffer,
- &(VkCmdBufferBeginInfo) {
- .sType = VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO,
- .flags = 0
- });
-
- vkCmdBeginRenderPass(ctx->cmdBuffer,
- &(VkRenderPassBegin) {
- .renderPass = ctx->pass,
- .framebuffer = ctx->framebuffer
- });
-}
-
-static void
-test_finish(struct test_context *ctx)
-{
- vkCmdEndRenderPass(ctx->cmdBuffer, ctx->pass);
-
- VkBufferImageCopy copy = {
- .bufferOffset = 0,
- .imageSubresource = {
- .aspect = VK_IMAGE_ASPECT_COLOR,
- .mipLevel = 0,
- .arraySlice = 0,
- },
- .imageOffset = { .x = 0, .y = 0, .z = 0 },
- .imageExtent = { .width = ctx->width, .height = ctx->height, .depth = 1 },
- };
-
- vkCmdCopyImageToBuffer(ctx->cmdBuffer, ctx->rt, VK_IMAGE_LAYOUT_GENERAL,
- ctx->image_buffer, 1, ©);
-
-
- vkEndCommandBuffer(ctx->cmdBuffer);
-
- vkQueueSubmit(ctx->queue, 1, &ctx->cmdBuffer, 0);
-
- vkQueueWaitIdle(ctx->queue);
-
- write_png("vk-map.png", ctx->width, ctx->height, 1024, ctx->rt_map);
- write_png("vk-copy.png", ctx->width, ctx->height, 1024, ctx->image_map);
-
- vkDestroyObject(ctx->device, VK_OBJECT_TYPE_COMMAND_BUFFER, ctx->cmdBuffer);
- vkDestroyObject(ctx->device, VK_OBJECT_TYPE_PIPELINE, ctx->pipeline);
- vkDestroyObject(ctx->device, VK_OBJECT_TYPE_IMAGE, ctx->rt);
- vkDestroyObject(ctx->device, VK_OBJECT_TYPE_BUFFER, ctx->vertex_buffer);
- vkDestroyObject(ctx->device, VK_OBJECT_TYPE_BUFFER, ctx->image_buffer);
- vkUnmapMemory(ctx->device, ctx->mem);
- vkFreeMemory(ctx->device, ctx->mem);
- vkDestroyObject(ctx->device, VK_OBJECT_TYPE_DYNAMIC_VP_STATE, ctx->vp_state);
- vkDestroyObject(ctx->device, VK_OBJECT_TYPE_DYNAMIC_RS_STATE, ctx->rs_state);
- vkDestroyObject(ctx->device, VK_OBJECT_TYPE_DYNAMIC_CB_STATE, ctx->cb_state);
- vkDestroyObject(ctx->device, VK_OBJECT_TYPE_COLOR_ATTACHMENT_VIEW, ctx->rt_view);
- vkDestroyObject(ctx->device, VK_OBJECT_TYPE_FRAMEBUFFER, ctx->framebuffer);
- vkDestroyObject(ctx->device, VK_OBJECT_TYPE_RENDER_PASS, ctx->pass);
-}
-
-static void
-test_create_solid_color_pipeline(struct test_context *ctx)
-{
- VkPipelineIaStateCreateInfo ia_create_info = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO,
- .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
- .disableVertexReuse = false,
- .primitiveRestartEnable = false,
- .primitiveRestartIndex = 0
- };
-
- VkShader vs = GLSL_VK_SHADER(ctx->device, VERTEX,
- layout(location = 0) in vec4 a_position;
- layout(location = 1) in vec4 a_color;
- out vec4 v_color;
- void main()
- {
- gl_Position = a_position;
- v_color = a_color;
- }
- );
-
- VkShader fs = GLSL_VK_SHADER(ctx->device, FRAGMENT,
- out vec4 f_color;
- in vec4 v_color;
- void main()
- {
- f_color = v_color;
- }
- );
-
- VkPipelineShaderStageCreateInfo vs_create_info = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
- .pNext = &ia_create_info,
- .shader = {
- .stage = VK_SHADER_STAGE_VERTEX,
- .shader = vs,
- .linkConstBufferCount = 0,
- .pLinkConstBufferInfo = NULL,
- .pSpecializationInfo = NULL
- }
- };
-
- VkPipelineShaderStageCreateInfo fs_create_info = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
- .pNext = &vs_create_info,
- .shader = {
- .stage = VK_SHADER_STAGE_FRAGMENT,
- .shader = fs,
- .linkConstBufferCount = 0,
- .pLinkConstBufferInfo = NULL,
- .pSpecializationInfo = NULL
- }
- };
-
- VkPipelineVertexInputCreateInfo vi_create_info = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO,
- .pNext = &fs_create_info,
- .bindingCount = 2,
- .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
- {
- .binding = 0,
- .strideInBytes = 16,
- .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
- },
- {
- .binding = 1,
- .strideInBytes = 16,
- .stepRate = VK_VERTEX_INPUT_STEP_RATE_INSTANCE
- }
- },
- .attributeCount = 2,
- .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
- {
- .location = 0,
- .binding = 0,
- .format = VK_FORMAT_R32G32B32A32_SFLOAT,
- .offsetInBytes = 0
- },
- {
- .location = 1,
- .binding = 1,
- .format = VK_FORMAT_R32G32B32A32_SFLOAT,
- .offsetInBytes = 0
- }
- }
- };
-
- VkPipelineRsStateCreateInfo rs_create_info = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO,
- .pNext = &vi_create_info,
-
- .depthClipEnable = true,
- .rasterizerDiscardEnable = false,
- .fillMode = VK_FILL_MODE_SOLID,
- .cullMode = VK_CULL_MODE_NONE,
- .frontFace = VK_FRONT_FACE_CCW
- };
-
- VkPipelineDsStateCreateInfo ds_create_info = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_DS_STATE_CREATE_INFO,
- .pNext = &rs_create_info,
- .format = VK_FORMAT_D24_UNORM,
- .depthTestEnable = true,
- .depthWriteEnable = true,
- .depthCompareOp = VK_COMPARE_OP_GREATER
- };
-
- VkPipelineCbStateCreateInfo cb_create_info = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO,
- .pNext = &ds_create_info,
- .attachmentCount = 1,
- .pAttachments = (VkPipelineCbAttachmentState []) {
- { .channelWriteMask = VK_CHANNEL_A_BIT |
- VK_CHANNEL_R_BIT | VK_CHANNEL_G_BIT | VK_CHANNEL_B_BIT },
- }
- };
-
- vkCreateGraphicsPipeline(ctx->device,
- &(VkGraphicsPipelineCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
- .pNext = &cb_create_info,
- .flags = 0,
- .layout = VK_NULL_HANDLE
- },
- &ctx->pipeline);
-
- vkDestroyObject(ctx->device, VK_OBJECT_TYPE_SHADER, fs);
- vkDestroyObject(ctx->device, VK_OBJECT_TYPE_SHADER, vs);
-}
-
-static void
-test_depth_stencil(VkDevice device, VkQueue queue)
-{
- struct test_context ctx;
-
- ctx.width = 256;
- ctx.height = 256;
-
- test_prepare(&ctx, device, queue, TEST_DEPTH_FLAG);
- test_create_solid_color_pipeline(&ctx);
-
- static const float vertex_data[] = {
- /* Triangle coordinates */
- -0.5, -0.5, 0.5, 1.0,
- 0.5, -0.5, 0.5, 1.0,
- 0.0, 0.5, 0.5, 1.0,
-
- /* Triangle coordinates */
- -0.3, -0.3, 0.0, 1.0,
- 0.7, -0.3, 0.0, 1.0,
- 0.2, 0.7, 0.8, 1.0,
-
- /* Color */
- 1.0, 1.0, 0.2, 1.0,
- 0.2, 0.2, 1.0, 1.0,
- };
- memcpy(ctx.vertex_map, vertex_data, sizeof(vertex_data));
-
- vkCmdBindVertexBuffers(ctx.cmdBuffer, 0, 2,
- (VkBuffer[]) { ctx.vertex_buffer, ctx.vertex_buffer },
- (VkDeviceSize[]) { 0, 6 * 4 * sizeof(float) });
-
- vkCmdBindPipeline(ctx.cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx.pipeline);
-
- vkCmdBindDynamicStateObject(ctx.cmdBuffer,
- VK_STATE_BIND_POINT_VIEWPORT, ctx.vp_state);
- vkCmdBindDynamicStateObject(ctx.cmdBuffer,
- VK_STATE_BIND_POINT_RASTER, ctx.rs_state);
- vkCmdBindDynamicStateObject(ctx.cmdBuffer,
- VK_STATE_BIND_POINT_DEPTH_STENCIL, ctx.ds_state);
- vkCmdBindDynamicStateObject(ctx.cmdBuffer,
- VK_STATE_BIND_POINT_COLOR_BLEND, ctx.cb_state);
-
- vkCmdDraw(ctx.cmdBuffer, 0, 3, 0, 1);
- vkCmdDraw(ctx.cmdBuffer, 3, 3, 1, 1);
-
- test_finish(&ctx);
-}
-
-static void
-test_triangle(VkDevice device, VkQueue queue)
-{
- uint32_t count;
-
- VkCmdBuffer cmdBuffer;
- vkCreateCommandBuffer(device,
- &(VkCmdBufferCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO,
- .queueNodeIndex = 0,
- .flags = 0
- },
- &cmdBuffer);
-
-
- VkDescriptorSetLayout set_layout[2];
- vkCreateDescriptorSetLayout(device,
- &(VkDescriptorSetLayoutCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
- .count = 3,
- .pBinding = (VkDescriptorSetLayoutBinding[]) {
- {
- .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
- .count = 2,
- .stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
- .pImmutableSamplers = NULL
- },
- {
- .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
- .count = 1,
- .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
- .pImmutableSamplers = NULL
- },
- {
- .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
- .count = 1,
- .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
- .pImmutableSamplers = NULL
- }
- }
- },
- &set_layout[0]);
-
- vkCreateDescriptorSetLayout(device,
- &(VkDescriptorSetLayoutCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
- .count = 1,
- .pBinding = (VkDescriptorSetLayoutBinding[]) {
- {
- .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
- .count = 1,
- .stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
- .pImmutableSamplers = NULL
- }
- }
- },
- &set_layout[1]);
-
- VkPipelineLayout pipeline_layout;
- vkCreatePipelineLayout(device,
- &(VkPipelineLayoutCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
- .descriptorSetCount = 2,
- .pSetLayouts = set_layout,
- },
- &pipeline_layout);
-
- VkPipeline pipeline;
- create_pipeline(device, &pipeline, pipeline_layout);
-
- VkDescriptorSet set[2];
- vkAllocDescriptorSets(device, 0 /* pool */,
- VK_DESCRIPTOR_SET_USAGE_STATIC,
- 2, set_layout, set, &count);
-
- VkBuffer buffer;
- vkCreateBuffer(device,
- &(VkBufferCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
- .size = 1024,
- .usage = VK_BUFFER_USAGE_GENERAL,
- .flags = 0
- },
- &buffer);
-
- VkMemoryRequirements buffer_requirements;
- size_t size = sizeof(buffer_requirements);
- vkGetObjectInfo(device, VK_OBJECT_TYPE_BUFFER, buffer,
- VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
- &size, &buffer_requirements);
-
- int32_t width = 256, height = 256;
-
- VkImage rt;
- vkCreateImage(device,
- &(VkImageCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
- .imageType = VK_IMAGE_TYPE_2D,
- .format = VK_FORMAT_R8G8B8A8_UNORM,
- .extent = { .width = width, .height = height, .depth = 1 },
- .mipLevels = 1,
- .arraySize = 1,
- .samples = 1,
- .tiling = VK_IMAGE_TILING_OPTIMAL,
- .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
- .flags = 0,
- },
- &rt);
-
- VkMemoryRequirements rt_requirements;
- size = sizeof(rt_requirements);
- vkGetObjectInfo(device, VK_OBJECT_TYPE_IMAGE, rt,
- VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
- &size, &rt_requirements);
-
- VkBuffer vertex_buffer;
- vkCreateBuffer(device,
- &(VkBufferCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
- .size = 1024,
- .usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
- .flags = 0
- },
- &vertex_buffer);
-
- VkMemoryRequirements vb_requirements;
- size = sizeof(vb_requirements);
- vkGetObjectInfo(device, VK_OBJECT_TYPE_BUFFER, vertex_buffer,
- VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
- &size, &vb_requirements);
-
- VkBuffer image_buffer;
- vkCreateBuffer(device,
- &(VkBufferCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
- .size = width * height * 4,
- .usage = VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT,
- .flags = 0
- },
- &image_buffer);
-
- VkMemoryRequirements ib_requirements;
- size = sizeof(ib_requirements);
- vkGetObjectInfo(device, VK_OBJECT_TYPE_BUFFER, image_buffer,
- VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
- &size, &ib_requirements);
-
- printf("buffer size: %lu, buffer alignment: %lu\n",
- buffer_requirements.size, buffer_requirements.alignment);
- printf("rt size: %lu, rt alignment: %lu\n",
- rt_requirements.size, rt_requirements.alignment);
- printf("vb size: %lu vb alignment: %lu\n",
- vb_requirements.size, vb_requirements.alignment);
- printf("ib size: %lu ib alignment: %lu\n",
- ib_requirements.size, ib_requirements.alignment);
-
- size_t mem_size = rt_requirements.size + ib_requirements.size +
- 2048 + 16 * 16 * 4;
- VkDeviceMemory mem;
- vkAllocMemory(device,
- &(VkMemoryAllocInfo) {
- .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
- .allocationSize = mem_size,
- .memProps = VK_MEMORY_PROPERTY_HOST_DEVICE_COHERENT_BIT,
- .memPriority = VK_MEMORY_PRIORITY_NORMAL
- },
- &mem);
-
- void *map;
- vkMapMemory(device, mem, 0, mem_size, 0, &map);
- memset(map, 192, mem_size);
-
- vkQueueBindObjectMemory(queue, VK_OBJECT_TYPE_BUFFER,
- buffer,
- 0, /* allocation index; for objects which need to bind to multiple mems */
- mem, 128);
-
- float color[12] = {
- 0.0, 0.2, 0.0, 0.0,
- 0.0, 0.0, 0.5, 0.0,
- 0.0, 0.0, 0.5, 0.5
- };
- memcpy(map + 128 + 16, color, sizeof(color));
- VkBufferView buffer_view[3];
- vkCreateBufferView(device,
- &(VkBufferViewCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
- .buffer = buffer,
- .viewType = VK_BUFFER_VIEW_TYPE_RAW,
- .format = VK_FORMAT_R32G32B32A32_SFLOAT,
- .offset = 16,
- .range = 64
- },
- &buffer_view[0]);
-
- vkCreateBufferView(device,
- &(VkBufferViewCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
- .buffer = buffer,
- .viewType = VK_BUFFER_VIEW_TYPE_RAW,
- .format = VK_FORMAT_R32G32B32A32_SFLOAT,
- .offset = 32,
- .range = 64
- },
- &buffer_view[1]);
-
- vkCreateBufferView(device,
- &(VkBufferViewCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
- .buffer = buffer,
- .viewType = VK_BUFFER_VIEW_TYPE_RAW,
- .format = VK_FORMAT_R32G32B32A32_SFLOAT,
- .offset = 48,
- .range = 64
- },
- &buffer_view[2]);
-
- vkQueueBindObjectMemory(queue, VK_OBJECT_TYPE_BUFFER,
- vertex_buffer,
- 0, /* allocation index; for objects which need to bind to multiple mems */
- mem, 1024);
- static const float vertex_data[] = {
- /* Triangle coordinates */
- -0.5, -0.5, 0.0, 1.0,
- 0.5, -0.5, 0.0, 1.0,
- 0.0, 0.5, 0.0, 1.0,
- /* Color */
- 1.0, 0.0, 0.0, 0.2,
- };
- memcpy(map + 1024, vertex_data, sizeof(vertex_data));
-
- VkDynamicVpState vp_state;
- vkCreateDynamicViewportState(device,
- &(VkDynamicVpStateCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO,
- .viewportAndScissorCount = 2,
- .pViewports = (VkViewport[]) {
- {
- .originX = 0,
- .originY = 0,
- .width = width,
- .height = height,
- .minDepth = 0,
- .maxDepth = 1
- },
- {
- .originX = -10,
- .originY = -10,
- .width = 20,
- .height = 20,
- .minDepth = -1,
- .maxDepth = 1
- },
- },
- .pScissors = (VkRect[]) {
- { { 0, 0 }, { width, height } },
- { { 10, 10 }, { 236, 236 } }
- }
- },
- &vp_state);
-
- VkDynamicRsState rs_state;
- vkCreateDynamicRasterState(device,
- &(VkDynamicRsStateCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO,
- },
- &rs_state);
-
- VkDynamicCbState cb_state;
- vkCreateDynamicColorBlendState(device,
- &(VkDynamicCbStateCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_DYNAMIC_CB_STATE_CREATE_INFO
- },
- &cb_state);
-
- /* FIXME: Need to query memory info before binding to memory */
- vkQueueBindObjectMemory(queue, VK_OBJECT_TYPE_IMAGE,
- rt,
- 0, /* allocation index; for objects which need to bind to multiple mems */
- mem, 2048);
-
- vkQueueBindObjectMemory(queue, VK_OBJECT_TYPE_BUFFER,
- image_buffer,
- 0, /* allocation index; for objects which need to bind to multiple mems */
- mem, 2048 + rt_requirements.size);
-
- const uint32_t texture_width = 16, texture_height = 16;
- VkImage texture;
- vkCreateImage(device,
- &(VkImageCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
- .imageType = VK_IMAGE_TYPE_2D,
- .format = VK_FORMAT_R8G8B8A8_UNORM,
- .extent = { .width = texture_width, .height = texture_height, .depth = 1 },
- .mipLevels = 1,
- .arraySize = 1,
- .samples = 1,
- .tiling = VK_IMAGE_TILING_LINEAR,
- .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
- .flags = 0,
- },
- &texture);
-
- vkQueueBindObjectMemory(queue, VK_OBJECT_TYPE_IMAGE,
- texture,
- 0, /* allocation index; for objects which need to bind to multiple mems */
- mem, 2048 + 256 * 256 * 4);
-
- VkImageView image_view;
- vkCreateImageView(device,
- &(VkImageViewCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
- .image = texture,
- .viewType = VK_IMAGE_VIEW_TYPE_2D,
- .format = VK_FORMAT_R8G8B8A8_UNORM,
- .channels = {
- VK_CHANNEL_SWIZZLE_R,
- VK_CHANNEL_SWIZZLE_G,
- VK_CHANNEL_SWIZZLE_B,
- VK_CHANNEL_SWIZZLE_A
- },
- .subresourceRange = {
- .aspect = VK_IMAGE_ASPECT_COLOR,
- .baseMipLevel = 0,
- .mipLevels = 1,
- .baseArraySlice = 0,
- .arraySize = 1
- },
- .minLod = 0
- },
- &image_view);
-
- VkSampler sampler;
- vkCreateSampler(device,
- &(VkSamplerCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
- .magFilter = VK_TEX_FILTER_LINEAR,
- .minFilter = VK_TEX_FILTER_LINEAR,
- .mipMode = VK_TEX_MIPMAP_MODE_NEAREST,
- .addressU = VK_TEX_ADDRESS_CLAMP,
- .addressV = VK_TEX_ADDRESS_CLAMP,
- .addressW = VK_TEX_ADDRESS_CLAMP,
- .mipLodBias = 0,
- .maxAnisotropy = 0,
- .compareOp = VK_COMPARE_OP_GREATER,
- .minLod = 0,
- .maxLod = 0,
- .borderColor = VK_BORDER_COLOR_TRANSPARENT_BLACK
- },
- &sampler);
-
- vkUpdateDescriptors(device, set[0], 3,
- (const void * []) {
- &(VkUpdateBuffers) {
- .sType = VK_STRUCTURE_TYPE_UPDATE_BUFFERS,
- .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
- .arrayIndex = 0,
- .binding = 0,
- .count = 2,
- .pBufferViews = (VkBufferViewAttachInfo[]) {
- {
- .sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_ATTACH_INFO,
- .view = buffer_view[0]
- },
- {
- .sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_ATTACH_INFO,
- .view = buffer_view[1]
- }
- }
- },
- &(VkUpdateImages) {
- .sType = VK_STRUCTURE_TYPE_UPDATE_IMAGES,
- .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
- .binding = 2,
- .count = 1,
- .pImageViews = (VkImageViewAttachInfo[]) {
- {
- .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_ATTACH_INFO,
- .view = image_view,
- .layout = VK_IMAGE_LAYOUT_GENERAL,
- }
- }
- },
- &(const VkUpdateSamplers) {
- .sType = VK_STRUCTURE_TYPE_UPDATE_SAMPLERS,
- .binding = 3,
- .count = 1,
- .pSamplers = (const VkSampler[]) { sampler }
- }
- });
-
- vkUpdateDescriptors(device, set[1], 1,
- (const void * []) {
- &(VkUpdateBuffers) {
- .sType = VK_STRUCTURE_TYPE_UPDATE_BUFFERS,
- .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
- .arrayIndex = 0,
- .count = 1,
- .pBufferViews = (VkBufferViewAttachInfo[]) {
- {
- .sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_ATTACH_INFO,
- .view = buffer_view[2]
- }
- }
- }
- });
-
- VkColorAttachmentView view;
- vkCreateColorAttachmentView(device,
- &(VkColorAttachmentViewCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO,
- .image = rt,
- .format = VK_FORMAT_R8G8B8A8_UNORM,
- .mipLevel = 0,
- .baseArraySlice = 0,
- .arraySize = 1,
- .msaaResolveImage = 0,
- .msaaResolveSubResource = { 0, }
- },
- &view);
-
- VkFramebuffer framebuffer;
- vkCreateFramebuffer(device,
- &(VkFramebufferCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
- .colorAttachmentCount = 1,
- .pColorAttachments = (VkColorAttachmentBindInfo[]) {
- {
- .view = view,
- .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
- }
- },
- .pDepthStencilAttachment = NULL,
- .sampleCount = 1,
- .width = width,
- .height = height,
- .layers = 1
- },
- &framebuffer);
-
- VkRenderPass pass;
- vkCreateRenderPass(device,
- &(VkRenderPassCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
- .renderArea = { { 0, 0 }, { width, height } },
- .colorAttachmentCount = 1,
- .extent = { },
- .sampleCount = 1,
- .layers = 1,
- .pColorFormats = (VkFormat[]) { VK_FORMAT_R8G8B8A8_UNORM },
- .pColorLayouts = (VkImageLayout[]) { VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL },
- .pColorLoadOps = (VkAttachmentLoadOp[]) { VK_ATTACHMENT_LOAD_OP_CLEAR },
- .pColorStoreOps = (VkAttachmentStoreOp[]) { VK_ATTACHMENT_STORE_OP_STORE },
- .pColorLoadClearValues = (VkClearColor[]) {
- { .color = { .floatColor = { 1.0, 0.0, 0.0, 1.0 } }, .useRawValue = false }
- },
- .depthStencilFormat = VK_FORMAT_UNDEFINED,
- },
- &pass);
-
- VkQueryPool query_pool;
- vkCreateQueryPool(device,
- &(VkQueryPoolCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,
- .queryType = VK_QUERY_TYPE_OCCLUSION,
- .slots = 4,
- .pipelineStatistics = 0
- },
- &query_pool);
-
- vkBeginCommandBuffer(cmdBuffer,
- &(VkCmdBufferBeginInfo) {
- .sType = VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO,
- .flags = 0
- });
-
- vkCmdBeginRenderPass(cmdBuffer,
- &(VkRenderPassBegin) {
- .renderPass = pass,
- .framebuffer = framebuffer
- });
-
- vkCmdBindVertexBuffers(cmdBuffer, 0, 2,
- (VkBuffer[]) { vertex_buffer, vertex_buffer },
- (VkDeviceSize[]) { 0, 3 * 4 * sizeof(float) });
-
- vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
-
- vkCmdBindDescriptorSets(cmdBuffer,
- VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 1,
- &set[0], 0, NULL);
- vkCmdBindDescriptorSets(cmdBuffer,
- VK_PIPELINE_BIND_POINT_GRAPHICS, 1, 1,
- &set[1], 0, NULL);
-
- vkCmdBindDynamicStateObject(cmdBuffer,
- VK_STATE_BIND_POINT_VIEWPORT, vp_state);
- vkCmdBindDynamicStateObject(cmdBuffer,
- VK_STATE_BIND_POINT_RASTER, rs_state);
- vkCmdBindDynamicStateObject(cmdBuffer,
- VK_STATE_BIND_POINT_COLOR_BLEND, cb_state);
-
- vkCmdBeginQuery(cmdBuffer, query_pool, 0 /*slot*/, 0 /* flags */);
-
- vkCmdDraw(cmdBuffer, 0, 3, 0, 1);
-
- vkCmdEndQuery(cmdBuffer, query_pool, 0);
-
- vkCmdEndRenderPass(cmdBuffer, pass);
-
- vkCmdCopyQueryPoolResults(cmdBuffer, query_pool, 0, 1, buffer, 16, 8,
- VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT);
-
- VkBufferImageCopy copy = {
- .bufferOffset = 0,
- .imageSubresource = {
- .aspect = VK_IMAGE_ASPECT_COLOR,
- .mipLevel = 0,
- .arraySlice = 0,
- },
- .imageOffset = { .x = 0, .y = 0, .z = 0 },
- .imageExtent = { .width = width, .height = height, .depth = 1 },
- };
-
- vkCmdCopyImageToBuffer(cmdBuffer, rt, VK_IMAGE_LAYOUT_GENERAL,
- image_buffer, 1, ©);
-
- vkEndCommandBuffer(cmdBuffer);
-
- vkQueueSubmit(queue, 1, &cmdBuffer, 0);
-
- vkQueueWaitIdle(queue);
-
- /* Result gets written to buffer at offset 0. The buffer is bound to the
- * memory object at offset 128 */
- uint64_t *results = map + 128;
-
- uint64_t get_result;
- size = sizeof(get_result);
- vkGetQueryPoolResults(device, query_pool, 0, 1, &size, &get_result,
- VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
-
- printf("oc query (copy): %20ld (%016lx)\n", results[2], results[2]);
- printf("oc query (get): %20ld (%016lx)\n", get_result, get_result);
-
- write_png("vk-map.png", width, height, 1024, map + 2048);
- write_png("vk-copy.png", width, height, 1024,
- map + 2048 + rt_requirements.size);
-
- vkDestroyObject(device, VK_OBJECT_TYPE_IMAGE, texture);
- vkDestroyObject(device, VK_OBJECT_TYPE_IMAGE, rt);
- vkDestroyObject(device, VK_OBJECT_TYPE_BUFFER, buffer);
- vkDestroyObject(device, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer);
- vkDestroyObject(device, VK_OBJECT_TYPE_PIPELINE, pipeline);
- vkDestroyObject(device, VK_OBJECT_TYPE_QUERY_POOL, query_pool);
-}
-
-int main(int argc, char *argv[])
-{
- VkInstance instance;
- vkCreateInstance(&(VkInstanceCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
- .pAllocCb = &(VkAllocCallbacks) {
- .pUserData = NULL,
- .pfnAlloc = test_alloc,
- .pfnFree = test_free
- },
- .pAppInfo = &(VkApplicationInfo) {
- .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
- .pAppName = "vk",
- .apiVersion = 1
- }
- },
- &instance);
-
- uint32_t count = 1;
- VkPhysicalDevice physicalDevices[1];
- vkEnumeratePhysicalDevices(instance, &count, physicalDevices);
- printf("%d physical devices\n", count);
-
- VkPhysicalDeviceProperties properties;
- size_t size = sizeof(properties);
- vkGetPhysicalDeviceInfo(physicalDevices[0],
- VK_PHYSICAL_DEVICE_INFO_TYPE_PROPERTIES,
- &size, &properties);
- printf("vendor id %04x, device name %s\n",
- properties.vendorId, properties.deviceName);
-
- VkDevice device;
- vkCreateDevice(physicalDevices[0],
- &(VkDeviceCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
- .queueRecordCount = 1,
- .pRequestedQueues = &(VkDeviceQueueCreateInfo) {
- .queueNodeIndex = 0,
- .queueCount = 1
- }
- },
- &device);
-
- VkQueue queue;
- vkGetDeviceQueue(device, 0, 0, &queue);
-
- if (argc > 1 && strcmp(argv[1], "timestamp") == 0) {
- test_timestamp(device, queue);
- } else if (argc > 1 && strcmp(argv[1], "formats") == 0) {
- test_formats(device, queue);
- } else if (argc > 1 && strcmp(argv[1], "buffer-copy") == 0) {
- test_buffer_copy(device, queue);
- } else if (argc > 1 && strcmp(argv[1], "depth-stencil") == 0) {
- test_depth_stencil(device, queue);
- } else {
- test_triangle(device, queue);
- }
-
- vkDestroyDevice(device);
-
- vkDestroyInstance(instance);
-
- return 0;
-}