[Mesa-dev] [PATCH 10/13] anv: Create render target surface states in CreateFramebuffer
Jason Ekstrand
jason at jlekstrand.net
Sun Sep 25 16:59:09 UTC 2016
Signed-off-by: Jason Ekstrand <jason at jlekstrand.net>
---
src/intel/vulkan/anv_blorp.c | 4 ++--
src/intel/vulkan/anv_cmd_buffer.c | 14 ++++++++------
src/intel/vulkan/anv_device.c | 38 +++++++++++++++++++++++++++++++++++---
src/intel/vulkan/anv_dump.c | 2 +-
src/intel/vulkan/anv_image.c | 33 ---------------------------------
src/intel/vulkan/anv_meta_clear.c | 4 ++--
src/intel/vulkan/anv_private.h | 12 ++++++++----
7 files changed, 56 insertions(+), 51 deletions(-)
diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c
index 9589510..5cc19eb 100644
--- a/src/intel/vulkan/anv_blorp.c
+++ b/src/intel/vulkan/anv_blorp.c
@@ -911,8 +911,8 @@ anv_cmd_buffer_resolve_subpass(struct anv_cmd_buffer *cmd_buffer)
if (dst_att == VK_ATTACHMENT_UNUSED)
continue;
- struct anv_image_view *src_iview = fb->attachments[src_att];
- struct anv_image_view *dst_iview = fb->attachments[dst_att];
+ struct anv_image_view *src_iview = fb->attachments[src_att].view;
+ struct anv_image_view *dst_iview = fb->attachments[dst_att].view;
const VkRect2D render_area = cmd_buffer->state.render_area;
diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c
index 3d627d0..34109c9 100644
--- a/src/intel/vulkan/anv_cmd_buffer.c
+++ b/src/intel/vulkan/anv_cmd_buffer.c
@@ -820,12 +820,14 @@ anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
assert(stage == MESA_SHADER_FRAGMENT);
assert(binding->binding == 0);
if (binding->index < subpass->color_count) {
- const struct anv_image_view *iview =
- fb->attachments[subpass->color_attachments[binding->index]];
+ const struct anv_framebuffer_attachment *fb_att =
+ &fb->attachments[subpass->color_attachments[binding->index]];
- assert(iview->color_rt_surface_state.alloc_size);
- surface_state = iview->color_rt_surface_state;
- add_image_view_relocs(cmd_buffer, iview, surface_state);
+ surface_state = fb->surface_states;
+ surface_state.offset += fb_att->rt_state_offset;
+ surface_state.map += fb_att->rt_state_offset;
+
+ add_image_view_relocs(cmd_buffer, fb_att->view, surface_state);
} else {
/* Null render target */
struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
@@ -1292,7 +1294,7 @@ anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer *cmd_buffer)
return NULL;
const struct anv_image_view *iview =
- fb->attachments[subpass->depth_stencil_attachment];
+ fb->attachments[subpass->depth_stencil_attachment].view;
assert(iview->aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT |
VK_IMAGE_ASPECT_STENCIL_BIT));
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index f786ebe..cda7324 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -1797,18 +1797,48 @@ VkResult anv_CreateFramebuffer(
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
size_t size = sizeof(*framebuffer) +
- sizeof(struct anv_image_view *) * pCreateInfo->attachmentCount;
+ sizeof(*framebuffer->attachments) * pCreateInfo->attachmentCount;
framebuffer = anv_alloc2(&device->alloc, pAllocator, size, 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (framebuffer == NULL)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
framebuffer->attachment_count = pCreateInfo->attachmentCount;
+ unsigned color_count = 0;
for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
- VkImageView _iview = pCreateInfo->pAttachments[i];
- framebuffer->attachments[i] = anv_image_view_from_handle(_iview);
+ ANV_FROM_HANDLE(anv_image_view, iview, pCreateInfo->pAttachments[i]);
+
+ framebuffer->attachments[i].view = iview;
+ framebuffer->attachments[i].rt_state_offset = -1;
+
+ if (iview->image->aspects & VK_IMAGE_ASPECT_COLOR_BIT)
+ color_count++;
}
+ framebuffer->surface_states =
+ anv_state_pool_alloc(&device->surface_state_pool,
+ device->isl_dev.ss.align * color_count,
+ device->isl_dev.ss.align);
+ unsigned color_idx = 0;
+ for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
+ struct anv_image_view *iview = framebuffer->attachments[i].view;
+ if (iview->image->aspects & VK_IMAGE_ASPECT_COLOR_BIT) {
+ const uint16_t offset = (color_idx++) * device->isl_dev.ss.align;
+ framebuffer->attachments[i].rt_state_offset = offset;
+
+ struct isl_view isl_view = iview->isl;
+ isl_view.usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
+ isl_surf_fill_state(&device->isl_dev,
+ framebuffer->surface_states.map + offset,
+ .surf = &iview->image->color_surface.isl,
+ .view = &isl_view,
+ .mocs = device->default_mocs);
+ }
+ }
+
+ if (device->info.has_llc)
+ anv_state_clflush(framebuffer->surface_states);
+
framebuffer->width = pCreateInfo->width;
framebuffer->height = pCreateInfo->height;
framebuffer->layers = pCreateInfo->layers;
@@ -1826,5 +1856,7 @@ void anv_DestroyFramebuffer(
ANV_FROM_HANDLE(anv_device, device, _device);
ANV_FROM_HANDLE(anv_framebuffer, fb, _fb);
+ anv_state_pool_free(&device->surface_state_pool, fb->surface_states);
+
anv_free2(&device->alloc, pAllocator, fb);
}
diff --git a/src/intel/vulkan/anv_dump.c b/src/intel/vulkan/anv_dump.c
index ed1b575..ea35d3f 100644
--- a/src/intel/vulkan/anv_dump.c
+++ b/src/intel/vulkan/anv_dump.c
@@ -408,7 +408,7 @@ anv_dump_add_framebuffer(struct anv_cmd_buffer *cmd_buffer,
unsigned dump_idx = dump_count++;
for (unsigned i = 0; i < fb->attachment_count; i++) {
- struct anv_image_view *iview = fb->attachments[i];
+ struct anv_image_view *iview = fb->attachments[i].view;
uint32_t b;
for_each_bit(b, iview->image->aspects) {
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
index fd8956b..1068cd4 100644
--- a/src/intel/vulkan/anv_image.c
+++ b/src/intel/vulkan/anv_image.c
@@ -470,34 +470,6 @@ anv_image_view_init(struct anv_image_view *iview,
iview->sampler_surface_state.alloc_size = 0;
}
- /* This is kind-of hackish. It is possible, due to get_full_usage above,
- * to get a surface state with a non-renderable format but with
- * VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT. This happens in particular for
- * formats which aren't renderable but where we want to use Vulkan copy
- * commands so VK_IMAGE_USAGE_TRANSFER_DST_BIT is set. In the case of a
- * copy, meta will use a format that we can render to, but most of the rest
- * of the time, we don't want to create those surface states. Once we
- * start using blorp for copies, this problem will go away and we can
- * remove a lot of hacks.
- */
- if ((image->usage & usage_mask & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) &&
- isl_format_supports_rendering(&device->info, format.isl_format)) {
- iview->color_rt_surface_state = alloc_surface_state(device, cmd_buffer);
-
- struct isl_view view = iview->isl;
- view.usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
- isl_surf_fill_state(&device->isl_dev,
- iview->color_rt_surface_state.map,
- .surf = &surface->isl,
- .view = &view,
- .mocs = device->default_mocs);
-
- if (!device->info.has_llc)
- anv_state_clflush(iview->color_rt_surface_state);
- } else {
- iview->color_rt_surface_state.alloc_size = 0;
- }
-
/* NOTE: This one needs to go last since it may stomp isl_view.format */
if (image->usage & usage_mask & VK_IMAGE_USAGE_STORAGE_BIT) {
iview->storage_surface_state = alloc_surface_state(device, cmd_buffer);
@@ -559,11 +531,6 @@ anv_DestroyImageView(VkDevice _device, VkImageView _iview,
ANV_FROM_HANDLE(anv_device, device, _device);
ANV_FROM_HANDLE(anv_image_view, iview, _iview);
- if (iview->color_rt_surface_state.alloc_size > 0) {
- anv_state_pool_free(&device->surface_state_pool,
- iview->color_rt_surface_state);
- }
-
if (iview->sampler_surface_state.alloc_size > 0) {
anv_state_pool_free(&device->surface_state_pool,
iview->sampler_surface_state);
diff --git a/src/intel/vulkan/anv_meta_clear.c b/src/intel/vulkan/anv_meta_clear.c
index 11b471f..4fcec06 100644
--- a/src/intel/vulkan/anv_meta_clear.c
+++ b/src/intel/vulkan/anv_meta_clear.c
@@ -346,7 +346,7 @@ emit_color_clear(struct anv_cmd_buffer *cmd_buffer,
const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
const uint32_t subpass_att = clear_att->colorAttachment;
const uint32_t pass_att = subpass->color_attachments[subpass_att];
- const struct anv_image_view *iview = fb->attachments[pass_att];
+ const struct anv_image_view *iview = fb->attachments[pass_att].view;
const uint32_t samples = iview->image->samples;
const uint32_t samples_log2 = ffs(samples) - 1;
struct anv_pipeline *pipeline =
@@ -513,7 +513,7 @@ emit_depthstencil_clear(struct anv_cmd_buffer *cmd_buffer,
const struct anv_subpass *subpass = cmd_buffer->state.subpass;
const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
const uint32_t pass_att = subpass->depth_stencil_attachment;
- const struct anv_image_view *iview = fb->attachments[pass_att];
+ const struct anv_image_view *iview = fb->attachments[pass_att].view;
const uint32_t samples = iview->image->samples;
const uint32_t samples_log2 = ffs(samples) - 1;
VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil;
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index a09403c..4046c6c 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -1730,9 +1730,6 @@ struct anv_image_view {
VkFormat vk_format;
VkExtent3D extent; /**< Extent of VkImageViewCreateInfo::baseMipLevel. */
- /** RENDER_SURFACE_STATE when using image as a color render target. */
- struct anv_state color_rt_surface_state;
-
/** RENDER_SURFACE_STATE when using image as a sampler surface. */
struct anv_state sampler_surface_state;
@@ -1836,13 +1833,20 @@ struct anv_sampler {
uint32_t state[4];
};
+struct anv_framebuffer_attachment {
+ struct anv_image_view * view;
+ int16_t rt_state_offset;
+};
+
struct anv_framebuffer {
uint32_t width;
uint32_t height;
uint32_t layers;
+ struct anv_state surface_states;
+
uint32_t attachment_count;
- struct anv_image_view * attachments[0];
+ struct anv_framebuffer_attachment attachments[0];
};
struct anv_subpass {
--
2.5.0.400.gff86faf
More information about the mesa-dev
mailing list