tu: Split out part of tiling config to vsc config
For FDM offset, we will need to expand the number of bins by 1, which can change how pipes are allocated. We don't necessarily know whether FDM offset will be used when creating the VkFramebuffer, so we'll have to create two different configs when FDM is enabled. Split out the parts that are affected by the number of bins into a separate "VSC config" struct that will be duplicated with FDM offset. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33500>
This commit is contained in:
@@ -955,6 +955,7 @@ use_hw_binning(struct tu_cmd_buffer *cmd)
|
||||
{
|
||||
const struct tu_framebuffer *fb = cmd->state.framebuffer;
|
||||
const struct tu_tiling_config *tiling = &fb->tiling[cmd->state.gmem_layout];
|
||||
const struct tu_vsc_config *vsc = &tiling->vsc;
|
||||
|
||||
/* XFB commands are emitted for BINNING || SYSMEM, which makes it
|
||||
* incompatible with non-hw binning GMEM rendering. this is required because
|
||||
@@ -963,7 +964,7 @@ use_hw_binning(struct tu_cmd_buffer *cmd)
|
||||
* XFB was used.
|
||||
*/
|
||||
if (cmd->state.rp.xfb_used) {
|
||||
assert(tiling->binning_possible);
|
||||
assert(vsc->binning_possible);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -974,11 +975,11 @@ use_hw_binning(struct tu_cmd_buffer *cmd)
|
||||
*/
|
||||
if (cmd->state.rp.has_prim_generated_query_in_rp ||
|
||||
cmd->state.prim_generated_query_running_before_rp) {
|
||||
assert(tiling->binning_possible);
|
||||
assert(vsc->binning_possible);
|
||||
return true;
|
||||
}
|
||||
|
||||
return tiling->binning;
|
||||
return vsc->binning;
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -1013,8 +1014,10 @@ use_sysmem_rendering(struct tu_cmd_buffer *cmd,
|
||||
return true;
|
||||
}
|
||||
|
||||
const struct tu_vsc_config *vsc = &cmd->state.tiling->vsc;
|
||||
|
||||
/* XFB is incompatible with non-hw binning GMEM rendering, see use_hw_binning */
|
||||
if (cmd->state.rp.xfb_used && !cmd->state.tiling->binning_possible) {
|
||||
if (cmd->state.rp.xfb_used && !vsc->binning_possible) {
|
||||
cmd->state.rp.gmem_disable_reason =
|
||||
"XFB is incompatible with non-hw binning GMEM rendering";
|
||||
return true;
|
||||
@@ -1025,7 +1028,7 @@ use_sysmem_rendering(struct tu_cmd_buffer *cmd,
|
||||
*/
|
||||
if ((cmd->state.rp.has_prim_generated_query_in_rp ||
|
||||
cmd->state.prim_generated_query_running_before_rp) &&
|
||||
!cmd->state.tiling->binning_possible) {
|
||||
!vsc->binning_possible) {
|
||||
cmd->state.rp.gmem_disable_reason =
|
||||
"QUERY_TYPE_PRIMITIVES_GENERATED is incompatible with non-hw binning GMEM rendering";
|
||||
return true;
|
||||
@@ -1056,7 +1059,9 @@ static void
|
||||
tu6_emit_cond_for_load_stores(struct tu_cmd_buffer *cmd, struct tu_cs *cs,
|
||||
uint32_t pipe, uint32_t slot, bool skip_wfm)
|
||||
{
|
||||
if (cmd->state.tiling->binning_possible &&
|
||||
const struct tu_vsc_config *vsc = &cmd->state.tiling->vsc;
|
||||
|
||||
if (vsc->binning_possible &&
|
||||
cmd->state.pass->has_cond_load_store) {
|
||||
tu_cs_emit_pkt7(cs, CP_REG_TEST, 1);
|
||||
tu_cs_emit(cs, A6XX_CP_REG_TEST_0_REG(REG_A6XX_VSC_STATE_REG(pipe)) |
|
||||
@@ -1084,6 +1089,7 @@ tu6_emit_tile_select(struct tu_cmd_buffer *cmd,
|
||||
{
|
||||
struct tu_physical_device *phys_dev = cmd->device->physical_device;
|
||||
const struct tu_tiling_config *tiling = cmd->state.tiling;
|
||||
const struct tu_vsc_config *vsc = &tiling->vsc;
|
||||
bool hw_binning = use_hw_binning(cmd);
|
||||
|
||||
tu_cs_emit_pkt7(cs, CP_SET_MARKER, 1);
|
||||
@@ -1128,7 +1134,7 @@ tu6_emit_tile_select(struct tu_cmd_buffer *cmd,
|
||||
tu_cs_emit(cs, 0x0);
|
||||
|
||||
tu_cs_emit_pkt7(cs, CP_SET_BIN_DATA5_OFFSET, abs_mask ? 5 : 4);
|
||||
tu_cs_emit(cs, tiling->pipe_sizes[tile->pipe] |
|
||||
tu_cs_emit(cs, vsc->pipe_sizes[tile->pipe] |
|
||||
CP_SET_BIN_DATA5_0_VSC_N(slot) |
|
||||
CP_SET_BIN_DATA5_0_VSC_MASK(tile->slot_mask >> slot) |
|
||||
COND(abs_mask, CP_SET_BIN_DATA5_0_ABS_MASK(ABS_MASK)));
|
||||
@@ -1246,6 +1252,7 @@ tu6_emit_tile_store(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
|
||||
const struct tu_render_pass *pass = cmd->state.pass;
|
||||
const struct tu_subpass *subpass = &pass->subpasses[pass->subpass_count-1];
|
||||
const struct tu_framebuffer *fb = cmd->state.framebuffer;
|
||||
const struct tu_vsc_config *vsc = &cmd->state.tiling->vsc;
|
||||
|
||||
if (pass->has_fdm)
|
||||
tu_cs_set_writeable(cs, true);
|
||||
@@ -1274,7 +1281,7 @@ tu6_emit_tile_store(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
|
||||
|
||||
for (uint32_t a = 0; a < pass->attachment_count; ++a) {
|
||||
if (pass->attachments[a].gmem) {
|
||||
const bool cond_exec_allowed = cmd->state.tiling->binning_possible &&
|
||||
const bool cond_exec_allowed = vsc->binning_possible &&
|
||||
cmd->state.pass->has_cond_load_store;
|
||||
tu_store_gmem_attachment<CHIP>(cmd, cs, &resolve_group, a, a,
|
||||
fb->layers, subpass->multiview_mask,
|
||||
@@ -1645,17 +1652,18 @@ update_vsc_pipe(struct tu_cmd_buffer *cmd,
|
||||
uint32_t num_vsc_pipes)
|
||||
{
|
||||
const struct tu_tiling_config *tiling = cmd->state.tiling;
|
||||
const struct tu_vsc_config *vsc = &tiling->vsc;
|
||||
|
||||
tu_cs_emit_regs(cs,
|
||||
A6XX_VSC_BIN_SIZE(.width = tiling->tile0.width,
|
||||
.height = tiling->tile0.height));
|
||||
|
||||
tu_cs_emit_regs(cs,
|
||||
A6XX_VSC_BIN_COUNT(.nx = tiling->tile_count.width,
|
||||
.ny = tiling->tile_count.height));
|
||||
A6XX_VSC_BIN_COUNT(.nx = vsc->tile_count.width,
|
||||
.ny = vsc->tile_count.height));
|
||||
|
||||
tu_cs_emit_pkt4(cs, REG_A6XX_VSC_PIPE_CONFIG_REG(0), num_vsc_pipes);
|
||||
tu_cs_emit_array(cs, tiling->pipe_config, num_vsc_pipes);
|
||||
tu_cs_emit_array(cs, vsc->pipe_config, num_vsc_pipes);
|
||||
|
||||
tu_cs_emit_regs(cs,
|
||||
A6XX_VSC_PRIM_STRM_PITCH(cmd->vsc_prim_strm_pitch),
|
||||
@@ -1672,8 +1680,9 @@ static void
|
||||
emit_vsc_overflow_test(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
|
||||
{
|
||||
const struct tu_tiling_config *tiling = cmd->state.tiling;
|
||||
const struct tu_vsc_config *vsc = &tiling->vsc;
|
||||
const uint32_t used_pipe_count =
|
||||
tiling->pipe_count.width * tiling->pipe_count.height;
|
||||
vsc->pipe_count.width * vsc->pipe_count.height;
|
||||
|
||||
for (int i = 0; i < used_pipe_count; i++) {
|
||||
tu_cs_emit_pkt7(cs, CP_COND_WRITE5, 8);
|
||||
@@ -2168,6 +2177,7 @@ tu6_tile_render_begin(struct tu_cmd_buffer *cmd, struct tu_cs *cs,
|
||||
{
|
||||
struct tu_physical_device *phys_dev = cmd->device->physical_device;
|
||||
const struct tu_tiling_config *tiling = cmd->state.tiling;
|
||||
const struct tu_vsc_config *vsc = &tiling->vsc;
|
||||
tu_lrz_tiling_begin<CHIP>(cmd, cs);
|
||||
|
||||
tu_cs_emit_pkt7(cs, CP_SKIP_IB2_ENABLE_GLOBAL, 1);
|
||||
@@ -2226,18 +2236,18 @@ tu6_tile_render_begin(struct tu_cmd_buffer *cmd, struct tu_cs *cs,
|
||||
tu_cs_emit_pkt7(cs, CP_SKIP_IB2_ENABLE_LOCAL, 1);
|
||||
tu_cs_emit(cs, 0x1);
|
||||
} else {
|
||||
if (tiling->binning_possible) {
|
||||
if (vsc->binning_possible) {
|
||||
/* Mark all tiles as visible for tu6_emit_cond_for_load_stores(), since
|
||||
* the actual binner didn't run.
|
||||
*/
|
||||
int pipe_count = tiling->pipe_count.width * tiling->pipe_count.height;
|
||||
int pipe_count = vsc->pipe_count.width * vsc->pipe_count.height;
|
||||
tu_cs_emit_pkt4(cs, REG_A6XX_VSC_STATE_REG(0), pipe_count);
|
||||
for (int i = 0; i < pipe_count; i++)
|
||||
tu_cs_emit(cs, ~0);
|
||||
}
|
||||
}
|
||||
|
||||
if (tiling->binning_possible) {
|
||||
if (vsc->binning_possible) {
|
||||
/* Upload state regs to memory to be restored on skipsaverestore
|
||||
* preemption.
|
||||
*/
|
||||
@@ -2546,6 +2556,7 @@ tu_cmd_render_tiles(struct tu_cmd_buffer *cmd,
|
||||
struct tu_renderpass_result *autotune_result)
|
||||
{
|
||||
const struct tu_tiling_config *tiling = cmd->state.tiling;
|
||||
const struct tu_vsc_config *vsc = &tiling->vsc;
|
||||
const struct tu_image_view *fdm = NULL;
|
||||
|
||||
if (cmd->state.pass->fragment_density_map.attachment != VK_ATTACHMENT_UNUSED) {
|
||||
@@ -2572,19 +2583,19 @@ tu_cmd_render_tiles(struct tu_cmd_buffer *cmd,
|
||||
/* Note: we reverse the order of walking the pipes and tiles on every
|
||||
* other row, to improve texture cache locality compared to raster order.
|
||||
*/
|
||||
for (uint32_t py = 0; py < tiling->pipe_count.height; py++) {
|
||||
uint32_t pipe_row = py * tiling->pipe_count.width;
|
||||
for (uint32_t pipe_row_i = 0; pipe_row_i < tiling->pipe_count.width; pipe_row_i++) {
|
||||
for (uint32_t py = 0; py < vsc->pipe_count.height; py++) {
|
||||
uint32_t pipe_row = py * vsc->pipe_count.width;
|
||||
for (uint32_t pipe_row_i = 0; pipe_row_i < vsc->pipe_count.width; pipe_row_i++) {
|
||||
uint32_t px;
|
||||
if (py & 1)
|
||||
px = tiling->pipe_count.width - 1 - pipe_row_i;
|
||||
px = vsc->pipe_count.width - 1 - pipe_row_i;
|
||||
else
|
||||
px = pipe_row_i;
|
||||
uint32_t pipe = pipe_row + px;
|
||||
uint32_t tx1 = px * tiling->pipe0.width;
|
||||
uint32_t ty1 = py * tiling->pipe0.height;
|
||||
uint32_t tx2 = MIN2(tx1 + tiling->pipe0.width, tiling->tile_count.width);
|
||||
uint32_t ty2 = MIN2(ty1 + tiling->pipe0.height, tiling->tile_count.height);
|
||||
uint32_t tx1 = px * vsc->pipe0.width;
|
||||
uint32_t ty1 = py * vsc->pipe0.height;
|
||||
uint32_t tx2 = MIN2(tx1 + vsc->pipe0.width, vsc->tile_count.width);
|
||||
uint32_t ty2 = MIN2(ty1 + vsc->pipe0.height, vsc->tile_count.height);
|
||||
|
||||
if (merge_tiles) {
|
||||
tu_render_pipe_fdm<CHIP>(cmd, pipe, tx1, ty1, tx2, ty2, fdm);
|
||||
@@ -4854,6 +4865,7 @@ tu_emit_subpass_begin_gmem(struct tu_cmd_buffer *cmd, struct tu_resolve_group *r
|
||||
{
|
||||
struct tu_cs *cs = &cmd->draw_cs;
|
||||
uint32_t subpass_idx = cmd->state.subpass - cmd->state.pass->subpasses;
|
||||
const struct tu_vsc_config *vsc = &cmd->state.tiling->vsc;
|
||||
|
||||
/* If we might choose to bin, then put the loads under a check for geometry
|
||||
* having been binned to this tile. If we don't choose to bin in the end,
|
||||
@@ -4863,7 +4875,7 @@ tu_emit_subpass_begin_gmem(struct tu_cmd_buffer *cmd, struct tu_resolve_group *r
|
||||
* (perf queries), then we can't do this optimization since the
|
||||
* start-of-the-CS geometry condition will have been overwritten.
|
||||
*/
|
||||
bool cond_load_allowed = cmd->state.tiling->binning &&
|
||||
bool cond_load_allowed = vsc->binning &&
|
||||
cmd->state.pass->has_cond_load_store &&
|
||||
!cmd->state.rp.draw_cs_writes_to_cond_pred;
|
||||
|
||||
|
||||
@@ -462,31 +462,35 @@ struct tu_attachment_info
|
||||
struct tu_image_view *attachment;
|
||||
};
|
||||
|
||||
struct tu_tiling_config {
|
||||
/* size of the first tile */
|
||||
VkExtent2D tile0;
|
||||
struct tu_vsc_config {
|
||||
/* number of tiles */
|
||||
VkExtent2D tile_count;
|
||||
|
||||
/* size of the first VSC pipe */
|
||||
VkExtent2D pipe0;
|
||||
/* number of VSC pipes */
|
||||
VkExtent2D pipe_count;
|
||||
|
||||
/* Whether using GMEM is even possible with this configuration */
|
||||
bool possible;
|
||||
/* Whether binning could be used for gmem rendering using this framebuffer. */
|
||||
bool binning_possible;
|
||||
|
||||
/* Whether binning should be used for gmem rendering using this framebuffer. */
|
||||
bool binning;
|
||||
|
||||
/* Whether binning could be used for gmem rendering using this framebuffer. */
|
||||
bool binning_possible;
|
||||
|
||||
/* pipe register values */
|
||||
uint32_t pipe_config[MAX_VSC_PIPES];
|
||||
uint32_t pipe_sizes[MAX_VSC_PIPES];
|
||||
};
|
||||
|
||||
struct tu_tiling_config {
|
||||
/* size of the first tile */
|
||||
VkExtent2D tile0;
|
||||
|
||||
/* Whether using GMEM is even possible with this configuration */
|
||||
bool possible;
|
||||
|
||||
struct tu_vsc_config vsc;
|
||||
};
|
||||
|
||||
struct tu_framebuffer
|
||||
{
|
||||
struct vk_object_base base;
|
||||
|
||||
@@ -89,7 +89,7 @@ begin_end_tp('render_pass',
|
||||
tp_struct=[Arg(type='uint16_t', name='width', var='fb->width', c_format='%u'),
|
||||
Arg(type='uint16_t', name='height', var='fb->height', c_format='%u'),
|
||||
Arg(type='uint8_t', name='attachment_count', var='fb->attachment_count', c_format='%u'),
|
||||
Arg(type='uint16_t', name='numberOfBins', var='tiling->tile_count.width * tiling->tile_count.height', c_format='%u'),
|
||||
Arg(type='uint16_t', name='numberOfBins', var='tiling->vsc.tile_count.width * tiling->vsc.tile_count.height', c_format='%u'),
|
||||
Arg(type='uint16_t', name='binWidth', var='tiling->tile0.width', c_format='%u'),
|
||||
Arg(type='uint16_t', name='binHeight', var='tiling->tile0.height', c_format='%u'),],
|
||||
# Args known only at the end of the renderpass:
|
||||
|
||||
@@ -220,8 +220,10 @@ tu_tiling_config_update_tile_layout(struct tu_framebuffer *fb,
|
||||
* them, since you shouldn't be doing gmem work if gmem is not possible.
|
||||
*/
|
||||
.tile0 = (VkExtent2D) { ~0, ~0 },
|
||||
.tile_count = (VkExtent2D) { .width = 1, .height = 1 },
|
||||
.possible = false,
|
||||
.vsc = {
|
||||
.tile_count = (VkExtent2D) { .width = 1, .height = 1 },
|
||||
},
|
||||
};
|
||||
|
||||
/* From the Vulkan 1.3.232 spec, under VkFramebufferCreateInfo:
|
||||
@@ -300,37 +302,37 @@ tu_tiling_config_update_tile_layout(struct tu_framebuffer *fb,
|
||||
abs((int)(tiling->tile0.width - tiling->tile0.height)))) {
|
||||
tiling->possible = true;
|
||||
tiling->tile0 = tile_size;
|
||||
tiling->tile_count = tile_count;
|
||||
tiling->vsc.tile_count = tile_count;
|
||||
best_tile_count = tile_count.width * tile_count.height;
|
||||
}
|
||||
}
|
||||
|
||||
/* If forcing binning, try to get at least 2 tiles in each direction. */
|
||||
if (TU_DEBUG(FORCEBIN) && tiling->possible) {
|
||||
if (tiling->tile_count.width == 1 && tiling->tile0.width != tile_align_w) {
|
||||
if (tiling->vsc.tile_count.width == 1 && tiling->tile0.width != tile_align_w) {
|
||||
tiling->tile0.width = util_align_npot(DIV_ROUND_UP(tiling->tile0.width, 2), tile_align_w);
|
||||
tiling->tile_count.width = 2;
|
||||
tiling->vsc.tile_count.width = 2;
|
||||
}
|
||||
if (tiling->tile_count.height == 1 && tiling->tile0.height != tile_align_h) {
|
||||
if (tiling->vsc.tile_count.height == 1 && tiling->tile0.height != tile_align_h) {
|
||||
tiling->tile0.height = align(DIV_ROUND_UP(tiling->tile0.height, 2), tile_align_h);
|
||||
tiling->tile_count.height = 2;
|
||||
tiling->vsc.tile_count.height = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
is_hw_binning_possible(const struct tu_tiling_config *tiling)
|
||||
is_hw_binning_possible(const struct tu_vsc_config *vsc)
|
||||
{
|
||||
/* Similar to older gens, # of tiles per pipe cannot be more than 32.
|
||||
* But there are no hangs with 16 or more tiles per pipe in either
|
||||
* X or Y direction, so that limit does not seem to apply.
|
||||
*/
|
||||
uint32_t tiles_per_pipe = tiling->pipe0.width * tiling->pipe0.height;
|
||||
uint32_t tiles_per_pipe = vsc->pipe0.width * vsc->pipe0.height;
|
||||
return tiles_per_pipe <= 32;
|
||||
}
|
||||
|
||||
static void
|
||||
tu_tiling_config_update_pipe_layout(struct tu_tiling_config *tiling,
|
||||
tu_tiling_config_update_pipe_layout(struct tu_vsc_config *vsc,
|
||||
const struct tu_device *dev,
|
||||
bool fdm)
|
||||
{
|
||||
@@ -345,94 +347,94 @@ tu_tiling_config_update_pipe_layout(struct tu_tiling_config *tiling,
|
||||
*/
|
||||
if (fdm && dev->physical_device->info->a6xx.has_bin_mask &&
|
||||
!TU_DEBUG(NO_BIN_MERGING)) {
|
||||
tiling->pipe0.width = 4;
|
||||
tiling->pipe0.height = 8;
|
||||
tiling->pipe_count.width =
|
||||
DIV_ROUND_UP(tiling->tile_count.width, tiling->pipe0.width);
|
||||
tiling->pipe_count.height =
|
||||
DIV_ROUND_UP(tiling->tile_count.height, tiling->pipe0.height);
|
||||
tiling->binning_possible =
|
||||
tiling->pipe_count.width * tiling->pipe_count.height <= max_pipe_count;
|
||||
vsc->pipe0.width = 4;
|
||||
vsc->pipe0.height = 8;
|
||||
vsc->pipe_count.width =
|
||||
DIV_ROUND_UP(vsc->tile_count.width, vsc->pipe0.width);
|
||||
vsc->pipe_count.height =
|
||||
DIV_ROUND_UP(vsc->tile_count.height, vsc->pipe0.height);
|
||||
vsc->binning_possible =
|
||||
vsc->pipe_count.width * vsc->pipe_count.height <= max_pipe_count;
|
||||
return;
|
||||
}
|
||||
|
||||
/* start from 1 tile per pipe */
|
||||
tiling->pipe0 = (VkExtent2D) {
|
||||
vsc->pipe0 = (VkExtent2D) {
|
||||
.width = 1,
|
||||
.height = 1,
|
||||
};
|
||||
tiling->pipe_count = tiling->tile_count;
|
||||
vsc->pipe_count = vsc->tile_count;
|
||||
|
||||
while (tiling->pipe_count.width * tiling->pipe_count.height > max_pipe_count) {
|
||||
if (tiling->pipe0.width < tiling->pipe0.height) {
|
||||
tiling->pipe0.width += 1;
|
||||
tiling->pipe_count.width =
|
||||
DIV_ROUND_UP(tiling->tile_count.width, tiling->pipe0.width);
|
||||
while (vsc->pipe_count.width * vsc->pipe_count.height > max_pipe_count) {
|
||||
if (vsc->pipe0.width < vsc->pipe0.height) {
|
||||
vsc->pipe0.width += 1;
|
||||
vsc->pipe_count.width =
|
||||
DIV_ROUND_UP(vsc->tile_count.width, vsc->pipe0.width);
|
||||
} else {
|
||||
tiling->pipe0.height += 1;
|
||||
tiling->pipe_count.height =
|
||||
DIV_ROUND_UP(tiling->tile_count.height, tiling->pipe0.height);
|
||||
vsc->pipe0.height += 1;
|
||||
vsc->pipe_count.height =
|
||||
DIV_ROUND_UP(vsc->tile_count.height, vsc->pipe0.height);
|
||||
}
|
||||
}
|
||||
|
||||
tiling->binning_possible = is_hw_binning_possible(tiling);
|
||||
vsc->binning_possible = is_hw_binning_possible(vsc);
|
||||
}
|
||||
|
||||
static void
|
||||
tu_tiling_config_update_pipes(struct tu_tiling_config *tiling,
|
||||
tu_tiling_config_update_pipes(struct tu_vsc_config *vsc,
|
||||
const struct tu_device *dev)
|
||||
{
|
||||
const uint32_t max_pipe_count =
|
||||
dev->physical_device->info->num_vsc_pipes;
|
||||
const uint32_t used_pipe_count =
|
||||
tiling->pipe_count.width * tiling->pipe_count.height;
|
||||
vsc->pipe_count.width * vsc->pipe_count.height;
|
||||
const VkExtent2D last_pipe = {
|
||||
.width = (tiling->tile_count.width - 1) % tiling->pipe0.width + 1,
|
||||
.height = (tiling->tile_count.height - 1) % tiling->pipe0.height + 1,
|
||||
.width = (vsc->tile_count.width - 1) % vsc->pipe0.width + 1,
|
||||
.height = (vsc->tile_count.height - 1) % vsc->pipe0.height + 1,
|
||||
};
|
||||
|
||||
if (!tiling->binning_possible)
|
||||
if (!vsc->binning_possible)
|
||||
return;
|
||||
|
||||
assert(used_pipe_count <= max_pipe_count);
|
||||
assert(max_pipe_count <= ARRAY_SIZE(tiling->pipe_config));
|
||||
assert(max_pipe_count <= ARRAY_SIZE(vsc->pipe_config));
|
||||
|
||||
for (uint32_t y = 0; y < tiling->pipe_count.height; y++) {
|
||||
for (uint32_t x = 0; x < tiling->pipe_count.width; x++) {
|
||||
const uint32_t pipe_x = tiling->pipe0.width * x;
|
||||
const uint32_t pipe_y = tiling->pipe0.height * y;
|
||||
const uint32_t pipe_w = (x == tiling->pipe_count.width - 1)
|
||||
for (uint32_t y = 0; y < vsc->pipe_count.height; y++) {
|
||||
for (uint32_t x = 0; x < vsc->pipe_count.width; x++) {
|
||||
const uint32_t pipe_x = vsc->pipe0.width * x;
|
||||
const uint32_t pipe_y = vsc->pipe0.height * y;
|
||||
const uint32_t pipe_w = (x == vsc->pipe_count.width - 1)
|
||||
? last_pipe.width
|
||||
: tiling->pipe0.width;
|
||||
const uint32_t pipe_h = (y == tiling->pipe_count.height - 1)
|
||||
: vsc->pipe0.width;
|
||||
const uint32_t pipe_h = (y == vsc->pipe_count.height - 1)
|
||||
? last_pipe.height
|
||||
: tiling->pipe0.height;
|
||||
const uint32_t n = tiling->pipe_count.width * y + x;
|
||||
: vsc->pipe0.height;
|
||||
const uint32_t n = vsc->pipe_count.width * y + x;
|
||||
|
||||
tiling->pipe_config[n] = A6XX_VSC_PIPE_CONFIG_REG_X(pipe_x) |
|
||||
vsc->pipe_config[n] = A6XX_VSC_PIPE_CONFIG_REG_X(pipe_x) |
|
||||
A6XX_VSC_PIPE_CONFIG_REG_Y(pipe_y) |
|
||||
A6XX_VSC_PIPE_CONFIG_REG_W(pipe_w) |
|
||||
A6XX_VSC_PIPE_CONFIG_REG_H(pipe_h);
|
||||
tiling->pipe_sizes[n] = CP_SET_BIN_DATA5_0_VSC_SIZE(pipe_w * pipe_h);
|
||||
vsc->pipe_sizes[n] = CP_SET_BIN_DATA5_0_VSC_SIZE(pipe_w * pipe_h);
|
||||
}
|
||||
}
|
||||
|
||||
memset(tiling->pipe_config + used_pipe_count, 0,
|
||||
memset(vsc->pipe_config + used_pipe_count, 0,
|
||||
sizeof(uint32_t) * (max_pipe_count - used_pipe_count));
|
||||
}
|
||||
|
||||
static void
|
||||
tu_tiling_config_update_binning(struct tu_tiling_config *tiling, const struct tu_device *device)
|
||||
tu_tiling_config_update_binning(struct tu_vsc_config *vsc, const struct tu_device *device)
|
||||
{
|
||||
if (tiling->binning_possible) {
|
||||
tiling->binning = (tiling->tile_count.width * tiling->tile_count.height) > 2;
|
||||
if (vsc->binning_possible) {
|
||||
vsc->binning = (vsc->tile_count.width * vsc->tile_count.height) > 2;
|
||||
|
||||
if (TU_DEBUG(FORCEBIN))
|
||||
tiling->binning = true;
|
||||
vsc->binning = true;
|
||||
if (TU_DEBUG(NOBIN))
|
||||
tiling->binning = false;
|
||||
vsc->binning = false;
|
||||
} else {
|
||||
tiling->binning = false;
|
||||
vsc->binning = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -448,9 +450,10 @@ tu_framebuffer_tiling_config(struct tu_framebuffer *fb,
|
||||
if (!tiling->possible)
|
||||
continue;
|
||||
|
||||
tu_tiling_config_update_pipe_layout(tiling, device, pass->has_fdm);
|
||||
tu_tiling_config_update_pipes(tiling, device);
|
||||
tu_tiling_config_update_binning(tiling, device);
|
||||
struct tu_vsc_config *vsc = &tiling->vsc;
|
||||
tu_tiling_config_update_pipe_layout(vsc, device, pass->has_fdm);
|
||||
tu_tiling_config_update_pipes(vsc, device);
|
||||
tu_tiling_config_update_binning(vsc, device);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user