cl_emit(&job->bcl, TILE_BINNING_MODE_CONFIGURATION_PART1, config) {
#if V3D_VERSION >= 40
- config.width_in_pixels_minus_1 = v3d->framebuffer.width - 1;
- config.height_in_pixels_minus_1 = v3d->framebuffer.height - 1;
- config.number_of_render_targets_minus_1 =
- MAX2(v3d->framebuffer.nr_cbufs, 1) - 1;
+ config.width_in_pixels = v3d->framebuffer.width;
+ config.height_in_pixels = v3d->framebuffer.height;
+ config.number_of_render_targets =
+ MAX2(v3d->framebuffer.nr_cbufs, 1);
#else /* V3D_VERSION < 40 */
config.tile_state_data_array_base_address =
cl_address(job->tile_state, 0);
shader.fragment_shader_uniforms_address = fs_uniforms;
#if V3D_VERSION >= 41
+ shader.min_coord_shader_input_segments_required_in_play = 1;
+ shader.min_vertex_shader_input_segments_required_in_play = 1;
+
shader.coordinate_shader_4_way_threadable =
v3d->prog.cs->prog_data.vs->base.threads == 4;
shader.vertex_shader_4_way_threadable =
}
}
}
+
+ /* A flush is required in between a TF draw and any following TF specs
+ * packet, or the GPU may hang. Just flush each time for now.
+ */
+ if (v3d->streamout.num_targets)
+ cl_emit(&job->bcl, TRANSFORM_FEEDBACK_FLUSH_AND_COUNT, flush);
+
job->draw_calls_queued++;
/* Increment the TF offsets by how many verts we wrote. XXX: This
struct v3d_resource *rsc = v3d_resource(job->zsbuf->texture);
v3d_job_add_bo(job, rsc->bo);
- job->resolve |= PIPE_CLEAR_DEPTH;
+ job->store |= PIPE_CLEAR_DEPTH;
rsc->initialized_buffers = PIPE_CLEAR_DEPTH;
}
v3d_job_add_bo(job, rsc->bo);
- job->resolve |= PIPE_CLEAR_STENCIL;
+ job->store |= PIPE_CLEAR_STENCIL;
rsc->initialized_buffers |= PIPE_CLEAR_STENCIL;
}
for (int i = 0; i < VC5_MAX_DRAW_BUFFERS; i++) {
uint32_t bit = PIPE_CLEAR_COLOR0 << i;
- if (job->resolve & bit || !job->cbufs[i])
+ if (job->store & bit || !job->cbufs[i])
continue;
struct v3d_resource *rsc = v3d_resource(job->cbufs[i]->texture);
- job->resolve |= bit;
+ job->store |= bit;
v3d_job_add_bo(job, rsc->bo);
}
v3d_flush(pctx);
}
+/* GFXH-1461: If we were to emit a load of just depth or just stencil, then
+ * the clear for the other may get lost. Just fall back to drawing a quad in
+ * that case.
+ */
+static bool
+v3d_gfxh1461_clear_workaround(struct v3d_context *v3d,
+ unsigned buffers, double depth, unsigned stencil)
+{
+ unsigned zsclear = buffers & PIPE_CLEAR_DEPTHSTENCIL;
+ if (!zsclear || zsclear == PIPE_CLEAR_DEPTHSTENCIL)
+ return false;
+
+ static const union pipe_color_union dummy_color = {};
+
+ v3d_blitter_save(v3d);
+ util_blitter_clear(v3d->blitter,
+ v3d->framebuffer.width,
+ v3d->framebuffer.height,
+ 1,
+ zsclear,
+ &dummy_color, depth, stencil);
+ return true;
+}
+
static void
v3d_clear(struct pipe_context *pctx, unsigned buffers,
const union pipe_color_union *color, double depth, unsigned stencil)
struct v3d_context *v3d = v3d_context(pctx);
struct v3d_job *job = v3d_get_job_for_fbo(v3d);
+ if (v3d_gfxh1461_clear_workaround(v3d, buffers, depth, stencil))
+ buffers &= ~PIPE_CLEAR_DEPTHSTENCIL;
+
+ if (!buffers)
+ return;
+
/* We can't flag new buffers for clearing once we've queued draws. We
* could avoid this by using the 3d engine to clear.
*/
job->draw_min_y = 0;
job->draw_max_x = v3d->framebuffer.width;
job->draw_max_y = v3d->framebuffer.height;
- job->cleared |= buffers;
- job->resolve |= buffers;
+ job->clear |= buffers;
+ job->store |= buffers;
v3d_start_draw(v3d);
}