#include "fd5_program.h"
#include "fd5_rasterizer.h"
#include "fd5_texture.h"
+#include "fd5_screen.h"
#include "fd5_format.h"
#include "fd5_zsa.h"
* sizedwords: size of const value buffer
*/
static void
-fd5_emit_const(struct fd_ringbuffer *ring, enum shader_t type,
+fd5_emit_const(struct fd_ringbuffer *ring, gl_shader_stage type,
uint32_t regid, uint32_t offset, uint32_t sizedwords,
const uint32_t *dwords, struct pipe_resource *prsc)
{
}
static void
-fd5_emit_const_bo(struct fd_ringbuffer *ring, enum shader_t type, boolean write,
+fd5_emit_const_bo(struct fd_ringbuffer *ring, gl_shader_stage type, boolean write,
uint32_t regid, uint32_t num, struct pipe_resource **prscs, uint32_t *offsets)
{
uint32_t anum = align(num, 2);
uint32_t size = fd_bo_size(rsc->bo) - off;
debug_assert(fmt != ~0);
+#ifdef DEBUG
+ /* see dEQP-GLES31.stress.vertex_attribute_binding.buffer_bounds.bind_vertex_buffer_offset_near_wrap_10
+ */
+ if (off > fd_bo_size(rsc->bo))
+ continue;
+#endif
+
OUT_PKT4(ring, REG_A5XX_VFD_FETCH(j), 4);
OUT_RELOC(ring, rsc->bo, off, 0, 0);
OUT_RING(ring, size); /* VFD_FETCH[j].SIZE */
emit_marker5(ring, 5);
- if ((dirty & FD_DIRTY_FRAMEBUFFER) && !emit->key.binning_pass) {
+ if ((dirty & FD_DIRTY_FRAMEBUFFER) && !emit->binning_pass) {
unsigned char mrt_comp[A5XX_MAX_RENDER_TARGETS] = {0};
for (unsigned i = 0; i < A5XX_MAX_RENDER_TARGETS; i++) {
if (emit->no_lrz_write || !rsc->lrz || !rsc->lrz_valid)
gras_lrz_cntl = 0;
- else if (emit->key.binning_pass && blend->lrz_write && zsa->lrz_write)
+ else if (emit->binning_pass && blend->lrz_write && zsa->lrz_write)
gras_lrz_cntl |= A5XX_GRAS_LRZ_CNTL_LRZ_WRITE;
OUT_PKT4(ring, REG_A5XX_GRAS_LRZ_CNTL, 1);
COND(fragz && fp->frag_coord, A5XX_GRAS_SU_DEPTH_PLANE_CNTL_UNK1));
}
- if (dirty & FD_DIRTY_SCISSOR) {
+ /* NOTE: scissor enabled bit is part of rasterizer state: */
+ if (dirty & (FD_DIRTY_SCISSOR | FD_DIRTY_RASTERIZER)) {
struct pipe_scissor_state *scissor = fd_context_get_scissor(ctx);
OUT_PKT4(ring, REG_A5XX_GRAS_SC_SCREEN_SCISSOR_TL_0, 2);
fd5_rasterizer_stateobj(ctx->rasterizer);
OUT_PKT4(ring, REG_A5XX_GRAS_SU_CNTL, 1);
- OUT_RING(ring, rasterizer->gras_su_cntl);
+ OUT_RING(ring, rasterizer->gras_su_cntl |
+ COND(pfb->samples > 1, A5XX_GRAS_SU_CNTL_MSAA_ENABLE));
OUT_PKT4(ring, REG_A5XX_GRAS_SU_POINT_MINMAX, 2);
OUT_RING(ring, rasterizer->gras_su_point_minmax);
uint32_t posz_regid = ir3_find_output_regid(fp, FRAG_RESULT_DEPTH);
unsigned nr = pfb->nr_cbufs;
- if (emit->key.binning_pass)
+ if (emit->binning_pass)
nr = 0;
else if (ctx->rasterizer->rasterizer_discard)
nr = 0;
A5XX_SP_FS_OUTPUT_CNTL_SAMPLEMASK_REGID(regid(63, 0)));
}
- if (emit->prog == &ctx->prog) { /* evil hack to deal sanely with clear path */
- ir3_emit_vs_consts(vp, ring, ctx, emit->info);
- if (!emit->key.binning_pass)
- ir3_emit_fs_consts(fp, ring, ctx);
+ ir3_emit_vs_consts(vp, ring, ctx, emit->info);
+ if (!emit->binning_pass)
+ ir3_emit_fs_consts(fp, ring, ctx);
- struct pipe_stream_output_info *info = &vp->shader->stream_output;
- if (info->num_outputs) {
- struct fd_streamout_stateobj *so = &ctx->streamout;
+ struct ir3_stream_output_info *info = &vp->shader->stream_output;
+ if (info->num_outputs) {
+ struct fd_streamout_stateobj *so = &ctx->streamout;
- for (unsigned i = 0; i < so->num_targets; i++) {
- struct pipe_stream_output_target *target = so->targets[i];
+ for (unsigned i = 0; i < so->num_targets; i++) {
+ struct pipe_stream_output_target *target = so->targets[i];
- if (!target)
- continue;
+ if (!target)
+ continue;
- unsigned offset = (so->offsets[i] * info->stride[i] * 4) +
- target->buffer_offset;
+ unsigned offset = (so->offsets[i] * info->stride[i] * 4) +
+ target->buffer_offset;
- OUT_PKT4(ring, REG_A5XX_VPC_SO_BUFFER_BASE_LO(i), 3);
- /* VPC_SO[i].BUFFER_BASE_LO: */
- OUT_RELOCW(ring, fd_resource(target->buffer)->bo, 0, 0, 0);
- OUT_RING(ring, target->buffer_size + offset);
+ OUT_PKT4(ring, REG_A5XX_VPC_SO_BUFFER_BASE_LO(i), 3);
+ /* VPC_SO[i].BUFFER_BASE_LO: */
+ OUT_RELOCW(ring, fd_resource(target->buffer)->bo, 0, 0, 0);
+ OUT_RING(ring, target->buffer_size + offset);
- OUT_PKT4(ring, REG_A5XX_VPC_SO_BUFFER_OFFSET(i), 3);
- OUT_RING(ring, offset);
- /* VPC_SO[i].FLUSH_BASE_LO/HI: */
- // TODO just give hw a dummy addr for now.. we should
- // be using this an then CP_MEM_TO_REG to set the
- // VPC_SO[i].BUFFER_OFFSET for the next draw..
- OUT_RELOCW(ring, fd5_context(ctx)->blit_mem, 0x100, 0, 0);
+ OUT_PKT4(ring, REG_A5XX_VPC_SO_BUFFER_OFFSET(i), 3);
+ OUT_RING(ring, offset);
+ /* VPC_SO[i].FLUSH_BASE_LO/HI: */
+ // TODO just give hw a dummy addr for now.. we should
+ // be using this an then CP_MEM_TO_REG to set the
+ // VPC_SO[i].BUFFER_OFFSET for the next draw..
+ OUT_RELOCW(ring, fd5_context(ctx)->blit_mem, 0x100, 0, 0);
- emit->streamout_mask |= (1 << i);
- }
+ emit->streamout_mask |= (1 << i);
}
}
- if ((dirty & FD_DIRTY_BLEND)) {
+ if (dirty & FD_DIRTY_BLEND) {
struct fd5_blend_stateobj *blend = fd5_blend_stateobj(ctx->blend);
uint32_t i;
OUT_RING(ring, blend_control);
}
- OUT_PKT4(ring, REG_A5XX_RB_BLEND_CNTL, 1);
- OUT_RING(ring, blend->rb_blend_cntl |
- A5XX_RB_BLEND_CNTL_SAMPLE_MASK(0xffff));
-
OUT_PKT4(ring, REG_A5XX_SP_BLEND_CNTL, 1);
OUT_RING(ring, blend->sp_blend_cntl);
}
+ if (dirty & (FD_DIRTY_BLEND | FD_DIRTY_SAMPLE_MASK)) {
+ struct fd5_blend_stateobj *blend = fd5_blend_stateobj(ctx->blend);
+
+ OUT_PKT4(ring, REG_A5XX_RB_BLEND_CNTL, 1);
+ OUT_RING(ring, blend->rb_blend_cntl |
+ A5XX_RB_BLEND_CNTL_SAMPLE_MASK(ctx->sample_mask));
+ }
+
if (dirty & FD_DIRTY_BLEND_COLOR) {
struct pipe_blend_color *bcolor = &ctx->blend_color;
static void
fd5_emit_ib(struct fd_ringbuffer *ring, struct fd_ringbuffer *target)
{
+ /* for debug after a lock up, write a unique counter value
+ * to scratch6 for each IB, to make it easier to match up
+ * register dumps to cmdstream. The combination of IB and
+ * DRAW (scratch7) is enough to "triangulate" the particular
+ * draw that caused lockup.
+ */
+ emit_marker5(ring, 6);
__OUT_IB5(ring, target);
+ emit_marker5(ring, 6);
}
static void