lavapipe: add transform feedback support
This adds support for EXT_transform_feedback which can be used by zink to enable more CI Reviewed-by: Roland Scheidegger <sroland@vmware.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7981>
This commit is contained in:
parent
29955cbbc0
commit
448e60314a
|
@ -1642,3 +1642,125 @@ void lvp_CmdPushDescriptorSetWithTemplateKHR(
|
|||
}
|
||||
cmd_buf_queue(cmd_buffer, cmd);
|
||||
}
|
||||
|
||||
void lvp_CmdBindTransformFeedbackBuffersEXT(
|
||||
VkCommandBuffer commandBuffer,
|
||||
uint32_t firstBinding,
|
||||
uint32_t bindingCount,
|
||||
const VkBuffer* pBuffers,
|
||||
const VkDeviceSize* pOffsets,
|
||||
const VkDeviceSize* pSizes)
|
||||
{
|
||||
LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer);
|
||||
struct lvp_cmd_buffer_entry *cmd;
|
||||
uint32_t cmd_size = 0;
|
||||
|
||||
cmd_size += bindingCount * (sizeof(struct lvp_buffer *) + sizeof(VkDeviceSize) * 2);
|
||||
|
||||
cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, LVP_CMD_BIND_TRANSFORM_FEEDBACK_BUFFERS);
|
||||
if (!cmd)
|
||||
return;
|
||||
|
||||
cmd->u.bind_transform_feedback_buffers.first_binding = firstBinding;
|
||||
cmd->u.bind_transform_feedback_buffers.binding_count = bindingCount;
|
||||
cmd->u.bind_transform_feedback_buffers.buffers = (struct lvp_buffer **)(cmd + 1);
|
||||
cmd->u.bind_transform_feedback_buffers.offsets = (VkDeviceSize *)(cmd->u.bind_transform_feedback_buffers.buffers + bindingCount);
|
||||
cmd->u.bind_transform_feedback_buffers.sizes = (VkDeviceSize *)(cmd->u.bind_transform_feedback_buffers.offsets + bindingCount);
|
||||
|
||||
for (unsigned i = 0; i < bindingCount; i++) {
|
||||
cmd->u.bind_transform_feedback_buffers.buffers[i] = lvp_buffer_from_handle(pBuffers[i]);
|
||||
cmd->u.bind_transform_feedback_buffers.offsets[i] = pOffsets[i];
|
||||
cmd->u.bind_transform_feedback_buffers.sizes[i] = pSizes[i];
|
||||
}
|
||||
cmd_buf_queue(cmd_buffer, cmd);
|
||||
}
|
||||
|
||||
void lvp_CmdBeginTransformFeedbackEXT(
|
||||
VkCommandBuffer commandBuffer,
|
||||
uint32_t firstCounterBuffer,
|
||||
uint32_t counterBufferCount,
|
||||
const VkBuffer* pCounterBuffers,
|
||||
const VkDeviceSize* pCounterBufferOffsets)
|
||||
{
|
||||
LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer);
|
||||
struct lvp_cmd_buffer_entry *cmd;
|
||||
uint32_t cmd_size = 0;
|
||||
|
||||
cmd_size += counterBufferCount * (sizeof(struct lvp_buffer *) + sizeof(VkDeviceSize));
|
||||
|
||||
cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, LVP_CMD_BEGIN_TRANSFORM_FEEDBACK);
|
||||
if (!cmd)
|
||||
return;
|
||||
|
||||
cmd->u.begin_transform_feedback.first_counter_buffer = firstCounterBuffer;
|
||||
cmd->u.begin_transform_feedback.counter_buffer_count = counterBufferCount;
|
||||
cmd->u.begin_transform_feedback.counter_buffers = (struct lvp_buffer **)(cmd + 1);
|
||||
cmd->u.begin_transform_feedback.counter_buffer_offsets = (VkDeviceSize *)(cmd->u.begin_transform_feedback.counter_buffers + counterBufferCount);
|
||||
|
||||
for (unsigned i = 0; i < counterBufferCount; i++) {
|
||||
cmd->u.begin_transform_feedback.counter_buffers[i] = lvp_buffer_from_handle(pCounterBuffers[i]);
|
||||
if (pCounterBufferOffsets)
|
||||
cmd->u.begin_transform_feedback.counter_buffer_offsets[i] = pCounterBufferOffsets[i];
|
||||
else
|
||||
cmd->u.begin_transform_feedback.counter_buffer_offsets[i] = 0;
|
||||
}
|
||||
cmd_buf_queue(cmd_buffer, cmd);
|
||||
}
|
||||
|
||||
void lvp_CmdEndTransformFeedbackEXT(
|
||||
VkCommandBuffer commandBuffer,
|
||||
uint32_t firstCounterBuffer,
|
||||
uint32_t counterBufferCount,
|
||||
const VkBuffer* pCounterBuffers,
|
||||
const VkDeviceSize* pCounterBufferOffsets)
|
||||
{
|
||||
LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer);
|
||||
struct lvp_cmd_buffer_entry *cmd;
|
||||
uint32_t cmd_size = 0;
|
||||
|
||||
cmd_size += counterBufferCount * (sizeof(struct lvp_buffer *) + sizeof(VkDeviceSize));
|
||||
|
||||
cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, LVP_CMD_END_TRANSFORM_FEEDBACK);
|
||||
if (!cmd)
|
||||
return;
|
||||
|
||||
cmd->u.begin_transform_feedback.first_counter_buffer = firstCounterBuffer;
|
||||
cmd->u.begin_transform_feedback.counter_buffer_count = counterBufferCount;
|
||||
cmd->u.begin_transform_feedback.counter_buffers = (struct lvp_buffer **)(cmd + 1);
|
||||
cmd->u.begin_transform_feedback.counter_buffer_offsets = (VkDeviceSize *)(cmd->u.begin_transform_feedback.counter_buffers + counterBufferCount);
|
||||
|
||||
for (unsigned i = 0; i < counterBufferCount; i++) {
|
||||
cmd->u.begin_transform_feedback.counter_buffers[i] = lvp_buffer_from_handle(pCounterBuffers[i]);
|
||||
if (pCounterBufferOffsets)
|
||||
cmd->u.begin_transform_feedback.counter_buffer_offsets[i] = pCounterBufferOffsets[i];
|
||||
else
|
||||
cmd->u.begin_transform_feedback.counter_buffer_offsets[i] = 0;
|
||||
}
|
||||
cmd_buf_queue(cmd_buffer, cmd);
|
||||
}
|
||||
|
||||
void lvp_CmdDrawIndirectByteCountEXT(
|
||||
VkCommandBuffer commandBuffer,
|
||||
uint32_t instanceCount,
|
||||
uint32_t firstInstance,
|
||||
VkBuffer counterBuffer,
|
||||
VkDeviceSize counterBufferOffset,
|
||||
uint32_t counterOffset,
|
||||
uint32_t vertexStride)
|
||||
{
|
||||
LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer);
|
||||
struct lvp_cmd_buffer_entry *cmd;
|
||||
|
||||
cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_DRAW_INDIRECT_BYTE_COUNT);
|
||||
if (!cmd)
|
||||
return;
|
||||
|
||||
cmd->u.draw_indirect_byte_count.instance_count = instanceCount;
|
||||
cmd->u.draw_indirect_byte_count.first_instance = firstInstance;
|
||||
cmd->u.draw_indirect_byte_count.counter_buffer = lvp_buffer_from_handle(counterBuffer);
|
||||
cmd->u.draw_indirect_byte_count.counter_buffer_offset = counterBufferOffset;
|
||||
cmd->u.draw_indirect_byte_count.counter_offset = counterOffset;
|
||||
cmd->u.draw_indirect_byte_count.vertex_stride = vertexStride;
|
||||
|
||||
cmd_buf_queue(cmd_buffer, cmd);
|
||||
}
|
||||
|
|
|
@ -392,7 +392,14 @@ void lvp_GetPhysicalDeviceFeatures2(
|
|||
features->indexTypeUint8 = true;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT: {
|
||||
VkPhysicalDeviceTransformFeedbackFeaturesEXT *features =
|
||||
(VkPhysicalDeviceTransformFeedbackFeaturesEXT*)ext;
|
||||
|
||||
features->transformFeedback = true;
|
||||
features->geometryStreams = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -606,6 +613,20 @@ void lvp_GetPhysicalDeviceProperties2(
|
|||
props->maxVertexAttribDivisor = 1;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT: {
|
||||
VkPhysicalDeviceTransformFeedbackPropertiesEXT *properties =
|
||||
(VkPhysicalDeviceTransformFeedbackPropertiesEXT*)ext;
|
||||
properties->maxTransformFeedbackStreams = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_VERTEX_STREAMS);
|
||||
properties->maxTransformFeedbackBuffers = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS);
|
||||
properties->maxTransformFeedbackBufferSize = UINT32_MAX;
|
||||
properties->maxTransformFeedbackStreamDataSize = 512;
|
||||
properties->maxTransformFeedbackBufferDataSize = 512;
|
||||
properties->maxTransformFeedbackBufferDataStride = 512;
|
||||
properties->transformFeedbackQueries = true;
|
||||
properties->transformFeedbackStreamsLinesTriangles = false;
|
||||
properties->transformFeedbackRasterizationStreamSelect = false;
|
||||
properties->transformFeedbackDraw = true;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -125,6 +125,10 @@ struct rendering_state {
|
|||
const struct lvp_attachment_state *attachments;
|
||||
VkImageAspectFlags *pending_clear_aspects;
|
||||
int num_pending_aspects;
|
||||
|
||||
uint32_t num_so_targets;
|
||||
struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS];
|
||||
uint32_t so_offsets[PIPE_MAX_SO_BUFFERS];
|
||||
};
|
||||
|
||||
static void emit_compute_state(struct rendering_state *state)
|
||||
|
@ -2422,6 +2426,81 @@ static void handle_push_descriptor_set(struct lvp_cmd_buffer_entry *cmd,
|
|||
}
|
||||
}
|
||||
|
||||
static void handle_bind_transform_feedback_buffers(struct lvp_cmd_buffer_entry *cmd,
|
||||
struct rendering_state *state)
|
||||
{
|
||||
struct lvp_cmd_bind_transform_feedback_buffers *btfb = &cmd->u.bind_transform_feedback_buffers;
|
||||
|
||||
for (unsigned i = 0; i < btfb->binding_count; i++) {
|
||||
int idx = i + btfb->first_binding;
|
||||
if (state->so_targets[idx])
|
||||
state->pctx->stream_output_target_destroy(state->pctx, state->so_targets[idx]);
|
||||
|
||||
state->so_targets[idx] = state->pctx->create_stream_output_target(state->pctx,
|
||||
btfb->buffers[i]->bo,
|
||||
btfb->offsets[i],
|
||||
btfb->sizes[i]);
|
||||
}
|
||||
state->num_so_targets = btfb->first_binding + btfb->binding_count;
|
||||
}
|
||||
|
||||
static void handle_begin_transform_feedback(struct lvp_cmd_buffer_entry *cmd,
|
||||
struct rendering_state *state)
|
||||
{
|
||||
struct lvp_cmd_begin_transform_feedback *btf = &cmd->u.begin_transform_feedback;
|
||||
uint32_t offsets[4];
|
||||
|
||||
memset(offsets, 0, sizeof(uint32_t)*4);
|
||||
|
||||
for (unsigned i = 0; i < btf->counter_buffer_count; i++) {
|
||||
pipe_buffer_read(state->pctx,
|
||||
btf->counter_buffers[i]->bo,
|
||||
btf->counter_buffer_offsets[i],
|
||||
4,
|
||||
&offsets[i]);
|
||||
}
|
||||
state->pctx->set_stream_output_targets(state->pctx, state->num_so_targets,
|
||||
state->so_targets, offsets);
|
||||
}
|
||||
|
||||
static void handle_end_transform_feedback(struct lvp_cmd_buffer_entry *cmd,
|
||||
struct rendering_state *state)
|
||||
{
|
||||
struct lvp_cmd_end_transform_feedback *etf = &cmd->u.end_transform_feedback;
|
||||
|
||||
if (etf->counter_buffer_count) {
|
||||
for (unsigned i = 0; i < etf->counter_buffer_count; i++) {
|
||||
uint32_t offset;
|
||||
offset = state->pctx->stream_output_target_offset(state->so_targets[i]);
|
||||
|
||||
pipe_buffer_write(state->pctx,
|
||||
etf->counter_buffers[i]->bo,
|
||||
etf->counter_buffer_offsets[i],
|
||||
4,
|
||||
&offset);
|
||||
}
|
||||
}
|
||||
state->pctx->set_stream_output_targets(state->pctx, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
static void handle_draw_indirect_byte_count(struct lvp_cmd_buffer_entry *cmd,
|
||||
struct rendering_state *state)
|
||||
{
|
||||
struct lvp_cmd_draw_indirect_byte_count *dibc = &cmd->u.draw_indirect_byte_count;
|
||||
|
||||
pipe_buffer_read(state->pctx,
|
||||
dibc->counter_buffer->bo,
|
||||
dibc->counter_buffer->offset + dibc->counter_buffer_offset,
|
||||
4, &state->draw.count);
|
||||
|
||||
state->info.start_instance = cmd->u.draw_indirect_byte_count.first_instance;
|
||||
state->info.instance_count = cmd->u.draw_indirect_byte_count.instance_count;
|
||||
state->info.index_size = 0;
|
||||
|
||||
state->draw.count /= cmd->u.draw_indirect_byte_count.vertex_stride;
|
||||
state->pctx->draw_vbo(state->pctx, &state->info, &state->indirect_info, &state->draw, 1);
|
||||
}
|
||||
|
||||
static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer,
|
||||
struct rendering_state *state)
|
||||
{
|
||||
|
@ -2576,6 +2655,19 @@ static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer,
|
|||
case LVP_CMD_PUSH_DESCRIPTOR_SET:
|
||||
handle_push_descriptor_set(cmd, state);
|
||||
break;
|
||||
case LVP_CMD_BIND_TRANSFORM_FEEDBACK_BUFFERS:
|
||||
handle_bind_transform_feedback_buffers(cmd, state);
|
||||
break;
|
||||
case LVP_CMD_BEGIN_TRANSFORM_FEEDBACK:
|
||||
handle_begin_transform_feedback(cmd, state);
|
||||
break;
|
||||
case LVP_CMD_END_TRANSFORM_FEEDBACK:
|
||||
handle_end_transform_feedback(cmd, state);
|
||||
break;
|
||||
case LVP_CMD_DRAW_INDIRECT_BYTE_COUNT:
|
||||
emit_state(state);
|
||||
handle_draw_indirect_byte_count(cmd, state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ EXTENSIONS = [
|
|||
Extension('VK_EXT_shader_stencil_export', 1, True),
|
||||
Extension('VK_EXT_shader_subgroup_ballot', 1, False),
|
||||
Extension('VK_EXT_shader_subgroup_vote', 1, False),
|
||||
Extension('VK_EXT_transform_feedback', 1, False),
|
||||
Extension('VK_EXT_transform_feedback', 1, True),
|
||||
Extension('VK_EXT_vertex_attribute_divisor', 3, True),
|
||||
Extension('VK_EXT_ycbcr_image_arrays', 1, False),
|
||||
Extension('VK_GOOGLE_decorate_string', 1, True),
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "lvp_lower_vulkan_resource.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "nir/nir_xfb_info.h"
|
||||
|
||||
#define SPIR_V_MAGIC_NUMBER 0x07230203
|
||||
|
||||
|
@ -505,6 +506,8 @@ lvp_shader_compile_to_ir(struct lvp_pipeline *pipeline,
|
|||
.variable_pointers = true,
|
||||
.stencil_export = true,
|
||||
.post_depth_coverage = true,
|
||||
.transform_feedback = true,
|
||||
.geometry_streams = true,
|
||||
},
|
||||
.ubo_addr_format = nir_address_format_32bit_index_offset,
|
||||
.ssbo_addr_format = nir_address_format_32bit_index_offset,
|
||||
|
@ -699,6 +702,39 @@ lvp_pipeline_compile(struct lvp_pipeline *pipeline,
|
|||
} else {
|
||||
struct pipe_shader_state shstate = {};
|
||||
fill_shader_prog(&shstate, stage, pipeline);
|
||||
|
||||
nir_xfb_info *xfb_info = NULL;
|
||||
if (stage == MESA_SHADER_VERTEX ||
|
||||
stage == MESA_SHADER_GEOMETRY ||
|
||||
stage == MESA_SHADER_TESS_EVAL) {
|
||||
xfb_info = nir_gather_xfb_info(pipeline->pipeline_nir[stage], NULL);
|
||||
if (xfb_info) {
|
||||
unsigned num_outputs = 0;
|
||||
uint8_t output_mapping[VARYING_SLOT_TESS_MAX];
|
||||
memset(output_mapping, 0, sizeof(output_mapping));
|
||||
|
||||
for (unsigned attr = 0; attr < VARYING_SLOT_MAX; attr++) {
|
||||
if (pipeline->pipeline_nir[stage]->info.outputs_written & BITFIELD64_BIT(attr))
|
||||
output_mapping[attr] = num_outputs++;
|
||||
}
|
||||
|
||||
shstate.stream_output.num_outputs = xfb_info->output_count;
|
||||
for (unsigned i = 0; i < PIPE_MAX_SO_BUFFERS; i++) {
|
||||
if (xfb_info->buffers_written & (1 << i)) {
|
||||
shstate.stream_output.stride[i] = xfb_info->buffers[i].stride / 4;
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < xfb_info->output_count; i++) {
|
||||
shstate.stream_output.output[i].output_buffer = xfb_info->outputs[i].buffer;
|
||||
shstate.stream_output.output[i].dst_offset = xfb_info->outputs[i].offset / 4;
|
||||
shstate.stream_output.output[i].register_index = output_mapping[xfb_info->outputs[i].location];
|
||||
shstate.stream_output.output[i].num_components = util_bitcount(xfb_info->outputs[i].component_mask);
|
||||
shstate.stream_output.output[i].start_component = ffs(xfb_info->outputs[i].component_mask) - 1;
|
||||
shstate.stream_output.output[i].stream = xfb_info->buffer_to_stream[xfb_info->outputs[i].buffer];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (stage) {
|
||||
case MESA_SHADER_FRAGMENT:
|
||||
pipeline->shader_cso[PIPE_SHADER_FRAGMENT] = device->queue.ctx->create_fs_state(device->queue.ctx, &shstate);
|
||||
|
|
|
@ -660,6 +660,10 @@ enum lvp_cmds {
|
|||
LVP_CMD_DRAW_INDIRECT_COUNT,
|
||||
LVP_CMD_DRAW_INDEXED_INDIRECT_COUNT,
|
||||
LVP_CMD_PUSH_DESCRIPTOR_SET,
|
||||
LVP_CMD_BIND_TRANSFORM_FEEDBACK_BUFFERS,
|
||||
LVP_CMD_BEGIN_TRANSFORM_FEEDBACK,
|
||||
LVP_CMD_END_TRANSFORM_FEEDBACK,
|
||||
LVP_CMD_DRAW_INDIRECT_BYTE_COUNT,
|
||||
};
|
||||
|
||||
struct lvp_cmd_bind_pipeline {
|
||||
|
@ -949,6 +953,37 @@ struct lvp_cmd_push_descriptor_set {
|
|||
union lvp_descriptor_info *infos;
|
||||
};
|
||||
|
||||
struct lvp_cmd_bind_transform_feedback_buffers {
|
||||
uint32_t first_binding;
|
||||
uint32_t binding_count;
|
||||
struct lvp_buffer **buffers;
|
||||
VkDeviceSize *offsets;
|
||||
VkDeviceSize *sizes;
|
||||
};
|
||||
|
||||
struct lvp_cmd_begin_transform_feedback {
|
||||
uint32_t first_counter_buffer;
|
||||
uint32_t counter_buffer_count;
|
||||
struct lvp_buffer **counter_buffers;
|
||||
VkDeviceSize *counter_buffer_offsets;
|
||||
};
|
||||
|
||||
struct lvp_cmd_end_transform_feedback {
|
||||
uint32_t first_counter_buffer;
|
||||
uint32_t counter_buffer_count;
|
||||
struct lvp_buffer **counter_buffers;
|
||||
VkDeviceSize *counter_buffer_offsets;
|
||||
};
|
||||
|
||||
struct lvp_cmd_draw_indirect_byte_count {
|
||||
uint32_t instance_count;
|
||||
uint32_t first_instance;
|
||||
struct lvp_buffer *counter_buffer;
|
||||
VkDeviceSize counter_buffer_offset;
|
||||
uint32_t counter_offset;
|
||||
uint32_t vertex_stride;
|
||||
};
|
||||
|
||||
struct lvp_cmd_buffer_entry {
|
||||
struct list_head cmd_link;
|
||||
uint32_t cmd_type;
|
||||
|
@ -991,6 +1026,10 @@ struct lvp_cmd_buffer_entry {
|
|||
struct lvp_cmd_execute_commands execute_commands;
|
||||
struct lvp_cmd_draw_indirect_count draw_indirect_count;
|
||||
struct lvp_cmd_push_descriptor_set push_descriptor_set;
|
||||
struct lvp_cmd_bind_transform_feedback_buffers bind_transform_feedback_buffers;
|
||||
struct lvp_cmd_begin_transform_feedback begin_transform_feedback;
|
||||
struct lvp_cmd_end_transform_feedback end_transform_feedback;
|
||||
struct lvp_cmd_draw_indirect_byte_count draw_indirect_byte_count;
|
||||
} u;
|
||||
};
|
||||
|
||||
|
|
|
@ -40,6 +40,9 @@ VkResult lvp_CreateQueryPool(
|
|||
case VK_QUERY_TYPE_TIMESTAMP:
|
||||
pipeq = PIPE_QUERY_TIMESTAMP;
|
||||
break;
|
||||
case VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT:
|
||||
pipeq = PIPE_QUERY_SO_STATISTICS;
|
||||
break;
|
||||
case VK_QUERY_TYPE_PIPELINE_STATISTICS:
|
||||
pipeq = PIPE_QUERY_PIPELINE_STATISTICS;
|
||||
break;
|
||||
|
@ -126,6 +129,11 @@ VkResult lvp_GetQueryPoolResults(
|
|||
*(uint64_t *)dptr = pstats[i];
|
||||
dptr += 8;
|
||||
}
|
||||
} else if (pool->type == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT) {
|
||||
*(uint64_t *)dptr = result.so_statistics.num_primitives_written;
|
||||
dptr += 8;
|
||||
*(uint64_t *)dptr = result.so_statistics.primitives_storage_needed;
|
||||
dptr += 8;
|
||||
} else {
|
||||
*(uint64_t *)dptr = result.u64;
|
||||
dptr += 8;
|
||||
|
@ -147,6 +155,17 @@ VkResult lvp_GetQueryPoolResults(
|
|||
*(uint32_t *)dptr = pstats[i];
|
||||
dptr += 4;
|
||||
}
|
||||
} else if (pool->type == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT) {
|
||||
if (result.so_statistics.num_primitives_written > UINT32_MAX)
|
||||
*(uint32_t *)dptr = UINT32_MAX;
|
||||
else
|
||||
*(uint32_t *)dptr = (uint32_t)result.so_statistics.num_primitives_written;
|
||||
dptr += 4;
|
||||
if (result.so_statistics.primitives_storage_needed > UINT32_MAX)
|
||||
*(uint32_t *)dptr = UINT32_MAX;
|
||||
else
|
||||
*(uint32_t *)dptr = (uint32_t)result.so_statistics.primitives_storage_needed;
|
||||
dptr += 4;
|
||||
} else {
|
||||
if (result.u64 > UINT32_MAX)
|
||||
*(uint32_t *)dptr = UINT32_MAX;
|
||||
|
|
Loading…
Reference in New Issue