pvr: implement dynamically set vertex buffer strides

Co-Authored-by: Frank Binns <frank.binns@imgtec.com>
Signed-off-by: Frank Binns <frank.binns@imgtec.com>
Signed-off-by: Vlad Schiller <vlad-radu.schiller@imgtec.com>
Acked-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36412>
This commit is contained in:
Vlad Schiller
2023-11-23 11:28:59 +00:00
committed by Marge Bot
parent 58e4408b33
commit 1d46696887
4 changed files with 62 additions and 20 deletions
+8
View File
@@ -25,6 +25,7 @@
#define PVR_PDS_H
#include <stdbool.h>
#include <stdint.h>
#include "pvr_device_info.h"
#include "pvr_limits.h"
@@ -1021,6 +1022,7 @@ struct pvr_pds_vertex_primary_program_input {
#define PVR_PDS_CONST_MAP_ENTRY_TYPE_BASE_VERTEX (13)
#define PVR_PDS_CONST_MAP_ENTRY_TYPE_BASE_WORKGROUP (14)
#define PVR_PDS_CONST_MAP_ENTRY_TYPE_COND_RENDER (15)
#define PVR_PDS_CONST_MAP_ENTRY_TYPE_VERTEX_ATTRIBUTE_STRIDE (16)
/* We pack all the following structs tightly into a buffer using += sizeof(x)
* offsets, this can lead to data that is not native aligned. Supplying the
@@ -1106,6 +1108,12 @@ struct pvr_const_map_entry_vertex_attribute_address {
uint8_t size_in_dwords;
} PVR_PACKED;
struct pvr_const_map_entry_vertex_attribute_stride {
uint8_t type;
uint8_t const_offset;
uint8_t binding_index;
} PVR_PACKED;
struct pvr_const_map_entry_robust_vertex_attribute_address {
uint8_t type;
uint8_t const_offset;
@@ -741,6 +741,7 @@ void pvr_pds_generate_vertex_primary_program(
}
for (uint32_t dma = 0; dma < input_program->dma_count; dma++) {
struct pvr_const_map_entry_vertex_attribute_stride *stride_entry;
uint32_t const_base = dma * PVR_PDS_DDMAD_NUM_CONSTS;
uint32_t control_word;
struct pvr_const_map_entry_literal32 *literal_entry;
@@ -1011,12 +1012,12 @@ void pvr_pds_generate_vertex_primary_program(
use_robust_vertex_fetch);
/* DDMAD Const Usage [__XXX---] */
literal_entry =
stride_entry =
pvr_prepare_next_pds_const_map_entry(&entry_write_state,
sizeof(*literal_entry));
literal_entry->type = PVR_PDS_CONST_MAP_ENTRY_TYPE_LITERAL32;
literal_entry->const_offset = const_base + 3;
literal_entry->literal_value = vertex_dma->stride;
sizeof(*stride_entry));
stride_entry->type = PVR_PDS_CONST_MAP_ENTRY_TYPE_VERTEX_ATTRIBUTE_STRIDE;
stride_entry->const_offset = const_base + 3;
stride_entry->binding_index = vertex_dma->binding_index;
control_word = vertex_dma->size_in_dwords
<< PVR_ROGUE_PDSINST_DDMAD_FIELDS_SRC3_BSIZE_SHIFT;
+47 -15
View File
@@ -2735,27 +2735,38 @@ void pvr_CmdBindDescriptorSets2KHR(
cmd_buffer->state.dirty.compute_desc_dirty = true;
}
void pvr_CmdBindVertexBuffers(VkCommandBuffer commandBuffer,
uint32_t firstBinding,
uint32_t bindingCount,
const VkBuffer *pBuffers,
const VkDeviceSize *pOffsets)
void pvr_CmdBindVertexBuffers2(VkCommandBuffer commandBuffer,
uint32_t firstBinding,
uint32_t bindingCount,
const VkBuffer *pBuffers,
const VkDeviceSize *pOffsets,
const VkDeviceSize *pSizes,
const VkDeviceSize *pStrides)
{
PVR_FROM_HANDLE(pvr_cmd_buffer, cmd_buffer, commandBuffer);
struct pvr_vertex_binding *const vb = cmd_buffer->state.vertex_bindings;
/* We have to defer setting up vertex buffer since we need the buffer
* stride from the pipeline.
*/
assert(firstBinding < PVR_MAX_VERTEX_INPUT_BINDINGS &&
bindingCount <= PVR_MAX_VERTEX_INPUT_BINDINGS);
PVR_CHECK_COMMAND_BUFFER_BUILDING_STATE(cmd_buffer);
for (uint32_t i = 0; i < bindingCount; i++) {
vb[firstBinding + i].buffer = pvr_buffer_from_handle(pBuffers[i]);
vb[firstBinding + i].offset = pOffsets[i];
VK_FROM_HANDLE(pvr_buffer, buffer, pBuffers[i]);
const uint64_t size = pSizes ? pSizes[i] : VK_WHOLE_SIZE;
vb[firstBinding + i] = (struct pvr_vertex_binding){
.buffer = buffer,
.offset = pOffsets[i],
.size = vk_buffer_range(&buffer->vk, pOffsets[i], size),
};
}
if (pStrides != NULL) {
vk_cmd_set_vertex_binding_strides(&cmd_buffer->vk,
firstBinding,
bindingCount,
pStrides);
}
cmd_buffer->state.dirty.vertex_bindings = true;
@@ -3535,7 +3546,7 @@ pvr_setup_vertex_buffers(struct pvr_cmd_buffer *cmd_buffer,
&state->vertex_bindings[attribute->binding_index];
pvr_dev_addr_t addr;
if (binding->buffer->vk.size <
if (binding->size <
(attribute->offset + attribute->component_size_in_bytes)) {
/* Replace with load from robustness buffer when no attribute is in
* range
@@ -3608,18 +3619,22 @@ pvr_setup_vertex_buffers(struct pvr_cmd_buffer *cmd_buffer,
const uint64_t bound_size = binding->buffer->vk.size - binding->offset;
const uint32_t attribute_end =
attribute->offset + attribute->component_size_in_bytes;
const struct vk_dynamic_graphics_state *dynamic_state =
&cmd_buffer->vk.dynamic_graphics_state;
const uint32_t stride =
dynamic_state->vi_binding_strides[attribute->binding_index];
uint32_t max_index;
/* If the stride is 0 then all attributes use the same single
* element from the binding so the index can only be up to 0.
*/
if (bound_size < attribute_end || attribute->stride == 0) {
if (bound_size < attribute_end || stride == 0) {
max_index = 0;
} else {
max_index = (uint32_t)(bound_size / attribute->stride) - 1;
max_index = (uint32_t)(bound_size / stride) - 1;
/* There's one last attribute that can fit in. */
if (bound_size % attribute->stride >= attribute_end)
if (bound_size % stride >= attribute_end)
max_index++;
}
@@ -3632,6 +3647,23 @@ pvr_setup_vertex_buffers(struct pvr_cmd_buffer *cmd_buffer,
break;
}
case PVR_PDS_CONST_MAP_ENTRY_TYPE_VERTEX_ATTRIBUTE_STRIDE: {
const struct pvr_const_map_entry_vertex_attribute_stride *attribute =
(const struct pvr_const_map_entry_vertex_attribute_stride *)entries;
const struct vk_dynamic_graphics_state *dynamic_state =
&cmd_buffer->vk.dynamic_graphics_state;
const uint32_t stride =
dynamic_state->vi_binding_strides[attribute->binding_index];
PVR_WRITE(dword_buffer,
stride,
attribute->const_offset,
pds_info->data_size_in_dwords);
entries += sizeof(*attribute);
break;
}
default:
UNREACHABLE("Unsupported data section map");
break;
+1
View File
@@ -142,6 +142,7 @@ struct pvr_queue {
struct pvr_vertex_binding {
struct pvr_buffer *buffer;
VkDeviceSize offset;
VkDeviceSize size;
};
struct pvr_pds_upload {