00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027  
00028 
00029 
00030 
00031 
00032 #include "util/u_math.h"
00033 #include "util/u_memory.h"
00034 
00035 #include "brw_context.h"
00036 #include "brw_state.h"
00037 #include "brw_defines.h"
00038 #include "brw_util.h"
00039 
00040 
00041 static int brw_translate_compare_func(int func)
00042 {
00043    switch(func) {
00044    case PIPE_FUNC_NEVER:
00045       return BRW_COMPAREFUNCTION_NEVER;
00046    case PIPE_FUNC_LESS:
00047       return BRW_COMPAREFUNCTION_LESS;
00048    case PIPE_FUNC_LEQUAL:
00049       return BRW_COMPAREFUNCTION_LEQUAL;
00050    case PIPE_FUNC_GREATER:
00051       return BRW_COMPAREFUNCTION_GREATER;
00052    case PIPE_FUNC_GEQUAL:
00053       return BRW_COMPAREFUNCTION_GEQUAL;
00054    case PIPE_FUNC_NOTEQUAL:
00055       return BRW_COMPAREFUNCTION_NOTEQUAL;
00056    case PIPE_FUNC_EQUAL:
00057       return BRW_COMPAREFUNCTION_EQUAL;
00058    case PIPE_FUNC_ALWAYS:
00059       return BRW_COMPAREFUNCTION_ALWAYS;
00060    }
00061 
00062    debug_printf("Unknown value in %s: %x\n", __FUNCTION__, func);
00063    return BRW_COMPAREFUNCTION_ALWAYS;
00064 }
00065 
00066 static int brw_translate_stencil_op(int op)
00067 {
00068    switch(op) {
00069    case PIPE_STENCIL_OP_KEEP:
00070       return BRW_STENCILOP_KEEP;
00071    case PIPE_STENCIL_OP_ZERO:
00072       return BRW_STENCILOP_ZERO;
00073    case PIPE_STENCIL_OP_REPLACE:
00074       return BRW_STENCILOP_REPLACE;
00075    case PIPE_STENCIL_OP_INCR:
00076       return BRW_STENCILOP_INCRSAT;
00077    case PIPE_STENCIL_OP_DECR:
00078       return BRW_STENCILOP_DECRSAT;
00079    case PIPE_STENCIL_OP_INCR_WRAP:
00080       return BRW_STENCILOP_INCR;
00081    case PIPE_STENCIL_OP_DECR_WRAP:
00082       return BRW_STENCILOP_DECR;
00083    case PIPE_STENCIL_OP_INVERT:
00084       return BRW_STENCILOP_INVERT;
00085    default:
00086       return BRW_STENCILOP_ZERO;
00087    }
00088 }
00089 
00090 
00091 static int brw_translate_logic_op(int opcode)
00092 {
00093    switch(opcode) {
00094    case PIPE_LOGICOP_CLEAR:
00095       return BRW_LOGICOPFUNCTION_CLEAR;
00096    case PIPE_LOGICOP_AND:
00097       return BRW_LOGICOPFUNCTION_AND;
00098    case PIPE_LOGICOP_AND_REVERSE:
00099       return BRW_LOGICOPFUNCTION_AND_REVERSE;
00100    case PIPE_LOGICOP_COPY:
00101       return BRW_LOGICOPFUNCTION_COPY;
00102    case PIPE_LOGICOP_COPY_INVERTED:
00103       return BRW_LOGICOPFUNCTION_COPY_INVERTED;
00104    case PIPE_LOGICOP_AND_INVERTED:
00105       return BRW_LOGICOPFUNCTION_AND_INVERTED;
00106    case PIPE_LOGICOP_NOOP:
00107       return BRW_LOGICOPFUNCTION_NOOP;
00108    case PIPE_LOGICOP_XOR:
00109       return BRW_LOGICOPFUNCTION_XOR;
00110    case PIPE_LOGICOP_OR:
00111       return BRW_LOGICOPFUNCTION_OR;
00112    case PIPE_LOGICOP_OR_INVERTED:
00113       return BRW_LOGICOPFUNCTION_OR_INVERTED;
00114    case PIPE_LOGICOP_NOR:
00115       return BRW_LOGICOPFUNCTION_NOR;
00116    case PIPE_LOGICOP_EQUIV:
00117       return BRW_LOGICOPFUNCTION_EQUIV;
00118    case PIPE_LOGICOP_INVERT:
00119       return BRW_LOGICOPFUNCTION_INVERT;
00120    case PIPE_LOGICOP_OR_REVERSE:
00121       return BRW_LOGICOPFUNCTION_OR_REVERSE;
00122    case PIPE_LOGICOP_NAND:
00123       return BRW_LOGICOPFUNCTION_NAND;
00124    case PIPE_LOGICOP_SET:
00125       return BRW_LOGICOPFUNCTION_SET;
00126    default:
00127       return BRW_LOGICOPFUNCTION_SET;
00128    }
00129 }
00130 
00131 
00132 static void upload_cc_vp( struct brw_context *brw )
00133 {
00134    struct brw_cc_viewport ccv;
00135 
00136    memset(&ccv, 0, sizeof(ccv));
00137 
00138    ccv.min_depth = 0.0;
00139    ccv.max_depth = 1.0;
00140 
00141    brw->cc.vp_gs_offset = brw_cache_data( &brw->cache[BRW_CC_VP], &ccv );
00142 }
00143 
00144 const struct brw_tracked_state brw_cc_vp = {
00145    .dirty = {
00146       .brw = BRW_NEW_SCENE,
00147       .cache = 0
00148    },
00149    .update = upload_cc_vp
00150 };
00151 
00152 
00153 static void upload_cc_unit( struct brw_context *brw )
00154 {
00155    struct brw_cc_unit_state cc;
00156 
00157    memset(&cc, 0, sizeof(cc));
00158 
00159    
00160    if (brw->attribs.DepthStencil->stencil[0].enabled) {
00161       cc.cc0.stencil_enable = brw->attribs.DepthStencil->stencil[0].enabled;
00162       cc.cc0.stencil_func = brw_translate_compare_func(brw->attribs.DepthStencil->stencil[0].func);
00163       cc.cc0.stencil_fail_op = brw_translate_stencil_op(brw->attribs.DepthStencil->stencil[0].fail_op);
00164       cc.cc0.stencil_pass_depth_fail_op = brw_translate_stencil_op(
00165          brw->attribs.DepthStencil->stencil[0].zfail_op);
00166       cc.cc0.stencil_pass_depth_pass_op = brw_translate_stencil_op(
00167          brw->attribs.DepthStencil->stencil[0].zpass_op);
00168       cc.cc1.stencil_ref = brw->attribs.DepthStencil->stencil[0].ref_value;
00169       cc.cc1.stencil_write_mask = brw->attribs.DepthStencil->stencil[0].write_mask;
00170       cc.cc1.stencil_test_mask = brw->attribs.DepthStencil->stencil[0].value_mask;
00171 
00172       if (brw->attribs.DepthStencil->stencil[1].enabled) {
00173          cc.cc0.bf_stencil_enable = brw->attribs.DepthStencil->stencil[1].enabled;
00174          cc.cc0.bf_stencil_func = brw_translate_compare_func(
00175             brw->attribs.DepthStencil->stencil[1].func);
00176          cc.cc0.bf_stencil_fail_op = brw_translate_stencil_op(
00177             brw->attribs.DepthStencil->stencil[1].fail_op);
00178          cc.cc0.bf_stencil_pass_depth_fail_op = brw_translate_stencil_op(
00179             brw->attribs.DepthStencil->stencil[1].zfail_op);
00180          cc.cc0.bf_stencil_pass_depth_pass_op = brw_translate_stencil_op(
00181             brw->attribs.DepthStencil->stencil[1].zpass_op);
00182          cc.cc1.bf_stencil_ref = brw->attribs.DepthStencil->stencil[1].ref_value;
00183          cc.cc2.bf_stencil_write_mask = brw->attribs.DepthStencil->stencil[1].write_mask;
00184          cc.cc2.bf_stencil_test_mask = brw->attribs.DepthStencil->stencil[1].value_mask;
00185       }
00186 
00187       
00188 
00189       if (brw->attribs.DepthStencil->stencil[0].write_mask ||
00190           brw->attribs.DepthStencil->stencil[1].write_mask)
00191          cc.cc0.stencil_write_enable = 1;
00192    }
00193 
00194    
00195    if (brw->attribs.Blend->logicop_enable) {
00196       cc.cc2.logicop_enable = 1;
00197       cc.cc5.logicop_func = brw_translate_logic_op( brw->attribs.Blend->logicop_func );
00198    }
00199    else if (brw->attribs.Blend->blend_enable) {
00200       int eqRGB = brw->attribs.Blend->rgb_func;
00201       int eqA = brw->attribs.Blend->alpha_func;
00202       int srcRGB = brw->attribs.Blend->rgb_src_factor;
00203       int dstRGB = brw->attribs.Blend->rgb_dst_factor;
00204       int srcA = brw->attribs.Blend->alpha_src_factor;
00205       int dstA = brw->attribs.Blend->alpha_dst_factor;
00206 
00207       if (eqRGB == PIPE_BLEND_MIN || eqRGB == PIPE_BLEND_MAX) {
00208          srcRGB = dstRGB = PIPE_BLENDFACTOR_ONE;
00209       }
00210 
00211       if (eqA == PIPE_BLEND_MIN || eqA == PIPE_BLEND_MAX) {
00212          srcA = dstA = PIPE_BLENDFACTOR_ONE;
00213       }
00214 
00215       cc.cc6.dest_blend_factor = brw_translate_blend_factor(dstRGB);
00216       cc.cc6.src_blend_factor = brw_translate_blend_factor(srcRGB);
00217       cc.cc6.blend_function = brw_translate_blend_equation( eqRGB );
00218 
00219       cc.cc5.ia_dest_blend_factor = brw_translate_blend_factor(dstA);
00220       cc.cc5.ia_src_blend_factor = brw_translate_blend_factor(srcA);
00221       cc.cc5.ia_blend_function = brw_translate_blend_equation( eqA );
00222 
00223       cc.cc3.blend_enable = 1;
00224       cc.cc3.ia_blend_enable = (srcA != srcRGB ||
00225                                 dstA != dstRGB ||
00226                                 eqA != eqRGB);
00227    }
00228    
00229    
00230 
00231    if (brw->attribs.DepthStencil->alpha.enabled) {
00232       cc.cc3.alpha_test = 1;
00233       cc.cc3.alpha_test_func = 
00234          brw_translate_compare_func(brw->attribs.DepthStencil->alpha.func);
00235 
00236       cc.cc7.alpha_ref.ub[0] = float_to_ubyte(brw->attribs.DepthStencil->alpha.ref);
00237 
00238       cc.cc3.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8;
00239    }
00240 
00241    if (brw->attribs.Blend->dither) {
00242       cc.cc5.dither_enable = 1;
00243       cc.cc6.y_dither_offset = 0;
00244       cc.cc6.x_dither_offset = 0;
00245    }
00246 
00247    if (brw->attribs.DepthStencil->depth.enabled) {
00248       cc.cc2.depth_test = brw->attribs.DepthStencil->depth.enabled;
00249       cc.cc2.depth_test_function = brw_translate_compare_func(brw->attribs.DepthStencil->depth.func);
00250       cc.cc2.depth_write_enable = brw->attribs.DepthStencil->depth.writemask;
00251    }
00252 
00253    
00254    cc.cc4.cc_viewport_state_offset =  brw->cc.vp_gs_offset >> 5;
00255 
00256    if (BRW_DEBUG & DEBUG_STATS)
00257       cc.cc5.statistics_enable = 1;
00258 
00259    brw->cc.state_gs_offset = brw_cache_data( &brw->cache[BRW_CC_UNIT], &cc );
00260 }
00261 
00262 const struct brw_tracked_state brw_cc_unit = {
00263    .dirty = {
00264       .brw = BRW_NEW_DEPTH_STENCIL | BRW_NEW_BLEND | BRW_NEW_ALPHA_TEST,
00265       .cache = CACHE_NEW_CC_VP
00266    },
00267    .update = upload_cc_unit
00268 };
00269