diff options
author | Jason Ekstrand <[email protected]> | 2015-07-10 20:18:52 -0700 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2015-07-14 11:37:14 -0700 |
commit | 84783509926f01dcc6f96ddf8a86e4b9cac1c48f (patch) | |
tree | c0f6781b29792304b752f07e8542cd7591e140d2 /src | |
parent | 68768c40be5c81afd4b6bd8eab611526c789717d (diff) |
vk: Implement Multipass
Diffstat (limited to 'src')
-rw-r--r-- | src/vulkan/device.c | 196 | ||||
-rw-r--r-- | src/vulkan/formats.c | 13 | ||||
-rw-r--r-- | src/vulkan/image.c | 111 | ||||
-rw-r--r-- | src/vulkan/meta.c | 217 | ||||
-rw-r--r-- | src/vulkan/private.h | 98 |
5 files changed, 420 insertions, 215 deletions
diff --git a/src/vulkan/device.c b/src/vulkan/device.c index b7cbac97b78..90ac956c040 100644 --- a/src/vulkan/device.c +++ b/src/vulkan/device.c @@ -1216,11 +1216,8 @@ VkResult anv_DestroyObject( case VK_OBJECT_TYPE_IMAGE_VIEW: return anv_DestroyImageView(_device, _object); - case VK_OBJECT_TYPE_COLOR_ATTACHMENT_VIEW: - return anv_DestroyColorAttachmentView(_device, _object); - - case VK_OBJECT_TYPE_DEPTH_STENCIL_VIEW: - return anv_DestroyDepthStencilView(_device, _object); + case VK_OBJECT_TYPE_ATTACHMENT_VIEW: + return anv_DestroyAttachmentView(_device, _object); case VK_OBJECT_TYPE_IMAGE: return anv_DestroyImage(_device, _object); @@ -1722,8 +1719,10 @@ VkResult anv_DestroyBufferView( VkBufferView _view) { ANV_FROM_HANDLE(anv_device, device, _device); + struct anv_surface_view *view = (struct anv_surface_view *)_view; - anv_surface_view_destroy(device, (struct anv_surface_view *)_view); + anv_surface_view_fini(device, view); + anv_device_free(device, view); return VK_SUCCESS; } @@ -1882,6 +1881,7 @@ VkResult anv_CreateDescriptorSetLayout( case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: + case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: for_each_bit(s, pCreateInfo->pBinding[i].stageFlags) surface_count[s] += pCreateInfo->pBinding[i].arraySize; break; @@ -1970,6 +1970,7 @@ VkResult anv_CreateDescriptorSetLayout( case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: + case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: for_each_bit(s, pCreateInfo->pBinding[i].stageFlags) for (uint32_t j = 0; j < pCreateInfo->pBinding[i].arraySize; j++) { surface[s]->index = descriptor + j; @@ -2107,6 +2108,10 @@ VkResult anv_UpdateDescriptorSets( anv_finishme("texel buffers not implemented"); break; + case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: + anv_finishme("input attachments not implemented"); + break; + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: @@ -3049,8 +3054,10 @@ static VkResult cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer, unsigned stage, struct anv_state *bt_state) { + struct anv_framebuffer *fb = cmd_buffer->framebuffer; + struct anv_subpass *subpass = cmd_buffer->subpass; struct anv_pipeline_layout *layout; - uint32_t color_attachments, bias, size; + uint32_t attachments, bias, size; if (stage == VK_SHADER_STAGE_COMPUTE) layout = cmd_buffer->compute_pipeline->layout; @@ -3059,10 +3066,10 @@ cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer, if (stage == VK_SHADER_STAGE_FRAGMENT) { bias = MAX_RTS; - color_attachments = cmd_buffer->framebuffer->color_attachment_count; + attachments = subpass->color_count; } else { bias = 0; - color_attachments = 0; + attachments = 0; } /* This is a little awkward: layout can be NULL but we still have to @@ -3070,7 +3077,7 @@ cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer, * targets. */ uint32_t surface_count = layout ? layout->stage[stage].surface_count : 0; - if (color_attachments + surface_count == 0) + if (attachments + surface_count == 0) return VK_SUCCESS; size = (bias + surface_count) * sizeof(uint32_t); @@ -3080,9 +3087,19 @@ cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer, if (bt_state->map == NULL) return VK_ERROR_OUT_OF_DEVICE_MEMORY; - for (uint32_t ca = 0; ca < color_attachments; ca++) { - const struct anv_surface_view *view = - cmd_buffer->framebuffer->color_attachments[ca]; + /* This is highly annoying. The Vulkan spec puts the depth-stencil + * attachments in with the color attachments. Unfortunately, thanks to + * other aspects of the API, we cana't really saparate them before this + * point. Therefore, we have to walk all of the attachments but only + * put the color attachments into the binding table. + */ + for (uint32_t a = 0; a < attachments; a++) { + const struct anv_attachment_view *attachment = + fb->attachments[subpass->color_attachments[a]]; + + assert(attachment->attachment_type == ANV_ATTACHMENT_VIEW_TYPE_COLOR); + const struct anv_color_attachment_view *view = + (const struct anv_color_attachment_view *)attachment; struct anv_state state = anv_cmd_buffer_alloc_surface_state(cmd_buffer, 64, 64); @@ -3090,16 +3107,16 @@ cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer, if (state.map == NULL) return VK_ERROR_OUT_OF_DEVICE_MEMORY; - memcpy(state.map, view->surface_state.map, 64); + memcpy(state.map, view->view.surface_state.map, 64); /* The address goes in dwords 8 and 9 of the SURFACE_STATE */ *(uint64_t *)(state.map + 8 * 4) = anv_reloc_list_add(&cmd_buffer->surface_relocs, cmd_buffer->device, state.offset + 8 * 4, - view->bo, view->offset); + view->view.bo, view->view.offset); - bt_map[ca] = state.offset; + bt_map[a] = state.offset; } if (layout == NULL) @@ -3844,32 +3861,25 @@ VkResult anv_CreateFramebuffer( ANV_FROM_HANDLE(anv_device, device, _device); struct anv_framebuffer *framebuffer; - static const struct anv_depth_stencil_view null_view = - { .depth_format = D16_UNORM, .depth_stride = 0, .stencil_stride = 0 }; - assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO); - framebuffer = anv_device_alloc(device, sizeof(*framebuffer), 8, + size_t size = sizeof(*framebuffer) + + sizeof(struct anv_attachment_view *) * pCreateInfo->attachmentCount; + framebuffer = anv_device_alloc(device, size, 8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT); if (framebuffer == NULL) return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); framebuffer->base.destructor = anv_framebuffer_destroy; - framebuffer->color_attachment_count = pCreateInfo->colorAttachmentCount; - for (uint32_t i = 0; i < pCreateInfo->colorAttachmentCount; i++) { - framebuffer->color_attachments[i] = - (struct anv_surface_view *) pCreateInfo->pColorAttachments[i].view; - } + framebuffer->attachment_count = pCreateInfo->attachmentCount; + for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) { + ANV_FROM_HANDLE(anv_attachment_view, view, + pCreateInfo->pAttachments[i].view); - if (pCreateInfo->pDepthStencilAttachment) { - framebuffer->depth_stencil = - anv_depth_stencil_view_from_handle(pCreateInfo->pDepthStencilAttachment->view); - } else { - framebuffer->depth_stencil = &null_view; + framebuffer->attachments[i] = view; } - framebuffer->sample_count = pCreateInfo->sampleCount; framebuffer->width = pCreateInfo->width; framebuffer->height = pCreateInfo->height; framebuffer->layers = pCreateInfo->layers; @@ -3926,22 +3936,52 @@ VkResult anv_CreateRenderPass( assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO); size = sizeof(*pass) + - pCreateInfo->layers * sizeof(struct anv_render_pass_layer); + pCreateInfo->subpassCount * sizeof(struct anv_subpass); pass = anv_device_alloc(device, size, 8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT); if (pass == NULL) return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); - pass->render_area = pCreateInfo->renderArea; + pass->attachment_count = pCreateInfo->attachmentCount; + size = pCreateInfo->attachmentCount * sizeof(*pass->attachments); + pass->attachments = anv_device_alloc(device, size, 8, + VK_SYSTEM_ALLOC_TYPE_API_OBJECT); + for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) { + pass->attachments[i].format = pCreateInfo->pAttachments[i].format; + pass->attachments[i].samples = pCreateInfo->pAttachments[i].samples; + pass->attachments[i].load_op = pCreateInfo->pAttachments[i].loadOp; + pass->attachments[i].stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp; + // pass->attachments[i].store_op = pCreateInfo->pAttachments[i].storeOp; + // pass->attachments[i].stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp; + } - pass->num_layers = pCreateInfo->layers; + for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { + const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i]; + struct anv_subpass *subpass = &pass->subpasses[i]; + + subpass->input_count = desc->inputCount; + subpass->input_attachments = + anv_device_alloc(device, desc->inputCount * sizeof(uint32_t), + 8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT); + for (uint32_t j = 0; j < desc->inputCount; j++) + subpass->input_attachments[j] = desc->inputAttachments[j].attachment; + + subpass->color_count = desc->colorCount; + subpass->color_attachments = + anv_device_alloc(device, desc->colorCount * sizeof(uint32_t), + 8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT); + for (uint32_t j = 0; j < desc->colorCount; j++) + subpass->color_attachments[j] = desc->colorAttachments[j].attachment; + + if (desc->resolveAttachments) { + subpass->resolve_attachments = + anv_device_alloc(device, desc->colorCount * sizeof(uint32_t), + 8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT); + for (uint32_t j = 0; j < desc->colorCount; j++) + subpass->resolve_attachments[j] = desc->resolveAttachments[j].attachment; + } - pass->num_clear_layers = 0; - for (uint32_t i = 0; i < pCreateInfo->layers; i++) { - pass->layers[i].color_load_op = pCreateInfo->pColorLoadOps[i]; - pass->layers[i].clear_color = pCreateInfo->pColorLoadClearValues[i]; - if (pass->layers[i].color_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) - pass->num_clear_layers++; + subpass->depth_stencil_attachment = desc->depthStencilAttachment.attachment; } *pRenderPass = anv_render_pass_to_handle(pass); @@ -3956,6 +3996,14 @@ VkResult anv_DestroyRenderPass( ANV_FROM_HANDLE(anv_device, device, _device); ANV_FROM_HANDLE(anv_render_pass, pass, _pass); + anv_device_free(device, pass->attachments); + + for (uint32_t i = 0; i < pass->attachment_count; i++) { + anv_device_free(device, pass->subpasses[i].input_attachments); + anv_device_free(device, pass->subpasses[i].color_attachments); + anv_device_free(device, pass->subpasses[i].resolve_attachments); + } + anv_device_free(device, pass); return VK_SUCCESS; @@ -3972,11 +4020,23 @@ VkResult anv_GetRenderAreaGranularity( } static void -anv_cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer, - struct anv_render_pass *pass) +anv_cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer) { - const struct anv_depth_stencil_view *view = - cmd_buffer->framebuffer->depth_stencil; + struct anv_subpass *subpass = cmd_buffer->subpass; + struct anv_framebuffer *fb = cmd_buffer->framebuffer; + const struct anv_depth_stencil_view *view; + + static const struct anv_depth_stencil_view null_view = + { .depth_format = D16_UNORM, .depth_stride = 0, .stencil_stride = 0 }; + + if (subpass->depth_stencil_attachment != VK_ATTACHMENT_UNUSED) { + const struct anv_attachment_view *aview = + fb->attachments[subpass->depth_stencil_attachment]; + assert(aview->attachment_type == ANV_ATTACHMENT_VIEW_TYPE_DEPTH_STENCIL); + view = (const struct anv_depth_stencil_view *)aview; + } else { + view = &null_view; + } /* FIXME: Implement the PMA stall W/A */ /* FIXME: Width and Height are wrong */ @@ -3989,8 +4049,8 @@ anv_cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer, .SurfaceFormat = view->depth_format, .SurfacePitch = view->depth_stride > 0 ? view->depth_stride - 1 : 0, .SurfaceBaseAddress = { view->bo, view->depth_offset }, - .Height = pass->render_area.extent.height - 1, - .Width = pass->render_area.extent.width - 1, + .Height = cmd_buffer->framebuffer->height - 1, + .Width = cmd_buffer->framebuffer->width - 1, .LOD = 0, .Depth = 1 - 1, .MinimumArrayElement = 0, @@ -4023,33 +4083,59 @@ void anv_CmdPushConstants( stub(); } +void +anv_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer, + struct anv_subpass *subpass) +{ + cmd_buffer->subpass = subpass; + + cmd_buffer->descriptors_dirty |= VK_SHADER_STAGE_FRAGMENT_BIT; + + anv_cmd_buffer_emit_depth_stencil(cmd_buffer); +} + void anv_CmdBeginRenderPass( VkCmdBuffer cmdBuffer, - const VkRenderPassBegin* pRenderPassBegin) + const VkRenderPassBeginInfo* pRenderPassBegin, + VkRenderPassContents contents) { ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer); ANV_FROM_HANDLE(anv_render_pass, pass, pRenderPassBegin->renderPass); ANV_FROM_HANDLE(anv_framebuffer, framebuffer, pRenderPassBegin->framebuffer); - assert(pRenderPassBegin->contents == VK_RENDER_PASS_CONTENTS_INLINE); + assert(contents == VK_RENDER_PASS_CONTENTS_INLINE); cmd_buffer->framebuffer = framebuffer; + cmd_buffer->pass = pass; - cmd_buffer->descriptors_dirty |= VK_SHADER_STAGE_FRAGMENT_BIT; + const VkRect2D *render_area = &pRenderPassBegin->renderArea; anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DRAWING_RECTANGLE, - .ClippedDrawingRectangleYMin = pass->render_area.offset.y, - .ClippedDrawingRectangleXMin = pass->render_area.offset.x, + .ClippedDrawingRectangleYMin = render_area->offset.y, + .ClippedDrawingRectangleXMin = render_area->offset.x, .ClippedDrawingRectangleYMax = - pass->render_area.offset.y + pass->render_area.extent.height - 1, + render_area->offset.y + render_area->extent.height - 1, .ClippedDrawingRectangleXMax = - pass->render_area.offset.x + pass->render_area.extent.width - 1, + render_area->offset.x + render_area->extent.width - 1, .DrawingRectangleOriginY = 0, .DrawingRectangleOriginX = 0); - anv_cmd_buffer_emit_depth_stencil(cmd_buffer, pass); + anv_cmd_buffer_clear_attachments(cmd_buffer, pass, + pRenderPassBegin->pAttachmentClearValues); + + anv_cmd_buffer_begin_subpass(cmd_buffer, pass->subpasses); +} + +void anv_CmdNextSubpass( + VkCmdBuffer cmdBuffer, + VkRenderPassContents contents) +{ + ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer); + + assert(contents == VK_RENDER_PASS_CONTENTS_INLINE); - anv_cmd_buffer_clear(cmd_buffer, pass); + cmd_buffer->subpass++; + anv_cmd_buffer_begin_subpass(cmd_buffer, cmd_buffer->subpass + 1); } void anv_CmdEndRenderPass( diff --git a/src/vulkan/formats.c b/src/vulkan/formats.c index 0fa47fda681..a00dc8df75a 100644 --- a/src/vulkan/formats.c +++ b/src/vulkan/formats.c @@ -215,6 +215,19 @@ anv_format_for_vk_format(VkFormat format) return &anv_formats[format]; } +bool +anv_is_vk_format_depth_or_stencil(VkFormat format) +{ + const struct anv_format *format_info = + anv_format_for_vk_format(format); + + if (format_info->depth_format != UNSUPPORTED && + format_info->depth_format != 0) + return true; + + return format_info->has_stencil; +} + // Format capabilities struct surface_format_info { diff --git a/src/vulkan/image.c b/src/vulkan/image.c index 5b042a0e297..c29c6939ffb 100644 --- a/src/vulkan/image.c +++ b/src/vulkan/image.c @@ -326,12 +326,10 @@ VkResult anv_GetImageSubresourceLayout( } void -anv_surface_view_destroy(struct anv_device *device, - struct anv_surface_view *view) +anv_surface_view_fini(struct anv_device *device, + struct anv_surface_view *view) { anv_state_pool_free(&device->surface_state_pool, view->surface_state); - - anv_device_free(device, view); } void @@ -557,30 +555,32 @@ VkResult anv_DestroyImageView(VkDevice _device, VkImageView _view) { ANV_FROM_HANDLE(anv_device, device, _device); + struct anv_surface_view *view = (struct anv_surface_view *)_view; - anv_surface_view_destroy(device, (struct anv_surface_view *)_view); + anv_surface_view_fini(device, view); + anv_device_free(device, view); return VK_SUCCESS; } void -anv_color_attachment_view_init(struct anv_surface_view *view, +anv_color_attachment_view_init(struct anv_color_attachment_view *aview, struct anv_device *device, - const VkColorAttachmentViewCreateInfo* pCreateInfo, + const VkAttachmentViewCreateInfo* pCreateInfo, struct anv_cmd_buffer *cmd_buffer) { ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image); + struct anv_surface_view *view = &aview->view; struct anv_surface *surface = &image->primary_surface; const struct anv_format *format_info = anv_format_for_vk_format(pCreateInfo->format); + aview->base.attachment_type = ANV_ATTACHMENT_VIEW_TYPE_COLOR; + anv_assert(pCreateInfo->arraySize > 0); anv_assert(pCreateInfo->mipLevel < image->levels); anv_assert(pCreateInfo->baseArraySlice + pCreateInfo->arraySize <= image->array_size); - if (pCreateInfo->msaaResolveImage) - anv_finishme("msaaResolveImage"); - view->bo = image->bo; view->offset = image->offset + surface->offset; view->format = pCreateInfo->format; @@ -659,57 +659,17 @@ anv_color_attachment_view_init(struct anv_surface_view *view, GEN8_RENDER_SURFACE_STATE_pack(NULL, view->surface_state.map, &surface_state); } -VkResult -anv_CreateColorAttachmentView(VkDevice _device, - const VkColorAttachmentViewCreateInfo *pCreateInfo, - VkColorAttachmentView *pView) -{ - ANV_FROM_HANDLE(anv_device, device, _device); - struct anv_surface_view *view; - - assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO); - - view = anv_device_alloc(device, sizeof(*view), 8, - VK_SYSTEM_ALLOC_TYPE_API_OBJECT); - if (view == NULL) - return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); - - anv_color_attachment_view_init(view, device, pCreateInfo, NULL); - - *pView = (VkColorAttachmentView) view; - - return VK_SUCCESS; -} - -VkResult -anv_DestroyColorAttachmentView(VkDevice _device, VkColorAttachmentView _view) +static void +anv_depth_stencil_view_init(struct anv_depth_stencil_view *view, + const VkAttachmentViewCreateInfo *pCreateInfo) { - ANV_FROM_HANDLE(anv_device, device, _device); - - anv_surface_view_destroy(device, (struct anv_surface_view *)_view); - - return VK_SUCCESS; -} - -VkResult -anv_CreateDepthStencilView(VkDevice _device, - const VkDepthStencilViewCreateInfo *pCreateInfo, - VkDepthStencilView *pView) -{ - ANV_FROM_HANDLE(anv_device, device, _device); ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image); - struct anv_depth_stencil_view *view; struct anv_surface *depth_surface = &image->primary_surface; struct anv_surface *stencil_surface = &image->stencil_surface; const struct anv_format *format = anv_format_for_vk_format(image->format); - assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO); - - view = anv_device_alloc(device, sizeof(*view), 8, - VK_SYSTEM_ALLOC_TYPE_API_OBJECT); - if (view == NULL) - return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + view->base.attachment_type = ANV_ATTACHMENT_VIEW_TYPE_DEPTH_STENCIL; /* XXX: We don't handle any of these */ anv_assert(pCreateInfo->mipLevel == 0); @@ -726,17 +686,54 @@ anv_CreateDepthStencilView(VkDevice _device, view->stencil_stride = stencil_surface->stride; view->stencil_offset = image->offset + stencil_surface->offset; view->stencil_qpitch = 0; /* FINISHME: QPitch */ +} - *pView = anv_depth_stencil_view_to_handle(view); +VkResult +anv_CreateAttachmentView(VkDevice _device, + const VkAttachmentViewCreateInfo *pCreateInfo, + VkAttachmentView *pView) +{ + ANV_FROM_HANDLE(anv_device, device, _device); + + assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO); + + if (anv_is_vk_format_depth_or_stencil(pCreateInfo->format)) { + struct anv_depth_stencil_view *view = + anv_device_alloc(device, sizeof(*view), 8, + VK_SYSTEM_ALLOC_TYPE_API_OBJECT); + if (view == NULL) + return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + + anv_depth_stencil_view_init(view, pCreateInfo); + + *pView = anv_attachment_view_to_handle(&view->base); + } else { + struct anv_color_attachment_view *view = + anv_device_alloc(device, sizeof(*view), 8, + VK_SYSTEM_ALLOC_TYPE_API_OBJECT); + if (view == NULL) + return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + + anv_color_attachment_view_init(view, device, pCreateInfo, NULL); + + *pView = anv_attachment_view_to_handle(&view->base); + } return VK_SUCCESS; } VkResult -anv_DestroyDepthStencilView(VkDevice _device, VkDepthStencilView _view) +anv_DestroyAttachmentView(VkDevice _device, VkAttachmentView _view) { ANV_FROM_HANDLE(anv_device, device, _device); - ANV_FROM_HANDLE(anv_depth_stencil_view, view, _view); + ANV_FROM_HANDLE(anv_attachment_view, view, _view); + + if (view->attachment_type == ANV_ATTACHMENT_VIEW_TYPE_COLOR) { + struct anv_color_attachment_view *aview = + (struct anv_color_attachment_view *)view; + + anv_surface_view_fini(device, &aview->view); + } anv_device_free(device, view); diff --git a/src/vulkan/meta.c b/src/vulkan/meta.c index 4b15026f6d9..0844565a996 100644 --- a/src/vulkan/meta.c +++ b/src/vulkan/meta.c @@ -263,32 +263,57 @@ meta_emit_clear(struct anv_cmd_buffer *cmd_buffer, } void -anv_cmd_buffer_clear(struct anv_cmd_buffer *cmd_buffer, - struct anv_render_pass *pass) +anv_cmd_buffer_clear_attachments(struct anv_cmd_buffer *cmd_buffer, + struct anv_render_pass *pass, + const VkClearValue *clear_values) { struct anv_saved_state saved_state; int num_clear_layers = 0; - struct clear_instance_data instance_data[MAX_RTS]; + for (uint32_t i = 0; i < pass->attachment_count; i++) { + if (pass->attachments[i].load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) { + if (anv_is_vk_format_depth_or_stencil(pass->attachments[i].format)) { + anv_finishme("Can't clear depth-stencil yet"); + continue; + } + num_clear_layers++; + } + } + + if (num_clear_layers == 0) + return; - for (uint32_t i = 0; i < pass->num_layers; i++) { - if (pass->layers[i].color_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) { - instance_data[num_clear_layers++] = (struct clear_instance_data) { + struct clear_instance_data instance_data[num_clear_layers]; + uint32_t color_attachments[num_clear_layers]; + + int layer = 0; + for (uint32_t i = 0; i < pass->attachment_count; i++) { + if (pass->attachments[i].load_op == VK_ATTACHMENT_LOAD_OP_CLEAR && + !anv_is_vk_format_depth_or_stencil(pass->attachments[i].format)) { + instance_data[layer] = (struct clear_instance_data) { .vue_header = { .RTAIndex = i, .ViewportIndex = 0, .PointWidth = 0.0 }, - .color = pass->layers[i].clear_color, + .color = clear_values[i].color, }; + color_attachments[layer] = i; + layer++; } } - if (num_clear_layers == 0) - return; - anv_cmd_buffer_save(cmd_buffer, &saved_state); + struct anv_subpass subpass = { + .input_count = 0, + .color_count = num_clear_layers, + .color_attachments = color_attachments, + .depth_stencil_attachment = VK_ATTACHMENT_UNUSED, + }; + + anv_cmd_buffer_begin_subpass(cmd_buffer, &subpass); + meta_emit_clear(cmd_buffer, num_clear_layers, instance_data); /* Restore API state */ @@ -500,7 +525,7 @@ meta_emit_blit(struct anv_cmd_buffer *cmd_buffer, struct anv_surface_view *src, VkOffset3D src_offset, VkExtent3D src_extent, - struct anv_surface_view *dest, + struct anv_color_attachment_view *dest, VkOffset3D dest_offset, VkExtent3D dest_extent) { @@ -596,45 +621,67 @@ meta_emit_blit(struct anv_cmd_buffer *cmd_buffer, anv_CreateFramebuffer(anv_device_to_handle(device), &(VkFramebufferCreateInfo) { .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, - .colorAttachmentCount = 1, - .pColorAttachments = (VkColorAttachmentBindInfo[]) { + .attachmentCount = 1, + .pAttachments = (VkAttachmentBindInfo[]) { { - .view = (VkColorAttachmentView) dest, + .view = anv_attachment_view_to_handle(&dest->base), .layout = VK_IMAGE_LAYOUT_GENERAL } }, - .pDepthStencilAttachment = NULL, - .sampleCount = 1, - .width = dest->extent.width, - .height = dest->extent.height, + .width = dest->view.extent.width, + .height = dest->view.extent.height, .layers = 1 }, &fb); - VkRenderPass pass; anv_CreateRenderPass(anv_device_to_handle(device), &(VkRenderPassCreateInfo) { .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, - .renderArea = { { 0, 0 }, { dest->extent.width, dest->extent.height } }, - .colorAttachmentCount = 1, - .extent = { 0, }, - .sampleCount = 1, - .layers = 1, - .pColorFormats = (VkFormat[]) { dest->format }, - .pColorLayouts = (VkImageLayout[]) { VK_IMAGE_LAYOUT_GENERAL }, - .pColorLoadOps = (VkAttachmentLoadOp[]) { VK_ATTACHMENT_LOAD_OP_LOAD }, - .pColorStoreOps = (VkAttachmentStoreOp[]) { VK_ATTACHMENT_STORE_OP_STORE }, - .pColorLoadClearValues = (VkClearColorValue[]) { - { .f32 = { 1.0, 0.0, 0.0, 1.0 } } + .attachmentCount = 1, + .pAttachments = &(VkAttachmentDescription) { + .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION, + .format = dest->view.format, + .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + .initialLayout = VK_IMAGE_LAYOUT_GENERAL, + .finalLayout = VK_IMAGE_LAYOUT_GENERAL, + }, + .subpassCount = 1, + .pSubpasses = &(VkSubpassDescription) { + .sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION, + .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, + .inputCount = 0, + .colorCount = 1, + .colorAttachments = &(VkAttachmentReference) { + .attachment = 0, + .layout = VK_IMAGE_LAYOUT_GENERAL, + }, + .resolveAttachments = NULL, + .depthStencilAttachment = (VkAttachmentReference) { + .attachment = VK_ATTACHMENT_UNUSED, + .layout = VK_IMAGE_LAYOUT_GENERAL, + }, + .preserveCount = 1, + .preserveAttachments = &(VkAttachmentReference) { + .attachment = 0, + .layout = VK_IMAGE_LAYOUT_GENERAL, + }, }, - .depthStencilFormat = VK_FORMAT_UNDEFINED, + .dependencyCount = 0, }, &pass); anv_CmdBeginRenderPass(anv_cmd_buffer_to_handle(cmd_buffer), - &(VkRenderPassBegin) { + &(VkRenderPassBeginInfo) { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, .renderPass = pass, .framebuffer = fb, - }); + .renderArea = { + .offset = { dest_offset.x, dest_offset.y }, + .extent = { dest_extent.width, dest_extent.height }, + }, + .attachmentCount = 1, + .pAttachmentClearValues = NULL, + }, VK_RENDER_PASS_CONTENTS_INLINE); anv_CmdBindDynamicStateObject(anv_cmd_buffer_to_handle(cmd_buffer), VK_STATE_BIND_POINT_VIEWPORT, @@ -747,10 +794,10 @@ do_buffer_copy(struct anv_cmd_buffer *cmd_buffer, }, cmd_buffer); - struct anv_surface_view dest_view; + struct anv_color_attachment_view dest_view; anv_color_attachment_view_init(&dest_view, cmd_buffer->device, - &(VkColorAttachmentViewCreateInfo) { - .sType = VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO, + &(VkAttachmentViewCreateInfo) { + .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO, .image = dest_image, .format = copy_format, .mipLevel = 0, @@ -887,10 +934,10 @@ void anv_CmdCopyImage( }, cmd_buffer); - struct anv_surface_view dest_view; + struct anv_color_attachment_view dest_view; anv_color_attachment_view_init(&dest_view, cmd_buffer->device, - &(VkColorAttachmentViewCreateInfo) { - .sType = VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO, + &(VkAttachmentViewCreateInfo) { + .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO, .image = destImage, .format = src_image->format, .mipLevel = pRegions[r].destSubresource.mipLevel, @@ -955,10 +1002,10 @@ void anv_CmdBlitImage( }, cmd_buffer); - struct anv_surface_view dest_view; + struct anv_color_attachment_view dest_view; anv_color_attachment_view_init(&dest_view, cmd_buffer->device, - &(VkColorAttachmentViewCreateInfo) { - .sType = VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO, + &(VkAttachmentViewCreateInfo) { + .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO, .image = destImage, .format = dest_image->format, .mipLevel = pRegions[r].destSubresource.mipLevel, @@ -1051,10 +1098,10 @@ void anv_CmdCopyBufferToImage( }, cmd_buffer); - struct anv_surface_view dest_view; + struct anv_color_attachment_view dest_view; anv_color_attachment_view_init(&dest_view, cmd_buffer->device, - &(VkColorAttachmentViewCreateInfo) { - .sType = VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO, + &(VkAttachmentViewCreateInfo) { + .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO, .image = anv_image_to_handle(dest_image), .format = dest_image->format, .mipLevel = pRegions[r].imageSubresource.mipLevel, @@ -1149,10 +1196,10 @@ void anv_CmdCopyImageToBuffer( dest_image->bo = dest_buffer->bo; dest_image->offset = dest_buffer->offset + pRegions[r].bufferOffset; - struct anv_surface_view dest_view; + struct anv_color_attachment_view dest_view; anv_color_attachment_view_init(&dest_view, cmd_buffer->device, - &(VkColorAttachmentViewCreateInfo) { - .sType = VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO, + &(VkAttachmentViewCreateInfo) { + .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO, .image = destImage, .format = src_image->format, .mipLevel = 0, @@ -1212,10 +1259,10 @@ void anv_CmdClearColorImage( for (uint32_t r = 0; r < rangeCount; r++) { for (uint32_t l = 0; l < pRanges[r].mipLevels; l++) { for (uint32_t s = 0; s < pRanges[r].arraySize; s++) { - struct anv_surface_view view; + struct anv_color_attachment_view view; anv_color_attachment_view_init(&view, cmd_buffer->device, - &(VkColorAttachmentViewCreateInfo) { - .sType = VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO, + &(VkAttachmentViewCreateInfo) { + .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO, .image = _image, .format = image->format, .mipLevel = pRanges[r].baseMipLevel + l, @@ -1228,17 +1275,15 @@ void anv_CmdClearColorImage( anv_CreateFramebuffer(anv_device_to_handle(cmd_buffer->device), &(VkFramebufferCreateInfo) { .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, - .colorAttachmentCount = 1, - .pColorAttachments = (VkColorAttachmentBindInfo[]) { + .attachmentCount = 1, + .pAttachments = (VkAttachmentBindInfo[]) { { - .view = (VkColorAttachmentView) &view, + .view = anv_attachment_view_to_handle(&view.base), .layout = VK_IMAGE_LAYOUT_GENERAL } }, - .pDepthStencilAttachment = NULL, - .sampleCount = 1, - .width = view.extent.width, - .height = view.extent.height, + .width = view.view.extent.width, + .height = view.view.extent.height, .layers = 1 }, &fb); @@ -1246,24 +1291,54 @@ void anv_CmdClearColorImage( anv_CreateRenderPass(anv_device_to_handle(cmd_buffer->device), &(VkRenderPassCreateInfo) { .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, - .renderArea = { { 0, 0 }, { view.extent.width, view.extent.height } }, - .colorAttachmentCount = 1, - .extent = { 0, }, - .sampleCount = 1, - .layers = 1, - .pColorFormats = (VkFormat[]) { image->format }, - .pColorLayouts = (VkImageLayout[]) { imageLayout }, - .pColorLoadOps = (VkAttachmentLoadOp[]) { VK_ATTACHMENT_LOAD_OP_DONT_CARE }, - .pColorStoreOps = (VkAttachmentStoreOp[]) { VK_ATTACHMENT_STORE_OP_STORE }, - .pColorLoadClearValues = pColor, - .depthStencilFormat = VK_FORMAT_UNDEFINED, + .attachmentCount = 1, + .pAttachments = &(VkAttachmentDescription) { + .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION, + .format = view.view.format, + .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + .initialLayout = VK_IMAGE_LAYOUT_GENERAL, + .finalLayout = VK_IMAGE_LAYOUT_GENERAL, + }, + .subpassCount = 1, + .pSubpasses = &(VkSubpassDescription) { + .sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION, + .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, + .inputCount = 0, + .colorCount = 1, + .colorAttachments = &(VkAttachmentReference) { + .attachment = 0, + .layout = VK_IMAGE_LAYOUT_GENERAL, + }, + .resolveAttachments = NULL, + .depthStencilAttachment = (VkAttachmentReference) { + .attachment = VK_ATTACHMENT_UNUSED, + .layout = VK_IMAGE_LAYOUT_GENERAL, + }, + .preserveCount = 1, + .preserveAttachments = &(VkAttachmentReference) { + .attachment = 0, + .layout = VK_IMAGE_LAYOUT_GENERAL, + }, + }, + .dependencyCount = 0, }, &pass); anv_CmdBeginRenderPass(anv_cmd_buffer_to_handle(cmd_buffer), - &(VkRenderPassBegin) { + &(VkRenderPassBeginInfo) { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + .renderArea = { + .offset = { 0, 0, }, + .extent = { + .width = view.view.extent.width, + .height = view.view.extent.height, + }, + }, .renderPass = pass, .framebuffer = fb, - }); + .attachmentCount = 1, + .pAttachmentClearValues = NULL, + }, VK_RENDER_PASS_CONTENTS_INLINE); struct clear_instance_data instance_data = { .vue_header = { diff --git a/src/vulkan/private.h b/src/vulkan/private.h index a8ff24214fd..7dc420643fe 100644 --- a/src/vulkan/private.h +++ b/src/vulkan/private.h @@ -695,6 +695,8 @@ struct anv_cmd_buffer { struct anv_pipeline * pipeline; struct anv_pipeline * compute_pipeline; struct anv_framebuffer * framebuffer; + struct anv_render_pass * pass; + struct anv_subpass * subpass; struct anv_dynamic_rs_state * rs_state; struct anv_dynamic_ds_state * ds_state; struct anv_dynamic_vp_state * vp_state; @@ -797,12 +799,13 @@ struct anv_format { uint16_t surface_format; /**< RENDER_SURFACE_STATE.SurfaceFormat */ uint8_t cpp; /**< Bytes-per-pixel of anv_format::surface_format. */ uint8_t num_channels; - uint8_t depth_format; /**< 3DSTATE_DEPTH_BUFFER.SurfaceFormat */ + uint16_t depth_format; /**< 3DSTATE_DEPTH_BUFFER.SurfaceFormat */ bool has_stencil; }; const struct anv_format * anv_format_for_vk_format(VkFormat format); +bool anv_is_vk_format_depth_or_stencil(VkFormat format); /** * A proxy for the color surfaces, depth surfaces, and stencil surfaces. @@ -866,6 +869,36 @@ struct anv_surface_view { VkFormat format; }; +enum anv_attachment_view_type { + ANV_ATTACHMENT_VIEW_TYPE_COLOR, + ANV_ATTACHMENT_VIEW_TYPE_DEPTH_STENCIL, +}; + +struct anv_attachment_view { + enum anv_attachment_view_type attachment_type; +}; + +struct anv_color_attachment_view { + struct anv_attachment_view base; + + struct anv_surface_view view; +}; + +struct anv_depth_stencil_view { + struct anv_attachment_view base; + + struct anv_bo *bo; + + uint32_t depth_offset; /**< Offset into bo. */ + uint32_t depth_stride; /**< 3DSTATE_DEPTH_BUFFER.SurfacePitch */ + uint32_t depth_format; /**< 3DSTATE_DEPTH_BUFFER.SurfaceFormat */ + uint16_t depth_qpitch; /**< 3DSTATE_DEPTH_BUFFER.SurfaceQPitch */ + + uint32_t stencil_offset; /**< Offset into bo. */ + uint32_t stencil_stride; /**< 3DSTATE_STENCIL_BUFFER.SurfacePitch */ + uint16_t stencil_qpitch; /**< 3DSTATE_STENCIL_BUFFER.SurfaceQPitch */ +}; + struct anv_image_create_info { const VkImageCreateInfo *vk_info; bool force_tile_mode; @@ -881,65 +914,66 @@ void anv_image_view_init(struct anv_surface_view *view, const VkImageViewCreateInfo* pCreateInfo, struct anv_cmd_buffer *cmd_buffer); -void anv_color_attachment_view_init(struct anv_surface_view *view, +void anv_color_attachment_view_init(struct anv_color_attachment_view *view, struct anv_device *device, - const VkColorAttachmentViewCreateInfo* pCreateInfo, + const VkAttachmentViewCreateInfo* pCreateInfo, struct anv_cmd_buffer *cmd_buffer); -void anv_surface_view_destroy(struct anv_device *device, - struct anv_surface_view *view); +void anv_surface_view_fini(struct anv_device *device, + struct anv_surface_view *view); struct anv_sampler { uint32_t state[4]; }; -struct anv_depth_stencil_view { - struct anv_bo *bo; - - uint32_t depth_offset; /**< Offset into bo. */ - uint32_t depth_stride; /**< 3DSTATE_DEPTH_BUFFER.SurfacePitch */ - uint32_t depth_format; /**< 3DSTATE_DEPTH_BUFFER.SurfaceFormat */ - uint16_t depth_qpitch; /**< 3DSTATE_DEPTH_BUFFER.SurfaceQPitch */ - - uint32_t stencil_offset; /**< Offset into bo. */ - uint32_t stencil_stride; /**< 3DSTATE_STENCIL_BUFFER.SurfacePitch */ - uint16_t stencil_qpitch; /**< 3DSTATE_STENCIL_BUFFER.SurfaceQPitch */ -}; - struct anv_framebuffer { struct anv_object base; - uint32_t color_attachment_count; - const struct anv_surface_view * color_attachments[MAX_RTS]; - const struct anv_depth_stencil_view * depth_stencil; - uint32_t sample_count; uint32_t width; uint32_t height; uint32_t layers; /* Viewport for clears */ VkDynamicViewportState vp_state; + + uint32_t attachment_count; + const struct anv_attachment_view * attachments[0]; }; -struct anv_render_pass_layer { - VkAttachmentLoadOp color_load_op; - VkClearColorValue clear_color; +struct anv_subpass { + uint32_t input_count; + uint32_t * input_attachments; + uint32_t color_count; + uint32_t * color_attachments; + uint32_t * resolve_attachments; + uint32_t depth_stencil_attachment; +}; + +struct anv_render_pass_attachment { + VkFormat format; + uint32_t samples; + VkAttachmentLoadOp load_op; + VkAttachmentLoadOp stencil_load_op; }; struct anv_render_pass { - VkRect2D render_area; + uint32_t attachment_count; + struct anv_render_pass_attachment * attachments; - uint32_t num_clear_layers; - uint32_t num_layers; - struct anv_render_pass_layer layers[0]; + struct anv_subpass subpasses[0]; }; void anv_device_init_meta(struct anv_device *device); void anv_device_finish_meta(struct anv_device *device); void -anv_cmd_buffer_clear(struct anv_cmd_buffer *cmd_buffer, - struct anv_render_pass *pass); +anv_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer, + struct anv_subpass *subpass); + +void +anv_cmd_buffer_clear_attachments(struct anv_cmd_buffer *cmd_buffer, + struct anv_render_pass *pass, + const VkClearValue *clear_values); void * anv_lookup_entrypoint(const char *name); @@ -977,7 +1011,7 @@ ANV_DEFINE_CASTS(anv_shader, VkShader) ANV_DEFINE_CASTS(anv_pipeline, VkPipeline) ANV_DEFINE_CASTS(anv_image, VkImage) ANV_DEFINE_CASTS(anv_sampler, VkSampler) -ANV_DEFINE_CASTS(anv_depth_stencil_view, VkDepthStencilView) +ANV_DEFINE_CASTS(anv_attachment_view, VkAttachmentView) ANV_DEFINE_CASTS(anv_framebuffer, VkFramebuffer) ANV_DEFINE_CASTS(anv_render_pass, VkRenderPass) ANV_DEFINE_CASTS(anv_query_pool, VkQueryPool) |