anv: rewrite internal shaders using OpenCL
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26797>
This commit is contained in:
committed by
Marge Bot
parent
da391650f5
commit
b52e25d3a8
@@ -0,0 +1,206 @@
|
||||
/* Copyright © 2023 Intel Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "libintel_shaders.h"
|
||||
|
||||
void genX(write_3DSTATE_VERTEX_BUFFERS)(global void *dst_ptr,
|
||||
uint32_t buffer_count)
|
||||
{
|
||||
struct GENX(3DSTATE_VERTEX_BUFFERS) v = {
|
||||
GENX(3DSTATE_VERTEX_BUFFERS_header),
|
||||
};
|
||||
v.DWordLength = 1 + (buffer_count * 4) -
|
||||
GENX(3DSTATE_VERTEX_BUFFERS_length_bias);
|
||||
GENX(3DSTATE_VERTEX_BUFFERS_pack)(dst_ptr, &v);
|
||||
}
|
||||
|
||||
void genX(write_VERTEX_BUFFER_STATE)(global void *dst_ptr,
|
||||
uint32_t mocs,
|
||||
uint32_t buffer_idx,
|
||||
uint64_t address,
|
||||
uint32_t size,
|
||||
uint32_t stride)
|
||||
{
|
||||
bool buffer_null = address == 0;
|
||||
struct GENX(VERTEX_BUFFER_STATE) v = {
|
||||
.BufferPitch = stride,
|
||||
.NullVertexBuffer = address == 0,
|
||||
.AddressModifyEnable = true,
|
||||
.MOCS = mocs,
|
||||
#if GFX_VER >= 12
|
||||
.L3BypassDisable = true,
|
||||
#endif
|
||||
.VertexBufferIndex = buffer_idx,
|
||||
.BufferStartingAddress = address,
|
||||
.BufferSize = size,
|
||||
};
|
||||
GENX(VERTEX_BUFFER_STATE_pack)(dst_ptr, &v);
|
||||
}
|
||||
|
||||
#if GFX_VER == 9
|
||||
void genX(write_3DPRIMITIVE)(global void *dst_ptr,
|
||||
bool is_predicated,
|
||||
bool is_indexed,
|
||||
bool uses_tbimr,
|
||||
uint32_t vertex_count_per_instance,
|
||||
uint32_t start_vertex_location,
|
||||
uint32_t instance_count,
|
||||
uint32_t start_instance_location,
|
||||
uint32_t base_vertex_location)
|
||||
{
|
||||
struct GENX(3DPRIMITIVE) v = {
|
||||
GENX(3DPRIMITIVE_header),
|
||||
#if GFX_VERx10 >= 125
|
||||
.TBIMREnable = uses_tbimr,
|
||||
#endif
|
||||
.PredicateEnable = is_predicated,
|
||||
.VertexAccessType = is_indexed ? RANDOM : SEQUENTIAL,
|
||||
.VertexCountPerInstance = vertex_count_per_instance,
|
||||
.StartVertexLocation = start_vertex_location,
|
||||
.InstanceCount = instance_count,
|
||||
.StartInstanceLocation = start_instance_location,
|
||||
.BaseVertexLocation = base_vertex_location,
|
||||
};
|
||||
GENX(3DPRIMITIVE_pack)(dst_ptr, &v);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GFX_VER >= 11
|
||||
void genX(write_3DPRIMITIVE_EXTENDED)(global void *dst_ptr,
|
||||
bool is_predicated,
|
||||
bool is_indexed,
|
||||
bool uses_tbimr,
|
||||
uint32_t vertex_count_per_instance,
|
||||
uint32_t start_vertex_location,
|
||||
uint32_t instance_count,
|
||||
uint32_t start_instance_location,
|
||||
uint32_t base_vertex_location,
|
||||
uint32_t param_base_vertex,
|
||||
uint32_t param_base_instance,
|
||||
uint32_t param_draw_id)
|
||||
{
|
||||
struct GENX(3DPRIMITIVE_EXTENDED) v = {
|
||||
GENX(3DPRIMITIVE_EXTENDED_header),
|
||||
#if GFX_VERx10 >= 125
|
||||
.TBIMREnable = uses_tbimr,
|
||||
#endif
|
||||
.PredicateEnable = is_predicated,
|
||||
.VertexAccessType = is_indexed ? RANDOM : SEQUENTIAL,
|
||||
.VertexCountPerInstance = vertex_count_per_instance,
|
||||
.StartVertexLocation = start_vertex_location,
|
||||
.InstanceCount = instance_count,
|
||||
.StartInstanceLocation = start_instance_location,
|
||||
.BaseVertexLocation = base_vertex_location,
|
||||
.ExtendedParameter0 = param_base_vertex,
|
||||
.ExtendedParameter1 = param_base_instance,
|
||||
.ExtendedParameter2 = param_draw_id,
|
||||
};
|
||||
GENX(3DPRIMITIVE_EXTENDED_pack)(dst_ptr, &v);
|
||||
}
|
||||
#endif
|
||||
|
||||
void genX(write_MI_BATCH_BUFFER_START)(global void *dst_ptr, uint64_t addr)
|
||||
{
|
||||
struct GENX(MI_BATCH_BUFFER_START) v = {
|
||||
GENX(MI_BATCH_BUFFER_START_header),
|
||||
.AddressSpaceIndicator = ASI_PPGTT,
|
||||
.BatchBufferStartAddress = addr,
|
||||
};
|
||||
GENX(MI_BATCH_BUFFER_START_pack)(dst_ptr, &v);
|
||||
}
|
||||
|
||||
void genX(write_draw)(global uint32_t *dst_ptr,
|
||||
global void *indirect_ptr,
|
||||
global uint32_t *draw_id_ptr,
|
||||
uint32_t draw_id,
|
||||
uint32_t instance_multiplier,
|
||||
bool is_indexed,
|
||||
bool is_predicated,
|
||||
bool uses_tbimr,
|
||||
bool uses_base,
|
||||
bool uses_drawid,
|
||||
uint32_t mocs)
|
||||
{
|
||||
#if GFX_VER == 9
|
||||
if (uses_base || uses_drawid) {
|
||||
uint32_t vertex_buffer_count =
|
||||
(uses_base ? 1 : 0) + (uses_drawid ? 1 : 0);
|
||||
genX(write_3DSTATE_VERTEX_BUFFERS)(dst_ptr, vertex_buffer_count);
|
||||
dst_ptr += 1; /* GENX(3DSTATE_VERTEX_BUFFERS_length); */
|
||||
if (uses_base) {
|
||||
uint64_t base_addr = (uint64_t)indirect_ptr + (is_indexed ? 12 : 8);
|
||||
genX(write_VERTEX_BUFFER_STATE)(dst_ptr, mocs, 31, base_addr, 8, 0);
|
||||
dst_ptr += GENX(VERTEX_BUFFER_STATE_length);
|
||||
}
|
||||
if (uses_drawid) {
|
||||
*draw_id_ptr = draw_id;
|
||||
genX(write_VERTEX_BUFFER_STATE)(dst_ptr, mocs, 32,
|
||||
(uint64_t)draw_id_ptr, 4, 0);
|
||||
dst_ptr += GENX(VERTEX_BUFFER_STATE_length);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_indexed) {
|
||||
VkDrawIndexedIndirectCommand data =
|
||||
*((global VkDrawIndexedIndirectCommand *)indirect_ptr);
|
||||
|
||||
genX(write_3DPRIMITIVE)(dst_ptr,
|
||||
is_predicated,
|
||||
is_indexed,
|
||||
uses_tbimr,
|
||||
data.indexCount,
|
||||
data.firstIndex,
|
||||
data.instanceCount * instance_multiplier,
|
||||
data.firstInstance,
|
||||
data.vertexOffset);
|
||||
} else {
|
||||
VkDrawIndirectCommand data =
|
||||
*((global VkDrawIndirectCommand *)indirect_ptr);
|
||||
|
||||
genX(write_3DPRIMITIVE)(dst_ptr,
|
||||
is_predicated,
|
||||
is_indexed,
|
||||
uses_tbimr,
|
||||
data.vertexCount,
|
||||
data.firstVertex,
|
||||
data.instanceCount * instance_multiplier,
|
||||
data.firstInstance,
|
||||
0 /* base_vertex_location */);
|
||||
}
|
||||
#else
|
||||
if (is_indexed) {
|
||||
VkDrawIndexedIndirectCommand data =
|
||||
*((global VkDrawIndexedIndirectCommand *)indirect_ptr);
|
||||
|
||||
genX(write_3DPRIMITIVE_EXTENDED)(dst_ptr,
|
||||
is_predicated,
|
||||
is_indexed,
|
||||
uses_tbimr,
|
||||
data.indexCount,
|
||||
data.firstIndex,
|
||||
data.instanceCount * instance_multiplier,
|
||||
data.firstInstance,
|
||||
data.vertexOffset,
|
||||
data.vertexOffset,
|
||||
data.firstInstance,
|
||||
draw_id);
|
||||
} else {
|
||||
VkDrawIndirectCommand data =
|
||||
*((global VkDrawIndirectCommand *)indirect_ptr);
|
||||
|
||||
genX(write_3DPRIMITIVE_EXTENDED)(dst_ptr,
|
||||
is_predicated,
|
||||
is_indexed,
|
||||
uses_tbimr,
|
||||
data.vertexCount,
|
||||
data.firstVertex,
|
||||
data.instanceCount * instance_multiplier,
|
||||
data.firstInstance,
|
||||
0 /* base_vertex_location */,
|
||||
data.firstVertex,
|
||||
data.firstInstance,
|
||||
draw_id);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/* Copyright © 2023 Intel Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "libintel_shaders.h"
|
||||
|
||||
static void end_generated_draws(global void *dst_ptr,
|
||||
uint32_t item_idx,
|
||||
uint32_t draw_id, uint32_t draw_count,
|
||||
uint32_t ring_count, uint32_t max_draw_count,
|
||||
uint32_t flags,
|
||||
uint64_t gen_addr, uint64_t end_addr)
|
||||
{
|
||||
uint32_t _3dprim_size_B = ((flags >> 16) & 0xff) * 4;
|
||||
bool indirect_count = (flags & ANV_GENERATED_FLAG_COUNT) != 0;
|
||||
bool ring_mode = (flags & ANV_GENERATED_FLAG_RING_MODE) != 0;
|
||||
/* We can have an indirect draw count = 0. */
|
||||
uint32_t last_draw_id = draw_count == 0 ? 0 : (min(draw_count, max_draw_count) - 1);
|
||||
global void *jump_dst = draw_count == 0 ? dst_ptr : (dst_ptr + _3dprim_size_B);
|
||||
|
||||
if (ring_mode) {
|
||||
if (draw_id == last_draw_id) {
|
||||
/* Exit the ring buffer to the next user commands */
|
||||
genX(write_MI_BATCH_BUFFER_START)(jump_dst, end_addr);
|
||||
} else if (item_idx == (ring_count - 1)) {
|
||||
/* Jump back to the generation shader to generate mode draws */
|
||||
genX(write_MI_BATCH_BUFFER_START)(jump_dst, gen_addr);
|
||||
}
|
||||
} else {
|
||||
if (draw_id == last_draw_id && draw_count < max_draw_count) {
|
||||
/* Skip forward to the end of the generated draws */
|
||||
genX(write_MI_BATCH_BUFFER_START)(jump_dst, end_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
genX(libanv_write_draw)(global void *dst_base,
|
||||
global void *indirect_base,
|
||||
global void *draw_id_base,
|
||||
uint32_t indirect_stride,
|
||||
global uint32_t *_draw_count,
|
||||
uint32_t draw_base,
|
||||
uint32_t instance_multiplier,
|
||||
uint32_t max_draw_count,
|
||||
uint32_t flags,
|
||||
uint32_t ring_count,
|
||||
uint64_t gen_addr,
|
||||
uint64_t end_addr,
|
||||
uint32_t item_idx)
|
||||
{
|
||||
uint32_t _3dprim_size_B = ((flags >> 16) & 0xff) * 4;
|
||||
uint32_t draw_id = draw_base + item_idx;
|
||||
uint32_t draw_count = *_draw_count;
|
||||
global void *dst_ptr = dst_base + item_idx * _3dprim_size_B;
|
||||
global void *indirect_ptr = indirect_base + draw_id * indirect_stride;
|
||||
global void *draw_id_ptr = draw_id_base + item_idx * 4;
|
||||
|
||||
if (draw_id < min(draw_count, max_draw_count)) {
|
||||
bool is_indexed = (flags & ANV_GENERATED_FLAG_INDEXED) != 0;
|
||||
bool is_predicated = (flags & ANV_GENERATED_FLAG_PREDICATED) != 0;
|
||||
bool uses_tbimr = (flags & ANV_GENERATED_FLAG_TBIMR) != 0;
|
||||
bool uses_base = (flags & ANV_GENERATED_FLAG_BASE) != 0;
|
||||
bool uses_drawid = (flags & ANV_GENERATED_FLAG_DRAWID) != 0;
|
||||
uint32_t mocs = (flags >> 8) & 0xff;
|
||||
|
||||
genX(write_draw)(dst_ptr, indirect_ptr, draw_id_ptr,
|
||||
draw_id, instance_multiplier,
|
||||
is_indexed, is_predicated,
|
||||
uses_tbimr, uses_base, uses_drawid,
|
||||
mocs);
|
||||
}
|
||||
|
||||
end_generated_draws(dst_ptr, item_idx, draw_id, draw_count,
|
||||
ring_count, max_draw_count, flags,
|
||||
gen_addr, end_addr);
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/* Copyright © 2023 Intel Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef _LIBANV_SHADERS_H_
|
||||
#define _LIBANV_SHADERS_H_
|
||||
|
||||
/* Define stdint types compatible between the CPU and GPU for shared headers */
|
||||
#ifndef __OPENCL_VERSION__
|
||||
#include <stdint.h>
|
||||
|
||||
#include "util/macros.h"
|
||||
|
||||
#else
|
||||
#define BITFIELD_BIT(i) (1u << i)
|
||||
|
||||
typedef ulong uint64_t;
|
||||
typedef uint uint32_t;
|
||||
typedef ushort uint16_t;
|
||||
typedef uchar uint8_t;
|
||||
|
||||
typedef long int64_t;
|
||||
typedef int int32_t;
|
||||
typedef short int16_t;
|
||||
typedef char int8_t;
|
||||
|
||||
typedef struct VkDrawIndexedIndirectCommand {
|
||||
uint32_t indexCount;
|
||||
uint32_t instanceCount;
|
||||
uint32_t firstIndex;
|
||||
int32_t vertexOffset;
|
||||
uint32_t firstInstance;
|
||||
} VkDrawIndexedIndirectCommand __attribute__((aligned(4)));
|
||||
|
||||
typedef struct VkDrawIndirectCommand {
|
||||
uint32_t vertexCount;
|
||||
uint32_t instanceCount;
|
||||
uint32_t firstVertex;
|
||||
uint32_t firstInstance;
|
||||
} VkDrawIndirectCommand __attribute__((aligned(4)));
|
||||
|
||||
#include "genxml/gen_macros.h"
|
||||
#include "genxml/genX_cl_pack.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Flags for generated_draws.cl
|
||||
*/
|
||||
#define ANV_GENERATED_FLAG_INDEXED BITFIELD_BIT(0)
|
||||
#define ANV_GENERATED_FLAG_PREDICATED BITFIELD_BIT(1)
|
||||
/* Only used on Gfx9, means the pipeline is using gl_DrawID */
|
||||
#define ANV_GENERATED_FLAG_DRAWID BITFIELD_BIT(2)
|
||||
/* Only used on Gfx9, means the pipeline is using gl_BaseVertex or
|
||||
* gl_BaseInstance
|
||||
*/
|
||||
#define ANV_GENERATED_FLAG_BASE BITFIELD_BIT(3)
|
||||
/* Whether the count is indirect */
|
||||
#define ANV_GENERATED_FLAG_COUNT BITFIELD_BIT(4)
|
||||
/* Whether the generation shader writes to the ring buffer */
|
||||
#define ANV_GENERATED_FLAG_RING_MODE BITFIELD_BIT(5)
|
||||
/* Whether TBIMR tile-based rendering shall be enabled. */
|
||||
#define ANV_GENERATED_FLAG_TBIMR BITFIELD_BIT(6)
|
||||
|
||||
/**
|
||||
* Flags for query_copy.cl
|
||||
*/
|
||||
#define ANV_COPY_QUERY_FLAG_RESULT64 BITFIELD_BIT(0)
|
||||
#define ANV_COPY_QUERY_FLAG_AVAILABLE BITFIELD_BIT(1)
|
||||
#define ANV_COPY_QUERY_FLAG_DELTA BITFIELD_BIT(2)
|
||||
#define ANV_COPY_QUERY_FLAG_PARTIAL BITFIELD_BIT(3)
|
||||
|
||||
#ifdef __OPENCL_VERSION__
|
||||
|
||||
void genX(write_3DSTATE_VERTEX_BUFFERS)(global void *dst_ptr,
|
||||
uint32_t buffer_count);
|
||||
|
||||
void genX(write_VERTEX_BUFFER_STATE)(global void *dst_ptr,
|
||||
uint32_t mocs,
|
||||
uint32_t buffer_idx,
|
||||
uint64_t address,
|
||||
uint32_t size,
|
||||
uint32_t stride);
|
||||
|
||||
#if GFX_VER == 9
|
||||
void genX(write_3DPRIMITIVE)(global void *dst_ptr,
|
||||
bool is_predicated,
|
||||
bool is_indexed,
|
||||
bool use_tbimr,
|
||||
uint32_t vertex_count_per_instance,
|
||||
uint32_t start_vertex_location,
|
||||
uint32_t instance_count,
|
||||
uint32_t start_instance_location,
|
||||
uint32_t base_vertex_location);
|
||||
#endif
|
||||
|
||||
#if GFX_VER >= 11
|
||||
void genX(write_3DPRIMITIVE_EXTENDED)(global void *dst_ptr,
|
||||
bool is_predicated,
|
||||
bool is_indexed,
|
||||
bool use_tbimr,
|
||||
uint32_t vertex_count_per_instance,
|
||||
uint32_t start_vertex_location,
|
||||
uint32_t instance_count,
|
||||
uint32_t start_instance_location,
|
||||
uint32_t base_vertex_location,
|
||||
uint32_t param_base_vertex,
|
||||
uint32_t param_base_instance,
|
||||
uint32_t param_draw_id);
|
||||
#endif
|
||||
|
||||
void genX(write_MI_BATCH_BUFFER_START)(global void *dst_ptr, uint64_t addr);
|
||||
|
||||
void genX(write_draw)(global uint32_t *dst_ptr,
|
||||
global void *indirect_ptr,
|
||||
global uint32_t *draw_id_ptr,
|
||||
uint32_t draw_id,
|
||||
uint32_t instance_multiplier,
|
||||
bool is_indexed,
|
||||
bool is_predicated,
|
||||
bool uses_tbimr,
|
||||
bool uses_base,
|
||||
bool uses_draw_id,
|
||||
uint32_t mocs);
|
||||
|
||||
#endif /* __OPENCL_VERSION__ */
|
||||
|
||||
#endif /* _LIBANV_SHADERS_H_ */
|
||||
@@ -0,0 +1,23 @@
|
||||
/* Copyright © 2023 Intel Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
void
|
||||
genX(libanv_memcpy)(global void *dst_base,
|
||||
global void *src_base,
|
||||
uint num_dwords,
|
||||
uint dword_offset)
|
||||
{
|
||||
global void *dst = dst_base + 4 * dword_offset;
|
||||
global void *src = src_base + 4 * dword_offset;
|
||||
|
||||
if (dword_offset + 4 <= num_dwords) {
|
||||
*(global uint4 *)(dst) = *(global uint4 *)(src);
|
||||
} else if (dword_offset + 3 <= num_dwords) {
|
||||
*(global uint3 *)(dst) = *(global uint3 *)(src);
|
||||
} else if (dword_offset + 2 <= num_dwords) {
|
||||
*(global uint2 *)(dst) = *(global uint2 *)(src);
|
||||
} else if (dword_offset + 1 <= num_dwords) {
|
||||
*(global uint *)(dst) = *(global uint *)(src);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
# Copyright © 2023 Intel Corporation
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
intel_float64_spv_h = custom_target(
|
||||
'float64_spv.h',
|
||||
input : [glsl2spirv, float64_glsl_file],
|
||||
output : 'float64_spv.h',
|
||||
command : [
|
||||
prog_python, '@INPUT@', '@OUTPUT@',
|
||||
prog_glslang,
|
||||
'--create-entry', 'main',
|
||||
'--vn', 'float64_spv_source',
|
||||
'--glsl-version', '450',
|
||||
'-Olib',
|
||||
]
|
||||
)
|
||||
|
||||
intel_shader_files = files(
|
||||
'libintel_shaders.h',
|
||||
'generate.cl',
|
||||
'generate_draws.cl',
|
||||
'memcpy.cl',
|
||||
'query_copy.cl',
|
||||
)
|
||||
|
||||
prepended_input_args = []
|
||||
foreach input_arg : intel_shader_files
|
||||
prepended_input_args += ['--in', input_arg]
|
||||
endforeach
|
||||
|
||||
intel_shaders_gens = [ [ 90, 9],
|
||||
[110, 11],
|
||||
[120, 12],
|
||||
[125, 125],
|
||||
[200, 20] ]
|
||||
intel_shaders = []
|
||||
foreach gen : intel_shaders_gens
|
||||
intel_shaders += custom_target(
|
||||
'intel_gfx@0@_shaders_code.h'.format(gen[1]),
|
||||
input : intel_shader_files,
|
||||
output : 'intel_gfx@0@_shaders_code.h'.format(gen[1]),
|
||||
command : [
|
||||
prog_intel_clc, '--nir',
|
||||
'--prefix', 'gfx@0@_intel_shaders'.format(gen[1]),
|
||||
prepended_input_args, '-o', '@OUTPUT@', '--',
|
||||
'-cl-std=cl2.0', '-D__OPENCL_VERSION__=200',
|
||||
'-DGFX_VERx10=@0@'.format(gen[0]),
|
||||
'-I' + join_paths(meson.current_source_dir(), '.'),
|
||||
'-I' + join_paths(meson.source_root(), 'src'),
|
||||
'-I' + join_paths(meson.source_root(), 'src/intel'),
|
||||
'-I' + join_paths(meson.build_root(), 'src/intel'),
|
||||
'-I' + join_paths(meson.source_root(), 'src/intel/genxml'),
|
||||
'-include', 'opencl-c.h',
|
||||
],
|
||||
env: ['MESA_SHADER_CACHE_DISABLE=true'],
|
||||
depends : [dep_prog_intel_clc, gen_cl_xml_pack],
|
||||
)
|
||||
endforeach
|
||||
|
||||
idep_intel_shaders = declare_dependency(
|
||||
sources : intel_shaders,
|
||||
include_directories : include_directories('.'),
|
||||
)
|
||||
@@ -0,0 +1,72 @@
|
||||
/* Copyright © 2023 Intel Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
void
|
||||
genX(libanv_query_copy)(global void *destination_base,
|
||||
uint32_t destination_stride,
|
||||
global void *query_data,
|
||||
uint32_t first_query,
|
||||
uint32_t num_queries,
|
||||
uint32_t query_data_offset,
|
||||
uint32_t query_stride,
|
||||
uint32_t num_query_items,
|
||||
uint32_t copy_flags,
|
||||
uint32_t copy_item_idx)
|
||||
{
|
||||
if (copy_item_idx >= num_queries)
|
||||
return;
|
||||
|
||||
bool is_result64 = (copy_flags & ANV_COPY_QUERY_FLAG_RESULT64) != 0;
|
||||
bool write_available = (copy_flags & ANV_COPY_QUERY_FLAG_AVAILABLE) != 0;
|
||||
bool compute_delta = (copy_flags & ANV_COPY_QUERY_FLAG_DELTA) != 0;
|
||||
bool partial_result = (copy_flags & ANV_COPY_QUERY_FLAG_PARTIAL) != 0;
|
||||
|
||||
|
||||
uint query_byte = (first_query + copy_item_idx) * query_stride;
|
||||
uint query_data_byte = query_byte + query_data_offset;
|
||||
|
||||
global uint64_t *query = query_data + (first_query + copy_item_idx) * query_stride;
|
||||
global uint64_t *dest64 = destination_base + copy_item_idx * destination_stride;
|
||||
global uint32_t *dest32 = destination_base + copy_item_idx * destination_stride;
|
||||
|
||||
uint64_t availability = *(global uint32_t *)(query_data + query_byte);
|
||||
|
||||
if (write_available) {
|
||||
if (is_result64)
|
||||
dest64[num_query_items] = availability;
|
||||
else
|
||||
dest32[num_query_items] = availability;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < num_query_items; i++) {
|
||||
uint32_t qw_offset = 1 + i * 2;
|
||||
uint64_t v;
|
||||
if (compute_delta) {
|
||||
struct delta64 {
|
||||
uint64_t v0;
|
||||
uint64_t v1;
|
||||
} data = *((global struct delta64 *)&query[qw_offset]);
|
||||
v = data.v1 - data.v0;
|
||||
} else {
|
||||
v = query[qw_offset + 0];
|
||||
}
|
||||
|
||||
/* vkCmdCopyQueryPoolResults:
|
||||
*
|
||||
* "If VK_QUERY_RESULT_PARTIAL_BIT is set, then for any query that is
|
||||
* unavailable, an intermediate result between zero and the final
|
||||
* result value is written for that query."
|
||||
*
|
||||
* We write 0 as the values not being written yet, we can't really make
|
||||
* provide any sensible value.
|
||||
*/
|
||||
if (partial_result && availability == 0)
|
||||
v = 0;
|
||||
|
||||
if (is_result64)
|
||||
dest64[i] = v;
|
||||
else
|
||||
dest32[i] = v;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user