mesa: Fix AMD performance monitor implementation

For cmd GL_PERFMON_RESULT_SIZE_AMD and GL_PERFMON_RESULT_AMD of
glGetPerfMonitorCounterDataAMD(), the current implementation will
return 0 if the result is not available on HW, but according to the
sepc, if cmd is PERFMON_RESULT_SIZE_AMD, <data> will contain actual
size of all counter results being sampled, instead of 0. And if cmd is
PERFMON_RESULT_AMD, <data> will contain results. The spec doesn't
require the application to wait for the result available on HW before
executing cmd PERFMON_RESULT_SIZE_AMD and PERFMON_RESULT_AMD. So for
cmd PERFMON_RESULT_SIZE_AMD, it should immediately return the correct
result size for the counters enabled by
glSelectPerfMonitorCountersAMD(), and for cmd PERFMON_RESULT_AMD, it
should wait until the result is available on HW and then return the
result.

Without this fix, the Sample Usage in the spec will not work properly
as it always gets size 0 when calling the cmd PERFMON_RESULT_SIZE_AMD

V2: If SelectPerfMonitorCountersAMD is called on a monitor, then the
result of querying for PERFMON_RESULT_SIZE will be 0.

Signed-off-by: Trigger Huang <Trigger.Huang@amd.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31179>
This commit is contained in:
Trigger Huang
2024-09-14 16:32:49 +08:00
committed by Marge Bot
parent f8788b2a38
commit 7c01f70bdc
+19 -8
View File
@@ -941,6 +941,15 @@ perf_monitor_result_size(const struct gl_context *ctx,
unsigned group, counter;
unsigned size = 0;
/**
* If no BeginPerfMonitorAMD has been issued for a monitor,
* or if SelectPerfMonitorCountersAMD is called on a monitor, then the result
* of querying for PERFMON_RESULT_SIZE will be 0.
* Using the same logic in is_perf_monitor_result_available().
*/
if (!m->num_active_counters)
return 0;
for (group = 0; group < ctx->PerfMonitor.NumGroups; group++) {
const struct gl_perf_monitor_group *g = &ctx->PerfMonitor.Groups[group];
@@ -963,7 +972,6 @@ _mesa_GetPerfMonitorCounterDataAMD(GLuint monitor, GLenum pname,
GET_CURRENT_CONTEXT(ctx);
struct gl_perf_monitor_object *m = lookup_monitor(ctx, monitor);
bool result_available;
if (m == NULL) {
_mesa_error(ctx, GL_INVALID_VALUE,
@@ -985,12 +993,12 @@ _mesa_GetPerfMonitorCounterDataAMD(GLuint monitor, GLenum pname,
return;
}
/* If the monitor has never ended, there is no result. */
result_available = m->Ended &&
is_perf_monitor_result_available(ctx, m);
/* AMD appears to return 0 for all queries unless a result is available. */
if (!result_available) {
/**
* If no EndPerfMonitorAMD has been issued for a monitor
* then the result of querying for PERFMON_RESULT_AVAILABLE and
* PERFMON_RESULT_SIZE will be 0
*/
if (!m->Ended) {
*data = 0;
if (bytesWritten != NULL)
*bytesWritten = sizeof(GLuint);
@@ -999,7 +1007,10 @@ _mesa_GetPerfMonitorCounterDataAMD(GLuint monitor, GLenum pname,
switch (pname) {
case GL_PERFMON_RESULT_AVAILABLE_AMD:
*data = 1;
if (is_perf_monitor_result_available(ctx, m))
*data = 1;
else
*data = 0;
if (bytesWritten != NULL)
*bytesWritten = sizeof(GLuint);
break;