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:
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user