{
unsigned const_idx = fd2_get_const_idx(ctx, tex, samp_id);
static const struct fd2_sampler_stateobj dummy_sampler = {};
+ static const struct fd2_pipe_sampler_view dummy_view = {};
const struct fd2_sampler_stateobj *sampler;
- struct fd2_pipe_sampler_view *view;
+ const struct fd2_pipe_sampler_view *view;
if (emitted & (1 << const_idx))
return 0;
sampler = tex->samplers[samp_id] ?
fd2_sampler_stateobj(tex->samplers[samp_id]) :
&dummy_sampler;
- view = fd2_pipe_sampler_view(tex->textures[samp_id]);
+ view = tex->textures[samp_id] ?
+ fd2_pipe_sampler_view(tex->textures[samp_id]) :
+ &dummy_view;
OUT_PKT3(ring, CP_SET_CONSTANT, 7);
OUT_RING(ring, 0x00010000 + (0x6 * const_idx));
OUT_RING(ring, sampler->tex0 | view->tex0);
- OUT_RELOC(ring, fd_resource(view->base.texture)->bo, 0, view->fmt, 0);
+ if (view->base.texture)
+ OUT_RELOC(ring, fd_resource(view->base.texture)->bo, 0, view->fmt, 0);
+ else
+ OUT_RING(ring, 0);
+
OUT_RING(ring, view->tex2);
OUT_RING(ring, sampler->tex3 | view->tex3);
OUT_RING(ring, sampler->tex4);
static void
emit_textures(struct fd_ringbuffer *ring, struct fd_context *ctx)
{
+ struct fd_texture_stateobj *fragtex = &ctx->tex[PIPE_SHADER_FRAGMENT];
+ struct fd_texture_stateobj *verttex = &ctx->tex[PIPE_SHADER_VERTEX];
texmask emitted = 0;
unsigned i;
- for (i = 0; i < ctx->verttex.num_samplers; i++)
- if (ctx->verttex.samplers[i])
- emitted |= emit_texture(ring, ctx, &ctx->verttex, i, emitted);
+ for (i = 0; i < verttex->num_samplers; i++)
+ if (verttex->samplers[i])
+ emitted |= emit_texture(ring, ctx, verttex, i, emitted);
- for (i = 0; i < ctx->fragtex.num_samplers; i++)
- if (ctx->fragtex.samplers[i])
- emitted |= emit_texture(ring, ctx, &ctx->fragtex, i, emitted);
+ for (i = 0; i < fragtex->num_samplers; i++)
+ if (fragtex->samplers[i])
+ emitted |= emit_texture(ring, ctx, fragtex, i, emitted);
}
void
}
void
-fd2_emit_state(struct fd_context *ctx, uint32_t dirty)
+fd2_emit_state(struct fd_context *ctx, const enum fd_dirty_3d_state dirty)
{
struct fd2_blend_stateobj *blend = fd2_blend_stateobj(ctx->blend);
struct fd2_zsa_stateobj *zsa = fd2_zsa_stateobj(ctx->zsa);
- struct fd_ringbuffer *ring = ctx->ring;
+ struct fd_ringbuffer *ring = ctx->batch->draw;
/* NOTE: we probably want to eventually refactor this so each state
* object handles emitting it's own state.. although the mapping of
OUT_RING(ring, zsa->rb_alpha_ref);
}
- if (dirty & (FD_DIRTY_RASTERIZER | FD_DIRTY_FRAMEBUFFER)) {
+ if (ctx->rasterizer && dirty & FD_DIRTY_RASTERIZER) {
struct fd2_rasterizer_stateobj *rasterizer =
fd2_rasterizer_stateobj(ctx->rasterizer);
OUT_PKT3(ring, CP_SET_CONSTANT, 3);
OUT_RING(ring, xy2d(scissor->maxx, /* PA_SC_WINDOW_SCISSOR_BR */
scissor->maxy));
- ctx->max_scissor.minx = MIN2(ctx->max_scissor.minx, scissor->minx);
- ctx->max_scissor.miny = MIN2(ctx->max_scissor.miny, scissor->miny);
- ctx->max_scissor.maxx = MAX2(ctx->max_scissor.maxx, scissor->maxx);
- ctx->max_scissor.maxy = MAX2(ctx->max_scissor.maxy, scissor->maxy);
+ ctx->batch->max_scissor.minx = MIN2(ctx->batch->max_scissor.minx, scissor->minx);
+ ctx->batch->max_scissor.miny = MIN2(ctx->batch->max_scissor.miny, scissor->miny);
+ ctx->batch->max_scissor.maxx = MAX2(ctx->batch->max_scissor.maxx, scissor->maxx);
+ ctx->batch->max_scissor.maxy = MAX2(ctx->batch->max_scissor.maxy, scissor->maxy);
}
if (dirty & FD_DIRTY_VIEWPORT) {
fd2_program_emit(ring, &ctx->prog);
}
- if (dirty & (FD_DIRTY_PROG | FD_DIRTY_CONSTBUF)) {
+ if (dirty & (FD_DIRTY_PROG | FD_DIRTY_CONST)) {
emit_constants(ring, VS_CONST_BASE * 4,
&ctx->constbuf[PIPE_SHADER_VERTEX],
(dirty & FD_DIRTY_PROG) ? ctx->prog.vp : NULL);
OUT_RING(ring, zsa->rb_colorcontrol | blend->rb_colorcontrol);
}
- if (dirty & FD_DIRTY_BLEND) {
+ if (dirty & (FD_DIRTY_BLEND | FD_DIRTY_FRAMEBUFFER)) {
+ enum pipe_format format =
+ pipe_surface_format(ctx->batch->framebuffer.cbufs[0]);
+ bool has_alpha = util_format_has_alpha(format);
+
OUT_PKT3(ring, CP_SET_CONSTANT, 2);
OUT_RING(ring, CP_REG(REG_A2XX_RB_BLEND_CONTROL));
- OUT_RING(ring, blend->rb_blendcontrol);
+ OUT_RING(ring, blend->rb_blendcontrol_alpha |
+ COND(has_alpha, blend->rb_blendcontrol_rgb) |
+ COND(!has_alpha, blend->rb_blendcontrol_no_alpha_rgb));
OUT_PKT3(ring, CP_SET_CONSTANT, 2);
OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_MASK));
OUT_RING(ring, blend->rb_colormask);
}
- if (dirty & (FD_DIRTY_VERTTEX | FD_DIRTY_FRAGTEX | FD_DIRTY_PROG))
- emit_textures(ring, ctx);
+ if (dirty & FD_DIRTY_BLEND_COLOR) {
+ OUT_PKT3(ring, CP_SET_CONSTANT, 5);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_BLEND_RED));
+ OUT_RING(ring, float_to_ubyte(ctx->blend_color.color[0]));
+ OUT_RING(ring, float_to_ubyte(ctx->blend_color.color[1]));
+ OUT_RING(ring, float_to_ubyte(ctx->blend_color.color[2]));
+ OUT_RING(ring, float_to_ubyte(ctx->blend_color.color[3]));
+ }
- ctx->dirty &= ~dirty;
+ if (dirty & (FD_DIRTY_TEX | FD_DIRTY_PROG))
+ emit_textures(ring, ctx);
}
/* emit per-context initialization:
}
static void
-fd2_emit_ib(struct fd_ringbuffer *ring, struct fd_ringmarker *start,
- struct fd_ringmarker *end)
+fd2_emit_ib(struct fd_ringbuffer *ring, struct fd_ringbuffer *target)
{
- __OUT_IB(ring, false, start, end);
+ __OUT_IB(ring, false, target);
}
void