freedreno/a6xx: ARB_query_buffer_object support

Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19400>
This commit is contained in:
Rob Clark
2022-10-30 11:19:48 -07:00
committed by Marge Bot
parent 41455c6369
commit bb52332b50
4 changed files with 107 additions and 4 deletions

View File

@@ -205,7 +205,7 @@ GL 4.4, GLSL 4.40 -- all DONE: i965/gen8+, nvc0, r600, radeonsi, llvmpipe, zink
- specified transform/feedback layout DONE
- input/output block locations DONE
GL_ARB_multi_bind DONE (all drivers)
GL_ARB_query_buffer_object DONE (i965/hsw+, virgl)
GL_ARB_query_buffer_object DONE (freedreno/a6xx, i965/hsw+, virgl)
GL_ARB_texture_mirror_clamp_to_edge DONE (freedreno, i965, nv50, softpipe, virgl, v3d, panfrost)
GL_ARB_texture_stencil8 DONE (freedreno, i965/hsw+, nv50, softpipe, virgl, v3d, panfrost, d3d12)
GL_ARB_vertex_type_10f_11f_11f_rev DONE (freedreno, i965, nv50, softpipe, virgl, panfrost, d3d12)

View File

@@ -1,9 +1,6 @@
# Shader compilation error log: 0:6(1): error: invalid stream specified 1 is larger than MAX_VERTEX_STREAMS - 1
KHR-GL43.transform_feedback.draw_xfb_stream_instanced_test,Fail
# glGetError() returned GL_INVALID_ENUM at gl4cMapBufferAlignmentTests.cpp:279
KHR-GL43.map_buffer_alignment.functional,Fail
KHR-GL43.gpu_shader_fp64.fp64.max_uniform_components,Fail
KHR-GL43.gpu_shader_fp64.builtin.mod_dvec2,Fail
KHR-GL43.gpu_shader_fp64.builtin.mod_dvec3,Fail
@@ -368,6 +365,23 @@ spec@!opengl 1.0@depth-clear-precision-check@depth24,Fail
spec@!opengl 1.0@depth-clear-precision-check@depth24_stencil8,Fail
spec@!opengl 1.0@depth-clear-precision-check@depth32,Fail
# timestamp/time-elapsed qbo tests fail due to lack of way to convert
# from ticks to ns on the CP (ie. we'd need to spin up a compute shader
# or something equally drastic)
spec@arb_query_buffer_object@qbo,Fail
spec@arb_query_buffer_object@qbo@query-GL_TIMESTAMP-ASYNC_CPU_READ_AFTER-GL_INT,Fail
spec@arb_query_buffer_object@qbo@query-GL_TIMESTAMP-ASYNC_CPU_READ_AFTER-GL_UNSIGNED_INT,Fail
spec@arb_query_buffer_object@qbo@query-GL_TIMESTAMP-ASYNC_CPU_READ_AFTER-GL_UNSIGNED_INT64_ARB,Fail
spec@arb_query_buffer_object@qbo@query-GL_TIMESTAMP-SYNC_CPU_READ_AFTER_CACHE_TEST-GL_INT,Fail
spec@arb_query_buffer_object@qbo@query-GL_TIMESTAMP-SYNC_CPU_READ_AFTER_CACHE_TEST-GL_UNSIGNED_INT,Fail
spec@arb_query_buffer_object@qbo@query-GL_TIMESTAMP-SYNC_CPU_READ_AFTER_CACHE_TEST-GL_UNSIGNED_INT64_ARB,Fail
spec@arb_query_buffer_object@qbo@query-GL_TIME_ELAPSED-ASYNC_CPU_READ_AFTER-GL_INT,Fail
spec@arb_query_buffer_object@qbo@query-GL_TIME_ELAPSED-ASYNC_CPU_READ_AFTER-GL_UNSIGNED_INT,Fail
spec@arb_query_buffer_object@qbo@query-GL_TIME_ELAPSED-ASYNC_CPU_READ_AFTER-GL_UNSIGNED_INT64_ARB,Fail
spec@arb_query_buffer_object@qbo@query-GL_TIME_ELAPSED-SYNC_CPU_READ_AFTER_CACHE_TEST-GL_INT,Fail
spec@arb_query_buffer_object@qbo@query-GL_TIME_ELAPSED-SYNC_CPU_READ_AFTER_CACHE_TEST-GL_UNSIGNED_INT,Fail
spec@arb_query_buffer_object@qbo@query-GL_TIME_ELAPSED-SYNC_CPU_READ_AFTER_CACHE_TEST-GL_UNSIGNED_INT64_ARB,Fail
# https://gitlab.khronos.org/Tracker/vk-gl-cts/-/issues/3759
# deqp-vk: ../src/freedreno/vulkan/tu_pipeline.c:3894: tu_pipeline_builder_init_graphics: Assertion `subpass->color_count == 0 || !create_info->pColorBlendState || subpass->color_count == create_info->pColorBlendState->attachmentCount' failed
dEQP-VK.pipeline.monolithic.color_write_enable_maxa.cwe_after_bind.attachments4_more0,Crash

