1*61046927SAndroid Build Coastguard Worker/* 2*61046927SAndroid Build Coastguard Worker * Copyright 2024 Alyssa Rosenzweig 3*61046927SAndroid Build Coastguard Worker * Copyright 2024 Valve Corporation 4*61046927SAndroid Build Coastguard Worker * Copyright 2022 Collabora Ltd. and Red Hat Inc. 5*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT 6*61046927SAndroid Build Coastguard Worker */ 7*61046927SAndroid Build Coastguard Worker#include "libagx.h" 8*61046927SAndroid Build Coastguard Worker#include "query.h" 9*61046927SAndroid Build Coastguard Worker 10*61046927SAndroid Build Coastguard Workerstatic inline void 11*61046927SAndroid Build Coastguard Workerwrite_query_result(uintptr_t dst_addr, int32_t idx, bool is_64, uint64_t result) 12*61046927SAndroid Build Coastguard Worker{ 13*61046927SAndroid Build Coastguard Worker /* TODO: do we want real 64-bit stats? sync with CPU impl */ 14*61046927SAndroid Build Coastguard Worker result &= 0xffffffff; 15*61046927SAndroid Build Coastguard Worker 16*61046927SAndroid Build Coastguard Worker if (is_64) { 17*61046927SAndroid Build Coastguard Worker global uint64_t *out = (global uint64_t *)dst_addr; 18*61046927SAndroid Build Coastguard Worker out[idx] = result; 19*61046927SAndroid Build Coastguard Worker } else { 20*61046927SAndroid Build Coastguard Worker global uint32_t *out = (global uint32_t *)dst_addr; 21*61046927SAndroid Build Coastguard Worker out[idx] = result; 22*61046927SAndroid Build Coastguard Worker } 23*61046927SAndroid Build Coastguard Worker} 24*61046927SAndroid Build Coastguard Worker 25*61046927SAndroid Build Coastguard Workervoid 26*61046927SAndroid Build Coastguard Workerlibagx_copy_query(constant struct libagx_copy_query_push *push, unsigned i) 27*61046927SAndroid Build Coastguard Worker{ 28*61046927SAndroid Build Coastguard Worker uint64_t dst = push->dst_addr + (((uint64_t)i) * push->dst_stride); 29*61046927SAndroid Build Coastguard Worker uint32_t query = push->first_query + i; 30*61046927SAndroid Build Coastguard Worker bool available = push->availability[query]; 31*61046927SAndroid Build Coastguard Worker 32*61046927SAndroid Build Coastguard Worker if (available || push->partial) { 33*61046927SAndroid Build Coastguard Worker /* For occlusion queries, results[] points to the device global heap. We 34*61046927SAndroid Build Coastguard Worker * need to remap indices according to the query pool's allocation. 35*61046927SAndroid Build Coastguard Worker */ 36*61046927SAndroid Build Coastguard Worker uint result_index = push->oq_index ? push->oq_index[query] : query; 37*61046927SAndroid Build Coastguard Worker uint idx = result_index * push->reports_per_query; 38*61046927SAndroid Build Coastguard Worker 39*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < push->reports_per_query; ++i) { 40*61046927SAndroid Build Coastguard Worker write_query_result(dst, i, push->_64, push->results[idx + i]); 41*61046927SAndroid Build Coastguard Worker } 42*61046927SAndroid Build Coastguard Worker } 43*61046927SAndroid Build Coastguard Worker 44*61046927SAndroid Build Coastguard Worker if (push->with_availability) { 45*61046927SAndroid Build Coastguard Worker write_query_result(dst, push->reports_per_query, push->_64, available); 46*61046927SAndroid Build Coastguard Worker } 47*61046927SAndroid Build Coastguard Worker} 48*61046927SAndroid Build Coastguard Worker 49*61046927SAndroid Build Coastguard Workervoid 50*61046927SAndroid Build Coastguard Workerlibagx_copy_xfb_counters(constant struct libagx_xfb_counter_copy *push) 51*61046927SAndroid Build Coastguard Worker{ 52*61046927SAndroid Build Coastguard Worker unsigned i = get_local_id(0); 53*61046927SAndroid Build Coastguard Worker 54*61046927SAndroid Build Coastguard Worker *(push->dest[i]) = push->src[i] ? *(push->src[i]) : 0; 55*61046927SAndroid Build Coastguard Worker} 56*61046927SAndroid Build Coastguard Worker 57*61046927SAndroid Build Coastguard Workervoid 58*61046927SAndroid Build Coastguard Workerlibagx_increment_statistic(constant struct libagx_increment_params *p) 59*61046927SAndroid Build Coastguard Worker{ 60*61046927SAndroid Build Coastguard Worker *(p->statistic) += p->delta; 61*61046927SAndroid Build Coastguard Worker} 62*61046927SAndroid Build Coastguard Worker 63*61046927SAndroid Build Coastguard Workervoid 64*61046927SAndroid Build Coastguard Workerlibagx_increment_cs_invocations(constant struct libagx_cs_invocation_params *p) 65*61046927SAndroid Build Coastguard Worker{ 66*61046927SAndroid Build Coastguard Worker *(p->statistic) += libagx_cs_invocations(p->local_size_threads, p->grid[0], 67*61046927SAndroid Build Coastguard Worker p->grid[1], p->grid[2]); 68*61046927SAndroid Build Coastguard Worker} 69*61046927SAndroid Build Coastguard Worker 70*61046927SAndroid Build Coastguard Workerkernel void 71*61046927SAndroid Build Coastguard Workerlibagx_increment_ia_counters(constant struct libagx_increment_ia_counters *p, 72*61046927SAndroid Build Coastguard Worker uint index_size_B, uint tid) 73*61046927SAndroid Build Coastguard Worker{ 74*61046927SAndroid Build Coastguard Worker unsigned count = p->draw[0]; 75*61046927SAndroid Build Coastguard Worker local uint scratch; 76*61046927SAndroid Build Coastguard Worker 77*61046927SAndroid Build Coastguard Worker if (index_size_B /* implies primitive restart */) { 78*61046927SAndroid Build Coastguard Worker uint start = p->draw[2]; 79*61046927SAndroid Build Coastguard Worker uint partial = 0; 80*61046927SAndroid Build Coastguard Worker 81*61046927SAndroid Build Coastguard Worker /* Count non-restart indices */ 82*61046927SAndroid Build Coastguard Worker for (uint i = tid; i < count; i += 1024) { 83*61046927SAndroid Build Coastguard Worker uint index = libagx_load_index_buffer_internal( 84*61046927SAndroid Build Coastguard Worker p->index_buffer, p->index_buffer_range_el, start + i, index_size_B); 85*61046927SAndroid Build Coastguard Worker 86*61046927SAndroid Build Coastguard Worker if (index != p->restart_index) 87*61046927SAndroid Build Coastguard Worker partial++; 88*61046927SAndroid Build Coastguard Worker } 89*61046927SAndroid Build Coastguard Worker 90*61046927SAndroid Build Coastguard Worker /* Accumulate the partials across the workgroup */ 91*61046927SAndroid Build Coastguard Worker scratch = 0; 92*61046927SAndroid Build Coastguard Worker barrier(CLK_LOCAL_MEM_FENCE); 93*61046927SAndroid Build Coastguard Worker atomic_add(&scratch, partial); 94*61046927SAndroid Build Coastguard Worker barrier(CLK_LOCAL_MEM_FENCE); 95*61046927SAndroid Build Coastguard Worker count = scratch; 96*61046927SAndroid Build Coastguard Worker 97*61046927SAndroid Build Coastguard Worker /* Elect a single thread from the workgroup to increment the counters */ 98*61046927SAndroid Build Coastguard Worker if (tid != 0) 99*61046927SAndroid Build Coastguard Worker return; 100*61046927SAndroid Build Coastguard Worker } 101*61046927SAndroid Build Coastguard Worker 102*61046927SAndroid Build Coastguard Worker count *= p->draw[1]; 103*61046927SAndroid Build Coastguard Worker 104*61046927SAndroid Build Coastguard Worker if (p->ia_vertices) { 105*61046927SAndroid Build Coastguard Worker *(p->ia_vertices) += count; 106*61046927SAndroid Build Coastguard Worker } 107*61046927SAndroid Build Coastguard Worker 108*61046927SAndroid Build Coastguard Worker if (p->vs_invocations) { 109*61046927SAndroid Build Coastguard Worker *(p->vs_invocations) += count; 110*61046927SAndroid Build Coastguard Worker } 111*61046927SAndroid Build Coastguard Worker} 112