From 806e5a37ed820b9d6796df0663809e0e4d2bfebc Mon Sep 17 00:00:00 2001 From: Sagar Ghuge Date: Thu, 17 Jan 2019 10:28:36 -0800 Subject: [PATCH] anv: Implement VK_KHR_imageless_framebuffer v2: Pass pointer instead of struct instance (Lionel) v3: 1) Fix small nits (Jason) 2) Add way to detect anv_framebuffer don't have attachments (Jason) 3) Get rid of unncessary pNext chain walk (Jason) 4) Keep framebuffer instance in anv_cmd_state (Jason) v4: 1) Dump attachments from cmd_buffer (Jason) v5: 1) Fix condition check and add assertion (Lionel) Signed-off-by: Sagar Ghuge Reviewed-by: Lionel Landwerlin Reviewed-by: Jason Ekstrand --- src/intel/vulkan/anv_cmd_buffer.c | 3 +-- src/intel/vulkan/anv_device.c | 43 +++++++++++++++++++++++++++++--------- src/intel/vulkan/anv_dump.c | 9 ++++---- src/intel/vulkan/anv_extensions.py | 1 + src/intel/vulkan/anv_private.h | 4 ++-- src/intel/vulkan/genX_cmd_buffer.c | 42 ++++++++++++++++++++++++------------- 6 files changed, 68 insertions(+), 34 deletions(-) diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c index 3c020a1..0e54603 100644 --- a/src/intel/vulkan/anv_cmd_buffer.c +++ b/src/intel/vulkan/anv_cmd_buffer.c @@ -920,13 +920,12 @@ const struct anv_image_view * anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer *cmd_buffer) { const struct anv_subpass *subpass = cmd_buffer->state.subpass; - const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer; if (subpass->depth_stencil_attachment == NULL) return NULL; const struct anv_image_view *iview = - fb->attachments[subpass->depth_stencil_attachment->attachment]; + cmd_buffer->state.attachments[subpass->depth_stencil_attachment->attachment].image_view; assert(iview->aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)); diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index 24cec21..d0ddb3e 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -1108,6 +1108,13 @@ void anv_GetPhysicalDeviceFeatures2( break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR: { + VkPhysicalDeviceImagelessFramebufferFeaturesKHR *features = + (VkPhysicalDeviceImagelessFramebufferFeaturesKHR *)ext; + features->imagelessFramebuffer = true; + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES: { VkPhysicalDeviceProtectedMemoryFeatures *features = (void *)ext; features->protectedMemory = false; @@ -3708,17 +3715,33 @@ VkResult anv_CreateFramebuffer( assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO); - size_t size = sizeof(*framebuffer) + - sizeof(struct anv_image_view *) * pCreateInfo->attachmentCount; - framebuffer = vk_alloc2(&device->alloc, pAllocator, size, 8, - VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - if (framebuffer == NULL) - return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + size_t size = sizeof(*framebuffer); + + /* VK_KHR_imageless_framebuffer extension says: + * + * If flags includes VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR, + * parameter pAttachments is ignored. + */ + if (!(pCreateInfo->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR)) { + size += sizeof(struct anv_image_view *) * pCreateInfo->attachmentCount; + framebuffer = vk_alloc2(&device->alloc, pAllocator, size, 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (framebuffer == NULL) + return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + + for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) { + ANV_FROM_HANDLE(anv_image_view, iview, pCreateInfo->pAttachments[i]); + framebuffer->attachments[i] = iview; + } + framebuffer->attachment_count = pCreateInfo->attachmentCount; + } else { + assert(device->enabled_extensions.KHR_imageless_framebuffer); + framebuffer = vk_alloc2(&device->alloc, pAllocator, size, 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (framebuffer == NULL) + return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); - framebuffer->attachment_count = pCreateInfo->attachmentCount; - for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) { - VkImageView _iview = pCreateInfo->pAttachments[i]; - framebuffer->attachments[i] = anv_image_view_from_handle(_iview); + framebuffer->attachment_count = 0; } framebuffer->width = pCreateInfo->width; diff --git a/src/intel/vulkan/anv_dump.c b/src/intel/vulkan/anv_dump.c index f36a9b5..337423f 100644 --- a/src/intel/vulkan/anv_dump.c +++ b/src/intel/vulkan/anv_dump.c @@ -410,16 +410,15 @@ dump_add_image(struct anv_cmd_buffer *cmd_buffer, struct anv_image *image, } void -anv_dump_add_framebuffer(struct anv_cmd_buffer *cmd_buffer, - struct anv_framebuffer *fb) +anv_dump_add_attachments(struct anv_cmd_buffer *cmd_buffer) { if (!dump_lock(ANV_DUMP_FRAMEBUFFERS_BIT)) return; unsigned dump_idx = dump_count++; - for (unsigned i = 0; i < fb->attachment_count; i++) { - struct anv_image_view *iview = fb->attachments[i]; + for (unsigned i = 0; i < cmd_buffer->state.pass->attachment_count; i++) { + struct anv_image_view *iview = cmd_buffer->state.attachments[i].image_view; uint32_t b; for_each_bit(b, iview->image->aspects) { @@ -436,7 +435,7 @@ anv_dump_add_framebuffer(struct anv_cmd_buffer *cmd_buffer, unreachable("Invalid aspect"); } - char *filename = ralloc_asprintf(dump_ctx, "framebuffer%04d-%d%s.ppm", + char *filename = ralloc_asprintf(dump_ctx, "attachment%04d-%d%s.ppm", dump_idx, i, suffix); unsigned plane = anv_image_aspect_to_plane(iview->image->aspects, aspect); diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_extensions.py index 33b6afb..492f8ac 100644 --- a/src/intel/vulkan/anv_extensions.py +++ b/src/intel/vulkan/anv_extensions.py @@ -95,6 +95,7 @@ EXTENSIONS = [ Extension('VK_KHR_get_physical_device_properties2', 1, True), Extension('VK_KHR_get_surface_capabilities2', 1, 'ANV_HAS_SURFACE'), Extension('VK_KHR_image_format_list', 1, True), + Extension('VK_KHR_imageless_framebuffer', 1, True), Extension('VK_KHR_incremental_present', 1, 'ANV_HAS_SURFACE'), Extension('VK_KHR_maintenance1', 1, True), Extension('VK_KHR_maintenance2', 1, True), diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index e743d9f..aa799d2 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -2273,6 +2273,7 @@ struct anv_attachment_state { * have not been cleared yet when multiview is active. */ uint32_t pending_clear_views; + struct anv_image_view * image_view; }; /** State tracking for particular pipeline bind point @@ -3627,8 +3628,7 @@ enum anv_dump_action { void anv_dump_start(struct anv_device *device, enum anv_dump_action actions); void anv_dump_finish(void); -void anv_dump_add_framebuffer(struct anv_cmd_buffer *cmd_buffer, - struct anv_framebuffer *fb); +void anv_dump_add_attachments(struct anv_cmd_buffer *cmd_buffer); static inline uint32_t anv_get_subpass_id(const struct anv_cmd_state * const cmd_state) diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index f2b43d8..2045d16 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -246,7 +246,7 @@ color_attachment_compute_aux_usage(struct anv_device * device, union isl_color_value *fast_clear_color) { struct anv_attachment_state *att_state = &cmd_state->attachments[att]; - struct anv_image_view *iview = cmd_state->framebuffer->attachments[att]; + struct anv_image_view *iview = cmd_state->attachments[att].image_view; assert(iview->n_planes == 1); @@ -388,7 +388,7 @@ depth_stencil_attachment_compute_aux_usage(struct anv_device *device, struct anv_render_pass_attachment *pass_att = &cmd_state->pass->attachments[att]; struct anv_attachment_state *att_state = &cmd_state->attachments[att]; - struct anv_image_view *iview = cmd_state->framebuffer->attachments[att]; + struct anv_image_view *iview = cmd_state->attachments[att].image_view; /* These will be initialized after the first subpass transition. */ att_state->aux_usage = ISL_AUX_USAGE_NONE; @@ -1194,6 +1194,7 @@ genX(cmd_buffer_setup_attachments)(struct anv_cmd_buffer *cmd_buffer, { const struct isl_device *isl_dev = &cmd_buffer->device->isl_dev; struct anv_cmd_state *state = &cmd_buffer->state; + struct anv_framebuffer *framebuffer = cmd_buffer->state.framebuffer; vk_free(&cmd_buffer->pool->alloc, state->attachments); @@ -1233,6 +1234,12 @@ genX(cmd_buffer_setup_attachments)(struct anv_cmd_buffer *cmd_buffer, next_state.offset += ss_stride; next_state.map += ss_stride; + const VkRenderPassAttachmentBeginInfoKHR *begin_attachment = + vk_find_struct_const(begin, RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR); + + if (begin && !begin_attachment) + assert(pass->attachment_count == framebuffer->attachment_count); + for (uint32_t i = 0; i < pass->attachment_count; ++i) { if (vk_format_is_color(pass->attachments[i].format)) { state->attachments[i].color.state = next_state; @@ -1245,14 +1252,19 @@ genX(cmd_buffer_setup_attachments)(struct anv_cmd_buffer *cmd_buffer, next_state.offset += ss_stride; next_state.map += ss_stride; } + + if (begin_attachment && begin_attachment->attachmentCount != 0) { + assert(begin_attachment->attachmentCount == pass->attachment_count); + ANV_FROM_HANDLE(anv_image_view, iview, begin_attachment->pAttachments[i]); + cmd_buffer->state.attachments[i].image_view = iview; + } else if (framebuffer && i < framebuffer->attachment_count) { + cmd_buffer->state.attachments[i].image_view = framebuffer->attachments[i]; + } } assert(next_state.offset == state->render_pass_states.offset + state->render_pass_states.alloc_size); if (begin) { - ANV_FROM_HANDLE(anv_framebuffer, framebuffer, begin->framebuffer); - assert(pass->attachment_count == framebuffer->attachment_count); - isl_null_fill_state(isl_dev, state->null_surface_state.map, isl_extent3d(framebuffer->width, framebuffer->height, @@ -1295,7 +1307,7 @@ genX(cmd_buffer_setup_attachments)(struct anv_cmd_buffer *cmd_buffer, if (clear_aspects) state->attachments[i].clear_value = begin->pClearValues[i]; - struct anv_image_view *iview = framebuffer->attachments[i]; + struct anv_image_view *iview = cmd_buffer->state.attachments[i].image_view; anv_assert(iview->vk_format == att->format); const uint32_t num_layers = iview->planes[0].isl.array_len; @@ -4072,7 +4084,7 @@ cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer, assert(a < cmd_state->pass->attachment_count); struct anv_attachment_state *att_state = &cmd_state->attachments[a]; - struct anv_image_view *iview = fb->attachments[a]; + struct anv_image_view *iview = cmd_state->attachments[a].image_view; const struct anv_image *image = iview->image; /* A resolve is necessary before use as an input attachment if the clear @@ -4409,8 +4421,8 @@ cmd_buffer_end_subpass(struct anv_cmd_buffer *cmd_buffer) cmd_buffer->state.attachments[dst_att].pending_clear_aspects = 0; } - struct anv_image_view *src_iview = fb->attachments[src_att]; - struct anv_image_view *dst_iview = fb->attachments[dst_att]; + struct anv_image_view *src_iview = cmd_state->attachments[src_att].image_view; + struct anv_image_view *dst_iview = cmd_state->attachments[dst_att].image_view; const VkRect2D render_area = cmd_buffer->state.render_area; @@ -4464,8 +4476,8 @@ cmd_buffer_end_subpass(struct anv_cmd_buffer *cmd_buffer) cmd_buffer->state.attachments[dst_att].pending_clear_aspects = 0; } - struct anv_image_view *src_iview = fb->attachments[src_att]; - struct anv_image_view *dst_iview = fb->attachments[dst_att]; + struct anv_image_view *src_iview = cmd_state->attachments[src_att].image_view; + struct anv_image_view *dst_iview = cmd_state->attachments[dst_att].image_view; const VkRect2D render_area = cmd_buffer->state.render_area; @@ -4578,7 +4590,7 @@ cmd_buffer_end_subpass(struct anv_cmd_buffer *cmd_buffer) assert(a != VK_ATTACHMENT_UNUSED); struct anv_attachment_state *att_state = &cmd_state->attachments[a]; - struct anv_image_view *iview = fb->attachments[a]; + struct anv_image_view *iview = cmd_state->attachments[a].image_view;; const struct anv_image *image = iview->image; if (image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { @@ -4608,7 +4620,7 @@ cmd_buffer_end_subpass(struct anv_cmd_buffer *cmd_buffer) assert(a < cmd_state->pass->attachment_count); struct anv_attachment_state *att_state = &cmd_state->attachments[a]; - struct anv_image_view *iview = fb->attachments[a]; + struct anv_image_view *iview = cmd_state->attachments[a].image_view; const struct anv_image *image = iview->image; if ((image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) && @@ -4624,7 +4636,7 @@ cmd_buffer_end_subpass(struct anv_cmd_buffer *cmd_buffer) * SRGB view & a UNORM image). */ if (fast_clear_type != ANV_FAST_CLEAR_NONE) { - anv_perf_warn(cmd_buffer->device->instance, fb, + anv_perf_warn(cmd_buffer->device->instance, iview, "Doing a partial resolve to get rid of clear color at the " "end of a renderpass due to an image/view format mismatch"); @@ -4776,7 +4788,7 @@ void genX(CmdEndRenderPass)( cmd_buffer->state.hiz_enabled = false; #ifndef NDEBUG - anv_dump_add_framebuffer(cmd_buffer, cmd_buffer->state.framebuffer); + anv_dump_add_attachments(cmd_buffer); #endif /* Remove references to render pass specific state. This enables us to -- 2.7.4