uint32_t a;
const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
for (uint32_t i = 0; i < subpass->color_count; i++) {
- a = subpass->color_attachments[i].attachment;
+ if (!subpass->color_attachments[i])
+ continue;
+ a = subpass->color_attachments[i]->attachment;
if (attachment_needs_clear(state, a))
return true;
}
- if (subpass->depth_stencil_attachment) {
- a = subpass->depth_stencil_attachment->attachment;
+ if (subpass->depth_stencil_attachment && *subpass->depth_stencil_attachment) {
+ a = subpass->depth_stencil_attachment[0]->attachment;
if (attachment_needs_clear(state, a))
return true;
}
const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
for (unsigned i = 0; i < subpass->color_count; i++) {
- uint32_t a = subpass->color_attachments[i].attachment;
+ if (!subpass->color_attachments[i])
+ continue;
+ uint32_t a = subpass->color_attachments[i]->attachment;
if (!attachment_needs_clear(state, a))
continue;
}
}
- if (subpass->depth_stencil_attachment) {
- uint32_t ds = subpass->depth_stencil_attachment->attachment;
+ if (subpass->depth_stencil_attachment && subpass->depth_stencil_attachment[0]) {
+ uint32_t ds = subpass->depth_stencil_attachment[0]->attachment;
if (!attachment_needs_clear(state, ds))
return;
if (subpass->view_mask)
goto slow_clear;
for (unsigned i = 0; i < subpass->color_count; i++) {
- uint32_t a = subpass->color_attachments[i].attachment;
+ if (!subpass->color_attachments[i])
+ continue;
+ uint32_t a = subpass->color_attachments[i]->attachment;
if (!attachment_needs_clear(state, a))
continue;
}
for (unsigned i = 0; i < subpass->color_count; i++) {
- uint32_t a = subpass->color_attachments[i].attachment;
+ if (!subpass->color_attachments[i])
+ continue;
+ uint32_t a = subpass->color_attachments[i]->attachment;
if (!attachment_needs_clear(state, a))
continue;
state->pending_clear_aspects[a] = 0;
}
- if (subpass->depth_stencil_attachment &&
- attachment_needs_clear(state, subpass->depth_stencil_attachment->attachment)) {
- uint32_t ds = subpass->depth_stencil_attachment->attachment;
+ if (subpass->depth_stencil_attachment && *subpass->depth_stencil_attachment &&
+ attachment_needs_clear(state, subpass->depth_stencil_attachment[0]->attachment)) {
+ uint32_t ds = subpass->depth_stencil_attachment[0]->attachment;
struct lvp_render_pass_attachment *att = &state->pass->attachments[ds];
struct lvp_image_view *imgv = get_attachment(state, ds);
{
const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
- if (subpass->depth_stencil_attachment && subpass->ds_resolve_attachment) {
- struct lvp_subpass_attachment src_att = *subpass->depth_stencil_attachment;
- struct lvp_subpass_attachment dst_att = *subpass->ds_resolve_attachment;
- if (dst_att.attachment != VK_ATTACHMENT_UNUSED) {
- int num_blits = 1;
- if (subpass->depth_resolve_mode != subpass->stencil_resolve_mode)
- num_blits = 2;
+ if (subpass->depth_stencil_attachment && *subpass->depth_stencil_attachment &&
+ subpass->ds_resolve_attachment && *subpass->ds_resolve_attachment) {
+ struct lvp_render_pass_attachment *src_att = *subpass->depth_stencil_attachment;
+ struct lvp_render_pass_attachment *dst_att = *subpass->ds_resolve_attachment;
+ int num_blits = 1;
+ if (subpass->depth_resolve_mode != subpass->stencil_resolve_mode)
+ num_blits = 2;
- for (unsigned i = 0; i < num_blits; i++) {
+ for (unsigned i = 0; i < num_blits; i++) {
- if (i == 0 && subpass->depth_resolve_mode == VK_RESOLVE_MODE_NONE)
- continue;
+ if (i == 0 && subpass->depth_resolve_mode == VK_RESOLVE_MODE_NONE)
+ continue;
- if (i == 1 && subpass->stencil_resolve_mode == VK_RESOLVE_MODE_NONE)
- continue;
+ if (i == 1 && subpass->stencil_resolve_mode == VK_RESOLVE_MODE_NONE)
+ continue;
- struct lvp_image_view *src_imgv = get_attachment(state, src_att.attachment);
- struct lvp_image_view *dst_imgv = get_attachment(state, dst_att.attachment);
+ struct lvp_image_view *src_imgv = get_attachment(state, src_att->attachment);
+ struct lvp_image_view *dst_imgv = get_attachment(state, dst_att->attachment);
- struct pipe_blit_info info;
- memset(&info, 0, sizeof(info));
+ struct pipe_blit_info info;
+ memset(&info, 0, sizeof(info));
- info.src.resource = src_imgv->image->bo;
- info.dst.resource = dst_imgv->image->bo;
- info.src.format = src_imgv->pformat;
- info.dst.format = dst_imgv->pformat;
- info.filter = PIPE_TEX_FILTER_NEAREST;
+ info.src.resource = src_imgv->image->bo;
+ info.dst.resource = dst_imgv->image->bo;
+ info.src.format = src_imgv->pformat;
+ info.dst.format = dst_imgv->pformat;
+ info.filter = PIPE_TEX_FILTER_NEAREST;
- if (num_blits == 1)
- info.mask = PIPE_MASK_ZS;
- else if (i == 0)
- info.mask = PIPE_MASK_Z;
- else
- info.mask = PIPE_MASK_S;
+ if (num_blits == 1)
+ info.mask = PIPE_MASK_ZS;
+ else if (i == 0)
+ info.mask = PIPE_MASK_Z;
+ else
+ info.mask = PIPE_MASK_S;
- if (i == 0 && subpass->depth_resolve_mode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT)
- info.sample0_only = true;
- if (i == 1 && subpass->stencil_resolve_mode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT)
- info.sample0_only = true;
+ if (i == 0 && subpass->depth_resolve_mode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT)
+ info.sample0_only = true;
+ if (i == 1 && subpass->stencil_resolve_mode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT)
+ info.sample0_only = true;
- info.src.box.x = state->render_area.offset.x;
- info.src.box.y = state->render_area.offset.y;
- info.src.box.width = state->render_area.extent.width;
- info.src.box.height = state->render_area.extent.height;
- info.src.box.depth = state->vk_framebuffer->layers;
+ info.src.box.x = state->render_area.offset.x;
+ info.src.box.y = state->render_area.offset.y;
+ info.src.box.width = state->render_area.extent.width;
+ info.src.box.height = state->render_area.extent.height;
+ info.src.box.depth = state->vk_framebuffer->layers;
- info.dst.box = info.src.box;
+ info.dst.box = info.src.box;
- state->pctx->blit(state->pctx, &info);
- }
+ state->pctx->blit(state->pctx, &info);
}
}
if (!subpass->has_color_resolve)
return;
for (uint32_t i = 0; i < subpass->color_count; i++) {
- struct lvp_subpass_attachment src_att = subpass->color_attachments[i];
- struct lvp_subpass_attachment dst_att = subpass->resolve_attachments[i];
+ struct lvp_render_pass_attachment *src_att = subpass->color_attachments[i];
+ struct lvp_render_pass_attachment *dst_att = subpass->resolve_attachments[i];
- if (dst_att.attachment == VK_ATTACHMENT_UNUSED)
+ if (!src_att || !dst_att)
continue;
- struct lvp_image_view *src_imgv = get_attachment(state, src_att.attachment);
- struct lvp_image_view *dst_imgv = get_attachment(state, dst_att.attachment);
+ struct lvp_image_view *src_imgv = get_attachment(state, src_att->attachment);
+ struct lvp_image_view *dst_imgv = get_attachment(state, dst_att->attachment);
struct pipe_blit_info info;
memset(&info, 0, sizeof(info));
const struct lvp_subpass *subpass = &state->pass->subpasses[subpass_idx];
for (unsigned i = 0; i < subpass->color_count; i++) {
- struct lvp_subpass_attachment *color_att = &subpass->color_attachments[i];
- if (color_att->attachment != VK_ATTACHMENT_UNUSED) {
+ struct lvp_render_pass_attachment *color_att = subpass->color_attachments[i];
+ if (color_att) {
struct lvp_image_view *imgv = get_attachment(state, color_att->attachment);
add_img_view_surface(state, imgv, state->pass->attachments[color_att->attachment].format, state->framebuffer.width, state->framebuffer.height);
state->framebuffer.cbufs[state->framebuffer.nr_cbufs] = imgv->surface;
}
if (subpass->depth_stencil_attachment) {
- struct lvp_subpass_attachment *ds_att = subpass->depth_stencil_attachment;
+ struct lvp_render_pass_attachment *ds_att = *subpass->depth_stencil_attachment;
- if (ds_att->attachment != VK_ATTACHMENT_UNUSED) {
+ if (ds_att) {
struct lvp_image_view *imgv = get_attachment(state, ds_att->attachment);
add_img_view_surface(state, imgv, state->pass->attachments[ds_att->attachment].format, state->framebuffer.width, state->framebuffer.height);
state->framebuffer.zsbuf = imgv->surface;
struct lvp_image_view *imgv;
if (att->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) {
- struct lvp_subpass_attachment *color_att = &subpass->color_attachments[att->colorAttachment];
- if (!color_att || color_att->attachment == VK_ATTACHMENT_UNUSED)
+ struct lvp_render_pass_attachment *color_att = subpass->color_attachments[att->colorAttachment];
+ if (!color_att)
continue;
imgv = get_attachment(state, color_att->attachment);
} else {
- struct lvp_subpass_attachment *ds_att = subpass->depth_stencil_attachment;
- if (!ds_att || ds_att->attachment == VK_ATTACHMENT_UNUSED)
+ struct lvp_render_pass_attachment *ds_att = *subpass->depth_stencil_attachment;
+ if (!ds_att)
continue;
imgv = get_attachment(state, ds_att->attachment);
}
#include "vk_util.h"
-static void
-lvp_render_pass_compile(struct lvp_render_pass *pass)
-{
- for (uint32_t i = 0; i < pass->subpass_count; i++) {
- struct lvp_subpass *subpass = &pass->subpasses[i];
-
- for (uint32_t j = 0; j < subpass->attachment_count; j++) {
- struct lvp_subpass_attachment *subpass_att =
- &subpass->attachments[j];
- if (subpass_att->attachment == VK_ATTACHMENT_UNUSED)
- continue;
-
- struct lvp_render_pass_attachment *pass_att =
- &pass->attachments[subpass_att->attachment];
-
- pass_att->first_subpass_idx = UINT32_MAX;
- }
- }
-
- for (uint32_t i = 0; i < pass->subpass_count; i++) {
- struct lvp_subpass *subpass = &pass->subpasses[i];
-
- /* We don't allow depth_stencil_attachment to be non-NULL and
- * be VK_ATTACHMENT_UNUSED. This way something can just check
- * for NULL and be guaranteed that they have a valid
- * attachment.
- */
- if (subpass->depth_stencil_attachment &&
- subpass->depth_stencil_attachment->attachment == VK_ATTACHMENT_UNUSED)
- subpass->depth_stencil_attachment = NULL;
-
- if (subpass->ds_resolve_attachment &&
- subpass->ds_resolve_attachment->attachment == VK_ATTACHMENT_UNUSED)
- subpass->ds_resolve_attachment = NULL;
-
- for (uint32_t j = 0; j < subpass->attachment_count; j++) {
- struct lvp_subpass_attachment *subpass_att =
- &subpass->attachments[j];
- if (subpass_att->attachment == VK_ATTACHMENT_UNUSED)
- continue;
-
- struct lvp_render_pass_attachment *pass_att =
- &pass->attachments[subpass_att->attachment];
-
- if (i < pass_att->first_subpass_idx)
- pass_att->first_subpass_idx = i;
- pass_att->last_subpass_idx = i;
- }
-
- subpass->has_color_att = false;
- for (uint32_t j = 0; j < subpass->color_count; j++) {
- struct lvp_subpass_attachment *subpass_att =
- &subpass->color_attachments[j];
- if (subpass_att->attachment == VK_ATTACHMENT_UNUSED)
- continue;
-
- subpass->has_color_att = true;
- }
-
- /* We have to handle resolve attachments specially */
- subpass->has_color_resolve = false;
- if (subpass->resolve_attachments) {
- for (uint32_t j = 0; j < subpass->color_count; j++) {
- struct lvp_subpass_attachment *resolve_att =
- &subpass->resolve_attachments[j];
-
- if (resolve_att->attachment == VK_ATTACHMENT_UNUSED)
- continue;
-
- subpass->has_color_resolve = true;
- }
- }
- }
-}
-
static unsigned
lvp_num_subpass_attachments2(const VkSubpassDescription2 *desc)
{
size_t attachments_offset;
size_t size;
+ uint32_t subpass_attachment_count = 0;
+ for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
+ subpass_attachment_count += lvp_num_subpass_attachments2(&pCreateInfo->pSubpasses[i]);
+ }
+
size = sizeof(*pass);
size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]);
attachments_offset = size;
size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]);
+ uint32_t subpass_attachment_offset = size;
+ size += subpass_attachment_count * sizeof(void*);
- pass = vk_alloc2(&device->vk.alloc, pAllocator, size, 8,
+ pass = vk_zalloc2(&device->vk.alloc, pAllocator, size, 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (pass == NULL)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
att->samples = pCreateInfo->pAttachments[i].samples;
att->load_op = pCreateInfo->pAttachments[i].loadOp;
att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
- att->first_subpass_idx = UINT32_MAX;
att->attachment = i;
bool is_zs = util_format_is_depth_or_stencil(lvp_vk_format_to_pipe_format(att->format));
pass->has_zs_attachment |= is_zs;
pass->has_color_attachment |= !is_zs;
}
- uint32_t subpass_attachment_count = 0;
- for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
- subpass_attachment_count += lvp_num_subpass_attachments2(&pCreateInfo->pSubpasses[i]);
- }
- if (subpass_attachment_count) {
- pass->subpass_attachments =
- vk_alloc2(&device->vk.alloc, pAllocator,
- subpass_attachment_count * sizeof(struct lvp_subpass_attachment), 8,
- VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
- if (pass->subpass_attachments == NULL) {
- vk_free2(&device->vk.alloc, pAllocator, pass);
- return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
- }
- } else
- pass->subpass_attachments = NULL;
+ uint32_t subpass_attachment_idx = 0;
+#define ATTACHMENT_OFFSET (struct lvp_render_pass_attachment**)(((uint8_t*)pass) + subpass_attachment_offset + (subpass_attachment_idx * sizeof(void*)))
+#define CHECK_UNUSED_ATTACHMENT(SRC, DST, IDX) do { \
+ if (desc->SRC[IDX].attachment == VK_ATTACHMENT_UNUSED) \
+ subpass->DST[IDX] = NULL; \
+ else \
+ subpass->DST[IDX] = &pass->attachments[desc->SRC[IDX].attachment]; \
+ } while (0)
- struct lvp_subpass_attachment *p = pass->subpass_attachments;
for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
const VkSubpassDescription2 *desc = &pCreateInfo->pSubpasses[i];
struct lvp_subpass *subpass = &pass->subpasses[i];
subpass->input_count = desc->inputAttachmentCount;
subpass->color_count = desc->colorAttachmentCount;
- subpass->attachment_count = lvp_num_subpass_attachments2(desc);
- subpass->attachments = p;
subpass->view_mask = desc->viewMask;
+ subpass->has_color_resolve = false;
if (desc->inputAttachmentCount > 0) {
- subpass->input_attachments = p;
- p += desc->inputAttachmentCount;
+ subpass->input_attachments = ATTACHMENT_OFFSET;
+ subpass_attachment_idx += desc->inputAttachmentCount;
for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
- subpass->input_attachments[j] = (struct lvp_subpass_attachment) {
- .attachment = desc->pInputAttachments[j].attachment,
- };
+ CHECK_UNUSED_ATTACHMENT(pInputAttachments, input_attachments, j);
}
}
if (desc->colorAttachmentCount > 0) {
- subpass->color_attachments = p;
- p += desc->colorAttachmentCount;
+ subpass->color_attachments = ATTACHMENT_OFFSET;
+ subpass_attachment_idx += desc->colorAttachmentCount;
for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
- subpass->color_attachments[j] = (struct lvp_subpass_attachment) {
- .attachment = desc->pColorAttachments[j].attachment,
- };
+ CHECK_UNUSED_ATTACHMENT(pColorAttachments, color_attachments, j);
+ if (subpass->color_attachments[j])
+ subpass->has_color_att = true;
}
}
if (desc->pResolveAttachments) {
- subpass->resolve_attachments = p;
- p += desc->colorAttachmentCount;
+ subpass->resolve_attachments = ATTACHMENT_OFFSET;
+ subpass_attachment_idx += desc->colorAttachmentCount;
for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
- subpass->resolve_attachments[j] = (struct lvp_subpass_attachment) {
- .attachment = desc->pResolveAttachments[j].attachment,
- };
+ CHECK_UNUSED_ATTACHMENT(pResolveAttachments, resolve_attachments, j);
+ if (subpass->resolve_attachments[j])
+ subpass->has_color_resolve = true;
}
}
if (desc->pDepthStencilAttachment) {
- subpass->depth_stencil_attachment = p++;
+ subpass->depth_stencil_attachment = ATTACHMENT_OFFSET;
+ subpass_attachment_idx++;
- *subpass->depth_stencil_attachment = (struct lvp_subpass_attachment) {
- .attachment = desc->pDepthStencilAttachment->attachment,
- };
+ CHECK_UNUSED_ATTACHMENT(pDepthStencilAttachment, depth_stencil_attachment, 0);
}
const VkSubpassDescriptionDepthStencilResolve *ds_resolve =
vk_find_struct_const(desc->pNext, SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE);
if (ds_resolve && ds_resolve->pDepthStencilResolveAttachment) {
- subpass->ds_resolve_attachment = p++;
+ subpass->ds_resolve_attachment = ATTACHMENT_OFFSET;
+ subpass_attachment_idx++;
- *subpass->ds_resolve_attachment = (struct lvp_subpass_attachment){
- .attachment = ds_resolve->pDepthStencilResolveAttachment->attachment,
- };
+ if (ds_resolve->pDepthStencilResolveAttachment->attachment == VK_ATTACHMENT_UNUSED)
+ *subpass->ds_resolve_attachment = NULL;
+ else
+ *subpass->ds_resolve_attachment = &pass->attachments[ds_resolve->pDepthStencilResolveAttachment->attachment];
subpass->depth_resolve_mode = ds_resolve->depthResolveMode;
subpass->stencil_resolve_mode = ds_resolve->stencilResolveMode;
}
}
-
- lvp_render_pass_compile(pass);
+#undef ATTACHMENT_OFFSET
*pRenderPass = lvp_render_pass_to_handle(pass);
return VK_SUCCESS;
struct pipe_surface *surface; /* have we created a pipe surface for this? */
};
-struct lvp_subpass_attachment {
- uint32_t attachment;
+struct lvp_render_pass_attachment {
+ uint32_t attachment; //index
+ VkFormat format;
+ uint32_t samples;
+ VkAttachmentLoadOp load_op;
+ VkAttachmentLoadOp stencil_load_op;
};
struct lvp_subpass {
- uint32_t attachment_count;
- struct lvp_subpass_attachment * attachments;
-
uint32_t input_count;
uint32_t color_count;
- struct lvp_subpass_attachment * input_attachments;
- struct lvp_subpass_attachment * color_attachments;
- struct lvp_subpass_attachment * resolve_attachments;
- struct lvp_subpass_attachment * depth_stencil_attachment;
- struct lvp_subpass_attachment * ds_resolve_attachment;
+ struct lvp_render_pass_attachment ** input_attachments;
+ struct lvp_render_pass_attachment ** color_attachments;
+ struct lvp_render_pass_attachment ** resolve_attachments;
+ struct lvp_render_pass_attachment ** depth_stencil_attachment;
+ struct lvp_render_pass_attachment ** ds_resolve_attachment;
VkResolveModeFlagBits depth_resolve_mode;
VkResolveModeFlagBits stencil_resolve_mode;
uint32_t view_mask;
};
-struct lvp_render_pass_attachment {
- uint32_t attachment; //index
- VkFormat format;
- uint32_t samples;
- VkAttachmentLoadOp load_op;
- VkAttachmentLoadOp stencil_load_op;
-
- /* The subpass id in which the attachment will be used first/last. */
- uint32_t first_subpass_idx;
- uint32_t last_subpass_idx;
-};
-
struct lvp_render_pass {
struct vk_object_base base;
uint32_t attachment_count;