{
struct r600_context *rctx = (struct r600_context *)context;
+ if (rctx->no_blend) {
+ rctx->context.delete_blend_state(&rctx->context, rctx->no_blend);
+ }
if (rctx->dummy_pixel_shader) {
rctx->context.delete_fs_state(&rctx->context, rctx->dummy_pixel_shader);
}
{
struct r600_context *rctx = CALLOC_STRUCT(r600_context);
struct r600_screen* rscreen = (struct r600_screen *)screen;
+ struct pipe_blend_state no_blend = {};
if (rctx == NULL)
return NULL;
TGSI_INTERPOLATE_CONSTANT);
rctx->context.bind_fs_state(&rctx->context, rctx->dummy_pixel_shader);
+ no_blend.rt[0].colormask = 0xF;
+ rctx->no_blend = rctx->context.create_blend_state(&rctx->context, &no_blend);
+
return &rctx->context;
fail:
struct r600_cs_shader_state cs_shader_state;
struct r600_sample_mask sample_mask;
+ /* current external blend state (from state tracker) */
+ struct r600_pipe_blend *blend;
+ /* state with disabled blending - used internally with blend_override */
+ struct r600_pipe_blend *no_blend;
+
+ /* 1 - override current blend state with no_blend, 0 - use external state */
+ unsigned blend_override;
+
struct radeon_winsys_cs *cs;
struct r600_range *range;
}
/* common state between evergreen and r600 */
-void r600_bind_blend_state(struct pipe_context *ctx, void *state)
+
+static void r600_bind_blend_state_internal(struct r600_context *rctx,
+ struct r600_pipe_blend *blend)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
- struct r600_pipe_blend *blend = (struct r600_pipe_blend *)state;
struct r600_pipe_state *rstate;
bool update_cb = false;
- if (state == NULL)
- return;
rstate = &blend->rstate;
rctx->states[rstate->id] = rstate;
- rctx->dual_src_blend = blend->dual_src_blend;
- rctx->alpha_to_one = blend->alpha_to_one;
r600_context_pipe_state_set(rctx, rstate);
if (rctx->cb_misc_state.blend_colormask != blend->cb_target_mask) {
}
}
+void r600_bind_blend_state(struct pipe_context *ctx, void *state)
+{
+ struct r600_context *rctx = (struct r600_context *)ctx;
+ struct r600_pipe_blend *blend = (struct r600_pipe_blend *)state;
+
+ if (blend == NULL)
+ return;
+
+ rctx->blend = blend;
+ rctx->alpha_to_one = blend->alpha_to_one;
+ rctx->dual_src_blend = blend->dual_src_blend;
+
+ if (!rctx->blend_override)
+ r600_bind_blend_state_internal(rctx, blend);
+}
+
void r600_set_blend_color(struct pipe_context *ctx,
const struct pipe_blend_color *state)
{
static void r600_update_derived_state(struct r600_context *rctx)
{
struct pipe_context * ctx = (struct pipe_context*)rctx;
- unsigned ps_dirty = 0;
+ unsigned ps_dirty = 0, blend_override;
if (!rctx->blitter->running) {
/* Flush depth textures which need to be flushed. */
if (ps_dirty)
r600_context_pipe_state_set(rctx, &rctx->ps_shader->current->rstate);
-
+
+ blend_override = (rctx->dual_src_blend &&
+ rctx->ps_shader->current->nr_ps_color_outputs < 2);
+
+ if (blend_override != rctx->blend_override) {
+ rctx->blend_override = blend_override;
+ r600_bind_blend_state_internal(rctx,
+ blend_override ? rctx->no_blend : rctx->blend);
+ }
+
if (rctx->chip_class >= EVERGREEN) {
evergreen_update_dual_export_state(rctx);
} else {