uint32_t varyings_address;
};
+#define LIMA_PIXEL_FORMAT_B8G8R8A8 0x03
+#define LIMA_PIXEL_FORMAT_Z16 0x0e
+#define LIMA_PIXEL_FORMAT_Z24S8 0x0f
+
/* plbu commands */
#define PLBU_CMD_BEGIN(max) { \
int i = 0, max_n = max; \
- uint32_t *plbu_cmd = util_dynarray_grow_cap(&ctx->plbu_cmd_array, max_n * 4);
+ uint32_t *plbu_cmd = util_dynarray_ensure_cap(&ctx->plbu_cmd_array, ctx->plbu_cmd_array.size + max_n * 4);
#define PLBU_CMD_END() \
assert(i <= max_n); \
PLBU_CMD(((shift_min) << 28) | ((shift_h) << 16) | (shift_w), 0x1000010C)
#define PLBU_CMD_TILED_DIMENSIONS(tiled_w, tiled_h) \
PLBU_CMD((((tiled_w) - 1) << 24) | (((tiled_h) - 1) << 8), 0x10000109)
-#define PLBU_CMD_BLOCK_STRIDE(block_w) PLBU_CMD(block_w, 0x30000000)
+#define PLBU_CMD_BLOCK_STRIDE(block_w) PLBU_CMD((block_w) & 0xff, 0x30000000)
#define PLBU_CMD_ARRAY_ADDRESS(gp_stream, block_num) \
PLBU_CMD(gp_stream, 0x28000000 | ((block_num) - 1) | 1)
#define PLBU_CMD_VIEWPORT_X(v) PLBU_CMD(v, 0x10000107)
/* vs commands */
#define VS_CMD_BEGIN(max) { \
int i = 0, max_n = max; \
- uint32_t *vs_cmd = util_dynarray_grow_cap(&ctx->vs_cmd_array, max_n * 4);
+ uint32_t *vs_cmd = util_dynarray_ensure_cap(&ctx->vs_cmd_array, ctx->vs_cmd_array.size + max_n * 4);
#define VS_CMD_END() \
assert(i <= max_n); \
static bool
lima_fb_need_reload(struct lima_context *ctx)
{
+ /* Depth buffer is always discarded */
+ if (!ctx->framebuffer.base.nr_cbufs)
+ return false;
if (ctx->damage.region) {
/* for EGL_KHR_partial_update we just want to reload the
* region not aligned to tile boundary */
else
ctx->pp_stream.bo = NULL;
- struct lima_resource *res = lima_resource(ctx->framebuffer.base.cbufs[0]->texture);
- lima_submit_add_bo(ctx->pp_submit, res->bo, LIMA_SUBMIT_BO_WRITE);
+ if (ctx->framebuffer.base.nr_cbufs) {
+ struct lima_resource *res = lima_resource(ctx->framebuffer.base.cbufs[0]->texture);
+ lima_submit_add_bo(ctx->pp_submit, res->bo, LIMA_SUBMIT_BO_WRITE);
+ }
+ if (ctx->framebuffer.base.zsbuf) {
+ struct lima_resource *res = lima_resource(ctx->framebuffer.base.zsbuf->texture);
+ lima_submit_add_bo(ctx->pp_submit, res->bo, LIMA_SUBMIT_BO_WRITE);
+ }
lima_submit_add_bo(ctx->pp_submit, ctx->plb[ctx->plb_index], LIMA_SUBMIT_BO_READ);
lima_submit_add_bo(ctx->pp_submit, ctx->gp_tile_heap[ctx->plb_index], LIMA_SUBMIT_BO_READ);
lima_submit_add_bo(ctx->pp_submit, screen->pp_buffer, LIMA_SUBMIT_BO_READ);
lima_flush(ctx);
/* no need to reload if cleared */
- if (buffers & PIPE_CLEAR_COLOR0) {
+ if (ctx->framebuffer.base.nr_cbufs && (buffers & PIPE_CLEAR_COLOR0)) {
struct lima_surface *surf = lima_surface(ctx->framebuffer.base.cbufs[0]);
surf->reload = false;
}
0x0C000000; /* need check if this GLESv1 glAlphaFunc */
}
+#if 0
static int
lima_stencil_op(enum pipe_stencil_op pipe)
{
}
return -1;
}
+#endif
static int
lima_calculate_depth_test(struct pipe_depth_state *depth, struct pipe_rasterizer_state *rst)
lima_finish_plbu_cmd(struct lima_context *ctx)
{
int i = 0;
- uint32_t *plbu_cmd = util_dynarray_grow_cap(&ctx->plbu_cmd_array, 2 * 4);
+ uint32_t *plbu_cmd = util_dynarray_ensure_cap(&ctx->plbu_cmd_array, ctx->plbu_cmd_array.size + 2 * 4);
plbu_cmd[i++] = 0x00000000;
plbu_cmd[i++] = 0x50000000; /* END */
}
static void
-lima_pack_pp_frame_reg(struct lima_context *ctx, uint32_t *frame_reg,
- uint32_t *wb_reg)
+lima_pack_wb_zsbuf_reg(struct lima_context *ctx, uint32_t *wb_reg, int wb_idx)
{
- struct lima_resource *res = lima_resource(ctx->framebuffer.base.cbufs[0]->texture);
+ struct lima_context_framebuffer *fb = &ctx->framebuffer;
+ struct lima_resource *res = lima_resource(fb->base.zsbuf->texture);
+ int level = fb->base.zsbuf->u.tex.level;
+
+ uint32_t format;
+
+ switch (fb->base.zsbuf->format) {
+ case PIPE_FORMAT_Z16_UNORM:
+ format = LIMA_PIXEL_FORMAT_Z16;
+ break;
+ case PIPE_FORMAT_Z24_UNORM_S8_UINT:
+ case PIPE_FORMAT_Z24X8_UNORM:
+ default:
+ /* Assume Z24S8 */
+ format = LIMA_PIXEL_FORMAT_Z24S8;
+ break;
+ }
+
+ struct lima_pp_wb_reg *wb = (void *)wb_reg;
+ wb[wb_idx].type = 0x01; /* 1 for depth, stencil */
+ wb[wb_idx].address = res->bo->va + res->levels[level].offset;
+ wb[wb_idx].pixel_format = format;
+ if (res->tiled) {
+ wb[wb_idx].pixel_layout = 0x2;
+ wb[wb_idx].pitch = fb->tiled_w;
+ } else {
+ wb[wb_idx].pixel_layout = 0x0;
+ wb[wb_idx].pitch = res->levels[level].stride / 8;
+ }
+ wb[wb_idx].mrt_bits = 0;
+}
+
+static void
+lima_pack_wb_cbuf_reg(struct lima_context *ctx, uint32_t *wb_reg, int wb_idx)
+{
+ struct lima_context_framebuffer *fb = &ctx->framebuffer;
+ struct lima_resource *res = lima_resource(fb->base.cbufs[0]->texture);
+ int level = fb->base.cbufs[0]->u.tex.level;
bool swap_channels = false;
- switch (ctx->framebuffer.base.cbufs[0]->format) {
+ switch (fb->base.cbufs[0]->format) {
case PIPE_FORMAT_R8G8B8A8_UNORM:
case PIPE_FORMAT_R8G8B8X8_UNORM:
swap_channels = true;
break;
}
+ struct lima_pp_wb_reg *wb = (void *)wb_reg;
+ wb[wb_idx].type = 0x02; /* 2 for color buffer */
+ wb[wb_idx].address = res->bo->va + res->levels[level].offset;
+ wb[wb_idx].pixel_format = LIMA_PIXEL_FORMAT_B8G8R8A8;
+ if (res->tiled) {
+ wb[wb_idx].pixel_layout = 0x2;
+ wb[wb_idx].pitch = fb->tiled_w;
+ } else {
+ wb[wb_idx].pixel_layout = 0x0;
+ wb[wb_idx].pitch = res->levels[level].stride / 8;
+ }
+ wb[wb_idx].mrt_bits = swap_channels ? 0x4 : 0x0;
+}
+
+
+static void
+lima_pack_pp_frame_reg(struct lima_context *ctx, uint32_t *frame_reg,
+ uint32_t *wb_reg)
+{
struct lima_context_framebuffer *fb = &ctx->framebuffer;
struct lima_pp_frame_reg *frame = (void *)frame_reg;
struct lima_screen *screen = lima_screen(ctx->base.screen);
+ int wb_idx = 0;
+
frame->render_address = screen->pp_buffer->va + pp_frame_rsw_offset;
frame->flags = 0x02;
frame->clear_value_depth = ctx->clear.depth;
frame->blocking = (fb->shift_min << 28) | (fb->shift_h << 16) | fb->shift_w;
frame->foureight = 0x8888;
- struct lima_pp_wb_reg *wb = (void *)wb_reg;
- wb[0].type = 0x02; /* 1 for depth, stencil */
- wb[0].address = res->bo->va;
- wb[0].pixel_format = 0x03; /* BGRA8888 */
- if (res->tiled) {
- wb[0].pixel_layout = 0x2;
- wb[0].pitch = fb->tiled_w;
- } else {
- wb[0].pixel_layout = 0x0;
- wb[0].pitch = res->levels[0].stride / 8;
- }
- wb[0].mrt_bits = swap_channels ? 0x4 : 0x0;
+ if (fb->base.nr_cbufs)
+ lima_pack_wb_cbuf_reg(ctx, wb_reg, wb_idx++);
+
+ /* Mali4x0 can use on-tile buffer for depth/stencil, so to save some
+ * memory bandwidth don't write depth/stencil back to memory if we're
+ * rendering to scanout
+ */
+ if (!lima_is_scanout(ctx) && fb->base.zsbuf)
+ lima_pack_wb_zsbuf_reg(ctx, wb_reg, wb_idx++);
}
static void
ctx->plb_index = (ctx->plb_index + 1) % lima_ctx_num_plb;
- /* this surface may need reload when next draw if not end of frame */
- struct lima_surface *surf = lima_surface(ctx->framebuffer.base.cbufs[0]);
- surf->reload = !end_of_frame;
+ if (ctx->framebuffer.base.nr_cbufs) {
+ /* Set reload flag for next draw. It'll be unset if buffer is cleared */
+ struct lima_surface *surf = lima_surface(ctx->framebuffer.base.cbufs[0]);
+ surf->reload = true;
+ }
}
void