View File

@@ -134,6 +134,16 @@ occlusion_counter_result(struct fd_acc_query *aq,
result->u64 = sp->result;
}
static void
occlusion_counter_result_resource(struct fd_acc_query *aq, struct fd_ringbuffer *ring,
enum pipe_query_value_type result_type,
int index, struct fd_resource *dst,
unsigned offset)
{
copy_result(ring, result_type, dst, offset, fd_resource(aq->prsc),
offsetof(struct fd6_query_sample, result));
}
static void
occlusion_predicate_result(struct fd_acc_query *aq,
struct fd_acc_query_sample *s,
@@ -143,12 +153,39 @@ occlusion_predicate_result(struct fd_acc_query *aq,
result->b = !!sp->result;
}
static void
occlusion_predicate_result_resource(struct fd_acc_query *aq, struct fd_ringbuffer *ring,
enum pipe_query_value_type result_type,
int index, struct fd_resource *dst,
unsigned offset)
{
/* This is a bit annoying but we need to turn the result into a one or
* zero.. to do this use a CP_COND_WRITE to overwrite the result with
* a one if it is non-zero. This doesn't change the results if the
* query is also read on the CPU (ie. occlusion_predicate_result()).
*/
OUT_PKT7(ring, CP_COND_WRITE5, 9);
OUT_RING(ring, CP_COND_WRITE5_0_FUNCTION(WRITE_NE) |
CP_COND_WRITE5_0_POLL_MEMORY |
CP_COND_WRITE5_0_WRITE_MEMORY);
OUT_RELOC(ring, query_sample(aq, result)); /* POLL_ADDR_LO/HI */
OUT_RING(ring, CP_COND_WRITE5_3_REF(0));
OUT_RING(ring, CP_COND_WRITE5_4_MASK(~0));
OUT_RELOC(ring, query_sample(aq, result)); /* WRITE_ADDR_LO/HI */
OUT_RING(ring, 1);
OUT_RING(ring, 0);
copy_result(ring, result_type, dst, offset, fd_resource(aq->prsc),
offsetof(struct fd6_query_sample, result));
}
static const struct fd_acc_sample_provider occlusion_counter = {
.query_type = PIPE_QUERY_OCCLUSION_COUNTER,
.size = sizeof(struct fd6_query_sample),
.resume = occlusion_resume,
.pause = occlusion_pause,
.result = occlusion_counter_result,
.result_resource = occlusion_counter_result_resource,
};
static const struct fd_acc_sample_provider occlusion_predicate = {
@@ -157,6 +194,7 @@ static const struct fd_acc_sample_provider occlusion_predicate = {
.resume = occlusion_resume,
.pause = occlusion_pause,
.result = occlusion_predicate_result,
.result_resource = occlusion_predicate_result_resource,
};
static const struct fd_acc_sample_provider occlusion_predicate_conservative = {
@@ -165,6 +203,7 @@ static const struct fd_acc_sample_provider occlusion_predicate_conservative = {
.resume = occlusion_resume,
.pause = occlusion_pause,
.result = occlusion_predicate_result,
.result_resource = occlusion_predicate_result_resource,
};
/*
@@ -244,6 +283,17 @@ time_elapsed_accumulate_result(struct fd_acc_query *aq,
result->u64 = ticks_to_ns(sp->result);
}
static void
time_elapsed_result_resource(struct fd_acc_query *aq, struct fd_ringbuffer *ring,
enum pipe_query_value_type result_type,
int index, struct fd_resource *dst,
unsigned offset)
{
// TODO ticks_to_ns conversion would require spinning up a compute shader?
copy_result(ring, result_type, dst, offset, fd_resource(aq->prsc),
offsetof(struct fd6_query_sample, result));
}
static void
timestamp_accumulate_result(struct fd_acc_query *aq,
struct fd_acc_query_sample *s,
@@ -253,6 +303,17 @@ timestamp_accumulate_result(struct fd_acc_query *aq,
result->u64 = ticks_to_ns(sp->start);
}
static void
timestamp_result_resource(struct fd_acc_query *aq, struct fd_ringbuffer *ring,
enum pipe_query_value_type result_type,
int index, struct fd_resource *dst,
unsigned offset)
{
// TODO ticks_to_ns conversion would require spinning up a compute shader?
copy_result(ring, result_type, dst, offset, fd_resource(aq->prsc),
offsetof(struct fd6_query_sample, start));
}
static const struct fd_acc_sample_provider time_elapsed = {
.query_type = PIPE_QUERY_TIME_ELAPSED,
.always = true,
@@ -260,6 +321,7 @@ static const struct fd_acc_sample_provider time_elapsed = {
.resume = timestamp_resume,
.pause = time_elapsed_pause,
.result = time_elapsed_accumulate_result,
.result_resource = time_elapsed_result_resource,
};
/* NOTE: timestamp query isn't going to give terribly sensible results
@@ -276,6 +338,7 @@ static const struct fd_acc_sample_provider timestamp = {
.resume = timestamp_resume,
.pause = timestamp_pause,
.result = timestamp_accumulate_result,
.result_resource = timestamp_result_resource,
};
struct PACKED fd6_primitives_sample {
@@ -406,12 +469,24 @@ primitives_generated_result(struct fd_acc_query *aq,
result->u64 = ps->result.generated;
}
static void
primitives_generated_result_resource(struct fd_acc_query *aq,
struct fd_ringbuffer *ring,
enum pipe_query_value_type result_type,
int index, struct fd_resource *dst,
unsigned offset)
{
copy_result(ring, result_type, dst, offset, fd_resource(aq->prsc),
offsetof(struct fd6_primitives_sample, result.generated));
}
static const struct fd_acc_sample_provider primitives_generated = {
.query_type = PIPE_QUERY_PRIMITIVES_GENERATED,
.size = sizeof(struct fd6_primitives_sample),
.resume = primitives_generated_resume,
.pause = primitives_generated_pause,
.result = primitives_generated_result,
.result_resource = primitives_generated_result_resource,
};
static void
@@ -468,12 +543,24 @@ primitives_emitted_result(struct fd_acc_query *aq,
result->u64 = ps->result.emitted;
}
static void
primitives_emitted_result_resource(struct fd_acc_query *aq,
struct fd_ringbuffer *ring,
enum pipe_query_value_type result_type,
int index, struct fd_resource *dst,
unsigned offset)
{
copy_result(ring, result_type, dst, offset, fd_resource(aq->prsc),
offsetof(struct fd6_primitives_sample, result.emitted));
}
static const struct fd_acc_sample_provider primitives_emitted = {
.query_type = PIPE_QUERY_PRIMITIVES_EMITTED,
.size = sizeof(struct fd6_primitives_sample),
.resume = primitives_emitted_resume,
.pause = primitives_emitted_pause,
.result = primitives_emitted_result,
.result_resource = primitives_emitted_result_resource,
};
/*

View File

@@ -526,6 +526,8 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
/* only a4xx, requires new enough kernel so we know max_freq: */
return (screen->max_freq > 0) &&
(is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen));
case PIPE_CAP_QUERY_BUFFER_OBJECT:
return is_a6xx(screen);
case PIPE_CAP_VENDOR_ID:
return 0x5143;