mesa/src/intel/dev/intel_device_info.h
Kenneth Graunke 9531c6b89e brw: Make indirect_ubos_use_sampler a static inline bool taking devinfo
Having the named field allowed us to indicate that our code conditions
are referring to the specific decision about how we handle indirect
UBOs, rather than some other arbitrary hardware change.

Still, there's no need to store this in a singleton struct - we can
easily have a static inline bool that does the devinfo check for us.

Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com>
Reviewed-by: Caio Oliveira <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39839>
2026-02-16 21:33:42 +00:00

233 lines
8.3 KiB
C

/*
* Copyright © 2013 Intel Corporation
*
* 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 INTEL_DEVICE_INFO_H
#define INTEL_DEVICE_INFO_H
#include <stdbool.h>
#include <stdint.h>
#include "util/bitset.h"
#include "util/macros.h"
#include "compiler/shader_enums.h"
#include "intel_kmd.h"
#include "intel/dev/intel_wa.h"
#include "intel/dev/intel_device_info_gen.h"
#ifdef __cplusplus
extern "C" {
#endif
#define intel_platform_in_range(platform, platform_range) \
(((platform) >= INTEL_PLATFORM_ ## platform_range ## _START) && \
((platform) <= INTEL_PLATFORM_ ## platform_range ## _END))
#define intel_device_info_is_atsm(devinfo) \
intel_platform_in_range((devinfo)->platform, ATSM)
#define intel_device_info_is_dg2(devinfo) \
(intel_platform_in_range((devinfo)->platform, DG2) || \
intel_platform_in_range((devinfo)->platform, ATSM))
#define intel_device_info_is_mtl(devinfo) \
intel_platform_in_range((devinfo)->platform, MTL)
#define intel_device_info_is_arl(devinfo) \
intel_platform_in_range((devinfo)->platform, ARL)
#define intel_device_info_is_mtl_or_arl(devinfo) \
(intel_device_info_is_mtl(devinfo) || intel_device_info_is_arl(devinfo))
#define PAT_ENTRY(index_, mmap_) \
{ \
.index = index_, \
.mmap = INTEL_DEVICE_INFO_MMAP_MODE_##mmap_ \
}
#ifdef GFX_VER
#define intel_device_info_is_9lp(devinfo) \
(GFX_VER == 9 && ((devinfo)->platform == INTEL_PLATFORM_BXT || \
(devinfo)->platform == INTEL_PLATFORM_GLK))
#else
#define intel_device_info_is_9lp(devinfo) \
((devinfo)->platform == INTEL_PLATFORM_BXT || \
(devinfo)->platform == INTEL_PLATFORM_GLK)
#endif
#define GFX_IP_VER(major, minor) ((major << 16) | minor)
#define BMG_G31_IP_VER GFX_IP_VER(20, 2)
#define intel_device_info_is_bmg_g31(devinfo) (devinfo->gfx_ip_ver == BMG_G31_IP_VER)
static inline bool
intel_device_info_slice_available(const struct intel_device_info *devinfo,
int slice)
{
assert(slice < INTEL_DEVICE_MAX_SLICES);
return (devinfo->slice_masks & (1U << slice)) != 0;
}
static inline bool
intel_device_info_subslice_available(const struct intel_device_info *devinfo,
int slice, int subslice)
{
return (devinfo->subslice_masks[slice * devinfo->subslice_slice_stride +
subslice / 8] & (1U << (subslice % 8))) != 0;
}
static inline bool
intel_device_info_eu_available(const struct intel_device_info *devinfo,
int slice, int subslice, int eu)
{
unsigned subslice_offset = slice * devinfo->eu_slice_stride +
subslice * devinfo->eu_subslice_stride;
return (devinfo->eu_masks[subslice_offset + eu / 8] & (1U << eu % 8)) != 0;
}
static inline uint32_t
intel_device_info_subslice_total(const struct intel_device_info *devinfo)
{
uint32_t total = 0;
for (size_t i = 0; i < ARRAY_SIZE(devinfo->subslice_masks); i++) {
total += __builtin_popcount(devinfo->subslice_masks[i]);
}
return total;
}
static inline uint32_t
intel_device_info_eu_total(const struct intel_device_info *devinfo)
{
uint32_t total = 0;
for (size_t i = 0; i < ARRAY_SIZE(devinfo->eu_masks); i++)
total += __builtin_popcount(devinfo->eu_masks[i]);
return total;
}
/**
* Computes the bound of dualsubslice ID that can be used on this device.
*
* You should use this number if you're going to make calculation based on the
* slice/dualsubslice ID provided by the SR0.0 EU register. The maximum
* dualsubslice ID can be superior to the total number of dualsubslices on the
* device, depending on fusing.
*
* On a 16 dualsubslice GPU, the maximum dualsubslice ID is 15. This function
* would return the exclusive bound : 16.
*/
static inline unsigned
intel_device_info_dual_subslice_id_bound(const struct intel_device_info *devinfo)
{
/* Start from the last slice/subslice so we find the answer faster. */
for (int s = devinfo->max_slices - 1; s >= 0; s--) {
for (int ss = devinfo->max_subslices_per_slice - 1; ss >= 0; ss--) {
if (intel_device_info_subslice_available(devinfo, s, ss))
return s * devinfo->max_subslices_per_slice + ss + 1;
}
}
UNREACHABLE("Invalid topology");
return 0;
}
int intel_device_name_to_pci_device_id(const char *name);
static inline uint64_t
intel_device_info_timebase_scale(const struct intel_device_info *devinfo,
uint64_t gpu_timestamp)
{
/* Try to avoid going over the 64bits when doing the scaling */
uint64_t upper_ts = gpu_timestamp >> 32;
uint64_t lower_ts = gpu_timestamp & 0xffffffff;
uint64_t upper_scaled_ts = upper_ts * 1000000000ull / devinfo->timestamp_frequency;
uint64_t lower_scaled_ts = lower_ts * 1000000000ull / devinfo->timestamp_frequency;
return (upper_scaled_ts << 32) + lower_scaled_ts;
}
static inline bool
intel_vram_all_mappable(const struct intel_device_info *devinfo)
{
return devinfo->mem.vram.unmappable.size == 0;
}
bool intel_get_device_info_from_fd(int fh, struct intel_device_info *devinfo, int min_ver, int max_ver);
bool intel_get_device_info_from_pci_id(int pci_id,
struct intel_device_info *devinfo);
bool intel_get_device_info_for_build(int pci_id,
struct intel_device_info *devinfo);
/* Only updates intel_device_info::regions::...::free fields. The
* class/instance/size should remain the same over time.
*/
bool intel_device_info_update_memory_info(struct intel_device_info *devinfo,
int fd);
void intel_device_info_topology_reset_masks(struct intel_device_info *devinfo);
void intel_device_info_topology_update_counts(struct intel_device_info *devinfo);
void intel_device_info_update_pixel_pipes(struct intel_device_info *devinfo, uint8_t *subslice_masks);
void intel_device_info_update_l3_banks(struct intel_device_info *devinfo);
uint32_t intel_device_info_get_eu_count_first_subslice(const struct intel_device_info *devinfo);
void intel_device_info_update_cs_workgroup_threads(struct intel_device_info *devinfo);
bool intel_device_info_compute_system_memory(struct intel_device_info *devinfo, bool update);
#ifdef GFX_VERx10
#define intel_needs_workaround(devinfo, id) \
(INTEL_WA_ ## id ## _GFX_VER && \
BITSET_TEST(devinfo->workarounds, INTEL_WA_##id))
#else
#define intel_needs_workaround(devinfo, id) \
BITSET_TEST(devinfo->workarounds, INTEL_WA_##id)
#endif
enum intel_wa_steppings intel_device_info_wa_stepping(struct intel_device_info *devinfo);
uint32_t intel_device_info_get_max_slm_size(const struct intel_device_info *devinfo);
uint32_t intel_device_info_get_max_preferred_slm_size(const struct intel_device_info *devinfo);
/**
* Whether indirect UBO loads should use the sampler or go through the
* data/constant cache. For the sampler, UBO surface states have to be set
* up with VK_FORMAT_R32G32B32A32_FLOAT whereas if it's going through the
* constant or data cache, UBOs must use VK_FORMAT_RAW.
*/
static inline bool
intel_indirect_ubos_use_sampler(const struct intel_device_info *devinfo)
{
return devinfo->ver < 12;
}
#ifdef __cplusplus
}
#endif
#endif /* INTEL_DEVICE_INFO_H */