This commit is contained in:
elwrcl committed 2026-06-06 13:25:15 +03:00
1 parent 04d4dc8b09
commit 818cab85dc
12511 files changed
+6156641

No files matched your search

@@ -0,0 +1,47 @@
/*
* Copyright © 2022 Imagination Technologies Ltd.
*
* SPDX-License-Identifier: MIT
*/
#ifndef PVR_HW_UTILS_H
#define PVR_HW_UTILS_H
#include <stdint.h>
#include <assert.h>
#include "util/macros.h"
#include "pvr_device_info.h"
static inline uint32_t
pvr_get_slc_cache_line_size(const struct pvr_device_info *dev_info)
{
return PVR_GET_FEATURE_VALUE(dev_info, slc_cache_line_size_bits, 8U) / 8U;
}
static inline uint32_t pvr_get_max_user_vertex_output_components(
const struct pvr_device_info *dev_info)
{
/* Default value based on the minimum value found in all existing cores. */
const uint32_t uvs_pba_entries =
PVR_GET_FEATURE_VALUE(dev_info, uvs_pba_entries, 160U);
/* Default value based on the minimum value found in all existing cores. */
const uint32_t uvs_banks = PVR_GET_FEATURE_VALUE(dev_info, uvs_banks, 2U);
if (uvs_banks <= 8U && uvs_pba_entries == 160U) {
ASSERTED const uint32_t tpu_parallel_instances =
PVR_GET_FEATURE_VALUE(dev_info, tpu_parallel_instances, 1U);
/* Cores with > 2 ppc support vertex sizes of >= 128 dwords */
assert(tpu_parallel_instances <= 2 ||
(dev_info->ident.b <= 36 || dev_info->ident.b == 46));
return 64U;
}
return 128U;
}
#endif /* PVR_HW_UTILS_H */
@@ -0,0 +1,207 @@
/*
* Copyright © 2022 Imagination Technologies Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/* This file is based on rgxdefs.h and should only contain object-like macros.
* Any function-like macros or inline functions should instead appear in
* rogue_hw_utils.h.
*/
#ifndef ROGUE_HW_DEFS_H
#define ROGUE_HW_DEFS_H
#include <stdint.h>
#include "util/macros.h"
#define ROGUE_BIF_PM_PHYSICAL_PAGE_SHIFT 12U
#define ROGUE_BIF_PM_PHYSICAL_PAGE_SIZE \
BITFIELD_BIT(ROGUE_BIF_PM_PHYSICAL_PAGE_SHIFT)
/* ISP triangle merging constants. */
/* tan(15) (0x3E8930A3) */
#define ROGUE_ISP_MERGE_LOWER_LIMIT_NUMERATOR 0.267949f
/* tan(60) (0x3FDDB3D7) */
#define ROGUE_ISP_MERGE_UPPER_LIMIT_NUMERATOR 1.732051f
#define ROGUE_ISP_MERGE_SCALE_FACTOR 16.0f
#define ROGUE_MAX_INSTR_BYTES 32U
#define ROGUE_ICACHE_ALIGN 8U
#define ROGUE_OQUERY_ALIGN 16U
#define ROGUE_MAX_ALU_INPUTS 6U
#define ROGUE_ALU_INPUT_GROUP_SIZE (ROGUE_MAX_ALU_INPUTS / 2)
#define ROGUE_MAX_ALU_OUTPUTS 2U
#define ROGUE_MAX_ALU_INTERNAL_SOURCES 6U
/* MList entry stride in bytes */
#define ROGUE_MLIST_ENTRY_STRIDE 4U
/* VCE & TE share virtual space and Alist. */
#define ROGUE_NUM_PM_ADDRESS_SPACES 2U
/* PM Maximum addressable limit (as determined by the size field of the
* PM_*_FSTACK registers).
*/
#define ROGUE_PM_MAX_PB_VIRT_ADDR_SPACE UINT64_C(0x400000000)
/* Vheap entry size in bytes. */
#define ROGUE_PM_VHEAP_ENTRY_SIZE 4U
#define ROGUE_RTC_SIZE_IN_BYTES 256U
#define ROGUE_NUM_VCE 1U
#define ROGUE_NUM_TEAC 1U
#define ROGUE_NUM_TE 1U
/* Tail pointer size in bytes. */
#define ROGUE_TAIL_POINTER_SIZE 8U
/* Tail pointer cache line size. */
#define ROGUE_TE_TPC_CACHE_LINE_SIZE 64U
#define ROGUE_MAX_VERTEX_SHARED_REGISTERS 1024U
#define ROGUE_MAX_PIXEL_SHARED_REGISTERS 1024U
#define ROGUE_MAX_COMPUTE_SHARED_REGISTERS (2U * 1024U)
/* Number of CR_PDS_BGRND values that need setting up. */
#define ROGUE_NUM_CR_PDS_BGRND_WORDS 3U
/* Number of PBESTATE_REG_WORD values that need setting up. */
#define ROGUE_NUM_PBESTATE_REG_WORDS 3U
/* Number of PBESTATE_REG_WORD used in transfer.
* The last word is not used.
*/
#define ROGUE_NUM_PBESTATE_REG_WORDS_FOR_TRANSFER 2U
/* Number of PBESTATE_STATE_WORD values that need setting up. */
#define ROGUE_NUM_PBESTATE_STATE_WORDS 2U
/* Number of TEXSTATE_IMAGE_WORD values that need setting up. */
#define ROGUE_NUM_TEXSTATE_IMAGE_WORDS 2U
/* Number of TEXSTATE_SAMPLER state words that need setting up. */
#define ROGUE_NUM_TEXSTATE_SAMPLER_WORDS 2U
#define ROGUE_NUM_TEXSTATE_DWORDS 4U
/* 12 dwords reserved for shared register management. The first dword is the
* number of shared register blocks to reload. Should be a multiple of 4 dwords,
* size in bytes.
*/
#define ROGUE_LLS_SHARED_REGS_RESERVE_SIZE 48U
#define ROGUE_CSRM_LINE_SIZE_IN_DWORDS (64U * 4U * 4U)
/* The maximum amount of local memory which can be allocated by a single kernel
* (in dwords/32-bit registers).
*
* ROGUE_CDMCTRL_USC_COMMON_SIZE_UNIT_SIZE is in bytes so we divide by four.
*/
#define ROGUE_MAX_PER_KERNEL_LOCAL_MEM_SIZE_REGS \
((ROGUE_CDMCTRL_KERNEL0_USC_COMMON_SIZE_UNIT_SIZE * \
ROGUE_CDMCTRL_KERNEL0_USC_COMMON_SIZE_MAX_SIZE) >> \
2)
#define ROGUE_MAX_INSTANCES_PER_TASK \
(ROGUE_CDMCTRL_KERNEL8_MAX_INSTANCES_MAX_SIZE + 1U)
/* Optimal number for packing work groups into a slot. */
#define ROGUE_CDM_MAX_PACKED_WORKGROUPS_PER_TASK 8U
/* The maximum number of pixel task instances which might be running overlapped
* with compute. Once we have 8 pixel task instances we have a complete set and
* task will be able to run and allocations will be freed.
*/
#define ROGUE_MAX_OVERLAPPED_PIXEL_TASK_INSTANCES 7U
/* Size of the image state in 64-bit units. */
#define ROGUE_MAXIMUM_IMAGE_STATE_SIZE_IN_ULONGLONGS 2U
/* Size of the image state in dwords. The last 64-bit word is optional for
* non-YUV textures.
*/
#define ROGUE_MAXIMUM_IMAGE_STATE_SIZE \
(ROGUE_MAXIMUM_IMAGE_STATE_SIZE_IN_ULONGLONGS * \
(sizeof(uint64_t) / sizeof(uint32_t)))
#define PVR_NUM_PBE_EMIT_REGS 8U
#define ROGUE_USRM_GRANULARITY_IN_REGISTERS 4U
#define ROGUE_RESERVED_USRM_LINES 2U
#define ROGUE_USC_NUM_UNIFIED_STORE_BANKS 8U
#define ROGUE_PDS_US_REGISTER_ALLOCATION_GRANULARITY 8U
#define ROGUE_PDS_US_TEMP_ALLOCATION_GRANULARITY \
ROGUE_PDS_US_REGISTER_ALLOCATION_GRANULARITY
#define ROGUE_USRM_LINE_SIZE 16U
#define ROGUE_USRM_LINE_SIZE_PER_INSTANCE \
(ROGUE_PDS_US_TEMP_ALLOCATION_GRANULARITY * ROGUE_USRM_LINE_SIZE)
enum {
ROGUE_USC_COEFFICIENT_SET_A = 0,
ROGUE_USC_COEFFICIENT_SET_B,
ROGUE_USC_COEFFICIENT_SET_C,
ROGUE_USC_COEFFICIENT_SET_PAD,
ROGUE_USC_COEFFICIENT_SET_SIZE,
};
enum {
ROGUE_SMP_COEFF_UFRAC = 0,
ROGUE_SMP_COEFF_VFRAC,
ROGUE_SMP_COEFF_SFRAC,
ROGUE_SMP_COEFF_LOD_DVAL_POST_CLAMP,
ROGUE_SMP_COEFF_LOD_DVAL_PRE_CLAMP,
ROGUE_SMP_COEFF_TFRAC_POST_CLAMP,
ROGUE_SMP_COEFF_TFRAC_PRE_CLAMP,
ROGUE_SMP_COEFF_COUNT,
};
#define ROGUE_SMP_MAX_DATA_WORDS 18U
#define ROGUE_SMP_LOOKUP_MS_NUM_START 16U
#define ROGUE_SMP_LOOKUP_MS_NUM_BITS 3U
#define ROGUE_SMP_LOOKUP_W_OFF_START 12U
#define ROGUE_SMP_LOOKUP_W_OFF_BITS 4U
#define ROGUE_SMP_LOOKUP_V_OFF_START 6U
#define ROGUE_SMP_LOOKUP_V_OFF_BITS 6U
#define ROGUE_SMP_LOOKUP_U_OFF_START 0U
#define ROGUE_SMP_LOOKUP_U_OFF_BITS 6U
#define ROGUE_REG_SIZE_BYTES 4U
#endif /* ROGUE_HW_DEFS_H */
@@ -0,0 +1,517 @@
/*
* Copyright © 2022 Imagination Technologies Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/* This file is based on rgxdefs.h and should only contain function-like macros
* and inline functions. Any object-like macros should instead appear in
* rogue_hw_defs.h.
*/
#ifndef ROGUE_HW_UTILS_H
#define ROGUE_HW_UTILS_H
#include <stdint.h>
#include "pvr_types.h"
#define __pvr_address_type pvr_dev_addr_t
#define __pvr_get_address(pvr_dev_addr) (pvr_dev_addr).addr
/* clang-format off */
#define __pvr_make_address(addr_u64) PVR_DEV_ADDR(addr_u64)
/* clang-format on */
#include "csbgen/rogue/cdm.h"
#include "csbgen/rogue/lls.h"
#undef __pvr_make_address
#undef __pvr_get_address
#undef __pvr_address_type
#include "rogue_hw_defs.h"
#include "pvr_device_info.h"
#include "util/compiler.h"
#include "util/macros.h"
#include "pvr_hw_utils.h"
static inline void
rogue_get_isp_samples_per_tile_xy(const struct pvr_device_info *dev_info,
uint32_t samples,
uint32_t *const x_out,
uint32_t *const y_out)
{
const uint32_t tile_size_x =
PVR_GET_FEATURE_VALUE(dev_info, tile_size_x, 0U);
const uint32_t tile_size_y =
PVR_GET_FEATURE_VALUE(dev_info, tile_size_y, 0U);
const uint32_t samples_per_pixel =
PVR_GET_FEATURE_VALUE(dev_info, isp_samples_per_pixel, 0U);
#if !defined(NDEBUG)
switch (samples_per_pixel) {
case 1:
case 2:
case 4:
break;
default:
assert(!"Unsupported ISP samples per pixel");
}
#endif
*x_out = tile_size_x;
*y_out = tile_size_y;
switch (samples) {
case 1:
break;
case 2:
if (samples_per_pixel == 2 || samples_per_pixel == 4)
*y_out *= 2;
break;
case 4:
if (samples_per_pixel == 2 || samples_per_pixel == 4)
*x_out *= 2;
if (samples_per_pixel == 4)
*y_out *= 2;
break;
case 8:
if (samples_per_pixel == 2)
*y_out *= 2;
break;
default:
assert(!"Unsupported number of samples");
}
}
static void rogue_get_isp_scale_xy_from_samples(const uint32_t samples,
uint32_t *const x_scale_out,
uint32_t *const y_scale_out)
{
switch (samples) {
case 1:
*x_scale_out = 1;
*y_scale_out = 1;
break;
case 2:
*x_scale_out = 1;
*y_scale_out = 2;
break;
case 4:
*x_scale_out = 2;
*y_scale_out = 2;
break;
case 8:
*x_scale_out = 2;
*y_scale_out = 4;
break;
default:
UNREACHABLE("Unsupported number of samples");
}
}
static inline void
rogue_get_isp_num_tiles_xy(const struct pvr_device_info *dev_info,
uint32_t samples,
uint32_t width,
uint32_t height,
uint32_t *const x_out,
uint32_t *const y_out)
{
uint32_t tile_samples_x;
uint32_t tile_samples_y;
uint32_t scale_x;
uint32_t scale_y;
rogue_get_isp_samples_per_tile_xy(dev_info,
samples,
&tile_samples_x,
&tile_samples_y);
rogue_get_isp_scale_xy_from_samples(samples, &scale_x, &scale_y);
*x_out = DIV_ROUND_UP(width * scale_x, tile_samples_x);
*y_out = DIV_ROUND_UP(height * scale_y, tile_samples_y);
if (PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format)) {
assert(PVR_GET_FEATURE_VALUE(dev_info,
simple_parameter_format_version,
0U) == 2U);
/* Align to a 2x2 tile block. */
*x_out = ALIGN_POT(*x_out, 2);
*y_out = ALIGN_POT(*y_out, 2);
}
}
static inline void
rogue_get_zls_tile_size_xy(const struct pvr_device_info *dev_info,
uint32_t *const x_out,
uint32_t *const y_out)
{
uint32_t version = 0;
bool has_version;
has_version =
!PVR_FEATURE_VALUE(dev_info, simple_parameter_format_version, &version);
*x_out = PVR_GET_FEATURE_VALUE(dev_info, tile_size_x, 0U);
*y_out = PVR_GET_FEATURE_VALUE(dev_info, tile_size_y, 0U);
if (PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format) &&
has_version && version == 2) {
*x_out *= 2;
*y_out *= 2;
}
}
static inline uint32_t
rogue_get_max_output_regs_per_pixel(const struct pvr_device_info *dev_info)
{
if (PVR_HAS_FEATURE(dev_info, eight_output_registers))
return 8U;
return 4U;
}
static inline void
rogue_get_num_macrotiles_xy(const struct pvr_device_info *dev_info,
uint32_t *const x_out,
uint32_t *const y_out)
{
uint32_t version;
if (PVR_FEATURE_VALUE(dev_info, simple_parameter_format_version, &version))
version = 0;
if (!PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format) ||
version == 2) {
*x_out = 4;
*y_out = 4;
} else {
*x_out = 1;
*y_out = 1;
}
}
static inline uint32_t
rogue_get_macrotile_array_size(const struct pvr_device_info *dev_info)
{
uint32_t num_macrotiles_x;
uint32_t num_macrotiles_y;
if (PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format))
return 0;
rogue_get_num_macrotiles_xy(dev_info, &num_macrotiles_x, &num_macrotiles_y);
return num_macrotiles_x * num_macrotiles_y * 8U;
}
/* Region header size in bytes. */
static inline uint32_t
rogue_get_region_header_size(const struct pvr_device_info *dev_info)
{
uint32_t version;
if (PVR_FEATURE_VALUE(dev_info, simple_parameter_format_version, &version))
version = 0;
if (PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format) &&
version == 2) {
return 6;
}
return 5;
}
static inline uint32_t
rogue_get_render_size_max(const struct pvr_device_info *dev_info)
{
if (PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format))
if (!PVR_HAS_FEATURE(dev_info, screen_size8K))
return 4096U;
return 8192U;
}
#define rogue_get_render_size_max_x(dev_info) \
rogue_get_render_size_max(dev_info)
#define rogue_get_render_size_max_y(dev_info) \
rogue_get_render_size_max(dev_info)
static inline uint32_t
rogue_get_render_size_max_z(const struct pvr_device_info *dev_info)
{
switch (dev_info->ident.arch) {
case PVR_DEVICE_ARCH_ROGUE:
return 2048;
default:
UNREACHABLE("unexpected arch");
}
}
static inline uint32_t
rogue_get_texture_extent_max(const struct pvr_device_info *dev_info)
{
switch (dev_info->ident.arch) {
case PVR_DEVICE_ARCH_ROGUE:
return 16384;
default:
UNREACHABLE("unexpected arch");
}
}
static inline uint32_t
rogue_max_compute_shared_registers(const struct pvr_device_info *dev_info)
{
if (PVR_HAS_FEATURE(dev_info, compute))
return 1024U;
return 0U;
}
static inline uint32_t
rogue_get_max_num_cores(const struct pvr_device_info *dev_info)
{
if (PVR_HAS_FEATURE(dev_info, gpu_multicore_support) &&
PVR_HAS_FEATURE(dev_info, xpu_max_slaves)) {
return PVR_GET_FEATURE_VALUE(dev_info, xpu_max_slaves, 0U) + 1U;
}
return 1U;
}
static inline uint32_t
rogue_get_cdm_context_resume_buffer_size(const struct pvr_device_info *dev_info)
{
if (PVR_HAS_FEATURE(dev_info, gpu_multicore_support)) {
const uint32_t max_num_cores = rogue_get_max_num_cores(dev_info);
const uint32_t cache_line_size = pvr_get_slc_cache_line_size(dev_info);
const uint32_t cdm_context_resume_buffer_stride =
ALIGN_POT(ROGUE_LLS_CDM_CONTEXT_RESUME_BUFFER_SIZE, cache_line_size);
/*
* TODO: Optimise buffer size based on the core_count,
* not max_num_cores
*/
return cdm_context_resume_buffer_stride * max_num_cores;
}
return ROGUE_LLS_CDM_CONTEXT_RESUME_BUFFER_SIZE;
}
static inline uint32_t rogue_get_cdm_context_resume_buffer_alignment(
const struct pvr_device_info *dev_info)
{
if (PVR_HAS_FEATURE(dev_info, gpu_multicore_support))
return pvr_get_slc_cache_line_size(dev_info);
return ROGUE_LLS_CDM_CONTEXT_RESUME_BUFFER_ALIGNMENT;
}
static inline uint32_t
rogue_get_compute_max_work_group_size(const struct pvr_device_info *dev_info)
{
/* The number of tasks which can be executed per USC - Limited to 16U by the
* CDM.
*/
const uint32_t max_tasks_per_usc = 16U;
if (!PVR_HAS_ENHANCEMENT(dev_info, 35421)) {
/* Barriers on work-groups > 32 instances aren't supported. */
return ROGUE_MAX_INSTANCES_PER_TASK;
}
return ROGUE_MAX_INSTANCES_PER_TASK * max_tasks_per_usc;
}
/* Don't use this directly. Use the x and y define macros. */
static inline uint32_t
__rogue_get_param_vf_max(const struct pvr_device_info *dev_info)
{
return (rogue_get_render_size_max(dev_info) * 3 / 2) - 1;
}
#define rogue_get_param_vf_max_x(dev_info) __rogue_get_param_vf_max(dev_info)
#define rogue_get_param_vf_max_y(dev_info) __rogue_get_param_vf_max(dev_info)
static inline uint32_t
rogue_get_max_total_instances(const struct pvr_device_info *dev_info)
{
const uint32_t usc_slots = PVR_GET_FEATURE_VALUE(dev_info, usc_slots, 0U);
assert(usc_slots);
return usc_slots * ROGUE_MAX_INSTANCES_PER_TASK;
}
static inline uint32_t rogue_get_unified_store_size_per_instance(
const struct pvr_device_info *dev_info)
{
const uint32_t unified_store_depth =
PVR_GET_FEATURE_VALUE(dev_info, unified_store_depth, 0U);
assert(unified_store_depth);
return unified_store_depth * ROGUE_USC_NUM_UNIFIED_STORE_BANKS;
}
static inline uint32_t
rogue_get_min_attr_in_usrm_lines(const struct pvr_device_info *dev_info)
{
const uint32_t unified_store_size_per_instance =
rogue_get_unified_store_size_per_instance(dev_info);
assert(unified_store_size_per_instance);
return (unified_store_size_per_instance /
ROGUE_USRM_LINE_SIZE_PER_INSTANCE) -
ROGUE_RESERVED_USRM_LINES;
}
static inline uint32_t
rogue_get_parallel_instances(const struct pvr_device_info *dev_info)
{
return ROGUE_MAX_INSTANCES_PER_TASK / 2;
}
static inline uint32_t rogue_get_unified_store_temps_per_instance(
const struct pvr_device_info *dev_info)
{
return rogue_get_min_attr_in_usrm_lines(dev_info) *
ROGUE_USRM_LINE_SIZE_PER_INSTANCE;
}
static inline uint32_t
rogue_get_unified_store_total_temps(const struct pvr_device_info *dev_info)
{
return rogue_get_unified_store_temps_per_instance(dev_info) *
rogue_get_parallel_instances(dev_info);
}
static inline uint32_t
rogue_get_instance_groups_per_slot(const struct pvr_device_info *dev_info)
{
return ROGUE_MAX_INSTANCES_PER_TASK / rogue_get_parallel_instances(dev_info);
}
static inline uint32_t
rogue_get_optimal_temps(const struct pvr_device_info *dev_info)
{
const uint32_t usc_slots = PVR_GET_FEATURE_VALUE(dev_info, usc_slots, 0U);
assert(usc_slots);
uint32_t max_temps_full_slot_use =
rogue_get_unified_store_temps_per_instance(dev_info) /
(rogue_get_instance_groups_per_slot(dev_info) * usc_slots);
max_temps_full_slot_use &= ~(ROGUE_PDS_US_TEMP_ALLOCATION_GRANULARITY - 1);
return MAX2(max_temps_full_slot_use, 24U);
}
static inline uint32_t rogue_get_temps(const struct pvr_device_info *dev_info)
{
uint32_t temps = rogue_get_unified_store_temps_per_instance(dev_info) / 2;
return MIN2(temps, 248U);
}
static inline uint32_t
rogue_max_wg_temps(const struct pvr_device_info *dev_info,
unsigned temps,
unsigned wg_size,
bool has_barrier)
{
assert(wg_size <= rogue_get_max_total_instances(dev_info));
if (!wg_size)
wg_size = rogue_get_compute_max_work_group_size(dev_info);
if (wg_size > ROGUE_MAX_INSTANCES_PER_TASK && has_barrier) {
/* Number of slots allocated for each workgroup. */
unsigned slots_per_wg =
DIV_ROUND_UP(wg_size, ROGUE_MAX_INSTANCES_PER_TASK);
/* Lines of USRM lines available for each slot
* (+1 for fragmentation / coarse checking).
*/
unsigned lines_per_slot =
rogue_get_min_attr_in_usrm_lines(dev_info) / (slots_per_wg + 1);
unsigned max_allocs;
if (lines_per_slot != 0) {
/* Convert lines to USRM allocs. */
max_allocs = lines_per_slot * ROGUE_USRM_LINE_SIZE;
} else {
max_allocs = (rogue_get_min_attr_in_usrm_lines(dev_info) *
ROGUE_USRM_LINE_SIZE) /
(slots_per_wg + 1);
}
/* Convert USRM allocs to temporary registers. */
unsigned max_temps_for_barrier =
max_allocs * ROGUE_USRM_GRANULARITY_IN_REGISTERS;
/* Clamp to provided limit */
temps = MIN2(temps, max_temps_for_barrier);
}
return temps;
}
static inline uint32_t rogue_get_vtxins(void)
{
/* TODO: use highest safe number of vertex input registers. */
return 12;
}
static inline uint32_t
rogue_num_uscs_per_tile(const struct pvr_device_info *dev_info)
{
if (PVR_HAS_FEATURE(dev_info, tile_per_usc) ||
PVR_HAS_FEATURE(dev_info, pbe2_in_xe))
return 1;
return 4;
}
static inline uint32_t rogue_usc_indexed_pixel_output_index_scale(
const struct pvr_device_info *dev_info)
{
if (PVR_HAS_FEATURE(dev_info, tile_per_usc))
return 4;
return 1;
}
static inline uint32_t
rogue_get_total_instance_count(const struct pvr_device_info *dev_info)
{
/* Number of instances calculated as such:
* USC_SLOTS * INSTANCES_PER_SLOT * MAX_NUM_CORES * NUM_CLUSTERS
*/
/* TODO: Optimise tile buffer size to use core_count, not max_num_cores. */
return rogue_get_max_total_instances(dev_info) *
rogue_get_max_num_cores(dev_info) *
PVR_GET_FEATURE_VALUE(dev_info, num_clusters, 1);
}
#endif /* ROGUE_HW_UTILS_H */
+39
View File
@@ -0,0 +1,39 @@
/*
* Copyright © 2022 Imagination Technologies Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/* This file is based on rgx_fwif_shared.h and rgx_fwif_client.h. It contains
* information about the firmware that is needed by the driver.
*/
#ifndef PVR_ROGUE_FW_H
#define PVR_ROGUE_FW_H
/* FIXME: This will change based on the firmware configuration, which will vary
* depending on the BVNC and firmware version. The powervr KM driver allows this
* information to be queried, but the pvrsrvkm KM driver doesn't. This
* information should really be queried from the winsys.
*/
/* Indicates the number of Render Target Datas in a Render Target Dataset. */
#define ROGUE_NUM_RTDATAS 2U
#endif /* PVR_ROGUE_FW_H */
+58
View File
@@ -0,0 +1,58 @@
/*
* Copyright © 2022 Imagination Technologies Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef PVR_TYPES_H
#define PVR_TYPES_H
#include <inttypes.h>
#include <stdint.h>
/**
* \brief Convert dwords to bytes.
*
* Throughout the code base we keep sizes in dwords (e.g. code_size and
* data_size returned by the pds api) and in some cases we need to convert those
* to be in bytes.
*
* This macro makes the conversion more obvious.
*/
/* clang-format off */
#define PVR_DW_TO_BYTES(_value) ((_value) * 4)
/* clang-format on */
/*****************************************************************************
Device virtual addresses
*****************************************************************************/
typedef struct pvr_dev_addr {
uint64_t addr;
} pvr_dev_addr_t;
#define PVR_DEV_ADDR(addr_) ((pvr_dev_addr_t){ .addr = (addr_) })
#define PVR_DEV_ADDR_OFFSET(base, offset) PVR_DEV_ADDR((base).addr + (offset))
#define PVR_DEV_ADDR_INVALID PVR_DEV_ADDR(0)
/* All currently supported devices use a 40-bit virtual address space. */
#define PVR_DEV_ADDR_FMT "0x%010" PRIx64
#endif /* PVR_TYPES_H */