summaryrefslogtreecommitdiffstats
path: root/src/intel/vulkan
diff options
context:
space:
mode:
Diffstat (limited to 'src/intel/vulkan')
-rw-r--r--src/intel/vulkan/anv_device.c2
-rw-r--r--src/intel/vulkan/anv_image.c44
-rw-r--r--src/intel/vulkan/anv_nir_apply_pipeline_layout.c22
-rw-r--r--src/intel/vulkan/anv_pipeline.c1
-rw-r--r--src/intel/vulkan/anv_private.h11
-rw-r--r--src/intel/vulkan/genX_cmd_buffer.c8
6 files changed, 65 insertions, 23 deletions
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index 91ee67f053d..46b83a3617e 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -484,7 +484,7 @@ void anv_GetPhysicalDeviceFeatures(
.shaderStorageImageExtendedFormats = true,
.shaderStorageImageMultisample = false,
.shaderStorageImageReadWithoutFormat = false,
- .shaderStorageImageWriteWithoutFormat = false,
+ .shaderStorageImageWriteWithoutFormat = true,
.shaderUniformBufferArrayDynamicIndexing = true,
.shaderSampledImageArrayDynamicIndexing = true,
.shaderStorageBufferArrayDynamicIndexing = true,
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
index e59ef4dbb67..cf4304a0cc3 100644
--- a/src/intel/vulkan/anv_image.c
+++ b/src/intel/vulkan/anv_image.c
@@ -583,13 +583,31 @@ anv_CreateImageView(VkDevice _device,
/* NOTE: This one needs to go last since it may stomp isl_view.format */
if (image->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
iview->storage_surface_state = alloc_surface_state(device);
+ iview->writeonly_storage_surface_state = alloc_surface_state(device);
+
+ struct isl_view view = iview->isl;
+ view.usage |= ISL_SURF_USAGE_STORAGE_BIT;
+
+ /* Write-only accesses always used a typed write instruction and should
+ * therefore use the real format.
+ */
+ isl_surf_fill_state(&device->isl_dev,
+ iview->writeonly_storage_surface_state.map,
+ .surf = &surface->isl,
+ .view = &view,
+ .aux_surf = &image->aux_surface.isl,
+ .aux_usage = surf_usage,
+ .mocs = device->default_mocs);
if (isl_has_matching_typed_storage_image_format(&device->info,
format.isl_format)) {
- struct isl_view view = iview->isl;
- view.usage |= ISL_SURF_USAGE_STORAGE_BIT;
+ /* Typed surface reads support a very limited subset of the shader
+ * image formats. Translate it into the closest format the hardware
+ * supports.
+ */
view.format = isl_lower_storage_image_format(&device->info,
format.isl_format);
+
isl_surf_fill_state(&device->isl_dev,
iview->storage_surface_state.map,
.surf = &surface->isl,
@@ -608,10 +626,13 @@ anv_CreateImageView(VkDevice _device,
&iview->storage_image_param,
&surface->isl, &iview->isl);
- if (!device->info.has_llc)
+ if (!device->info.has_llc) {
anv_state_clflush(iview->storage_surface_state);
+ anv_state_clflush(iview->writeonly_storage_surface_state);
+ }
} else {
iview->storage_surface_state.alloc_size = 0;
+ iview->writeonly_storage_surface_state.alloc_size = 0;
}
*pView = anv_image_view_to_handle(iview);
@@ -639,6 +660,11 @@ anv_DestroyImageView(VkDevice _device, VkImageView _iview,
iview->storage_surface_state);
}
+ if (iview->writeonly_storage_surface_state.alloc_size > 0) {
+ anv_state_pool_free(&device->surface_state_pool,
+ iview->writeonly_storage_surface_state);
+ }
+
vk_free2(&device->alloc, pAllocator, iview);
}
@@ -682,6 +708,7 @@ anv_CreateBufferView(VkDevice _device,
if (buffer->usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) {
view->storage_surface_state = alloc_surface_state(device);
+ view->writeonly_storage_surface_state = alloc_surface_state(device);
enum isl_format storage_format =
isl_has_matching_typed_storage_image_format(&device->info,
@@ -695,11 +722,18 @@ anv_CreateBufferView(VkDevice _device,
(storage_format == ISL_FORMAT_RAW ? 1 :
isl_format_get_layout(storage_format)->bpb / 8));
+ /* Write-only accesses should use the original format. */
+ anv_fill_buffer_surface_state(device, view->writeonly_storage_surface_state,
+ view->format,
+ view->offset, view->range,
+ isl_format_get_layout(view->format)->bpb / 8);
+
isl_buffer_fill_image_param(&device->isl_dev,
&view->storage_image_param,
view->format, view->range);
} else {
view->storage_surface_state = (struct anv_state){ 0 };
+ view->writeonly_storage_surface_state = (struct anv_state){ 0 };
}
*pView = anv_buffer_view_to_handle(view);
@@ -725,6 +759,10 @@ anv_DestroyBufferView(VkDevice _device, VkBufferView bufferView,
anv_state_pool_free(&device->surface_state_pool,
view->storage_surface_state);
+ if (view->writeonly_storage_surface_state.alloc_size > 0)
+ anv_state_pool_free(&device->surface_state_pool,
+ view->writeonly_storage_surface_state);
+
vk_free2(&device->alloc, pAllocator, view);
}
diff --git a/src/intel/vulkan/anv_nir_apply_pipeline_layout.c b/src/intel/vulkan/anv_nir_apply_pipeline_layout.c
index d6b85611419..67bcf5e29ef 100644
--- a/src/intel/vulkan/anv_nir_apply_pipeline_layout.c
+++ b/src/intel/vulkan/anv_nir_apply_pipeline_layout.c
@@ -351,9 +351,6 @@ anv_nir_apply_pipeline_layout(struct anv_pipeline *pipeline,
continue;
enum glsl_sampler_dim dim = glsl_get_sampler_dim(var->interface_type);
- if (dim != GLSL_SAMPLER_DIM_SUBPASS &&
- dim != GLSL_SAMPLER_DIM_SUBPASS_MS)
- continue;
const uint32_t set = var->data.descriptor_set;
const uint32_t binding = var->data.binding;
@@ -369,7 +366,12 @@ anv_nir_apply_pipeline_layout(struct anv_pipeline *pipeline,
assert(pipe_binding[i].set == set);
assert(pipe_binding[i].binding == binding);
assert(pipe_binding[i].index == i);
- pipe_binding[i].input_attachment_index = var->data.index + i;
+
+ if (dim == GLSL_SAMPLER_DIM_SUBPASS ||
+ dim == GLSL_SAMPLER_DIM_SUBPASS_MS)
+ pipe_binding[i].input_attachment_index = var->data.index + i;
+
+ pipe_binding[i].write_only = var->data.image.write_only;
}
}
@@ -398,18 +400,6 @@ anv_nir_apply_pipeline_layout(struct anv_pipeline *pipeline,
unsigned binding = var->data.binding;
unsigned image_index = state.set[set].image_offsets[binding];
- /* We have a very tight coupling between back-end compiler and
- * state setup which requires us to fill the image surface state
- * out differently if and only if the image is declared write-only.
- * Right now, our state setup code sets up all images as if they
- * are read-write. This means that the compiler needs to see
- * read-only as well.
- *
- * Whenever we implement shaderStorageImageWriteWithoutFormat, we
- * need to delete this.
- */
- var->data.image.write_only = false;
-
var->data.driver_location = shader->num_uniforms +
image_index * BRW_IMAGE_PARAM_SIZE * 4;
}
diff --git a/src/intel/vulkan/anv_pipeline.c b/src/intel/vulkan/anv_pipeline.c
index ca3823c2b66..44101038357 100644
--- a/src/intel/vulkan/anv_pipeline.c
+++ b/src/intel/vulkan/anv_pipeline.c
@@ -128,6 +128,7 @@ anv_shader_compile_to_nir(struct anv_device *device,
.float64 = device->instance->physicalDevice.info.gen >= 8,
.tessellation = true,
.draw_parameters = true,
+ .image_write_without_format = true,
};
nir_function *entry_point =
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 51e85c74bd1..ec791a42871 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -953,6 +953,9 @@ struct anv_pipeline_binding {
/* Input attachment index (relative to the subpass) */
uint8_t input_attachment_index;
+
+ /* For a storage image, whether it is write-only */
+ bool write_only;
};
struct anv_pipeline_layout {
@@ -1683,8 +1686,13 @@ struct anv_image_view {
/** RENDER_SURFACE_STATE when using image as a sampler surface. */
struct anv_state sampler_surface_state;
- /** RENDER_SURFACE_STATE when using image as a storage image. */
+ /**
+ * RENDER_SURFACE_STATE when using image as a storage image. Separate states
+ * for write-only and readable, using the real format for write-only and the
+ * lowered format for readable.
+ */
struct anv_state storage_surface_state;
+ struct anv_state writeonly_storage_surface_state;
struct brw_image_param storage_image_param;
};
@@ -1715,6 +1723,7 @@ struct anv_buffer_view {
struct anv_state surface_state;
struct anv_state storage_surface_state;
+ struct anv_state writeonly_storage_surface_state;
struct brw_image_param storage_image_param;
};
diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c
index d07fe78b52f..14338b22ece 100644
--- a/src/intel/vulkan/genX_cmd_buffer.c
+++ b/src/intel/vulkan/genX_cmd_buffer.c
@@ -1211,7 +1211,9 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
break;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
- surface_state = desc->image_view->storage_surface_state;
+ surface_state = (binding->write_only)
+ ? desc->image_view->writeonly_storage_surface_state
+ : desc->image_view->storage_surface_state;
assert(surface_state.alloc_size);
add_image_view_relocs(cmd_buffer, desc->image_view,
desc->image_view->image->aux_usage,
@@ -1238,7 +1240,9 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
break;
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
- surface_state = desc->buffer_view->storage_surface_state;
+ surface_state = (binding->write_only)
+ ? desc->buffer_view->writeonly_storage_surface_state
+ : desc->buffer_view->storage_surface_state;
assert(surface_state.alloc_size);
add_surface_state_reloc(cmd_buffer, surface_state,
desc->buffer_view->bo,