Home | History | Annotate | Download | only in freedreno
      1 /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
      2 
      3 /*
      4  * Copyright (C) 2012 Rob Clark <robclark (at) freedesktop.org>
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice (including the next
     14  * paragraph) shall be included in all copies or substantial portions of the
     15  * Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     23  * SOFTWARE.
     24  *
     25  * Authors:
     26  *    Rob Clark <robclark (at) freedesktop.org>
     27  */
     28 
     29 #include "pipe/p_state.h"
     30 #include "util/u_draw.h"
     31 #include "util/u_string.h"
     32 #include "util/u_memory.h"
     33 #include "util/u_prim.h"
     34 #include "util/u_format.h"
     35 #include "util/u_helpers.h"
     36 
     37 #include "freedreno_draw.h"
     38 #include "freedreno_context.h"
     39 #include "freedreno_state.h"
     40 #include "freedreno_resource.h"
     41 #include "freedreno_query_acc.h"
     42 #include "freedreno_query_hw.h"
     43 #include "freedreno_util.h"
     44 
     45 static void
     46 resource_read(struct fd_batch *batch, struct pipe_resource *prsc)
     47 {
     48 	if (!prsc)
     49 		return;
     50 	fd_batch_resource_used(batch, fd_resource(prsc), false);
     51 }
     52 
     53 static void
     54 resource_written(struct fd_batch *batch, struct pipe_resource *prsc)
     55 {
     56 	if (!prsc)
     57 		return;
     58 	fd_batch_resource_used(batch, fd_resource(prsc), true);
     59 }
     60 
     61 static void
     62 fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
     63 {
     64 	struct fd_context *ctx = fd_context(pctx);
     65 	struct fd_batch *batch = ctx->batch;
     66 	struct pipe_framebuffer_state *pfb = &batch->framebuffer;
     67 	struct pipe_scissor_state *scissor = fd_context_get_scissor(ctx);
     68 	unsigned i, prims, buffers = 0, restore_buffers = 0;
     69 
     70 	/* for debugging problems with indirect draw, it is convenient
     71 	 * to be able to emulate it, to determine if game is feeding us
     72 	 * bogus data:
     73 	 */
     74 	if (info->indirect && (fd_mesa_debug & FD_DBG_NOINDR)) {
     75 		util_draw_indirect(pctx, info);
     76 		return;
     77 	}
     78 
     79 	if (!info->count_from_stream_output && !info->indirect &&
     80 	    !info->primitive_restart &&
     81 	    !u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
     82 		return;
     83 
     84 	/* if we supported transform feedback, we'd have to disable this: */
     85 	if (((scissor->maxx - scissor->minx) *
     86 			(scissor->maxy - scissor->miny)) == 0) {
     87 		return;
     88 	}
     89 
     90 	/* TODO: push down the region versions into the tiles */
     91 	if (!fd_render_condition_check(pctx))
     92 		return;
     93 
     94 	/* emulate unsupported primitives: */
     95 	if (!fd_supported_prim(ctx, info->mode)) {
     96 		if (ctx->streamout.num_targets > 0)
     97 			debug_error("stream-out with emulated prims");
     98 		util_primconvert_save_rasterizer_state(ctx->primconvert, ctx->rasterizer);
     99 		util_primconvert_draw_vbo(ctx->primconvert, info);
    100 		return;
    101 	}
    102 
    103 	/* Upload a user index buffer. */
    104 	struct pipe_resource *indexbuf = NULL;
    105 	unsigned index_offset = 0;
    106 	struct pipe_draw_info new_info;
    107 	if (info->index_size) {
    108 		if (info->has_user_indices) {
    109 			if (!util_upload_index_buffer(pctx, info, &indexbuf, &index_offset))
    110 				return;
    111 			new_info = *info;
    112 			new_info.index.resource = indexbuf;
    113 			new_info.has_user_indices = false;
    114 			info = &new_info;
    115 		} else {
    116 			indexbuf = info->index.resource;
    117 		}
    118 	}
    119 
    120 	if (ctx->in_blit) {
    121 		fd_batch_reset(batch);
    122 		fd_context_all_dirty(ctx);
    123 	}
    124 
    125 	batch->blit = ctx->in_blit;
    126 	batch->back_blit = ctx->in_shadow;
    127 
    128 	/* NOTE: needs to be before resource_written(batch->query_buf), otherwise
    129 	 * query_buf may not be created yet.
    130 	 */
    131 	fd_batch_set_stage(batch, FD_STAGE_DRAW);
    132 
    133 	/*
    134 	 * Figure out the buffers/features we need:
    135 	 */
    136 
    137 	mtx_lock(&ctx->screen->lock);
    138 
    139 	if (fd_depth_enabled(ctx)) {
    140 		if (fd_resource(pfb->zsbuf->texture)->valid)
    141 			restore_buffers |= FD_BUFFER_DEPTH;
    142 		buffers |= FD_BUFFER_DEPTH;
    143 		resource_written(batch, pfb->zsbuf->texture);
    144 		batch->gmem_reason |= FD_GMEM_DEPTH_ENABLED;
    145 	}
    146 
    147 	if (fd_stencil_enabled(ctx)) {
    148 		if (fd_resource(pfb->zsbuf->texture)->valid)
    149 			restore_buffers |= FD_BUFFER_STENCIL;
    150 		buffers |= FD_BUFFER_STENCIL;
    151 		resource_written(batch, pfb->zsbuf->texture);
    152 		batch->gmem_reason |= FD_GMEM_STENCIL_ENABLED;
    153 	}
    154 
    155 	if (fd_logicop_enabled(ctx))
    156 		batch->gmem_reason |= FD_GMEM_LOGICOP_ENABLED;
    157 
    158 	for (i = 0; i < pfb->nr_cbufs; i++) {
    159 		struct pipe_resource *surf;
    160 
    161 		if (!pfb->cbufs[i])
    162 			continue;
    163 
    164 		surf = pfb->cbufs[i]->texture;
    165 
    166 		resource_written(batch, surf);
    167 
    168 		if (fd_resource(surf)->valid)
    169 			restore_buffers |= PIPE_CLEAR_COLOR0 << i;
    170 
    171 		buffers |= PIPE_CLEAR_COLOR0 << i;
    172 
    173 		if (surf->nr_samples > 1)
    174 			batch->gmem_reason |= FD_GMEM_MSAA_ENABLED;
    175 
    176 		if (fd_blend_enabled(ctx, i))
    177 			batch->gmem_reason |= FD_GMEM_BLEND_ENABLED;
    178 	}
    179 
    180 	/* Mark SSBOs as being written.. we don't actually know which ones are
    181 	 * read vs written, so just assume the worst
    182 	 */
    183 	foreach_bit(i, ctx->shaderbuf[PIPE_SHADER_FRAGMENT].enabled_mask)
    184 		resource_written(batch, ctx->shaderbuf[PIPE_SHADER_FRAGMENT].sb[i].buffer);
    185 
    186 	foreach_bit(i, ctx->shaderimg[PIPE_SHADER_FRAGMENT].enabled_mask) {
    187 		struct pipe_image_view *img =
    188 			&ctx->shaderimg[PIPE_SHADER_FRAGMENT].si[i];
    189 		if (img->access & PIPE_IMAGE_ACCESS_WRITE)
    190 			resource_written(batch, img->resource);
    191 		else
    192 			resource_read(batch, img->resource);
    193 	}
    194 
    195 	foreach_bit(i, ctx->constbuf[PIPE_SHADER_VERTEX].enabled_mask)
    196 		resource_read(batch, ctx->constbuf[PIPE_SHADER_VERTEX].cb[i].buffer);
    197 	foreach_bit(i, ctx->constbuf[PIPE_SHADER_FRAGMENT].enabled_mask)
    198 		resource_read(batch, ctx->constbuf[PIPE_SHADER_FRAGMENT].cb[i].buffer);
    199 
    200 	/* Mark VBOs as being read */
    201 	foreach_bit(i, ctx->vtx.vertexbuf.enabled_mask) {
    202 		assert(!ctx->vtx.vertexbuf.vb[i].is_user_buffer);
    203 		resource_read(batch, ctx->vtx.vertexbuf.vb[i].buffer.resource);
    204 	}
    205 
    206 	/* Mark index buffer as being read */
    207 	resource_read(batch, indexbuf);
    208 
    209 	/* Mark indirect draw buffer as being read */
    210 	if (info->indirect)
    211 		resource_read(batch, info->indirect->buffer);
    212 
    213 	/* Mark textures as being read */
    214 	foreach_bit(i, ctx->tex[PIPE_SHADER_VERTEX].valid_textures)
    215 		resource_read(batch, ctx->tex[PIPE_SHADER_VERTEX].textures[i]->texture);
    216 	foreach_bit(i, ctx->tex[PIPE_SHADER_FRAGMENT].valid_textures)
    217 		resource_read(batch, ctx->tex[PIPE_SHADER_FRAGMENT].textures[i]->texture);
    218 
    219 	/* Mark streamout buffers as being written.. */
    220 	for (i = 0; i < ctx->streamout.num_targets; i++)
    221 		if (ctx->streamout.targets[i])
    222 			resource_written(batch, ctx->streamout.targets[i]->buffer);
    223 
    224 	resource_written(batch, batch->query_buf);
    225 
    226 	list_for_each_entry(struct fd_acc_query, aq, &ctx->acc_active_queries, node)
    227 		resource_written(batch, aq->prsc);
    228 
    229 	mtx_unlock(&ctx->screen->lock);
    230 
    231 	batch->num_draws++;
    232 
    233 	prims = u_reduced_prims_for_vertices(info->mode, info->count);
    234 
    235 	ctx->stats.draw_calls++;
    236 
    237 	/* TODO prims_emitted should be clipped when the stream-out buffer is
    238 	 * not large enough.  See max_tf_vtx().. probably need to move that
    239 	 * into common code.  Although a bit more annoying since a2xx doesn't
    240 	 * use ir3 so no common way to get at the pipe_stream_output_info
    241 	 * which is needed for this calculation.
    242 	 */
    243 	if (ctx->streamout.num_targets > 0)
    244 		ctx->stats.prims_emitted += prims;
    245 	ctx->stats.prims_generated += prims;
    246 
    247 	/* any buffers that haven't been cleared yet, we need to restore: */
    248 	batch->restore |= restore_buffers & (FD_BUFFER_ALL & ~batch->cleared);
    249 	/* and any buffers used, need to be resolved: */
    250 	batch->resolve |= buffers;
    251 
    252 	DBG("%p: %x %ux%u num_draws=%u (%s/%s)", batch, buffers,
    253 		pfb->width, pfb->height, batch->num_draws,
    254 		util_format_short_name(pipe_surface_format(pfb->cbufs[0])),
    255 		util_format_short_name(pipe_surface_format(pfb->zsbuf)));
    256 
    257 	if (ctx->draw_vbo(ctx, info, index_offset))
    258 		batch->needs_flush = true;
    259 
    260 	for (i = 0; i < ctx->streamout.num_targets; i++)
    261 		ctx->streamout.offsets[i] += info->count;
    262 
    263 	if (fd_mesa_debug & FD_DBG_DDRAW)
    264 		fd_context_all_dirty(ctx);
    265 
    266 	fd_batch_check_size(batch);
    267 
    268 	if (info == &new_info)
    269 		pipe_resource_reference(&indexbuf, NULL);
    270 }
    271 
    272 /* Generic clear implementation (partially) using u_blitter: */
    273 static void
    274 fd_blitter_clear(struct pipe_context *pctx, unsigned buffers,
    275 		const union pipe_color_union *color, double depth, unsigned stencil)
    276 {
    277 	struct fd_context *ctx = fd_context(pctx);
    278 	struct pipe_framebuffer_state *pfb = &ctx->batch->framebuffer;
    279 	struct blitter_context *blitter = ctx->blitter;
    280 
    281 	fd_blitter_pipe_begin(ctx, false, true, FD_STAGE_CLEAR);
    282 
    283 	util_blitter_common_clear_setup(blitter, pfb->width, pfb->height,
    284 			buffers, NULL, NULL);
    285 
    286 	struct pipe_stencil_ref sr = {
    287 		.ref_value = { stencil & 0xff }
    288 	};
    289 	pctx->set_stencil_ref(pctx, &sr);
    290 
    291 	struct pipe_constant_buffer cb = {
    292 		.buffer_size = 16,
    293 		.user_buffer = &color->ui,
    294 	};
    295 	pctx->set_constant_buffer(pctx, PIPE_SHADER_FRAGMENT, 0, &cb);
    296 
    297 	if (!ctx->clear_rs_state) {
    298 		const struct pipe_rasterizer_state tmpl = {
    299 			.cull_face = PIPE_FACE_NONE,
    300 			.half_pixel_center = 1,
    301 			.bottom_edge_rule = 1,
    302 			.flatshade = 1,
    303 			.depth_clip = 1,
    304 		};
    305 		ctx->clear_rs_state = pctx->create_rasterizer_state(pctx, &tmpl);
    306 	}
    307 	pctx->bind_rasterizer_state(pctx, ctx->clear_rs_state);
    308 
    309 	struct pipe_viewport_state vp = {
    310 		.scale     = { 0.5f * pfb->width, -0.5f * pfb->height, depth },
    311 		.translate = { 0.5f * pfb->width,  0.5f * pfb->height, 0.0f },
    312 	};
    313 	pctx->set_viewport_states(pctx, 0, 1, &vp);
    314 
    315 	pctx->bind_vertex_elements_state(pctx, ctx->solid_vbuf_state.vtx);
    316 	pctx->set_vertex_buffers(pctx, blitter->vb_slot, 1,
    317 			&ctx->solid_vbuf_state.vertexbuf.vb[0]);
    318 	pctx->set_stream_output_targets(pctx, 0, NULL, NULL);
    319 	pctx->bind_vs_state(pctx, ctx->solid_prog.vp);
    320 	pctx->bind_fs_state(pctx, ctx->solid_prog.fp);
    321 
    322 	struct pipe_draw_info info = {
    323 		.mode = PIPE_PRIM_MAX,    /* maps to DI_PT_RECTLIST */
    324 		.count = 2,
    325 		.max_index = 1,
    326 		.instance_count = 1,
    327 	};
    328 	ctx->draw_vbo(ctx, &info, 0);
    329 
    330 	util_blitter_restore_constant_buffer_state(blitter);
    331 	util_blitter_restore_vertex_states(blitter);
    332 	util_blitter_restore_fragment_states(blitter);
    333 	util_blitter_restore_textures(blitter);
    334 	util_blitter_restore_fb_state(blitter);
    335 	util_blitter_restore_render_cond(blitter);
    336 	util_blitter_unset_running_flag(blitter);
    337 
    338 	fd_blitter_pipe_end(ctx);
    339 }
    340 
    341 /* TODO figure out how to make better use of existing state mechanism
    342  * for clear (and possibly gmem->mem / mem->gmem) so we can (a) keep
    343  * track of what state really actually changes, and (b) reduce the code
    344  * in the a2xx/a3xx parts.
    345  */
    346 
    347 static void
    348 fd_clear(struct pipe_context *pctx, unsigned buffers,
    349 		const union pipe_color_union *color, double depth, unsigned stencil)
    350 {
    351 	struct fd_context *ctx = fd_context(pctx);
    352 	struct fd_batch *batch = ctx->batch;
    353 	struct pipe_framebuffer_state *pfb = &batch->framebuffer;
    354 	struct pipe_scissor_state *scissor = fd_context_get_scissor(ctx);
    355 	unsigned cleared_buffers;
    356 	int i;
    357 
    358 	/* TODO: push down the region versions into the tiles */
    359 	if (!fd_render_condition_check(pctx))
    360 		return;
    361 
    362 	if (ctx->in_blit) {
    363 		fd_batch_reset(batch);
    364 		fd_context_all_dirty(ctx);
    365 	}
    366 
    367 	/* for bookkeeping about which buffers have been cleared (and thus
    368 	 * can fully or partially skip mem2gmem) we need to ignore buffers
    369 	 * that have already had a draw, in case apps do silly things like
    370 	 * clear after draw (ie. if you only clear the color buffer, but
    371 	 * something like alpha-test causes side effects from the draw in
    372 	 * the depth buffer, etc)
    373 	 */
    374 	cleared_buffers = buffers & (FD_BUFFER_ALL & ~batch->restore);
    375 
    376 	/* do we have full-screen scissor? */
    377 	if (!memcmp(scissor, &ctx->disabled_scissor, sizeof(*scissor))) {
    378 		batch->cleared |= cleared_buffers;
    379 	} else {
    380 		batch->partial_cleared |= cleared_buffers;
    381 		if (cleared_buffers & PIPE_CLEAR_COLOR)
    382 			batch->cleared_scissor.color = *scissor;
    383 		if (cleared_buffers & PIPE_CLEAR_DEPTH)
    384 			batch->cleared_scissor.depth = *scissor;
    385 		if (cleared_buffers & PIPE_CLEAR_STENCIL)
    386 			batch->cleared_scissor.stencil = *scissor;
    387 	}
    388 	batch->resolve |= buffers;
    389 	batch->needs_flush = true;
    390 
    391 	mtx_lock(&ctx->screen->lock);
    392 
    393 	if (buffers & PIPE_CLEAR_COLOR)
    394 		for (i = 0; i < pfb->nr_cbufs; i++)
    395 			if (buffers & (PIPE_CLEAR_COLOR0 << i))
    396 				resource_written(batch, pfb->cbufs[i]->texture);
    397 
    398 	if (buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) {
    399 		resource_written(batch, pfb->zsbuf->texture);
    400 		batch->gmem_reason |= FD_GMEM_CLEARS_DEPTH_STENCIL;
    401 	}
    402 
    403 	resource_written(batch, batch->query_buf);
    404 
    405 	list_for_each_entry(struct fd_acc_query, aq, &ctx->acc_active_queries, node)
    406 		resource_written(batch, aq->prsc);
    407 
    408 	mtx_unlock(&ctx->screen->lock);
    409 
    410 	DBG("%p: %x %ux%u depth=%f, stencil=%u (%s/%s)", batch, buffers,
    411 		pfb->width, pfb->height, depth, stencil,
    412 		util_format_short_name(pipe_surface_format(pfb->cbufs[0])),
    413 		util_format_short_name(pipe_surface_format(pfb->zsbuf)));
    414 
    415 	/* if per-gen backend doesn't implement ctx->clear() generic
    416 	 * blitter clear:
    417 	 */
    418 	bool fallback = true;
    419 
    420 	if (ctx->clear) {
    421 		fd_batch_set_stage(batch, FD_STAGE_CLEAR);
    422 
    423 		if (ctx->clear(ctx, buffers, color, depth, stencil)) {
    424 			if (fd_mesa_debug & FD_DBG_DCLEAR)
    425 				fd_context_all_dirty(ctx);
    426 
    427 			fallback = false;
    428 		}
    429 	}
    430 
    431 	if (fallback) {
    432 		fd_blitter_clear(pctx, buffers, color, depth, stencil);
    433 	}
    434 }
    435 
    436 static void
    437 fd_clear_render_target(struct pipe_context *pctx, struct pipe_surface *ps,
    438 		const union pipe_color_union *color,
    439 		unsigned x, unsigned y, unsigned w, unsigned h,
    440 		bool render_condition_enabled)
    441 {
    442 	DBG("TODO: x=%u, y=%u, w=%u, h=%u", x, y, w, h);
    443 }
    444 
    445 static void
    446 fd_clear_depth_stencil(struct pipe_context *pctx, struct pipe_surface *ps,
    447 		unsigned buffers, double depth, unsigned stencil,
    448 		unsigned x, unsigned y, unsigned w, unsigned h,
    449 		bool render_condition_enabled)
    450 {
    451 	DBG("TODO: buffers=%u, depth=%f, stencil=%u, x=%u, y=%u, w=%u, h=%u",
    452 			buffers, depth, stencil, x, y, w, h);
    453 }
    454 
    455 static void
    456 fd_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info)
    457 {
    458 	struct fd_context *ctx = fd_context(pctx);
    459 	struct fd_batch *batch, *save_batch = NULL;
    460 	unsigned i;
    461 
    462 	batch = fd_batch_create(ctx, true);
    463 	fd_batch_reference(&save_batch, ctx->batch);
    464 	fd_batch_reference(&ctx->batch, batch);
    465 
    466 	mtx_lock(&ctx->screen->lock);
    467 
    468 	/* Mark SSBOs as being written.. we don't actually know which ones are
    469 	 * read vs written, so just assume the worst
    470 	 */
    471 	foreach_bit(i, ctx->shaderbuf[PIPE_SHADER_COMPUTE].enabled_mask)
    472 		resource_read(batch, ctx->shaderbuf[PIPE_SHADER_COMPUTE].sb[i].buffer);
    473 
    474 	foreach_bit(i, ctx->shaderimg[PIPE_SHADER_COMPUTE].enabled_mask) {
    475 		struct pipe_image_view *img =
    476 			&ctx->shaderimg[PIPE_SHADER_COMPUTE].si[i];
    477 		if (img->access & PIPE_IMAGE_ACCESS_WRITE)
    478 			resource_written(batch, img->resource);
    479 		else
    480 			resource_read(batch, img->resource);
    481 	}
    482 
    483 	/* UBO's are read */
    484 	foreach_bit(i, ctx->constbuf[PIPE_SHADER_COMPUTE].enabled_mask)
    485 		resource_read(batch, ctx->constbuf[PIPE_SHADER_COMPUTE].cb[i].buffer);
    486 
    487 	/* Mark textures as being read */
    488 	foreach_bit(i, ctx->tex[PIPE_SHADER_COMPUTE].valid_textures)
    489 		resource_read(batch, ctx->tex[PIPE_SHADER_COMPUTE].textures[i]->texture);
    490 
    491 	if (info->indirect)
    492 		resource_read(batch, info->indirect);
    493 
    494 	mtx_unlock(&ctx->screen->lock);
    495 
    496 	batch->needs_flush = true;
    497 	ctx->launch_grid(ctx, info);
    498 
    499 	fd_batch_flush(batch, false, false);
    500 
    501 	fd_batch_reference(&ctx->batch, save_batch);
    502 	fd_batch_reference(&save_batch, NULL);
    503 }
    504 
    505 void
    506 fd_draw_init(struct pipe_context *pctx)
    507 {
    508 	pctx->draw_vbo = fd_draw_vbo;
    509 	pctx->clear = fd_clear;
    510 	pctx->clear_render_target = fd_clear_render_target;
    511 	pctx->clear_depth_stencil = fd_clear_depth_stencil;
    512 
    513 	if (has_compute(fd_screen(pctx->screen))) {
    514 		pctx->launch_grid = fd_launch_grid;
    515 	}
    516 }
    517