1 /* 2 * Copyright (C) 2009 Francisco Jerez. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial 15 * portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 */ 26 27 #include "nouveau_driver.h" 28 #include "nouveau_context.h" 29 #include "nouveau_util.h" 30 #include "nv_object.xml.h" 31 #include "nv04_3d.xml.h" 32 #include "nv04_driver.h" 33 34 static unsigned 35 get_comparison_op(unsigned op) 36 { 37 switch (op) { 38 case GL_NEVER: 39 return 0x1; 40 case GL_LESS: 41 return 0x2; 42 case GL_EQUAL: 43 return 0x3; 44 case GL_LEQUAL: 45 return 0x4; 46 case GL_GREATER: 47 return 0x5; 48 case GL_NOTEQUAL: 49 return 0x6; 50 case GL_GEQUAL: 51 return 0x7; 52 case GL_ALWAYS: 53 return 0x8; 54 default: 55 assert(0); 56 } 57 } 58 59 static unsigned 60 get_stencil_op(unsigned op) 61 { 62 switch (op) { 63 case GL_KEEP: 64 return 0x1; 65 case GL_ZERO: 66 return 0x2; 67 case GL_REPLACE: 68 return 0x3; 69 case GL_INCR: 70 return 0x4; 71 case GL_DECR: 72 return 0x5; 73 case GL_INVERT: 74 return 0x6; 75 case GL_INCR_WRAP: 76 return 0x7; 77 case GL_DECR_WRAP: 78 return 0x8; 79 default: 80 assert(0); 81 } 82 } 83 84 static unsigned 85 get_blend_func(unsigned func) 86 { 87 switch (func) { 88 case GL_ZERO: 89 return 0x1; 90 case GL_ONE: 91 return 0x2; 92 case GL_SRC_COLOR: 93 return 0x3; 94 case GL_ONE_MINUS_SRC_COLOR: 95 return 0x4; 96 case GL_SRC_ALPHA: 97 return 0x5; 98 case GL_ONE_MINUS_SRC_ALPHA: 99 return 0x6; 100 case GL_DST_ALPHA: 101 return 0x7; 102 case GL_ONE_MINUS_DST_ALPHA: 103 return 0x8; 104 case GL_DST_COLOR: 105 return 0x9; 106 case GL_ONE_MINUS_DST_COLOR: 107 return 0xa; 108 case GL_SRC_ALPHA_SATURATE: 109 return 0xb; 110 default: 111 assert(0); 112 } 113 } 114 115 void 116 nv04_defer_control(struct gl_context *ctx, int emit) 117 { 118 context_dirty(ctx, CONTROL); 119 } 120 121 void 122 nv04_emit_control(struct gl_context *ctx, int emit) 123 { 124 struct nv04_context *nv04 = to_nv04_context(ctx); 125 int cull = ctx->Polygon.CullFaceMode; 126 int front = ctx->Polygon.FrontFace; 127 128 nv04->ctrl[0] = NV04_TEXTURED_TRIANGLE_CONTROL_Z_FORMAT_FIXED | 129 NV04_TEXTURED_TRIANGLE_CONTROL_ORIGIN_CORNER; 130 nv04->ctrl[1] = 0; 131 nv04->ctrl[2] = 0; 132 133 /* Dithering. */ 134 if (ctx->Color.DitherFlag) 135 nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_DITHER_ENABLE; 136 137 /* Cull mode. */ 138 if (!ctx->Polygon.CullFlag) 139 nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_NONE; 140 else if (cull == GL_FRONT_AND_BACK) 141 nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_BOTH; 142 else 143 nv04->ctrl[0] |= (cull == GL_FRONT) ^ (front == GL_CCW) ? 144 NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_CW : 145 NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_CCW; 146 147 /* Depth test. */ 148 if (ctx->Depth.Test) 149 nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE; 150 if (ctx->Depth.Mask) 151 nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_WRITE; 152 153 nv04->ctrl[0] |= get_comparison_op(ctx->Depth.Func) << 16; 154 155 /* Alpha test. */ 156 if (ctx->Color.AlphaEnabled) 157 nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_ALPHA_ENABLE; 158 159 nv04->ctrl[0] |= get_comparison_op(ctx->Color.AlphaFunc) << 8 | 160 FLOAT_TO_UBYTE(ctx->Color.AlphaRef); 161 162 /* Color mask. */ 163 if (ctx->Color.ColorMask[0][RCOMP]) 164 nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_RED_WRITE; 165 if (ctx->Color.ColorMask[0][GCOMP]) 166 nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_GREEN_WRITE; 167 if (ctx->Color.ColorMask[0][BCOMP]) 168 nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_BLUE_WRITE; 169 if (ctx->Color.ColorMask[0][ACOMP]) 170 nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_ALPHA_WRITE; 171 172 /* Stencil test. */ 173 if (ctx->Stencil.WriteMask[0]) 174 nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_STENCIL_WRITE; 175 176 if (ctx->Stencil.Enabled) 177 nv04->ctrl[1] |= NV04_MULTITEX_TRIANGLE_CONTROL1_STENCIL_ENABLE; 178 179 nv04->ctrl[1] |= get_comparison_op(ctx->Stencil.Function[0]) << 4 | 180 ctx->Stencil.Ref[0] << 8 | 181 ctx->Stencil.ValueMask[0] << 16 | 182 ctx->Stencil.WriteMask[0] << 24; 183 184 nv04->ctrl[2] |= get_stencil_op(ctx->Stencil.ZPassFunc[0]) << 8 | 185 get_stencil_op(ctx->Stencil.ZFailFunc[0]) << 4 | 186 get_stencil_op(ctx->Stencil.FailFunc[0]); 187 } 188 189 void 190 nv04_defer_blend(struct gl_context *ctx, int emit) 191 { 192 context_dirty(ctx, BLEND); 193 } 194 195 void 196 nv04_emit_blend(struct gl_context *ctx, int emit) 197 { 198 struct nv04_context *nv04 = to_nv04_context(ctx); 199 200 nv04->blend &= NV04_TEXTURED_TRIANGLE_BLEND_TEXTURE_MAP__MASK; 201 nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_MASK_BIT_MSB | 202 NV04_TEXTURED_TRIANGLE_BLEND_TEXTURE_PERSPECTIVE_ENABLE; 203 204 /* Alpha blending. */ 205 nv04->blend |= get_blend_func(ctx->Color.Blend[0].DstRGB) << 28 | 206 get_blend_func(ctx->Color.Blend[0].SrcRGB) << 24; 207 208 if (ctx->Color.BlendEnabled) 209 nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_BLEND_ENABLE; 210 211 /* Shade model. */ 212 if (ctx->Light.ShadeModel == GL_SMOOTH) 213 nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_GOURAUD; 214 else 215 nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_FLAT; 216 217 /* Secondary color */ 218 if (_mesa_need_secondary_color(ctx)) 219 nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_SPECULAR_ENABLE; 220 221 /* Fog. */ 222 if (ctx->Fog.Enabled) { 223 nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_FOG_ENABLE; 224 nv04->fog = pack_rgba_f(MESA_FORMAT_ARGB8888, ctx->Fog.Color); 225 } 226 } 227