diff options
| author | Courtney Goeltzenleuchter <courtney@LunarG.com> | 2015-03-25 13:36:41 -0600 |
|---|---|---|
| committer | Chia-I Wu <olv@lunarg.com> | 2015-04-16 17:33:26 +0800 |
| commit | 752eb8e937a67c4a0241966752524af5849e3be2 (patch) | |
| tree | 4025b63c8139f9a74b2db21c90eee4994c723977 | |
| parent | 967cbff8425d867596439a0c890d4b193e0f1273 (diff) | |
| download | usermoji-752eb8e937a67c4a0241966752524af5849e3be2.tar.xz | |
demos: Correct use of pipeline barrier
| -rw-r--r-- | demos/cube.c | 274 | ||||
| -rw-r--r-- | demos/tri.c | 278 |
2 files changed, 347 insertions, 205 deletions
diff --git a/demos/cube.c b/demos/cube.c index 11041ac1..0221afa5 100644 --- a/demos/cube.c +++ b/demos/cube.c @@ -21,10 +21,12 @@ /* * structure to track all objects related to a texture. */ -struct texture_objects { +struct texture_object { XGL_SAMPLER sampler; XGL_IMAGE image; + XGL_IMAGE_LAYOUT imageLayout; + uint32_t num_mem; XGL_GPU_MEMORY *mem; XGL_IMAGE_VIEW view; @@ -205,6 +207,7 @@ struct demo { XGL_DEVICE device; XGL_QUEUE queue; uint32_t graphics_queue_node_index; + XGL_PHYSICAL_GPU_PROPERTIES *gpu_props; XGL_PHYSICAL_GPU_QUEUE_PROPERTIES *queue_props; XGL_FRAMEBUFFER framebuffer; @@ -229,7 +232,7 @@ struct demo { XGL_DEPTH_STENCIL_VIEW view; } depth; - struct texture_objects textures[DEMO_TEXTURE_COUNT]; + struct texture_object textures[DEMO_TEXTURE_COUNT]; struct { XGL_BUFFER buf; @@ -239,6 +242,9 @@ struct demo { XGL_BUFFER_VIEW_ATTACH_INFO attach; } uniform_data; + XGL_CMD_BUFFER cmd; // Buffer for initialization commands + XGL_MEMORY_REF mem_refs[16]; + int num_refs; XGL_DESCRIPTOR_SET_LAYOUT desc_layout; XGL_PIPELINE pipeline; @@ -265,6 +271,108 @@ struct demo { uint32_t current_buffer; }; +static void demo_flush_init_cmd(struct demo *demo) +{ + XGL_RESULT err; + + if (demo->cmd == XGL_NULL_HANDLE) + return; + + err = xglEndCommandBuffer(demo->cmd); + assert(!err); + + const XGL_CMD_BUFFER cmd_bufs[] = { demo->cmd }; + + err = xglQueueSubmit(demo->queue, 1, cmd_bufs, + demo->num_refs, demo->mem_refs, XGL_NULL_HANDLE); + assert(!err); + + err = xglQueueWaitIdle(demo->queue); + assert(!err); + + xglDestroyObject(demo->cmd); + demo->cmd = XGL_NULL_HANDLE; + demo->num_refs = 0; +} + +static void demo_add_mem_refs( + struct demo *demo, + XGL_MEMORY_REF_FLAGS flags, + int num_refs, XGL_GPU_MEMORY *mem) +{ + for (int i = 0; i < num_refs; i++) { + demo->mem_refs[demo->num_refs].flags = flags; + demo->mem_refs[demo->num_refs].mem = mem[i]; + demo->num_refs++; + assert(demo->num_refs < 16); + } +} + +static void demo_set_image_layout( + struct demo *demo, + XGL_IMAGE image, + XGL_IMAGE_LAYOUT old_image_layout, + XGL_IMAGE_LAYOUT new_image_layout) +{ + XGL_RESULT err; + + if (demo->cmd == XGL_NULL_HANDLE) { + const XGL_CMD_BUFFER_CREATE_INFO cmd = { + .sType = XGL_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, + .pNext = NULL, + .queueNodeIndex = demo->graphics_queue_node_index, + .flags = 0, + }; + + err = xglCreateCommandBuffer(demo->device, &cmd, &demo->cmd); + assert(!err); + + XGL_CMD_BUFFER_BEGIN_INFO cmd_buf_info = { + .sType = XGL_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, + .pNext = NULL, + .flags = XGL_CMD_BUFFER_OPTIMIZE_GPU_SMALL_BATCH_BIT | + XGL_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, + }; + err = xglBeginCommandBuffer(demo->cmd, &cmd_buf_info); + } + + XGL_IMAGE_MEMORY_BARRIER image_memory_barrier = { + .sType = XGL_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = NULL, + .outputMask = 0, + .inputMask = 0, + .oldLayout = old_image_layout, + .newLayout = new_image_layout, + .image = image, + .subresourceRange = { XGL_IMAGE_ASPECT_COLOR, 0, 1, 0, 0 } + }; + + if (new_image_layout == XGL_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL) { + /* Make sure anything that was copying from this image has completed */ + image_memory_barrier.inputMask = XGL_MEMORY_INPUT_COPY_BIT; + } + + if (new_image_layout == XGL_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { + /* Make sure any Copy or CPU writes to image are flushed */ + image_memory_barrier.outputMask = XGL_MEMORY_OUTPUT_COPY_BIT | XGL_MEMORY_OUTPUT_CPU_WRITE_BIT; + } + + XGL_IMAGE_MEMORY_BARRIER *pmemory_barrier = &image_memory_barrier; + + XGL_PIPE_EVENT set_events[] = { XGL_PIPE_EVENT_TOP_OF_PIPE }; + + XGL_PIPELINE_BARRIER pipeline_barrier; + pipeline_barrier.sType = XGL_STRUCTURE_TYPE_PIPELINE_BARRIER; + pipeline_barrier.pNext = NULL; + pipeline_barrier.eventCount = 1; + pipeline_barrier.pEvents = set_events; + pipeline_barrier.waitEvent = XGL_WAIT_EVENT_TOP_OF_PIPE; + pipeline_barrier.memBarrierCount = 1; + pipeline_barrier.ppMemBarriers = (const void **)&pmemory_barrier; + + xglCmdPipelineBarrier(demo->cmd, &pipeline_barrier); +} + static void demo_draw_build_cmd(struct demo *demo, XGL_CMD_BUFFER cmd_buf) { const XGL_COLOR_ATTACHMENT_BIND_INFO color_attachment = { @@ -472,6 +580,10 @@ static void demo_prepare_buffers(struct demo *demo) &demo->buffers[i].image, &demo->buffers[i].mem); assert(!err); + demo_set_image_layout(demo, demo->buffers[i].image, + XGL_IMAGE_LAYOUT_UNDEFINED, + XGL_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + color_attachment_view.image = demo->buffers[i].image; err = xglCreateColorAttachmentView(demo->device, @@ -536,7 +648,6 @@ static void demo_prepare_depth(struct demo *demo) &demo->depth.image); assert(!err); - err = xglGetObjectInfo(demo->depth.image, XGL_INFO_TYPE_MEMORY_ALLOCATION_COUNT, &num_alloc_size, &num_allocations); assert(!err && num_alloc_size == sizeof(num_allocations)); mem_reqs = malloc(num_allocations * sizeof(XGL_MEMORY_REQUIREMENTS)); @@ -567,6 +678,12 @@ static void demo_prepare_depth(struct demo *demo) assert(!err); } + demo_set_image_layout(demo, demo->depth.image, + XGL_IMAGE_LAYOUT_UNDEFINED, + XGL_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + + demo_add_mem_refs(demo, XGL_MEMORY_REF_READ_ONLY_BIT, num_allocations, demo->depth.mem); + /* create image view */ view.image = demo->depth.image; err = xglCreateDepthStencilView(demo->device, &view, @@ -724,7 +841,7 @@ bool loadTexture(const char *filename, uint8_t *rgba_data, static void demo_prepare_texture_image(struct demo *demo, const char *filename, - struct texture_objects *tex_objs, + struct texture_object *tex_obj, XGL_IMAGE_TILING tiling, XGL_FLAGS mem_props) { @@ -736,8 +853,8 @@ static void demo_prepare_texture_image(struct demo *demo, err = loadTexture(filename, NULL, NULL, &tex_width, &tex_height); assert(err); - tex_objs->tex_width = tex_width; - tex_objs->tex_height = tex_height; + tex_obj->tex_width = tex_width; + tex_obj->tex_height = tex_height; const XGL_IMAGE_CREATE_INFO image_create_info = { .sType = XGL_STRUCTURE_TYPE_IMAGE_CREATE_INFO, @@ -779,20 +896,20 @@ static void demo_prepare_texture_image(struct demo *demo, size_t num_alloc_size = sizeof(num_allocations); err = xglCreateImage(demo->device, &image_create_info, - &tex_objs->image); + &tex_obj->image); assert(!err); - err = xglGetObjectInfo(tex_objs->image, + err = xglGetObjectInfo(tex_obj->image, XGL_INFO_TYPE_MEMORY_ALLOCATION_COUNT, &num_alloc_size, &num_allocations); assert(!err && num_alloc_size == sizeof(num_allocations)); mem_reqs = malloc(num_allocations * sizeof(XGL_MEMORY_REQUIREMENTS)); - tex_objs->mem = malloc(num_allocations * sizeof(XGL_GPU_MEMORY)); - err = xglGetObjectInfo(tex_objs->image, + tex_obj->mem = malloc(num_allocations * sizeof(XGL_GPU_MEMORY)); + err = xglGetObjectInfo(tex_obj->image, XGL_INFO_TYPE_MEMORY_REQUIREMENTS, &mem_reqs_size, mem_reqs); assert(!err && mem_reqs_size == num_allocations * sizeof(XGL_MEMORY_REQUIREMENTS)); - err = xglGetObjectInfo(tex_objs->image, + err = xglGetObjectInfo(tex_obj->image, XGL_INFO_TYPE_IMAGE_MEMORY_REQUIREMENTS, &img_reqs_size, &img_reqs); assert(!err && img_reqs_size == sizeof(XGL_IMAGE_MEMORY_REQUIREMENTS)); @@ -805,7 +922,7 @@ static void demo_prepare_texture_image(struct demo *demo, mem_alloc.allocationSize = mem_reqs[j].size; if (mem_alloc.memType == XGL_MEMORY_TYPE_BUFFER) { - err = xglGetObjectInfo(tex_objs->image, + err = xglGetObjectInfo(tex_obj->image, XGL_INFO_TYPE_BUFFER_MEMORY_REQUIREMENTS, &buf_reqs_size, &buf_reqs); assert(!err && buf_reqs_size == sizeof(XGL_BUFFER_MEMORY_REQUIREMENTS)); @@ -817,17 +934,17 @@ static void demo_prepare_texture_image(struct demo *demo, /* allocate memory */ err = xglAllocMemory(demo->device, &mem_alloc, - &(tex_objs->mem[j])); + &(tex_obj->mem[j])); assert(!err); /* bind memory */ - err = xglBindObjectMemory(tex_objs->image, j, tex_objs->mem[j], 0); + err = xglBindObjectMemory(tex_obj->image, j, tex_obj->mem[j], 0); assert(!err); } free(mem_reqs); mem_reqs = NULL; - tex_objs->num_mem = num_allocations; + tex_obj->num_mem = num_allocations; if (mem_props & XGL_MEMORY_PROPERTY_CPU_VISIBLE_BIT) { const XGL_IMAGE_SUBRESOURCE subres = { @@ -839,26 +956,32 @@ static void demo_prepare_texture_image(struct demo *demo, size_t layout_size = sizeof(XGL_SUBRESOURCE_LAYOUT); void *data; - err = xglGetImageSubresourceInfo(tex_objs->image, &subres, + err = xglGetImageSubresourceInfo(tex_obj->image, &subres, XGL_INFO_TYPE_SUBRESOURCE_LAYOUT, &layout_size, &layout); assert(!err && layout_size == sizeof(layout)); /* Linear texture must be within a single memory object */ assert(num_allocations == 1); - err = xglMapMemory(tex_objs->mem[0], 0, &data); + err = xglMapMemory(tex_obj->mem[0], 0, &data); assert(!err); if (!loadTexture(filename, data, &layout, &tex_width, &tex_height)) { fprintf(stderr, "Error loading texture: %s\n", filename); } - err = xglUnmapMemory(tex_objs->mem[0]); + err = xglUnmapMemory(tex_obj->mem[0]); assert(!err); } + + tex_obj->imageLayout = XGL_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + demo_set_image_layout(demo, tex_obj->image, + XGL_IMAGE_LAYOUT_UNDEFINED, + tex_obj->imageLayout); + /* setting the image layout does not reference the actual memory so no need to add a mem ref */ } -static void demo_destroy_texture_image(struct texture_objects *tex_objs) +static void demo_destroy_texture_image(struct texture_object *tex_objs) { /* clean up staging resources */ for (uint32_t j = 0; j < tex_objs->num_mem; j ++) { @@ -889,9 +1012,9 @@ static void demo_prepare_textures(struct demo *demo) /* Device can texture using linear textures */ demo_prepare_texture_image(demo, tex_files[i], &demo->textures[i], XGL_LINEAR_TILING, XGL_MEMORY_PROPERTY_CPU_VISIBLE_BIT); - } else if (props.optimalTilingFeatures & XGL_FORMAT_IMAGE_SHADER_READ_BIT){ + } else if (props.optimalTilingFeatures & XGL_FORMAT_IMAGE_SHADER_READ_BIT) { /* Must use staging buffer to copy linear texture to optimized */ - struct texture_objects staging_texture; + struct texture_object staging_texture; memset(&staging_texture, 0, sizeof(staging_texture)); demo_prepare_texture_image(demo, tex_files[i], &staging_texture, @@ -900,29 +1023,13 @@ static void demo_prepare_textures(struct demo *demo) demo_prepare_texture_image(demo, tex_files[i], &demo->textures[i], XGL_OPTIMAL_TILING, XGL_MEMORY_PROPERTY_GPU_ONLY); - XGL_CMD_BUFFER staging_cmd_buf; - XGL_CMD_BUFFER_CREATE_INFO cmd_buf_create_info = { - .sType = XGL_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, - .pNext = NULL, - .queueNodeIndex = demo->graphics_queue_node_index, - .flags = 0 - }; + demo_set_image_layout(demo, staging_texture.image, + staging_texture.imageLayout, + XGL_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL); - err = xglCreateCommandBuffer(demo->device, &cmd_buf_create_info, &staging_cmd_buf); - assert(!err); - - /* Copy staging texture to usable texture */ - XGL_CMD_BUFFER_BEGIN_INFO cmd_buf_begin_info = { - .sType = XGL_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, - .pNext = NULL, - .flags = 0 - }; - - err = xglResetCommandBuffer(staging_cmd_buf); - assert(!err); - - err = xglBeginCommandBuffer(staging_cmd_buf, &cmd_buf_begin_info); - assert(!err); + demo_set_image_layout(demo, demo->textures[i].image, + demo->textures[i].imageLayout, + XGL_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL); XGL_IMAGE_COPY copy_region = { .srcSubresource = { XGL_IMAGE_ASPECT_COLOR, 0, 0 }, @@ -931,69 +1038,21 @@ static void demo_prepare_textures(struct demo *demo) .destOffset = { 0, 0, 0 }, .extent = { staging_texture.tex_width, staging_texture.tex_height, 1 }, }; - xglCmdCopyImage(staging_cmd_buf, - staging_texture.image, - XGL_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL, - demo->textures[i].image, - XGL_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, + xglCmdCopyImage(demo->cmd, + staging_texture.image, XGL_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL, + demo->textures[i].image, XGL_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, 1, ©_region); - XGL_IMAGE_MEMORY_BARRIER image_memory_barrier = { - .sType = XGL_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .pNext = NULL, - .outputMask = XGL_MEMORY_OUTPUT_COPY_BIT, - .inputMask = XGL_MEMORY_INPUT_SHADER_READ_BIT | XGL_MEMORY_INPUT_COPY_BIT, - .oldLayout = XGL_IMAGE_LAYOUT_GENERAL, - .newLayout = XGL_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL, - .image = staging_texture.image, - .subresourceRange = { XGL_IMAGE_ASPECT_COLOR, 0, 1, 0, 0 } - }; - XGL_IMAGE_MEMORY_BARRIER *pmemory_barrier = &image_memory_barrier; - - XGL_PIPE_EVENT set_events[] = { XGL_PIPE_EVENT_GPU_COMMANDS_COMPLETE }; - XGL_PIPELINE_BARRIER pipeline_barrier; - pipeline_barrier.sType = XGL_STRUCTURE_TYPE_PIPELINE_BARRIER; - pipeline_barrier.pNext = NULL; - pipeline_barrier.eventCount = 1; - pipeline_barrier.pEvents = set_events; - pipeline_barrier.waitEvent = XGL_WAIT_EVENT_TOP_OF_PIPE; - pipeline_barrier.memBarrierCount = 1; - pipeline_barrier.ppMemBarriers = (const void **)&pmemory_barrier; - - // write barrier to the command buffer - xglCmdPipelineBarrier(staging_cmd_buf, &pipeline_barrier); - - err = xglEndCommandBuffer(staging_cmd_buf); - assert(!err); - - const XGL_CMD_BUFFER cmd_bufs[] = { staging_cmd_buf }; - XGL_MEMORY_REF mem_refs[16]; - uint32_t num_refs = 0; - - for (uint32_t j = 0; j < staging_texture.num_mem; j++) { - mem_refs[num_refs].flags = XGL_MEMORY_REF_READ_ONLY_BIT; - mem_refs[num_refs].mem = staging_texture.mem[j]; - num_refs++; - assert(num_refs < 16); - } - - for (uint32_t j = 0; j < demo->textures[i].num_mem; j++) { - mem_refs[num_refs].flags = XGL_MEMORY_REF_READ_ONLY_BIT; - mem_refs[num_refs].mem = demo->textures[i].mem[j]; - num_refs++; - assert(num_refs < 16); - } + demo_add_mem_refs(demo, XGL_MEMORY_REF_READ_ONLY_BIT, staging_texture.num_mem, staging_texture.mem); + demo_add_mem_refs(demo, 0, demo->textures[i].num_mem, demo->textures[i].mem); - err = xglQueueSubmit(demo->queue, 1, cmd_bufs, - num_refs, mem_refs, XGL_NULL_HANDLE); - assert(!err); + demo_set_image_layout(demo, demo->textures[i].image, + XGL_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, + demo->textures[i].imageLayout); - err = xglQueueWaitIdle(demo->queue); - assert(!err); + demo_flush_init_cmd(demo); demo_destroy_texture_image(&staging_texture); - - xglDestroyObject(staging_cmd_buf); } else { /* Can't support XGL_FMT_B8G8R8A8_UNORM !? */ assert(!"No support for tB8G8R8A8_UNORM as texture image format"); @@ -1562,6 +1621,12 @@ static void demo_prepare(struct demo *demo) demo_draw_build_cmd(demo, demo->buffers[i].cmd); } + /* + * Prepare functions above may generate pipeline commands + * that need to be flushed before beginning the render loop. + */ + demo_flush_init_cmd(demo); + demo->current_buffer = 0; } @@ -1730,6 +1795,15 @@ static void demo_init_xgl(struct demo *demo) err = xglCreateDevice(demo->gpu, &device, &demo->device); assert(!err); + err = xglGetGpuInfo(demo->gpu, XGL_INFO_TYPE_PHYSICAL_GPU_PROPERTIES, + &data_size, NULL); + assert(!err); + + demo->gpu_props = (XGL_PHYSICAL_GPU_PROPERTIES *) malloc(data_size); + err = xglGetGpuInfo(demo->gpu, XGL_INFO_TYPE_PHYSICAL_GPU_PROPERTIES, + &data_size, demo->gpu_props); + assert(!err); + err = xglGetGpuInfo(demo->gpu, XGL_INFO_TYPE_PHYSICAL_GPU_QUEUE_PROPERTIES, &data_size, NULL); assert(!err); diff --git a/demos/tri.c b/demos/tri.c index 5e5dfb08..375300db 100644 --- a/demos/tri.c +++ b/demos/tri.c @@ -20,10 +20,12 @@ #define DEMO_BUFFER_COUNT 2 #define DEMO_TEXTURE_COUNT 1 -struct texture_objects { +struct texture_object { XGL_SAMPLER sampler; XGL_IMAGE image; + XGL_IMAGE_LAYOUT imageLayout; + uint32_t num_mem; XGL_GPU_MEMORY *mem; XGL_IMAGE_VIEW view; @@ -38,6 +40,7 @@ struct demo { XGL_PHYSICAL_GPU gpu; XGL_DEVICE device; XGL_QUEUE queue; + XGL_PHYSICAL_GPU_PROPERTIES *gpu_props; XGL_PHYSICAL_GPU_QUEUE_PROPERTIES *queue_props; uint32_t graphics_queue_node_index; @@ -61,7 +64,7 @@ struct demo { XGL_DEPTH_STENCIL_VIEW view; } depth; - struct texture_objects textures[DEMO_TEXTURE_COUNT]; + struct texture_object textures[DEMO_TEXTURE_COUNT]; struct { XGL_BUFFER buf; @@ -73,6 +76,9 @@ struct demo { XGL_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION vi_attrs[2]; } vertices; + XGL_CMD_BUFFER cmd; // Buffer for initialization commands + XGL_MEMORY_REF mem_refs[16]; + int num_refs; XGL_DESCRIPTOR_SET_LAYOUT desc_layout; XGL_PIPELINE pipeline; @@ -81,8 +87,6 @@ struct demo { XGL_DYNAMIC_CB_STATE_OBJECT color_blend; XGL_DYNAMIC_DS_STATE_OBJECT depth_stencil; - XGL_CMD_BUFFER cmd; - XGL_DESCRIPTOR_REGION desc_region; XGL_DESCRIPTOR_SET desc_set; @@ -94,6 +98,108 @@ struct demo { uint32_t current_buffer; }; +static void demo_flush_init_cmd(struct demo *demo) +{ + XGL_RESULT err; + + if (demo->cmd == XGL_NULL_HANDLE) + return; + + err = xglEndCommandBuffer(demo->cmd); + assert(!err); + + const XGL_CMD_BUFFER cmd_bufs[] = { demo->cmd }; + + err = xglQueueSubmit(demo->queue, 1, cmd_bufs, + demo->num_refs, demo->mem_refs, XGL_NULL_HANDLE); + assert(!err); + + err = xglQueueWaitIdle(demo->queue); + assert(!err); + + xglDestroyObject(demo->cmd); + demo->cmd = XGL_NULL_HANDLE; + demo->num_refs = 0; +} + +static void demo_add_mem_refs( + struct demo *demo, + XGL_MEMORY_REF_FLAGS flags, + int num_refs, XGL_GPU_MEMORY *mem) +{ + for (int i = 0; i < num_refs; i++) { + demo->mem_refs[demo->num_refs].flags = flags; + demo->mem_refs[demo->num_refs].mem = mem[i]; + demo->num_refs++; + assert(demo->num_refs < 16); + } +} + +static void demo_set_image_layout( + struct demo *demo, + XGL_IMAGE image, + XGL_IMAGE_LAYOUT old_image_layout, + XGL_IMAGE_LAYOUT new_image_layout) +{ + XGL_RESULT err; + + if (demo->cmd == XGL_NULL_HANDLE) { + const XGL_CMD_BUFFER_CREATE_INFO cmd = { + .sType = XGL_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, + .pNext = NULL, + .queueNodeIndex = demo->graphics_queue_node_index, + .flags = 0, + }; + + err = xglCreateCommandBuffer(demo->device, &cmd, &demo->cmd); + assert(!err); + + XGL_CMD_BUFFER_BEGIN_INFO cmd_buf_info = { + .sType = XGL_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, + .pNext = NULL, + .flags = XGL_CMD_BUFFER_OPTIMIZE_GPU_SMALL_BATCH_BIT | + XGL_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, + }; + err = xglBeginCommandBuffer(demo->cmd, &cmd_buf_info); + } + + XGL_IMAGE_MEMORY_BARRIER image_memory_barrier = { + .sType = XGL_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = NULL, + .outputMask = 0, + .inputMask = 0, + .oldLayout = old_image_layout, + .newLayout = new_image_layout, + .image = image, + .subresourceRange = { XGL_IMAGE_ASPECT_COLOR, 0, 1, 0, 0 } + }; + + if (new_image_layout == XGL_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL) { + /* Make sure anything that was copying from this image has completed */ + image_memory_barrier.inputMask = XGL_MEMORY_INPUT_COPY_BIT; + } + + if (new_image_layout == XGL_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { + /* Make sure any Copy or CPU writes to image are flushed */ + image_memory_barrier.outputMask = XGL_MEMORY_OUTPUT_COPY_BIT | XGL_MEMORY_OUTPUT_CPU_WRITE_BIT; + } + + XGL_IMAGE_MEMORY_BARRIER *pmemory_barrier = &image_memory_barrier; + + XGL_PIPE_EVENT set_events[] = { XGL_PIPE_EVENT_TOP_OF_PIPE }; + + XGL_PIPELINE_BARRIER pipeline_barrier; + pipeline_barrier.sType = XGL_STRUCTURE_TYPE_PIPELINE_BARRIER; + pipeline_barrier.pNext = NULL; + pipeline_barrier.eventCount = 1; + pipeline_barrier.pEvents = set_events; + pipeline_barrier.waitEvent = XGL_WAIT_EVENT_TOP_OF_PIPE; + pipeline_barrier.memBarrierCount = 1; + pipeline_barrier.ppMemBarriers = (const void **)&pmemory_barrier; + + xglCmdPipelineBarrier(demo->cmd, &pipeline_barrier); +} + static void demo_draw_build_cmd(struct demo *demo) { const XGL_COLOR_ATTACHMENT_BIND_INFO color_attachment = { @@ -278,6 +384,10 @@ static void demo_prepare_buffers(struct demo *demo) &demo->buffers[i].image, &demo->buffers[i].mem); assert(!err); + demo_set_image_layout(demo, demo->buffers[i].image, + XGL_IMAGE_LAYOUT_UNDEFINED, + XGL_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + color_attachment_view.image = demo->buffers[i].image; err = xglCreateColorAttachmentView(demo->device, @@ -345,7 +455,6 @@ static void demo_prepare_depth(struct demo *demo) &demo->depth.image); assert(!err); - err = xglGetObjectInfo(demo->depth.image, XGL_INFO_TYPE_MEMORY_ALLOCATION_COUNT, &num_alloc_size, &num_allocations); assert(!err && num_alloc_size == sizeof(num_allocations)); mem_reqs = malloc(num_allocations * sizeof(XGL_MEMORY_REQUIREMENTS)); @@ -376,6 +485,12 @@ static void demo_prepare_depth(struct demo *demo) assert(!err); } + demo_set_image_layout(demo, demo->depth.image, + XGL_IMAGE_LAYOUT_UNDEFINED, + XGL_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + + demo_add_mem_refs(demo, XGL_MEMORY_REF_READ_ONLY_BIT, num_allocations, demo->depth.mem); + /* create image view */ view.image = demo->depth.image; err = xglCreateDepthStencilView(demo->device, &view, @@ -385,7 +500,7 @@ static void demo_prepare_depth(struct demo *demo) static void demo_prepare_texture_image(struct demo *demo, const uint32_t *tex_colors, - struct texture_objects *tex_objs, + struct texture_object *tex_obj, XGL_IMAGE_TILING tiling, XGL_FLAGS mem_props) { @@ -394,8 +509,8 @@ static void demo_prepare_texture_image(struct demo *demo, const int32_t tex_height = 2; XGL_RESULT err; - tex_objs->tex_width = tex_width; - tex_objs->tex_height = tex_height; + tex_obj->tex_width = tex_width; + tex_obj->tex_height = tex_height; const XGL_IMAGE_CREATE_INFO image_create_info = { .sType = XGL_STRUCTURE_TYPE_IMAGE_CREATE_INFO, @@ -431,20 +546,20 @@ static void demo_prepare_texture_image(struct demo *demo, size_t num_alloc_size = sizeof(num_allocations); err = xglCreateImage(demo->device, &image_create_info, - &tex_objs->image); + &tex_obj->image); assert(!err); - err = xglGetObjectInfo(tex_objs->image, + err = xglGetObjectInfo(tex_obj->image, XGL_INFO_TYPE_MEMORY_ALLOCATION_COUNT, &num_alloc_size, &num_allocations); assert(!err && num_alloc_size == sizeof(num_allocations)); mem_reqs = malloc(num_allocations * sizeof(XGL_MEMORY_REQUIREMENTS)); - tex_objs->mem = malloc(num_allocations * sizeof(XGL_GPU_MEMORY)); - err = xglGetObjectInfo(tex_objs->image, + tex_obj->mem = malloc(num_allocations * sizeof(XGL_GPU_MEMORY)); + err = xglGetObjectInfo(tex_obj->image, XGL_INFO_TYPE_MEMORY_REQUIREMENTS, &mem_reqs_size, mem_reqs); assert(!err && mem_reqs_size == num_allocations * sizeof(XGL_MEMORY_REQUIREMENTS)); - err = xglGetObjectInfo(tex_objs->image, + err = xglGetObjectInfo(tex_obj->image, XGL_INFO_TYPE_IMAGE_MEMORY_REQUIREMENTS, &img_reqs_size, &img_reqs); assert(!err && img_reqs_size == sizeof(XGL_IMAGE_MEMORY_REQUIREMENTS)); @@ -458,17 +573,17 @@ static void demo_prepare_texture_image(struct demo *demo, /* allocate memory */ err = xglAllocMemory(demo->device, &mem_alloc, - &(tex_objs->mem[j])); + &(tex_obj->mem[j])); assert(!err); /* bind memory */ - err = xglBindObjectMemory(tex_objs->image, j, tex_objs->mem[j], 0); + err = xglBindObjectMemory(tex_obj->image, j, tex_obj->mem[j], 0); assert(!err); } free(mem_reqs); mem_reqs = NULL; - tex_objs->num_mem = num_allocations; + tex_obj->num_mem = num_allocations; if (mem_props & XGL_MEMORY_PROPERTY_CPU_VISIBLE_BIT) { const XGL_IMAGE_SUBRESOURCE subres = { @@ -481,14 +596,14 @@ static void demo_prepare_texture_image(struct demo *demo, void *data; int32_t x, y; - err = xglGetImageSubresourceInfo(tex_objs->image, &subres, + err = xglGetImageSubresourceInfo(tex_obj->image, &subres, XGL_INFO_TYPE_SUBRESOURCE_LAYOUT, &layout_size, &layout); assert(!err && layout_size == sizeof(layout)); /* Linear texture must be within a single memory object */ assert(num_allocations == 1); - err = xglMapMemory(tex_objs->mem[0], 0, &data); + err = xglMapMemory(tex_obj->mem[0], 0, &data); assert(!err); for (y = 0; y < tex_height; y++) { @@ -497,21 +612,27 @@ static void demo_prepare_texture_image(struct demo *demo, row[x] = tex_colors[(x & 1) ^ (y & 1)]; } - err = xglUnmapMemory(tex_objs->mem[0]); + err = xglUnmapMemory(tex_obj->mem[0]); assert(!err); } + + tex_obj->imageLayout = XGL_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + demo_set_image_layout(demo, tex_obj->image, + XGL_IMAGE_LAYOUT_UNDEFINED, + tex_obj->imageLayout); + /* setting the image layout does not reference the actual memory so no need to add a mem ref */ } -static void demo_destroy_texture_image(struct texture_objects *tex_objs) +static void demo_destroy_texture_image(struct texture_object *tex_obj) { /* clean up staging resources */ - for (uint32_t j = 0; j < tex_objs->num_mem; j ++) { - xglBindObjectMemory(tex_objs->image, j, XGL_NULL_HANDLE, 0); - xglFreeMemory(tex_objs->mem[j]); + for (uint32_t j = 0; j < tex_obj->num_mem; j ++) { + xglBindObjectMemory(tex_obj->image, j, XGL_NULL_HANDLE, 0); + xglFreeMemory(tex_obj->mem[j]); } - free(tex_objs->mem); - xglDestroyObject(tex_objs->image); + free(tex_obj->mem); + xglDestroyObject(tex_obj->image); } static void demo_prepare_textures(struct demo *demo) @@ -537,7 +658,7 @@ static void demo_prepare_textures(struct demo *demo) XGL_LINEAR_TILING, XGL_MEMORY_PROPERTY_CPU_VISIBLE_BIT); } else if (props.optimalTilingFeatures & XGL_FORMAT_IMAGE_SHADER_READ_BIT){ /* Must use staging buffer to copy linear texture to optimized */ - struct texture_objects staging_texture; + struct texture_object staging_texture; memset(&staging_texture, 0, sizeof(staging_texture)); demo_prepare_texture_image(demo, tex_colors[i], &staging_texture, @@ -546,29 +667,13 @@ static void demo_prepare_textures(struct demo *demo) demo_prepare_texture_image(demo, tex_colors[i], &demo->textures[i], XGL_OPTIMAL_TILING, XGL_MEMORY_PROPERTY_GPU_ONLY); - XGL_CMD_BUFFER staging_cmd_buf; - XGL_CMD_BUFFER_CREATE_INFO cmd_buf_create_info = { - .sType = XGL_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, - .pNext = NULL, - .queueNodeIndex = demo->graphics_queue_node_index, - .flags = 0 - }; - - err = xglCreateCommandBuffer(demo->device, &cmd_buf_create_info, &staging_cmd_buf); - assert(!err); + demo_set_image_layout(demo, staging_texture.image, + staging_texture.imageLayout, + XGL_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL); - /* Copy staging texture to usable texture */ - XGL_CMD_BUFFER_BEGIN_INFO cmd_buf_begin_info = { - .sType = XGL_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, - .pNext = NULL, - .flags = 0 - }; - - err = xglResetCommandBuffer(staging_cmd_buf); - assert(!err); - - err = xglBeginCommandBuffer(staging_cmd_buf, &cmd_buf_begin_info); - assert(!err); + demo_set_image_layout(demo, demo->textures[i].image, + demo->textures[i].imageLayout, + XGL_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL); XGL_IMAGE_COPY copy_region = { .srcSubresource = { XGL_IMAGE_ASPECT_COLOR, 0, 0 }, @@ -577,67 +682,21 @@ static void demo_prepare_textures(struct demo *demo) .destOffset = { 0, 0, 0 }, .extent = { staging_texture.tex_width, staging_texture.tex_height, 1 }, }; - xglCmdCopyImage(staging_cmd_buf, - staging_texture.image, XGL_IMAGE_LAYOUT_GENERAL, - demo->textures[i].image, XGL_IMAGE_LAYOUT_GENERAL, + xglCmdCopyImage(demo->cmd, + staging_texture.image, XGL_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL, + demo->textures[i].image, XGL_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, 1, ©_region); - XGL_IMAGE_MEMORY_BARRIER image_memory_barrier = { - .sType = XGL_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .pNext = NULL, - .outputMask = XGL_MEMORY_OUTPUT_COPY_BIT, - .inputMask = XGL_MEMORY_INPUT_SHADER_READ_BIT | XGL_MEMORY_INPUT_COPY_BIT, - .oldLayout = XGL_IMAGE_LAYOUT_GENERAL, - .newLayout = XGL_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, - .image = staging_texture.image, - .subresourceRange = { XGL_IMAGE_ASPECT_COLOR, 0, 1, 0, 0 } - }; - XGL_IMAGE_MEMORY_BARRIER *pmemory_barrier = &image_memory_barrier; - - XGL_PIPE_EVENT set_events[] = { XGL_PIPE_EVENT_GPU_COMMANDS_COMPLETE }; - XGL_PIPELINE_BARRIER pipeline_barrier; - pipeline_barrier.sType = XGL_STRUCTURE_TYPE_PIPELINE_BARRIER; - pipeline_barrier.pNext = NULL; - pipeline_barrier.eventCount = 1; - pipeline_barrier.pEvents = set_events; - pipeline_barrier.waitEvent = XGL_WAIT_EVENT_TOP_OF_PIPE; - pipeline_barrier.memBarrierCount = 1; - pipeline_barrier.ppMemBarriers = (const void **)&pmemory_barrier; - - // write barrier to the command buffer - xglCmdPipelineBarrier(staging_cmd_buf, &pipeline_barrier); - - err = xglEndCommandBuffer(staging_cmd_buf); - assert(!err); - - const XGL_CMD_BUFFER cmd_bufs[] = { staging_cmd_buf }; - XGL_MEMORY_REF mem_refs[16]; - uint32_t num_refs = 0; - - for (uint32_t j = 0; j < staging_texture.num_mem; j++) { - mem_refs[num_refs].flags = XGL_MEMORY_REF_READ_ONLY_BIT; - mem_refs[num_refs].mem = staging_texture.mem[j]; - num_refs++; - assert(num_refs < 16); - } - - for (uint32_t j = 0; j < demo->textures[i].num_mem; j++) { - mem_refs[num_refs].flags = XGL_MEMORY_REF_READ_ONLY_BIT; - mem_refs[num_refs].mem = demo->textures[i].mem[j]; - num_refs++; - assert(num_refs < 16); - } - - err = xglQueueSubmit(demo->queue, 1, cmd_bufs, - num_refs, mem_refs, XGL_NULL_HANDLE); - assert(!err); - - err = xglQueueWaitIdle(demo->queue); - assert(!err); + demo_add_mem_refs(demo, XGL_MEMORY_REF_READ_ONLY_BIT, staging_texture.num_mem, staging_texture.mem); + demo_add_mem_refs(demo, 0, demo->textures[i].num_mem, demo->textures[i].mem); - demo_destroy_texture_image(&staging_texture); + demo_set_image_layout(demo, demo->textures[i].image, + XGL_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, + demo->textures[i].imageLayout); + + demo_flush_init_cmd(demo); - xglDestroyObject(staging_cmd_buf); + demo_destroy_texture_image(&staging_texture); } else { /* Can't support XGL_FMT_B8G8R8A8_UNORM !? */ assert(!"No support for B8G8R8A8_UNORM as texture image format"); @@ -1248,6 +1307,15 @@ static void demo_init_xgl(struct demo *demo) err = xglCreateDevice(demo->gpu, &device, &demo->device); assert(!err); + err = xglGetGpuInfo(demo->gpu, XGL_INFO_TYPE_PHYSICAL_GPU_PROPERTIES, + &data_size, NULL); + assert(!err); + + demo->gpu_props = (XGL_PHYSICAL_GPU_PROPERTIES *) malloc(data_size); + err = xglGetGpuInfo(demo->gpu, XGL_INFO_TYPE_PHYSICAL_GPU_PROPERTIES, + &data_size, demo->gpu_props); + assert(!err); + err = xglGetGpuInfo(demo->gpu, XGL_INFO_TYPE_PHYSICAL_GPU_QUEUE_PROPERTIES, &data_size, NULL); assert(!err); |
