mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-07 04:20:18 +01:00
panvk/v10+: Implement nullDescriptor support
Adds support for nullDescriptors in PanVK by memsetting the relevant descriptors to zero. This is valid for v9+. Note that vertex/index buffers require special handling in order to rely on out-of-bounds behavior. For index buffers specifically, the approach is only valid for v10+, as v9 does not have a way to specify index buffer size. Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35609>
This commit is contained in:
parent
bbe3c7e1a3
commit
a789867cb4
3 changed files with 109 additions and 46 deletions
|
|
@ -311,7 +311,9 @@ prepare_vs_driver_set(struct panvk_cmd_buffer *cmdbuf,
|
|||
emit_vs_attrib(cmdbuf, i, vb_offset,
|
||||
(struct mali_attribute_packed *)(&descs[i]));
|
||||
} else {
|
||||
memset(&descs[i], 0, sizeof(descs[0]));
|
||||
/* Write a NullDescriptor and rely on OOB behavior */
|
||||
pan_cast_and_pack(&descs[i], NULL_DESCRIPTOR, cfg)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -326,15 +328,17 @@ prepare_vs_driver_set(struct panvk_cmd_buffer *cmdbuf,
|
|||
|
||||
for (uint32_t i = 0; i < vb_count; i++) {
|
||||
const struct panvk_attrib_buf *vb = &cmdbuf->state.gfx.vb.bufs[i];
|
||||
const bool nulldesc = (vb->address == 0 && vb->size == 0);
|
||||
|
||||
pan_cast_and_pack(&descs[vb_offset + i], BUFFER, cfg) {
|
||||
if (vi->bindings_valid & BITFIELD_BIT(i)) {
|
||||
if ((vi->bindings_valid & BITFIELD_BIT(i)) && !nulldesc) {
|
||||
pan_cast_and_pack(&descs[vb_offset + i], BUFFER, cfg) {
|
||||
cfg.address = vb->address;
|
||||
cfg.size = vb->size;
|
||||
} else {
|
||||
cfg.address = 0;
|
||||
cfg.size = 0;
|
||||
}
|
||||
} else {
|
||||
/* Write a NullDescriptor and rely on OOB behavior */
|
||||
pan_cast_and_pack(&descs[vb_offset + i], NULL_DESCRIPTOR, cfg)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2634,7 +2638,7 @@ panvk_per_arch(CmdDrawIndexedIndirect)(VkCommandBuffer commandBuffer,
|
|||
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
|
||||
VK_FROM_HANDLE(panvk_buffer, buffer, _buffer);
|
||||
|
||||
if (drawCount == 0 || cmdbuf->state.gfx.ib.size == 0)
|
||||
if (drawCount == 0)
|
||||
return;
|
||||
|
||||
struct panvk_draw_info draw = {
|
||||
|
|
@ -2687,7 +2691,7 @@ panvk_per_arch(CmdDrawIndexedIndirectCount)(VkCommandBuffer commandBuffer,
|
|||
VK_FROM_HANDLE(panvk_buffer, buffer, _buffer);
|
||||
VK_FROM_HANDLE(panvk_buffer, count_buffer, countBuffer);
|
||||
|
||||
if (maxDrawCount == 0 || cmdbuf->state.gfx.ib.size == 0)
|
||||
if (maxDrawCount == 0)
|
||||
return;
|
||||
|
||||
struct panvk_draw_info draw = {
|
||||
|
|
|
|||
|
|
@ -872,10 +872,15 @@ panvk_per_arch(CmdBindVertexBuffers2)(VkCommandBuffer commandBuffer,
|
|||
for (uint32_t i = 0; i < bindingCount; i++) {
|
||||
VK_FROM_HANDLE(panvk_buffer, buffer, pBuffers[i]);
|
||||
|
||||
cmdbuf->state.gfx.vb.bufs[firstBinding + i].address =
|
||||
panvk_buffer_gpu_ptr(buffer, pOffsets[i]);
|
||||
cmdbuf->state.gfx.vb.bufs[firstBinding + i].size = panvk_buffer_range(
|
||||
buffer, pOffsets[i], pSizes ? pSizes[i] : VK_WHOLE_SIZE);
|
||||
if (buffer) {
|
||||
cmdbuf->state.gfx.vb.bufs[firstBinding + i].address =
|
||||
panvk_buffer_gpu_ptr(buffer, pOffsets[i]);
|
||||
cmdbuf->state.gfx.vb.bufs[firstBinding + i].size = panvk_buffer_range(
|
||||
buffer, pOffsets[i], pSizes ? pSizes[i] : VK_WHOLE_SIZE);
|
||||
} else {
|
||||
cmdbuf->state.gfx.vb.bufs[firstBinding + i].address = 0;
|
||||
cmdbuf->state.gfx.vb.bufs[firstBinding + i].size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
cmdbuf->state.gfx.vb.count =
|
||||
|
|
@ -899,15 +904,18 @@ panvk_per_arch(CmdBindIndexBuffer2)(VkCommandBuffer commandBuffer,
|
|||
cmdbuf->state.gfx.ib.host_addr =
|
||||
buf && buf->host_ptr ? buf->host_ptr + offset : NULL;
|
||||
#endif
|
||||
cmdbuf->state.gfx.ib.index_size = vk_index_type_to_bytes(indexType);
|
||||
} else {
|
||||
cmdbuf->state.gfx.ib.size = 0;
|
||||
cmdbuf->state.gfx.ib.dev_addr = 0;
|
||||
/* In case of NullDescriptors, we need to set a non-NULL address and rely
|
||||
* on out-of-bounds behavior against the zero size of the buffer. Note
|
||||
* that this only works for v10+, as v9 does not have a way to specify the
|
||||
* index buffer size. */
|
||||
cmdbuf->state.gfx.ib.dev_addr = PAN_ARCH >= 10 ? 0x1000 : 0;
|
||||
#if PAN_ARCH < 9
|
||||
cmdbuf->state.gfx.ib.host_addr = 0;
|
||||
#endif
|
||||
cmdbuf->state.gfx.ib.index_size = 0;
|
||||
}
|
||||
cmdbuf->state.gfx.ib.index_size = vk_index_type_to_bytes(indexType);
|
||||
|
||||
gfx_state_set_dirty(cmdbuf, IB);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,20 @@ get_desc_slot_ptr(struct panvk_descriptor_set *set, uint32_t binding,
|
|||
memcpy(__dst, (desc), PANVK_DESCRIPTOR_SIZE); \
|
||||
} while (0)
|
||||
|
||||
#if PAN_ARCH >= 9
|
||||
#define write_nulldesc(set, binding, elem, subdesc) \
|
||||
do { \
|
||||
struct mali_null_descriptor_packed null_desc; \
|
||||
pan_pack(&null_desc, NULL_DESCRIPTOR, cfg) \
|
||||
; \
|
||||
write_desc(set, binding, elem, &null_desc, (subdesc)); \
|
||||
} while (0)
|
||||
#else
|
||||
#define write_nulldesc(set, binding, elem, subdesc) \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
static void
|
||||
write_sampler_desc(struct panvk_descriptor_set *set,
|
||||
const VkDescriptorImageInfo *const pImageInfo,
|
||||
|
|
@ -63,20 +77,25 @@ write_sampler_desc(struct panvk_descriptor_set *set,
|
|||
const struct panvk_descriptor_set_binding_layout *binding_layout =
|
||||
&set->layout->bindings[binding];
|
||||
|
||||
if (binding_layout->immutable_samplers && !write_immutable)
|
||||
return;
|
||||
|
||||
struct panvk_sampler *sampler;
|
||||
|
||||
if (binding_layout->immutable_samplers) {
|
||||
if (!write_immutable)
|
||||
return;
|
||||
sampler = binding_layout->immutable_samplers[elem];
|
||||
} else {
|
||||
sampler = panvk_sampler_from_handle(
|
||||
pImageInfo ? pImageInfo->sampler : VK_NULL_HANDLE);
|
||||
if (!pImageInfo)
|
||||
return;
|
||||
sampler = panvk_sampler_from_handle(pImageInfo->sampler);
|
||||
}
|
||||
|
||||
if (!sampler)
|
||||
if (!sampler) {
|
||||
for (uint8_t plane = 0; plane < binding_layout->samplers_per_desc;
|
||||
plane++)
|
||||
write_nulldesc(set, binding, elem,
|
||||
get_sampler_subdesc_info(binding_layout->type, plane));
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint8_t plane = 0; plane < sampler->desc_count; plane++) {
|
||||
write_desc(set, binding, elem, &sampler->descs[plane],
|
||||
|
|
@ -89,26 +108,38 @@ write_image_view_desc(struct panvk_descriptor_set *set,
|
|||
const VkDescriptorImageInfo *const pImageInfo,
|
||||
uint32_t binding, uint32_t elem, VkDescriptorType type)
|
||||
{
|
||||
if (pImageInfo && pImageInfo->imageView != VK_NULL_HANDLE) {
|
||||
VK_FROM_HANDLE(panvk_image_view, view, pImageInfo->imageView);
|
||||
if (!pImageInfo)
|
||||
return;
|
||||
|
||||
uint8_t plane_count = vk_format_get_plane_count(view->vk.format);
|
||||
for (uint8_t plane = 0; plane < plane_count; plane++) {
|
||||
struct panvk_subdesc_info subdesc = get_tex_subdesc_info(type, plane);
|
||||
const struct panvk_descriptor_set_binding_layout *binding_layout =
|
||||
&set->layout->bindings[binding];
|
||||
|
||||
if (pImageInfo->imageView == VK_NULL_HANDLE) {
|
||||
for (uint8_t plane = 0; plane < binding_layout->textures_per_desc;
|
||||
plane++)
|
||||
write_nulldesc(set, binding, elem,
|
||||
get_sampler_subdesc_info(binding_layout->type, plane));
|
||||
return;
|
||||
}
|
||||
|
||||
VK_FROM_HANDLE(panvk_image_view, view, pImageInfo->imageView);
|
||||
|
||||
uint8_t plane_count = vk_format_get_plane_count(view->vk.format);
|
||||
for (uint8_t plane = 0; plane < plane_count; plane++) {
|
||||
struct panvk_subdesc_info subdesc = get_tex_subdesc_info(type, plane);
|
||||
#if PAN_ARCH >= 9
|
||||
if (type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
|
||||
write_desc(set, binding, elem, &view->descs.storage_tex[plane],
|
||||
subdesc);
|
||||
else
|
||||
write_desc(set, binding, elem, &view->descs.tex[plane], subdesc);
|
||||
if (type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
|
||||
write_desc(set, binding, elem, &view->descs.storage_tex[plane],
|
||||
subdesc);
|
||||
else
|
||||
write_desc(set, binding, elem, &view->descs.tex[plane], subdesc);
|
||||
#else
|
||||
if (type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
|
||||
write_desc(set, binding, elem, &view->descs.img_attrib_buf,
|
||||
NO_SUBDESC);
|
||||
else
|
||||
write_desc(set, binding, elem, &view->descs.tex[plane], subdesc);
|
||||
if (type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
|
||||
write_desc(set, binding, elem, &view->descs.img_attrib_buf,
|
||||
NO_SUBDESC);
|
||||
else
|
||||
write_desc(set, binding, elem, &view->descs.tex[plane], subdesc);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -117,6 +148,11 @@ write_buffer_desc(struct panvk_descriptor_set *set,
|
|||
const VkDescriptorBufferInfo *const info, uint32_t binding,
|
||||
uint32_t elem, VkDescriptorType type)
|
||||
{
|
||||
if (info->buffer == VK_NULL_HANDLE) {
|
||||
write_nulldesc(set, binding, elem, NO_SUBDESC);
|
||||
return;
|
||||
}
|
||||
|
||||
VK_FROM_HANDLE(panvk_buffer, buffer, info->buffer);
|
||||
const uint64_t range = panvk_buffer_range(buffer, info->offset, info->range);
|
||||
assert(range <= UINT32_MAX);
|
||||
|
|
@ -158,6 +194,11 @@ write_dynamic_buffer_desc(struct panvk_descriptor_set *set,
|
|||
const VkDescriptorBufferInfo *const info,
|
||||
uint32_t binding, uint32_t elem)
|
||||
{
|
||||
if (info->buffer == VK_NULL_HANDLE) {
|
||||
write_nulldesc(set, binding, elem, NO_SUBDESC);
|
||||
return;
|
||||
}
|
||||
|
||||
VK_FROM_HANDLE(panvk_buffer, buffer, info->buffer);
|
||||
const struct panvk_descriptor_set_binding_layout *binding_layout =
|
||||
&set->layout->bindings[binding];
|
||||
|
|
@ -177,19 +218,21 @@ write_buffer_view_desc(struct panvk_descriptor_set *set,
|
|||
const VkBufferView bufferView, uint32_t binding,
|
||||
uint32_t elem, VkDescriptorType type)
|
||||
{
|
||||
if (bufferView != VK_NULL_HANDLE) {
|
||||
VK_FROM_HANDLE(panvk_buffer_view, view, bufferView);
|
||||
if (bufferView == VK_NULL_HANDLE) {
|
||||
write_nulldesc(set, binding, elem, NO_SUBDESC);
|
||||
return;
|
||||
}
|
||||
|
||||
VK_FROM_HANDLE(panvk_buffer_view, view, bufferView);
|
||||
|
||||
#if PAN_ARCH < 9
|
||||
if (type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
|
||||
write_desc(set, binding, elem, &view->descs.img_attrib_buf,
|
||||
NO_SUBDESC);
|
||||
else
|
||||
write_desc(set, binding, elem, &view->descs.tex, NO_SUBDESC);
|
||||
#else
|
||||
if (type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
|
||||
write_desc(set, binding, elem, &view->descs.img_attrib_buf, NO_SUBDESC);
|
||||
else
|
||||
write_desc(set, binding, elem, &view->descs.tex, NO_SUBDESC);
|
||||
#else
|
||||
write_desc(set, binding, elem, &view->descs.tex, NO_SUBDESC);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -340,6 +383,14 @@ desc_set_write_immutable_samplers(struct panvk_descriptor_set *set,
|
|||
for (uint32_t j = 0; j < array_size; j++) {
|
||||
struct panvk_sampler *sampler =
|
||||
layout->bindings[b].immutable_samplers[j];
|
||||
if (!sampler) {
|
||||
for (uint8_t plane = 0;
|
||||
plane < layout->bindings[b].samplers_per_desc; plane++)
|
||||
write_nulldesc(
|
||||
set, b, j,
|
||||
get_sampler_subdesc_info(layout->bindings[b].type, plane));
|
||||
continue;
|
||||
}
|
||||
for (uint8_t plane = 0; plane < sampler->desc_count; plane++) {
|
||||
write_desc(set, b, j,
|
||||
&sampler->descs[plane],
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue