From: Kristian Høgsberg Date: Fri, 22 May 2015 22:18:37 +0000 (-0700) Subject: vk/test: Add new depth-stencil test X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7c0d0021ebe3a3d751491a8843bfe0dcfebef7de;p=mesa.git vk/test: Add new depth-stencil test Not yet a depth stencil test, but will become one. --- diff --git a/src/vulkan/vk.c b/src/vulkan/vk.c index ea21ece78a8..ff5e184865d 100644 --- a/src/vulkan/vk.c +++ b/src/vulkan/vk.c @@ -20,6 +20,12 @@ (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, ...) { @@ -423,6 +429,502 @@ test_formats(VkDevice device, VkQueue queue) 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; + 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); + + 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_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 + }; + + vkCreateGraphicsPipeline(ctx->device, + &(VkGraphicsPipelineCreateInfo) { + .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + .pNext = &ds_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); + + 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) { @@ -1023,6 +1525,8 @@ int main(int argc, char *argv[]) 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); }