diff --git a/src/gallium/drivers/v3d/v3d_blit.c b/src/gallium/drivers/v3d/v3d_blit.c index 6ade7a1805f..91576699b0e 100644 --- a/src/gallium/drivers/v3d/v3d_blit.c +++ b/src/gallium/drivers/v3d/v3d_blit.c @@ -405,7 +405,8 @@ v3d_tlb_blit_fast(struct pipe_context *pctx, struct pipe_blit_info *info) if (info->dst.box.x != 0 || info->dst.box.width != dst_width || info->dst.box.y != 0 || info->dst.box.height != dst_height || job->draw_min_x != 0 || job->draw_min_y != 0 || - job->draw_max_x != dst_width || job->draw_max_y != dst_height) { + job->draw_max_x != dst_width || job->draw_max_y != dst_height || + !job->does_rasterization) { return; } @@ -551,6 +552,7 @@ v3d_tlb_blit(struct pipe_context *pctx, struct pipe_blit_info *info) job->draw_max_x = info->dst.box.x + info->dst.box.width; job->draw_max_y = info->dst.box.y + info->dst.box.height; job->scissor.disabled = false; + job->does_rasterization = true; /* The simulator complains if we do a TLB load from a source with a * stride that is smaller than the destination's, so we program the diff --git a/src/gallium/drivers/v3d/v3d_context.h b/src/gallium/drivers/v3d/v3d_context.h index 1951014afbe..0672114c965 100644 --- a/src/gallium/drivers/v3d/v3d_context.h +++ b/src/gallium/drivers/v3d/v3d_context.h @@ -537,6 +537,12 @@ struct v3d_job { */ bool early_zs_clear; + /** + * Tracks if at least one of the draws/clears submitted to the + * job was submitted with GL_RASTERIZER_DISCARD disabled. + */ + bool does_rasterization; + /** * Number of draw calls (not counting full buffer clears) queued in * the current job. diff --git a/src/gallium/drivers/v3d/v3dx_draw.c b/src/gallium/drivers/v3d/v3dx_draw.c index a88cb962b98..8237a46ce70 100644 --- a/src/gallium/drivers/v3d/v3dx_draw.c +++ b/src/gallium/drivers/v3d/v3dx_draw.c @@ -1062,6 +1062,7 @@ v3d_update_job_tlb_load_store(struct v3d_job *job) { if (v3d->rasterizer->base.rasterizer_discard) return; + job->does_rasterization = true; uint32_t no_load_mask = job->clear_tlb | job->clear_draw | job->invalidated_load; @@ -1798,6 +1799,12 @@ v3d_clear(struct pipe_context *pctx, unsigned buffers, const struct pipe_scissor struct v3d_context *v3d = v3d_context(pctx); struct v3d_job *job = v3d_get_job_for_fbo(v3d); + /* If the clear call reaches the drives implies that rasterizer + * discard is always disabled. The state tracker is already ignoring + * clear calls if rasterization discard is enabled. + */ + job->does_rasterization = true; + buffers &= ~v3d_tlb_clear(job, buffers, color, depth, stencil); if (!buffers || !v3d_render_condition_check(v3d)) diff --git a/src/gallium/drivers/v3d/v3dx_rcl.c b/src/gallium/drivers/v3d/v3dx_rcl.c index 65d9d0c88ab..7fc0c0a1f13 100644 --- a/src/gallium/drivers/v3d/v3dx_rcl.c +++ b/src/gallium/drivers/v3d/v3dx_rcl.c @@ -642,6 +642,14 @@ emit_render_layer(struct v3d_job *job, uint32_t layer) v3d_rcl_emit_generic_per_tile_list(job, layer); + /* If rasterization has been disabled for all the draws/clears of the + * job we can avoid the submission of the Supertile Coordinates. + * This disables the execution of the fragment shader for each of the + * tiles. + */ + if (!job->does_rasterization) + return; + /* XXX perf: We should expose GL_MESA_tile_raster_order to * improve X11 performance, but we should use Morton order * otherwise to improve cache locality. @@ -678,10 +686,12 @@ v3dX(emit_rcl)(struct v3d_job *job) /* The RCL list should be empty. */ assert(!job->rcl.bo); struct v3d_device_info *devinfo = &job->v3d->screen->devinfo; - - v3d_cl_ensure_space_with_branch(&job->rcl, 200 + - MAX2(job->num_layers, 1) * 256 * - cl_packet_length(SUPERTILE_COORDINATES)); + uint32_t cl_supertile_coordinates_size = 0; + if (job->does_rasterization) { + cl_supertile_coordinates_size = MAX2(job->num_layers, 1) * + 256 * cl_packet_length(SUPERTILE_COORDINATES); + } + v3d_cl_ensure_space_with_branch(&job->rcl, 200 + cl_supertile_coordinates_size); job->submit.rcl_start = job->rcl.bo->offset; v3d_job_add_bo(job, job->rcl.bo);