amd/common: add new helpers to build buffer descriptors

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29268>
This commit is contained in:
Samuel Pitoiset
2024-05-16 17:51:02 +02:00
committed by Marge Bot
parent 3224fd706c
commit d3b01fd95e
2 changed files with 135 additions and 0 deletions

View File

@@ -6,8 +6,10 @@
*/
#include "ac_descriptors.h"
#include "ac_formats.h"
#include "ac_surface.h"
#include "gfx10_format_table.h"
#include "sid.h"
#include "util/u_math.h"
@@ -484,3 +486,104 @@ ac_set_mutable_tex_desc_fields(const struct radeon_info *info, const struct ac_m
}
}
}
void
ac_build_buffer_descriptor(const enum amd_gfx_level gfx_level, const struct ac_buffer_state *state, uint32_t desc[4])
{
uint32_t rsrc_word1 = S_008F04_BASE_ADDRESS_HI(state->va >> 32) | S_008F04_STRIDE(state->stride);
if (gfx_level >= GFX11) {
rsrc_word1 |= S_008F04_SWIZZLE_ENABLE_GFX11(state->swizzle_enable);
} else {
rsrc_word1 |= S_008F04_SWIZZLE_ENABLE_GFX6(state->swizzle_enable);
}
uint32_t rsrc_word3 = S_008F0C_DST_SEL_X(ac_map_swizzle(state->swizzle[0])) |
S_008F0C_DST_SEL_Y(ac_map_swizzle(state->swizzle[1])) |
S_008F0C_DST_SEL_Z(ac_map_swizzle(state->swizzle[2])) |
S_008F0C_DST_SEL_W(ac_map_swizzle(state->swizzle[3])) |
S_008F0C_INDEX_STRIDE(state->index_stride) |
S_008F0C_ADD_TID_ENABLE(state->add_tid);
if (gfx_level >= GFX10) {
const struct gfx10_format *fmt = &ac_get_gfx10_format_table(gfx_level)[state->format];
/* OOB_SELECT chooses the out-of-bounds check.
*
* GFX10:
* - 0: (index >= NUM_RECORDS) || (offset >= STRIDE)
* - 1: index >= NUM_RECORDS
* - 2: NUM_RECORDS == 0
* - 3: if SWIZZLE_ENABLE:
* swizzle_address >= NUM_RECORDS
* else:
* offset >= NUM_RECORDS
*
* GFX11+:
* - 0: (index >= NUM_RECORDS) || (offset+payload > STRIDE)
* - 1: index >= NUM_RECORDS
* - 2: NUM_RECORDS == 0
* - 3: if SWIZZLE_ENABLE && STRIDE:
* (index >= NUM_RECORDS) || ( offset+payload > STRIDE)
* else:
* offset+payload > NUM_RECORDS
*/
rsrc_word3 |= gfx_level >= GFX12 ? S_008F0C_FORMAT_GFX12(fmt->img_format) :
S_008F0C_FORMAT_GFX10(fmt->img_format) |
S_008F0C_OOB_SELECT(state->gfx10_oob_select) |
S_008F0C_RESOURCE_LEVEL(gfx_level < GFX11);
} else {
const struct util_format_description * desc = util_format_description(state->format);
const int first_non_void = util_format_get_first_non_void_channel(state->format);
const uint32_t num_format = ac_translate_buffer_numformat(desc, first_non_void);
/* DATA_FORMAT is STRIDE[14:17] for MUBUF with ADD_TID_ENABLE=1 */
const uint32_t data_format =
gfx_level >= GFX8 && state->add_tid ? 0 : ac_translate_buffer_dataformat(desc, first_non_void);
rsrc_word3 |= S_008F0C_NUM_FORMAT(num_format) |
S_008F0C_DATA_FORMAT(data_format) |
S_008F0C_ELEMENT_SIZE(state->element_size);
}
desc[0] = state->va;
desc[1] = rsrc_word1;
desc[2] = state->size;
desc[3] = rsrc_word3;
}
void
ac_build_raw_buffer_descriptor(const enum amd_gfx_level gfx_level, uint64_t va, uint32_t size, uint32_t desc[4])
{
const struct ac_buffer_state ac_state = {
.va = va,
.size = size,
.format = PIPE_FORMAT_R32_FLOAT,
.swizzle = {
PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W,
},
.gfx10_oob_select = V_008F0C_OOB_SELECT_RAW,
};
ac_build_buffer_descriptor(gfx_level, &ac_state, desc);
}
void
ac_build_attr_ring_descriptor(const enum amd_gfx_level gfx_level, uint64_t va, uint32_t size, uint32_t desc[4])
{
assert(gfx_level >= GFX11);
const struct ac_buffer_state ac_state = {
.va = va,
.size = size,
.format = PIPE_FORMAT_R32G32B32A32_FLOAT,
.swizzle = {
PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W,
},
.gfx10_oob_select = V_008F0C_OOB_SELECT_STRUCTURED_WITH_OFFSET,
.swizzle_enable = 3, /* 16B */
.index_stride = 2, /* 32 elements */
};
ac_build_buffer_descriptor(gfx_level, &ac_state, desc);
}

View File

@@ -11,6 +11,8 @@
#include "ac_gpu_info.h"
#include "ac_surface.h"
#include "util/format/u_format.h"
#ifdef __cplusplus
extern "C" {
#endif
@@ -98,6 +100,36 @@ ac_set_mutable_tex_desc_fields(const struct radeon_info *info,
const struct ac_mutable_tex_state *state,
uint32_t desc[8]);
struct ac_buffer_state {
uint64_t va;
uint32_t size;
enum pipe_format format;
enum pipe_swizzle swizzle[4];
uint32_t stride;
uint32_t swizzle_enable : 2;
uint32_t element_size : 2;
uint32_t index_stride : 2;
uint32_t add_tid : 1;
uint32_t gfx10_oob_select : 2;
};
void
ac_build_buffer_descriptor(const enum amd_gfx_level gfx_level,
const struct ac_buffer_state *state,
uint32_t desc[4]);
void
ac_build_raw_buffer_descriptor(const enum amd_gfx_level gfx_level,
uint64_t va,
uint32_t size,
uint32_t desc[4]);
void
ac_build_attr_ring_descriptor(const enum amd_gfx_level gfx_level,
uint64_t va,
uint32_t size,
uint32_t desc[4]);
#ifdef __cplusplus
}
#endif