00001 00006 #include "sp_context.h" 00007 #include "sp_headers.h" 00008 #include "sp_quad.h" 00009 #include "pipe/p_defines.h" 00010 #include "util/u_memory.h" 00011 00012 00013 static void 00014 alpha_test_quad(struct quad_stage *qs, struct quad_header *quad) 00015 { 00016 struct softpipe_context *softpipe = qs->softpipe; 00017 const float ref = softpipe->depth_stencil->alpha.ref; 00018 unsigned passMask = 0x0, j; 00019 const uint cbuf = 0; /* only output[0].alpha is tested */ 00020 const float *aaaa = quad->output.color[cbuf][3]; 00021 00022 switch (softpipe->depth_stencil->alpha.func) { 00023 case PIPE_FUNC_NEVER: 00024 break; 00025 case PIPE_FUNC_LESS: 00026 /* 00027 * If mask were an array [4] we could do this SIMD-style: 00028 * passMask = (quad->outputs.color[0][3] <= vec4(ref)); 00029 */ 00030 for (j = 0; j < QUAD_SIZE; j++) { 00031 if (aaaa[j] < ref) { 00032 passMask |= (1 << j); 00033 } 00034 } 00035 break; 00036 case PIPE_FUNC_EQUAL: 00037 for (j = 0; j < QUAD_SIZE; j++) { 00038 if (aaaa[j] == ref) { 00039 passMask |= (1 << j); 00040 } 00041 } 00042 break; 00043 case PIPE_FUNC_LEQUAL: 00044 for (j = 0; j < QUAD_SIZE; j++) { 00045 if (aaaa[j] <= ref) { 00046 passMask |= (1 << j); 00047 } 00048 } 00049 break; 00050 case PIPE_FUNC_GREATER: 00051 for (j = 0; j < QUAD_SIZE; j++) { 00052 if (aaaa[j] > ref) { 00053 passMask |= (1 << j); 00054 } 00055 } 00056 break; 00057 case PIPE_FUNC_NOTEQUAL: 00058 for (j = 0; j < QUAD_SIZE; j++) { 00059 if (aaaa[j] != ref) { 00060 passMask |= (1 << j); 00061 } 00062 } 00063 break; 00064 case PIPE_FUNC_GEQUAL: 00065 for (j = 0; j < QUAD_SIZE; j++) { 00066 if (aaaa[j] >= ref) { 00067 passMask |= (1 << j); 00068 } 00069 } 00070 break; 00071 case PIPE_FUNC_ALWAYS: 00072 passMask = MASK_ALL; 00073 break; 00074 default: 00075 assert(0); 00076 } 00077 00078 quad->inout.mask &= passMask; 00079 00080 if (quad->inout.mask) 00081 qs->next->run(qs->next, quad); 00082 } 00083 00084 00085 static void alpha_test_begin(struct quad_stage *qs) 00086 { 00087 qs->next->begin(qs->next); 00088 } 00089 00090 00091 static void alpha_test_destroy(struct quad_stage *qs) 00092 { 00093 FREE( qs ); 00094 } 00095 00096 00097 struct quad_stage * 00098 sp_quad_alpha_test_stage( struct softpipe_context *softpipe ) 00099 { 00100 struct quad_stage *stage = CALLOC_STRUCT(quad_stage); 00101 00102 stage->softpipe = softpipe; 00103 stage->begin = alpha_test_begin; 00104 stage->run = alpha_test_quad; 00105 stage->destroy = alpha_test_destroy; 00106 00107 return stage; 00108 }