mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-19 07:08:05 +02:00
Reported by clang tools. See: https://clangd.llvm.org/guides/include-cleaner struct ac_cmdbuf had to be moved to ac_cmdbuf_base.h because we can't include ac_cmdbuf.h->sid.h->amdgfxregs.h in radeon_winsys.h for r300. Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Reviewed-by: Timur Kristóf <timur.kristof@gmail.com> Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41091>
108 lines
3.9 KiB
C
108 lines
3.9 KiB
C
/*
|
|
* Copyright 2012 Advanced Micro Devices, Inc.
|
|
* Copyright 2026 Valve Corporation
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#include "amd_family.h"
|
|
|
|
#include "ac_gpu_info.h"
|
|
#include "ac_guardband.h"
|
|
#include "util/macros.h"
|
|
|
|
void
|
|
ac_compute_guardband(const struct radeon_info *info, int minx, int miny,
|
|
int maxx, int maxy, enum ac_quant_mode quant_mode,
|
|
float clip_discard_distance, struct ac_guardband *guardband)
|
|
{
|
|
float left, top, right, bottom, max_range, guardband_x, guardband_y;
|
|
float scale[2], translate[2];
|
|
|
|
/* Determine the optimal hardware screen offset to center the viewport
|
|
* within the viewport range in order to maximize the guardband size.
|
|
*/
|
|
int hw_screen_offset_x = (maxx + minx) / 2;
|
|
int hw_screen_offset_y = (maxy + miny) / 2;
|
|
|
|
/* GFX6-GFX7 need to align the offset to an ubertile consisting of all SEs. */
|
|
const unsigned hw_screen_offset_alignment =
|
|
info->gfx_level >= GFX11 ? 32 :
|
|
info->gfx_level >= GFX8 ? 16 : MAX2(info->se_tile_repeat, 16);
|
|
const unsigned max_hw_screen_offset = info->gfx_level >= GFX12 ? 32768 : 8176;
|
|
|
|
/* Indexed by quantization modes */
|
|
static int max_viewport_size[] = {65536, 16384, 4096};
|
|
|
|
/* Ensure that the whole viewport stays representable in absolute
|
|
* coordinates.
|
|
*/
|
|
assert(maxx <= max_viewport_size[quant_mode] &&
|
|
maxy <= max_viewport_size[quant_mode]);
|
|
|
|
hw_screen_offset_x = CLAMP(hw_screen_offset_x, 0, max_hw_screen_offset);
|
|
hw_screen_offset_y = CLAMP(hw_screen_offset_y, 0, max_hw_screen_offset);
|
|
|
|
/* Align the screen offset by dropping the low bits. */
|
|
hw_screen_offset_x &= ~(hw_screen_offset_alignment - 1);
|
|
hw_screen_offset_y &= ~(hw_screen_offset_alignment - 1);
|
|
|
|
/* Apply the offset to center the viewport and maximize the guardband. */
|
|
minx -= hw_screen_offset_x;
|
|
maxx -= hw_screen_offset_x;
|
|
miny -= hw_screen_offset_y;
|
|
maxy -= hw_screen_offset_y;
|
|
|
|
/* Reconstruct the viewport transformation from the scissor. */
|
|
translate[0] = (minx + maxx) / 2.0;
|
|
translate[1] = (miny + maxy) / 2.0;
|
|
scale[0] = maxx - translate[0];
|
|
scale[1] = maxy - translate[1];
|
|
|
|
/* Treat a 0x0 viewport as 1x1 to prevent division by zero. */
|
|
if (minx == maxx)
|
|
scale[0] = 0.5;
|
|
if (miny == maxy)
|
|
scale[1] = 0.5;
|
|
|
|
/* Find the biggest guard band that is inside the supported viewport range.
|
|
* The guard band is specified as a horizontal and vertical distance from
|
|
* (0,0) in clip space.
|
|
*
|
|
* This is done by applying the inverse viewport transformation on the
|
|
* viewport limits to get those limits in clip space.
|
|
*
|
|
* The viewport range is [-max_viewport_size/2 - 1, max_viewport_size/2].
|
|
* (-1 to the min coord because max_viewport_size is odd and ViewportBounds
|
|
* Min/Max are -32768, 32767).
|
|
*/
|
|
assert(quant_mode < ARRAY_SIZE(max_viewport_size));
|
|
max_range = max_viewport_size[quant_mode] / 2;
|
|
left = (-max_range - 1 - translate[0]) / scale[0];
|
|
right = (max_range - translate[0]) / scale[0];
|
|
top = (-max_range - 1 - translate[1]) / scale[1];
|
|
bottom = (max_range - translate[1]) / scale[1];
|
|
|
|
assert(left <= -1 && top <= -1 && right >= 1 && bottom >= 1);
|
|
|
|
guardband_x = MIN2(-left, right);
|
|
guardband_y = MIN2(-top, bottom);
|
|
|
|
float discard_x = 1.0;
|
|
float discard_y = 1.0;
|
|
|
|
/* Add half the point size / line width */
|
|
discard_x += clip_discard_distance / (2.0 * scale[0]);
|
|
discard_y += clip_discard_distance / (2.0 * scale[1]);
|
|
|
|
/* Discard primitives that would lie entirely outside the viewport area. */
|
|
discard_x = MIN2(discard_x, guardband_x);
|
|
discard_y = MIN2(discard_y, guardband_y);
|
|
|
|
guardband->clip_x = guardband_x;
|
|
guardband->clip_y = guardband_y;
|
|
guardband->discard_x = discard_x;
|
|
guardband->discard_y = discard_y;
|
|
guardband->hw_screen_offset_x = hw_screen_offset_x;
|
|
guardband->hw_screen_offset_y = hw_screen_offset_y;
|
|
}
|