From: Kristian Høgsberg Date: Sat, 23 May 2015 05:59:12 +0000 (-0700) Subject: vk: Set up depth and stencil buffers X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=37743f90bcaf3aa34c86ad3a382308164e4f1eaa;p=mesa.git vk: Set up depth and stencil buffers --- diff --git a/src/vulkan/device.c b/src/vulkan/device.c index 4301739022d..0c35d503ab0 100644 --- a/src/vulkan/device.c +++ b/src/vulkan/device.c @@ -2260,15 +2260,6 @@ VkResult anv_BeginCommandBuffer( anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_SBE_SWIZ); anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_AA_LINE_PARAMETERS); - /* Hardcoded state: */ - anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DEPTH_BUFFER, - .SurfaceType = SURFTYPE_2D, - .Width = 1, - .Height = 1, - .SurfaceFormat = D16_UNORM, - .SurfaceBaseAddress = { NULL, 0 }, - .HierarchicalDepthBufferEnable = 0); - anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_WM_DEPTH_STENCIL, .DepthTestEnable = false, .DepthBufferWriteEnable = false); @@ -3118,6 +3109,9 @@ VkResult anv_CreateFramebuffer( struct anv_device *device = (struct anv_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, @@ -3136,6 +3130,8 @@ VkResult anv_CreateFramebuffer( if (pCreateInfo->pDepthStencilAttachment) { framebuffer->depth_stencil = (struct anv_depth_stencil_view *) pCreateInfo->pDepthStencilAttachment->view; + } else { + framebuffer->depth_stencil = &null_view; } framebuffer->sample_count = pCreateInfo->sampleCount; @@ -3211,7 +3207,7 @@ anv_cmd_buffer_fill_render_targets(struct anv_cmd_buffer *cmd_buffer) struct anv_bindings *bindings = cmd_buffer->bindings; for (uint32_t i = 0; i < framebuffer->color_attachment_count; i++) { - struct anv_surface_view *view = framebuffer->color_attachments[i]; + const struct anv_surface_view *view = framebuffer->color_attachments[i]; struct anv_state state = anv_cmd_buffer_alloc_surface_state(cmd_buffer, 64, 64); @@ -3228,6 +3224,46 @@ anv_cmd_buffer_fill_render_targets(struct anv_cmd_buffer *cmd_buffer) cmd_buffer->dirty |= ANV_CMD_BUFFER_DESCRIPTOR_SET_DIRTY; } +static void +anv_cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer, + struct anv_render_pass *pass) +{ + const struct anv_depth_stencil_view *view = + cmd_buffer->framebuffer->depth_stencil; + + /* FIXME: Implement the PMA stall W/A */ + + anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DEPTH_BUFFER, + .SurfaceType = SURFTYPE_2D, + .DepthWriteEnable = view->depth_stride > 0, + .StencilWriteEnable = view->stencil_stride > 0, + .HierarchicalDepthBufferEnable = false, + .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, + .LOD = 0, + .Depth = 1 - 1, + .MinimumArrayElement = 0, + .DepthBufferObjectControlState = GEN8_MOCS, + .RenderTargetViewExtent = 1 - 1, + .SurfaceQPitch = 0); + + /* Disable hierarchial depth buffers. */ + anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_HIER_DEPTH_BUFFER); + + anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_STENCIL_BUFFER, + .StencilBufferEnable = view->stencil_stride > 0, + .StencilBufferObjectControlState = GEN8_MOCS, + .SurfacePitch = view->stencil_stride > 0 ? view->stencil_stride - 1 : 0, + .SurfaceBaseAddress = { view->bo, view->stencil_offset }, + .SurfaceQPitch = 0); + + /* Clear the clear params. */ + anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_CLEAR_PARAMS); +} + void anv_CmdBeginRenderPass( VkCmdBuffer cmdBuffer, const VkRenderPassBegin* pRenderPassBegin) @@ -3251,6 +3287,8 @@ void anv_CmdBeginRenderPass( anv_cmd_buffer_fill_render_targets(cmd_buffer); + anv_cmd_buffer_emit_depth_stencil(cmd_buffer, pass); + anv_cmd_buffer_clear(cmd_buffer, pass); } diff --git a/src/vulkan/formats.c b/src/vulkan/formats.c index 13ae1ed7538..66208f23ea9 100644 --- a/src/vulkan/formats.c +++ b/src/vulkan/formats.c @@ -23,7 +23,7 @@ #include "private.h" -#define UNSUPPORTED ~0U +#define UNSUPPORTED 0xffff static const struct anv_format anv_formats[] = { [VK_FORMAT_UNDEFINED] = { .format = RAW, .cpp = 1, .channels = 1 }, @@ -116,13 +116,17 @@ static const struct anv_format anv_formats[] = { [VK_FORMAT_R11G11B10_UFLOAT] = { .format = R11G11B10_FLOAT, .cpp = 4, .channels = 3 }, [VK_FORMAT_R9G9B9E5_UFLOAT] = { .format = R9G9B9E5_SHAREDEXP, .cpp = 4, .channels = 3 }, - [VK_FORMAT_D16_UNORM] = { .format = UNSUPPORTED }, - [VK_FORMAT_D24_UNORM] = { .format = UNSUPPORTED }, - [VK_FORMAT_D32_SFLOAT] = { .format = UNSUPPORTED }, - [VK_FORMAT_S8_UINT] = { .format = UNSUPPORTED }, - [VK_FORMAT_D16_UNORM_S8_UINT] = { .format = UNSUPPORTED }, - [VK_FORMAT_D24_UNORM_S8_UINT] = { .format = UNSUPPORTED }, - [VK_FORMAT_D32_SFLOAT_S8_UINT] = { .format = UNSUPPORTED }, + /* For depth/stencil formats, the .format and .cpp fields describe the + * depth format. The field .has_stencil indicates whether or not there's a + * stencil buffer. + */ + [VK_FORMAT_D16_UNORM] = { .format = D16_UNORM, .cpp = 2, .channels = 1 }, + [VK_FORMAT_D24_UNORM] = { .format = D24_UNORM_X8_UINT, .cpp = 4, .channels = 1 }, + [VK_FORMAT_D32_SFLOAT] = { .format = D32_FLOAT, .cpp = 4, .channels = 1 }, + [VK_FORMAT_S8_UINT] = { .format = UNSUPPORTED, .cpp = 0, .channels = 1, .has_stencil = true }, + [VK_FORMAT_D16_UNORM_S8_UINT] = { .format = D16_UNORM, .cpp = 2, .channels = 2, .has_stencil = true }, + [VK_FORMAT_D24_UNORM_S8_UINT] = { .format = D24_UNORM_X8_UINT, .cpp = 4, .channels = 2, .has_stencil = true }, + [VK_FORMAT_D32_SFLOAT_S8_UINT] = { .format = D32_FLOAT, .cpp = 4, .channels = 2, .has_stencil = true }, [VK_FORMAT_BC1_RGB_UNORM] = { .format = UNSUPPORTED }, [VK_FORMAT_BC1_RGB_SRGB] = { .format = UNSUPPORTED }, diff --git a/src/vulkan/image.c b/src/vulkan/image.c index 109a248b9a0..99542f1b538 100644 --- a/src/vulkan/image.c +++ b/src/vulkan/image.c @@ -49,8 +49,9 @@ VkResult anv_image_create( { struct anv_device *device = (struct anv_device *) _device; struct anv_image *image; - const struct anv_format *format; + const struct anv_format *info; int32_t aligned_height; + uint32_t stencil_size; assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO); @@ -93,13 +94,32 @@ VkResult anv_image_create( image->alignment = 4096; } - format = anv_format_for_vk_format(pCreateInfo->format); - assert(format->cpp > 0); - image->stride = ALIGN_I32(image->extent.width * format->cpp, - tile_mode_info[image->tile_mode].tile_width); - aligned_height = ALIGN_I32(image->extent.height, - tile_mode_info[image->tile_mode].tile_height); - image->size = image->stride * aligned_height; + info = anv_format_for_vk_format(pCreateInfo->format); + assert(info->cpp > 0 || info->has_stencil); + + if (info->cpp > 0) { + image->stride = ALIGN_I32(image->extent.width * info->cpp, + tile_mode_info[image->tile_mode].tile_width); + aligned_height = ALIGN_I32(image->extent.height, + tile_mode_info[image->tile_mode].tile_height); + image->size = image->stride * aligned_height; + } else { + image->size = 0; + image->stride = 0; + } + + if (info->has_stencil) { + image->stencil_offset = ALIGN_U32(image->size, 4096); + image->stencil_stride = ALIGN_I32(image->extent.width, + tile_mode_info[WMAJOR].tile_width); + aligned_height = ALIGN_I32(image->extent.height, + tile_mode_info[WMAJOR].tile_height); + stencil_size = image->stencil_stride * aligned_height; + image->size = image->stencil_offset + stencil_size; + } else { + image->stencil_offset = 0; + image->stencil_stride = 0; + } *pImage = (VkImage) image; @@ -125,14 +145,13 @@ VkResult anv_GetImageSubresourceInfo( stub_return(VK_UNSUPPORTED); } -// Image view functions - static struct anv_state create_surface_state(struct anv_device *device, - struct anv_image *image, const struct anv_format *format, - struct anv_cmd_buffer *cmd_buffer) + struct anv_image *image, uint32_t format, uint32_t tile_mode, + uint32_t offset, struct anv_cmd_buffer *cmd_buffer) { struct anv_state state; + if (cmd_buffer) state = anv_state_stream_alloc(&cmd_buffer->surface_state_stream, 64, 64); else @@ -141,10 +160,10 @@ create_surface_state(struct anv_device *device, struct GEN8_RENDER_SURFACE_STATE surface_state = { .SurfaceType = SURFTYPE_2D, .SurfaceArray = false, - .SurfaceFormat = format->format, + .SurfaceFormat = format, .SurfaceVerticalAlignment = VALIGN4, .SurfaceHorizontalAlignment = HALIGN4, - .TileMode = image->tile_mode, + .TileMode = tile_mode, .VerticalLineStride = 0, .VerticalLineStrideOffset = 0, .SamplerL2BypassModeDisable = true, @@ -172,8 +191,7 @@ create_surface_state(struct anv_device *device, .ShaderChannelSelectBlue = SCS_BLUE, .ShaderChannelSelectAlpha = SCS_ALPHA, .ResourceMinLOD = 0, - /* FIXME: We assume that the image must be bound at this time. */ - .SurfaceBaseAddress = { NULL, image->offset }, + .SurfaceBaseAddress = { NULL, offset }, }; GEN8_RENDER_SURFACE_STATE_pack(NULL, state.map, &surface_state); @@ -188,17 +206,33 @@ anv_image_view_init(struct anv_surface_view *view, struct anv_cmd_buffer *cmd_buffer) { struct anv_image *image = (struct anv_image *) pCreateInfo->image; - const struct anv_format *format = + const struct anv_format *info = anv_format_for_vk_format(pCreateInfo->format); + uint32_t tile_mode, format; view->bo = image->bo; - view->offset = image->offset; - view->surface_state = create_surface_state(device, image, format, - cmd_buffer); - view->format = pCreateInfo->format; + switch (pCreateInfo->subresourceRange.aspect) { + case VK_IMAGE_ASPECT_STENCIL: + /* FIXME: How is stencil texturing formed? */ + view->offset = image->offset + image->stencil_offset; + tile_mode = WMAJOR; + format = R8_UINT; + break; + case VK_IMAGE_ASPECT_DEPTH: + case VK_IMAGE_ASPECT_COLOR: + view->offset = image->offset; + tile_mode = image->tile_mode; + format = info->format; + break; + default: + assert(0); + break; + } /* TODO: Miplevels */ view->extent = image->extent; + view->surface_state = + create_surface_state(device, image, format, tile_mode, view->offset, cmd_buffer); } VkResult anv_CreateImageView( @@ -235,10 +269,11 @@ anv_color_attachment_view_init(struct anv_surface_view *view, view->bo = image->bo; view->offset = image->offset; - view->surface_state = create_surface_state(device, image, format, - cmd_buffer); view->extent = image->extent; view->format = pCreateInfo->format; + view->surface_state = + create_surface_state(device, image, + format->format, image->tile_mode, view->offset, cmd_buffer); } VkResult anv_CreateColorAttachmentView( @@ -264,9 +299,33 @@ VkResult anv_CreateColorAttachmentView( } VkResult anv_CreateDepthStencilView( - VkDevice device, + VkDevice _device, const VkDepthStencilViewCreateInfo* pCreateInfo, VkDepthStencilView* pView) { - stub_return(VK_UNSUPPORTED); + struct anv_device *device = (struct anv_device *) _device; + struct anv_depth_stencil_view *view; + struct anv_image *image = (struct anv_image *) pCreateInfo->image; + 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->bo = image->bo; + + view->depth_stride = image->stride; + view->depth_offset = image->offset; + view->depth_format = format->format; + + view->stencil_stride = image->stencil_stride; + view->stencil_offset = image->offset + image->stencil_offset; + + *pView = (VkDepthStencilView) view; + + return VK_SUCCESS; } diff --git a/src/vulkan/private.h b/src/vulkan/private.h index e3e5bd52a64..f75e03c8598 100644 --- a/src/vulkan/private.h +++ b/src/vulkan/private.h @@ -659,9 +659,10 @@ int anv_compiler_run(struct anv_compiler *compiler, struct anv_pipeline *pipelin void anv_compiler_free(struct anv_pipeline *pipeline); struct anv_format { - uint32_t format; - uint32_t cpp; - uint32_t channels; + uint16_t format; + uint8_t cpp; + uint8_t channels; + bool has_stencil; }; const struct anv_format * @@ -669,12 +670,15 @@ anv_format_for_vk_format(VkFormat format); struct anv_image { VkImageType type; - VkFormat format; VkExtent3D extent; + VkFormat format; uint32_t tile_mode; VkDeviceSize size; uint32_t alignment; - int32_t stride; + uint32_t stride; + + uint32_t stencil_offset; + uint32_t stencil_stride; /* Set when bound */ struct anv_bo * bo; @@ -715,13 +719,21 @@ struct anv_sampler { }; struct anv_depth_stencil_view { + struct anv_bo * bo; + + uint32_t depth_offset; + uint32_t depth_stride; + uint32_t depth_format; + + uint32_t stencil_offset; + uint32_t stencil_stride; }; struct anv_framebuffer { struct anv_object base; uint32_t color_attachment_count; - struct anv_surface_view * color_attachments[MAX_RTS]; - struct anv_depth_stencil_view * depth_stencil; + const struct anv_surface_view * color_attachments[MAX_RTS]; + const struct anv_depth_stencil_view * depth_stencil; uint32_t sample_count; uint32_t width;