blob: b759a910b638bd08bebcc3103b1d1322ccd7e7b9 [file] [log] [blame]
#include "util/u_memory.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "brw_context.h"
#include "brw_defines.h"
#include "brw_debug.h"
static int translate_logicop(unsigned logicop)
{
switch (logicop) {
case PIPE_LOGICOP_CLEAR:
return BRW_LOGICOPFUNCTION_CLEAR;
case PIPE_LOGICOP_AND:
return BRW_LOGICOPFUNCTION_AND;
case PIPE_LOGICOP_AND_REVERSE:
return BRW_LOGICOPFUNCTION_AND_REVERSE;
case PIPE_LOGICOP_COPY:
return BRW_LOGICOPFUNCTION_COPY;
case PIPE_LOGICOP_COPY_INVERTED:
return BRW_LOGICOPFUNCTION_COPY_INVERTED;
case PIPE_LOGICOP_AND_INVERTED:
return BRW_LOGICOPFUNCTION_AND_INVERTED;
case PIPE_LOGICOP_NOOP:
return BRW_LOGICOPFUNCTION_NOOP;
case PIPE_LOGICOP_XOR:
return BRW_LOGICOPFUNCTION_XOR;
case PIPE_LOGICOP_OR:
return BRW_LOGICOPFUNCTION_OR;
case PIPE_LOGICOP_OR_INVERTED:
return BRW_LOGICOPFUNCTION_OR_INVERTED;
case PIPE_LOGICOP_NOR:
return BRW_LOGICOPFUNCTION_NOR;
case PIPE_LOGICOP_EQUIV:
return BRW_LOGICOPFUNCTION_EQUIV;
case PIPE_LOGICOP_INVERT:
return BRW_LOGICOPFUNCTION_INVERT;
case PIPE_LOGICOP_OR_REVERSE:
return BRW_LOGICOPFUNCTION_OR_REVERSE;
case PIPE_LOGICOP_NAND:
return BRW_LOGICOPFUNCTION_NAND;
case PIPE_LOGICOP_SET:
return BRW_LOGICOPFUNCTION_SET;
default:
assert(0);
return BRW_LOGICOPFUNCTION_SET;
}
}
static unsigned translate_blend_equation( unsigned mode )
{
switch (mode) {
case PIPE_BLEND_ADD:
return BRW_BLENDFUNCTION_ADD;
case PIPE_BLEND_MIN:
return BRW_BLENDFUNCTION_MIN;
case PIPE_BLEND_MAX:
return BRW_BLENDFUNCTION_MAX;
case PIPE_BLEND_SUBTRACT:
return BRW_BLENDFUNCTION_SUBTRACT;
case PIPE_BLEND_REVERSE_SUBTRACT:
return BRW_BLENDFUNCTION_REVERSE_SUBTRACT;
default:
assert(0);
return BRW_BLENDFUNCTION_ADD;
}
}
static unsigned translate_blend_factor( unsigned factor )
{
switch(factor) {
case PIPE_BLENDFACTOR_ZERO:
return BRW_BLENDFACTOR_ZERO;
case PIPE_BLENDFACTOR_SRC_ALPHA:
return BRW_BLENDFACTOR_SRC_ALPHA;
case PIPE_BLENDFACTOR_ONE:
return BRW_BLENDFACTOR_ONE;
case PIPE_BLENDFACTOR_SRC_COLOR:
return BRW_BLENDFACTOR_SRC_COLOR;
case PIPE_BLENDFACTOR_INV_SRC_COLOR:
return BRW_BLENDFACTOR_INV_SRC_COLOR;
case PIPE_BLENDFACTOR_DST_COLOR:
return BRW_BLENDFACTOR_DST_COLOR;
case PIPE_BLENDFACTOR_INV_DST_COLOR:
return BRW_BLENDFACTOR_INV_DST_COLOR;
case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
return BRW_BLENDFACTOR_INV_SRC_ALPHA;
case PIPE_BLENDFACTOR_DST_ALPHA:
return BRW_BLENDFACTOR_DST_ALPHA;
case PIPE_BLENDFACTOR_INV_DST_ALPHA:
return BRW_BLENDFACTOR_INV_DST_ALPHA;
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
return BRW_BLENDFACTOR_SRC_ALPHA_SATURATE;
case PIPE_BLENDFACTOR_CONST_COLOR:
return BRW_BLENDFACTOR_CONST_COLOR;
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
return BRW_BLENDFACTOR_INV_CONST_COLOR;
case PIPE_BLENDFACTOR_CONST_ALPHA:
return BRW_BLENDFACTOR_CONST_ALPHA;
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
return BRW_BLENDFACTOR_INV_CONST_ALPHA;
default:
assert(0);
return BRW_BLENDFACTOR_ZERO;
}
}
static void *brw_create_blend_state( struct pipe_context *pipe,
const struct pipe_blend_state *templ )
{
struct brw_blend_state *blend = CALLOC_STRUCT(brw_blend_state);
if (blend == NULL)
return NULL;
if (templ->logicop_enable) {
blend->cc2.logicop_enable = 1;
blend->cc5.logicop_func = translate_logicop(templ->logicop_func);
}
else if (templ->blend_enable) {
blend->cc6.dest_blend_factor = translate_blend_factor(templ->rgb_dst_factor);
blend->cc6.src_blend_factor = translate_blend_factor(templ->rgb_src_factor);
blend->cc6.blend_function = translate_blend_equation(templ->rgb_func);
blend->cc5.ia_dest_blend_factor = translate_blend_factor(templ->alpha_dst_factor);
blend->cc5.ia_src_blend_factor = translate_blend_factor(templ->alpha_src_factor);
blend->cc5.ia_blend_function = translate_blend_equation(templ->alpha_func);
blend->cc3.blend_enable = 1;
blend->cc3.ia_blend_enable =
(blend->cc6.dest_blend_factor != blend->cc5.ia_dest_blend_factor ||
blend->cc6.src_blend_factor != blend->cc5.ia_src_blend_factor ||
blend->cc6.blend_function != blend->cc5.ia_blend_function);
/* Per-surface blend enables, currently just follow global
* state:
*/
blend->ss0.color_blend = 1;
}
blend->cc5.dither_enable = templ->dither;
if (BRW_DEBUG & DEBUG_STATS)
blend->cc5.statistics_enable = 1;
/* Per-surface color mask -- just follow global state:
*/
blend->ss0.writedisable_red = (templ->colormask & PIPE_MASK_R) ? 0 : 1;
blend->ss0.writedisable_green = (templ->colormask & PIPE_MASK_G) ? 0 : 1;
blend->ss0.writedisable_blue = (templ->colormask & PIPE_MASK_B) ? 0 : 1;
blend->ss0.writedisable_alpha = (templ->colormask & PIPE_MASK_A) ? 0 : 1;
return (void *)blend;
}
static void brw_bind_blend_state(struct pipe_context *pipe,
void *cso)
{
struct brw_context *brw = brw_context(pipe);
brw->curr.blend = (const struct brw_blend_state *)cso;
brw->state.dirty.mesa |= PIPE_NEW_BLEND;
}
static void brw_delete_blend_state(struct pipe_context *pipe,
void *cso)
{
struct brw_context *brw = brw_context(pipe);
assert((const void *)cso != (const void *)brw->curr.blend);
FREE(cso);
}
static void brw_set_blend_color(struct pipe_context *pipe,
const struct pipe_blend_color *blend_color)
{
struct brw_context *brw = brw_context(pipe);
struct brw_blend_constant_color *bcc = &brw->curr.bcc;
bcc->blend_constant_color[0] = blend_color->color[0];
bcc->blend_constant_color[1] = blend_color->color[1];
bcc->blend_constant_color[2] = blend_color->color[2];
bcc->blend_constant_color[3] = blend_color->color[3];
brw->state.dirty.mesa |= PIPE_NEW_BLEND_COLOR;
}
void brw_pipe_blend_init( struct brw_context *brw )
{
brw->base.set_blend_color = brw_set_blend_color;
brw->base.create_blend_state = brw_create_blend_state;
brw->base.bind_blend_state = brw_bind_blend_state;
brw->base.delete_blend_state = brw_delete_blend_state;
{
struct brw_blend_constant_color *bcc = &brw->curr.bcc;
memset(bcc, 0, sizeof(*bcc));
bcc->header.opcode = CMD_BLEND_CONSTANT_COLOR;
bcc->header.length = sizeof(*bcc)/4-2;
}
}
void brw_pipe_blend_cleanup( struct brw_context *brw )
{
}