broadcom/vc5: Emit raw loads for MSAA buffers.

Similar to stores, but we also need to emit dummy stores in between each
load, to flush out the previous queued load.
This commit is contained in:
Eric Anholt
2017-10-25 12:29:51 -07:00
parent 464f1fb733
commit 0ec4b4178f
+58
View File
@@ -26,6 +26,25 @@
#include "vc5_tiling.h"
#include "broadcom/cle/v3d_packet_v33_pack.h"
static void
load_raw(struct vc5_cl *cl, struct pipe_surface *psurf, int buffer)
{
struct vc5_surface *surf = vc5_surface(psurf);
struct vc5_resource *rsc = vc5_resource(psurf->texture);
cl_emit(cl, LOAD_TILE_BUFFER_GENERAL, load) {
load.raw_mode = true;
load.buffer_to_load = buffer;
load.address = cl_address(rsc->bo, surf->offset);
struct vc5_resource_slice *slice =
&rsc->slices[psurf->u.tex.level];
load.padded_height_of_output_image_in_uif_blocks =
(slice->size / slice->stride) /
(2 * vc5_utile_height(rsc->cpp));
}
}
static void
store_raw(struct vc5_cl *cl, struct pipe_surface *psurf, int buffer,
bool color_clear, bool z_clear, bool s_clear)
@@ -64,6 +83,20 @@ zs_buffer_from_pipe_bits(int pipe_clear_bits)
}
}
/* The HW queues up the load until the tile coordinates show up, but can only
* track one at a time. If we need to do more than one load, then we need to
* flush out the previous load by emitting the tile coordinates and doing a
* dummy store.
*/
static void
flush_last_load(struct vc5_cl *cl)
{
cl_emit(cl, TILE_COORDINATES_IMPLICIT, coords);
cl_emit(cl, STORE_TILE_BUFFER_GENERAL, store) {
store.buffer_to_store = NONE;
}
}
static void
vc5_rcl_emit_generic_per_tile_list(struct vc5_job *job, int last_cbuf)
{
@@ -82,6 +115,31 @@ vc5_rcl_emit_generic_per_tile_list(struct vc5_job *job, int last_cbuf)
uint32_t read_but_not_cleared = job->resolve & ~job->cleared;
for (int i = 0; i < VC5_MAX_DRAW_BUFFERS; i++) {
uint32_t bit = PIPE_CLEAR_COLOR0 << i;
if (!(read_but_not_cleared & bit))
continue;
struct pipe_surface *psurf = job->cbufs[i];
if (!psurf || psurf->texture->nr_samples <= 1)
continue;
load_raw(cl, psurf, RENDER_TARGET_0 + i);
read_but_not_cleared &= ~bit;
if (read_but_not_cleared)
flush_last_load(cl);
}
if (job->zsbuf && job->zsbuf->texture->nr_samples > 1 &&
read_but_not_cleared & PIPE_CLEAR_DEPTHSTENCIL) {
load_raw(cl, job->zsbuf,
zs_buffer_from_pipe_bits(read_but_not_cleared));
read_but_not_cleared &= ~PIPE_CLEAR_DEPTHSTENCIL;
if (read_but_not_cleared)
cl_emit(cl, TILE_COORDINATES_IMPLICIT, coords);
}
/* The initial reload will be queued until we get the
* tile coordinates.
*/