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 #include "main/stencil.h" 34 35 static unsigned 36 get_comparison_op(unsigned op) 37 { 38 switch (op) { 39 case GL_NEVER: 40 return 0x1; 41 case GL_LESS: 42 return 0x2; 43 case GL_EQUAL: 44 return 0x3; 45 case GL_LEQUAL: 46 return 0x4; 47 case GL_GREATER: 48 return 0x5; 49 case GL_NOTEQUAL: 50 return 0x6; 51 case GL_GEQUAL: 52 return 0x7; 53 case GL_ALWAYS: 54 return 0x8; 55 default: 56 assert(0); 57 } 58 } 59 60 static unsigned 61 get_stencil_op(unsigned op) 62 { 63 switch (op) { 64 case GL_KEEP: 65 return 0x1; 66 case GL_ZERO: 67 return 0x2; 68 case GL_REPLACE: 69 return 0x3; 70 case GL_INCR: 71 return 0x4; 72 case GL_DECR: 73 return 0x5; 74 case GL_INVERT: 75 return 0x6; 76 case GL_INCR_WRAP: 77 return 0x7; 78 case GL_DECR_WRAP: 79 return 0x8; 80 default: 81 assert(0); 82 } 83 } 84 85 static unsigned 86 get_blend_func(unsigned func) 87 { 88 switch (func) { 89 case GL_ZERO: 90 return 0x1; 91 case GL_ONE: 92 return 0x2; 93 case GL_SRC_COLOR: 94 return 0x3; 95 case GL_ONE_MINUS_SRC_COLOR: 96 return 0x4; 97 case GL_SRC_ALPHA: 98 return 0x5; 99 case GL_ONE_MINUS_SRC_ALPHA: 100 return 0x6; 101 case GL_DST_ALPHA: 102 return 0x7; 103 case GL_ONE_MINUS_DST_ALPHA: 104 return 0x8; 105 case GL_DST_COLOR: 106 return 0x9; 107 case GL_ONE_MINUS_DST_COLOR: 108 return 0xa; 109 case GL_SRC_ALPHA_SATURATE: 110 return 0xb; 111 default: 112 assert(0); 113 } 114 } 115 116 void 117 nv04_defer_control(struct gl_context *ctx, int emit) 118 { 119 context_dirty(ctx, CONTROL); 120 } 121 122 void 123 nv04_emit_control(struct gl_context *ctx, int emit) 124 { 125 struct nv04_context *nv04 = to_nv04_context(ctx); 126 struct gl_framebuffer *fb = ctx->DrawBuffer; 127 int cull = ctx->Polygon.CullFaceMode; 128 int front = ctx->Polygon.FrontFace; 129 130 nv04->ctrl[0] = NV04_TEXTURED_TRIANGLE_CONTROL_Z_FORMAT_FIXED | 131 NV04_TEXTURED_TRIANGLE_CONTROL_ORIGIN_CORNER; 132 nv04->ctrl[1] = 0; 133 nv04->ctrl[2] = 0; 134 135 /* Dithering. */ 136 if (ctx->Color.DitherFlag) 137 nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_DITHER_ENABLE; 138 139 /* Cull mode. */ 140 if (!ctx->Polygon.CullFlag) 141 nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_NONE; 142 else if (cull == GL_FRONT_AND_BACK) 143 nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_BOTH; 144 else 145 nv04->ctrl[0] |= (cull == GL_FRONT) ^ (front == GL_CCW) ? 146 NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_CW : 147 NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_CCW; 148 149 /* Depth test. */ 150 if (ctx->Depth.Test && fb->Visual.depthBits > 0) 151 nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE; 152 if (ctx->Depth.Mask && fb->Visual.depthBits > 0) 153 nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_WRITE; 154 155 nv04->ctrl[0] |= get_comparison_op(ctx->Depth.Func) << 16; 156 157 /* Alpha test. */ 158 if (ctx->Color.AlphaEnabled) 159 nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_ALPHA_ENABLE; 160 161 nv04->ctrl[0] |= get_comparison_op(ctx->Color.AlphaFunc) << 8 | 162 FLOAT_TO_UBYTE(ctx->Color.AlphaRef); 163 164 /* Color mask. */ 165 if (ctx->Color.ColorMask[0][RCOMP]) 166 nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_RED_WRITE; 167 if (ctx->Color.ColorMask[0][GCOMP]) 168 nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_GREEN_WRITE; 169 if (ctx->Color.ColorMask[0][BCOMP]) 170 nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_BLUE_WRITE; 171 if (ctx->Color.ColorMask[0][ACOMP]) 172 nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_ALPHA_WRITE; 173 174 /* Stencil test. */ 175 if (ctx->Stencil.WriteMask[0]) 176 nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_STENCIL_WRITE; 177 178 if (_mesa_stencil_is_enabled(ctx)) 179 nv04->ctrl[1] |= NV04_MULTITEX_TRIANGLE_CONTROL1_STENCIL_ENABLE; 180 181 nv04->ctrl[1] |= get_comparison_op(ctx->Stencil.Function[0]) << 4 | 182 _mesa_get_stencil_ref(ctx, 0) << 8 | 183 ctx->Stencil.ValueMask[0] << 16 | 184 ctx->Stencil.WriteMask[0] << 24; 185 186 nv04->ctrl[2] |= get_stencil_op(ctx->Stencil.ZPassFunc[0]) << 8 | 187 get_stencil_op(ctx->Stencil.ZFailFunc[0]) << 4 | 188 get_stencil_op(ctx->Stencil.FailFunc[0]); 189 } 190 191 void 192 nv04_defer_blend(struct gl_context *ctx, int emit) 193 { 194 context_dirty(ctx, BLEND); 195 } 196 197 void 198 nv04_emit_blend(struct gl_context *ctx, int emit) 199 { 200 struct nv04_context *nv04 = to_nv04_context(ctx); 201 202 nv04->blend &= NV04_TEXTURED_TRIANGLE_BLEND_TEXTURE_MAP__MASK; 203 nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_MASK_BIT_MSB | 204 NV04_TEXTURED_TRIANGLE_BLEND_TEXTURE_PERSPECTIVE_ENABLE; 205 206 /* Alpha blending. */ 207 nv04->blend |= get_blend_func(ctx->Color.Blend[0].DstRGB) << 28 | 208 get_blend_func(ctx->Color.Blend[0].SrcRGB) << 24; 209 210 if (ctx->Color.BlendEnabled) 211 nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_BLEND_ENABLE; 212 213 /* Shade model. */ 214 if (ctx->Light.ShadeModel == GL_SMOOTH) 215 nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_GOURAUD; 216 else 217 nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_FLAT; 218 219 /* Secondary color */ 220 if (_mesa_need_secondary_color(ctx)) 221 nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_SPECULAR_ENABLE; 222 223 /* Fog. */ 224 if (ctx->Fog.Enabled) { 225 nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_FOG_ENABLE; 226 nv04->fog = pack_rgba_f(MESA_FORMAT_B8G8R8A8_UNORM, ctx->Fog.Color); 227 } 228 } 229