anv/image: Add a separate storage image surface state
Thanks to hardware limitations, storage images may need a different surface format and/or other bits in the surface state.
This commit is contained in:
+10
-2
@@ -252,8 +252,7 @@ anv_image_create(VkDevice _device,
|
||||
image->usage = anv_image_get_full_usage(pCreateInfo);
|
||||
image->surface_type = surf_type;
|
||||
|
||||
if (image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
|
||||
VK_IMAGE_USAGE_STORAGE_BIT)) {
|
||||
if (image->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
|
||||
image->needs_nonrt_surface_state = true;
|
||||
}
|
||||
|
||||
@@ -261,6 +260,10 @@ anv_image_create(VkDevice _device,
|
||||
image->needs_color_rt_surface_state = true;
|
||||
}
|
||||
|
||||
if (image->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
|
||||
image->needs_storage_surface_state = true;
|
||||
}
|
||||
|
||||
if (likely(anv_format_is_color(image->format))) {
|
||||
r = make_surface(device, image, create_info,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
@@ -533,6 +536,11 @@ anv_DestroyImageView(VkDevice _device, VkImageView _iview,
|
||||
iview->nonrt_surface_state);
|
||||
}
|
||||
|
||||
if (iview->image->needs_storage_surface_state) {
|
||||
anv_state_pool_free(&device->surface_state_pool,
|
||||
iview->storage_surface_state);
|
||||
}
|
||||
|
||||
anv_free2(&device->alloc, pAllocator, iview);
|
||||
}
|
||||
|
||||
|
||||
@@ -1433,6 +1433,7 @@ struct anv_image {
|
||||
|
||||
bool needs_nonrt_surface_state:1;
|
||||
bool needs_color_rt_surface_state:1;
|
||||
bool needs_storage_surface_state:1;
|
||||
|
||||
/**
|
||||
* Image subsurfaces
|
||||
@@ -1468,6 +1469,9 @@ struct anv_image_view {
|
||||
|
||||
/** RENDER_SURFACE_STATE when using image as a non render target. */
|
||||
struct anv_state nonrt_surface_state;
|
||||
|
||||
/** RENDER_SURFACE_STATE when using image as a storage image. */
|
||||
struct anv_state storage_surface_state;
|
||||
};
|
||||
|
||||
struct anv_image_create_info {
|
||||
|
||||
@@ -332,4 +332,18 @@ genX(image_view_init)(struct anv_image_view *iview,
|
||||
if (!device->info.has_llc)
|
||||
anv_state_clflush(iview->color_rt_surface_state);
|
||||
}
|
||||
|
||||
if (image->needs_storage_surface_state) {
|
||||
iview->storage_surface_state = alloc_surface_state(device, cmd_buffer);
|
||||
|
||||
surface_state.SurfaceFormat =
|
||||
isl_lower_storage_image_format(&device->isl_dev,
|
||||
format->surface_format);
|
||||
|
||||
surface_state.SurfaceMinLOD = range->baseMipLevel;
|
||||
surface_state.MIPCountLOD = range->levelCount - 1;
|
||||
|
||||
GENX(RENDER_SURFACE_STATE_pack)(NULL, iview->storage_surface_state.map,
|
||||
&surface_state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,6 +302,21 @@ genX(image_view_init)(struct anv_image_view *iview,
|
||||
if (!device->info.has_llc)
|
||||
anv_state_clflush(iview->color_rt_surface_state);
|
||||
}
|
||||
|
||||
if (image->needs_storage_surface_state) {
|
||||
iview->storage_surface_state =
|
||||
alloc_surface_state(device, cmd_buffer);
|
||||
|
||||
surface_state.SurfaceFormat =
|
||||
isl_lower_storage_image_format(&device->isl_dev,
|
||||
format_info->surface_format);
|
||||
|
||||
surface_state.SurfaceMinLOD = range->baseMipLevel;
|
||||
surface_state.MIPCountLOD = range->levelCount - 1;
|
||||
|
||||
GENX(RENDER_SURFACE_STATE_pack)(NULL, iview->storage_surface_state.map,
|
||||
&surface_state);
|
||||
}
|
||||
}
|
||||
|
||||
VkResult genX(CreateSampler)(
|
||||
|
||||
Reference in New Issue
Block a user