anv: Add support for storage texel buffers
authorJason Ekstrand <jason.ekstrand@intel.com>
Tue, 15 Dec 2015 00:51:12 +0000 (16:51 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Tue, 15 Dec 2015 00:51:12 +0000 (16:51 -0800)
src/vulkan/anv_cmd_buffer.c
src/vulkan/anv_descriptor_set.c
src/vulkan/anv_device.c
src/vulkan/anv_image.c
src/vulkan/anv_private.h

index 984b885a4b6696779dc1965bcb045a58994e9721..759c4677a74d2db1c232a35c9a06dcbca664971e 100644 (file)
@@ -736,7 +736,16 @@ anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
          break;
 
       case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
-         assert(!"Unsupported descriptor type");
+         surface_state = desc->buffer_view->storage_surface_state;
+         bo = desc->buffer_view->bo;
+         bo_offset = desc->buffer_view->offset;
+
+         struct brw_image_param *image_param =
+            &cmd_buffer->state.push_constants[stage]->images[image++];
+
+         anv_buffer_view_fill_image_param(cmd_buffer->device, desc->buffer_view,
+                                          image_param);
+         image_param->surface_idx = bias + s;
          break;
 
       default:
index 52d2ffecdd6755106955b8b974d18bb4c7a77083..a7b6b7730123b0739e10ce83c8dd12c191c5a545 100644 (file)
@@ -133,11 +133,16 @@ VkResult anv_CreateDescriptorSetLayout(
          break;
       }
 
-      if (binding->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) {
+      switch (binding->descriptorType) {
+      case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+      case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
          for_each_bit(s, binding->stageFlags) {
             set_layout->binding[b].stage[s].image_index = image_count[s];
             image_count[s] += binding->descriptorCount;
          }
+         break;
+      default:
+         break;
       }
 
       if (binding->pImmutableSamplers) {
index ff22490785430e15b1e44c794b676ebe56dffb8a..df6472edfde12dde3922e7c632a83eb3965e8f6e 100644 (file)
@@ -1472,6 +1472,7 @@ VkResult anv_CreateBuffer(
       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
    buffer->size = pCreateInfo->size;
+   buffer->usage = pCreateInfo->usage;
    buffer->bo = NULL;
    buffer->offset = 0;
 
index 659fe80b3200569b6a365d2aa866f028a985e1e7..159af6d19b0458e794e3b37f7918cc9783bcd77c 100644 (file)
@@ -505,26 +505,45 @@ anv_CreateBufferView(VkDevice _device,
    ANV_FROM_HANDLE(anv_buffer, buffer, pCreateInfo->buffer);
    struct anv_buffer_view *view;
 
-   /* TODO: Storage texel buffers */
-
    view = anv_alloc2(&device->alloc, pAllocator, sizeof(*view), 8,
                      VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
    if (!view)
       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
+   const struct anv_format *format =
+      anv_format_for_vk_format(pCreateInfo->format);
+
+   view->format = format->surface_format;
    view->bo = buffer->bo;
    view->offset = buffer->offset + pCreateInfo->offset;
+   view->range = pCreateInfo->range;
 
-   view->surface_state =
-      anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
+   if (buffer->usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) {
+      view->surface_state =
+         anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
 
-   const struct anv_format *format =
-      anv_format_for_vk_format(pCreateInfo->format);
+      anv_fill_buffer_surface_state(device, view->surface_state.map,
+                                    view->format,
+                                    view->offset, pCreateInfo->range,
+                                    format->isl_layout->bpb / 8);
+   } else {
+      view->surface_state = (struct anv_state){ 0 };
+   }
+
+   if (buffer->usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) {
+      view->storage_surface_state =
+         anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
 
-   anv_fill_buffer_surface_state(device, view->surface_state.map,
-                                 format->surface_format,
-                                 view->offset, pCreateInfo->range,
-                                 format->isl_layout->bpb / 8);
+      enum isl_format storage_format =
+         isl_lower_storage_image_format(&device->isl_dev, view->format);
+
+      anv_fill_buffer_surface_state(device, view->storage_surface_state.map,
+                                    storage_format,
+                                    view->offset, pCreateInfo->range,
+                                    format->isl_layout->bpb / 8);
+   } else {
+      view->storage_surface_state = (struct anv_state){ 0 };
+   }
 
    *pView = anv_buffer_view_to_handle(view);
 
@@ -538,7 +557,14 @@ anv_DestroyBufferView(VkDevice _device, VkBufferView bufferView,
    ANV_FROM_HANDLE(anv_device, device, _device);
    ANV_FROM_HANDLE(anv_buffer_view, view, bufferView);
 
-   anv_state_pool_free(&device->surface_state_pool, view->surface_state);
+   if (view->surface_state.alloc_size > 0)
+      anv_state_pool_free(&device->surface_state_pool,
+                          view->surface_state);
+
+   if (view->storage_surface_state.alloc_size > 0)
+      anv_state_pool_free(&device->surface_state_pool,
+                          view->storage_surface_state);
+
    anv_free2(&device->alloc, pAllocator, view);
 }
 
@@ -599,3 +625,19 @@ anv_image_view_fill_image_param(struct anv_device *device,
    memset(param, 0, sizeof *param);
    anv_finishme("Actually fill out brw_image_param");
 }
+
+void
+anv_buffer_view_fill_image_param(struct anv_device *device,
+                                 struct anv_buffer_view *view,
+                                 struct brw_image_param *param)
+{
+   /* Set the swizzling shifts to all-ones to effectively disable swizzling --
+    * See emit_address_calculation() in brw_fs_surface_builder.cpp for a more
+    * detailed explanation of these parameters.
+    */
+   param->swizzling[0] = 0xff;
+   param->swizzling[1] = 0xff;
+
+   param->stride[0] = isl_format_layouts[view->format].bpb / 8;
+   param->size[0] = view->range / param->stride[0];
+}
index c5ab92c543833a22163fd10f6872b44969c80ee9..8aaa2811fc767bad842b234cbc908a609c4cf736 100644 (file)
@@ -921,6 +921,8 @@ struct anv_buffer {
    struct anv_device *                          device;
    VkDeviceSize                                 size;
 
+   VkBufferUsageFlags                           usage;
+
    /* Set when bound */
    struct anv_bo *                              bo;
    VkDeviceSize                                 offset;
@@ -1517,10 +1519,13 @@ gen9_image_view_init(struct anv_image_view *iview,
                      struct anv_cmd_buffer *cmd_buffer);
 
 struct anv_buffer_view {
+   enum isl_format format; /**< VkBufferViewCreateInfo::format */
    struct anv_bo *bo;
    uint32_t offset; /**< Offset into bo. */
+   uint64_t range; /**< VkBufferViewCreateInfo::range */
 
    struct anv_state surface_state;
+   struct anv_state storage_surface_state;
 };
 
 void anv_fill_buffer_surface_state(struct anv_device *device, void *state,
@@ -1544,6 +1549,9 @@ void gen9_fill_buffer_surface_state(void *state, enum isl_format format,
 void anv_image_view_fill_image_param(struct anv_device *device,
                                      struct anv_image_view *view,
                                      struct brw_image_param *param);
+void anv_buffer_view_fill_image_param(struct anv_device *device,
+                                      struct anv_buffer_view *view,
+                                      struct brw_image_param *param);
 
 struct anv_sampler {
    uint32_t state[4];