Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (C) 2009-2010 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_gldefs.h"
  30. #include "nouveau_util.h"
  31. #include "nv20_3d.xml.h"
  32. #include "nv10_driver.h"
  33. #include "nv20_driver.h"
  34.  
  35. #define LIGHT_MODEL_AMBIENT_R(side)                     \
  36.         ((side) ? NV20_3D_LIGHT_MODEL_BACK_AMBIENT_R :  \
  37.          NV20_3D_LIGHT_MODEL_FRONT_AMBIENT_R)
  38. #define LIGHT_AMBIENT_R(side, i)                        \
  39.         ((side) ? NV20_3D_LIGHT_BACK_AMBIENT_R(i) :     \
  40.          NV20_3D_LIGHT_FRONT_AMBIENT_R(i))
  41. #define LIGHT_DIFFUSE_R(side, i)                        \
  42.         ((side) ? NV20_3D_LIGHT_BACK_DIFFUSE_R(i) :     \
  43.          NV20_3D_LIGHT_FRONT_DIFFUSE_R(i))
  44. #define LIGHT_SPECULAR_R(side, i)                       \
  45.         ((side) ? NV20_3D_LIGHT_BACK_SPECULAR_R(i) :    \
  46.          NV20_3D_LIGHT_FRONT_SPECULAR_R(i))
  47. #define MATERIAL_FACTOR_R(side)                         \
  48.         ((side) ? NV20_3D_MATERIAL_FACTOR_BACK_R :      \
  49.          NV20_3D_MATERIAL_FACTOR_FRONT_R)
  50. #define MATERIAL_FACTOR_A(side)                         \
  51.         ((side) ? NV20_3D_MATERIAL_FACTOR_BACK_A :      \
  52.          NV20_3D_MATERIAL_FACTOR_FRONT_A)
  53. #define MATERIAL_SHININESS(side)                        \
  54.         ((side) ? NV20_3D_BACK_MATERIAL_SHININESS(0) :  \
  55.          NV20_3D_FRONT_MATERIAL_SHININESS(0))
  56.  
  57. void
  58. nv20_emit_clip_plane(struct gl_context *ctx, int emit)
  59. {
  60. }
  61.  
  62. static inline unsigned
  63. get_material_bitmask(unsigned m)
  64. {
  65.         unsigned ret = 0;
  66.  
  67.         if (m & MAT_BIT_FRONT_EMISSION)
  68.                 ret |= NV20_3D_COLOR_MATERIAL_FRONT_EMISSION_COL1;
  69.         if (m & MAT_BIT_FRONT_AMBIENT)
  70.                 ret |= NV20_3D_COLOR_MATERIAL_FRONT_AMBIENT_COL1;
  71.         if (m & MAT_BIT_FRONT_DIFFUSE)
  72.                 ret |= NV20_3D_COLOR_MATERIAL_FRONT_DIFFUSE_COL1;
  73.         if (m & MAT_BIT_FRONT_SPECULAR)
  74.                 ret |= NV20_3D_COLOR_MATERIAL_FRONT_SPECULAR_COL1;
  75.  
  76.         if (m & MAT_BIT_BACK_EMISSION)
  77.                 ret |= NV20_3D_COLOR_MATERIAL_BACK_EMISSION_COL1;
  78.         if (m & MAT_BIT_BACK_AMBIENT)
  79.                 ret |= NV20_3D_COLOR_MATERIAL_BACK_AMBIENT_COL1;
  80.         if (m & MAT_BIT_BACK_DIFFUSE)
  81.                 ret |= NV20_3D_COLOR_MATERIAL_BACK_DIFFUSE_COL1;
  82.         if (m & MAT_BIT_BACK_SPECULAR)
  83.                 ret |= NV20_3D_COLOR_MATERIAL_BACK_SPECULAR_COL1;
  84.  
  85.         return ret;
  86. }
  87.  
  88. void
  89. nv20_emit_color_material(struct gl_context *ctx, int emit)
  90. {
  91.         struct nouveau_pushbuf *push = context_push(ctx);
  92.         unsigned mask = get_material_bitmask(ctx->Light._ColorMaterialBitmask);
  93.  
  94.         BEGIN_NV04(push, NV20_3D(COLOR_MATERIAL), 1);
  95.         PUSH_DATA (push, ctx->Light.ColorMaterialEnabled ? mask : 0);
  96. }
  97.  
  98. static unsigned
  99. get_fog_mode_signed(unsigned mode)
  100. {
  101.         switch (mode) {
  102.         case GL_LINEAR:
  103.                 return NV20_3D_FOG_MODE_LINEAR_SIGNED;
  104.         case GL_EXP:
  105.                 return NV20_3D_FOG_MODE_EXP_SIGNED;
  106.         case GL_EXP2:
  107.                 return NV20_3D_FOG_MODE_EXP2_SIGNED;
  108.         default:
  109.                 assert(0);
  110.         }
  111. }
  112.  
  113. static unsigned
  114. get_fog_mode_unsigned(unsigned mode)
  115. {
  116.         switch (mode) {
  117.         case GL_LINEAR:
  118.                 return NV20_3D_FOG_MODE_LINEAR_UNSIGNED;
  119.         case GL_EXP:
  120.                 return NV20_3D_FOG_MODE_EXP_UNSIGNED;
  121.         case GL_EXP2:
  122.                 return NV20_3D_FOG_MODE_EXP2_UNSIGNED;
  123.         default:
  124.                 assert(0);
  125.         }
  126. }
  127.  
  128. static unsigned
  129. get_fog_source(unsigned source, unsigned distance_mode)
  130. {
  131.         switch (source) {
  132.         case GL_FOG_COORDINATE_EXT:
  133.                 return NV20_3D_FOG_COORD_FOG;
  134.         case GL_FRAGMENT_DEPTH_EXT:
  135.                 switch (distance_mode) {
  136.                 case GL_EYE_PLANE_ABSOLUTE_NV:
  137.                         return NV20_3D_FOG_COORD_DIST_ORTHOGONAL_ABS;
  138.                 case GL_EYE_PLANE:
  139.                         return NV20_3D_FOG_COORD_DIST_ORTHOGONAL;
  140.                 case GL_EYE_RADIAL_NV:
  141.                         return NV20_3D_FOG_COORD_DIST_RADIAL;
  142.                 default:
  143.                         assert(0);
  144.                 }
  145.         default:
  146.                 assert(0);
  147.         }
  148. }
  149.  
  150. void
  151. nv20_emit_fog(struct gl_context *ctx, int emit)
  152. {
  153.         struct nouveau_context *nctx = to_nouveau_context(ctx);
  154.         struct nouveau_pushbuf *push = context_push(ctx);
  155.         struct gl_fog_attrib *f = &ctx->Fog;
  156.         unsigned source = nctx->fallback == HWTNL ?
  157.                 f->FogCoordinateSource : GL_FOG_COORDINATE_EXT;
  158.         float k[3];
  159.  
  160.         nv10_get_fog_coeff(ctx, k);
  161.  
  162.         BEGIN_NV04(push, NV20_3D(FOG_MODE), 4);
  163.         PUSH_DATA (push, ((source == GL_FRAGMENT_DEPTH_EXT &&
  164.                          f->FogDistanceMode == GL_EYE_PLANE_ABSOLUTE_NV) ?
  165.                         get_fog_mode_unsigned(f->Mode) :
  166.                         get_fog_mode_signed(f->Mode)));
  167.         PUSH_DATA (push, get_fog_source(source, f->FogDistanceMode));
  168.         PUSH_DATAb(push, f->Enabled);
  169.         PUSH_DATA (push, pack_rgba_f(MESA_FORMAT_R8G8B8A8_UNORM, f->Color));
  170.  
  171.         BEGIN_NV04(push, NV20_3D(FOG_COEFF(0)), 3);
  172.         PUSH_DATAp(push, k, 3);
  173. }
  174.  
  175. void
  176. nv20_emit_light_model(struct gl_context *ctx, int emit)
  177. {
  178.         struct nouveau_pushbuf *push = context_push(ctx);
  179.         struct gl_lightmodel *m = &ctx->Light.Model;
  180.  
  181.         BEGIN_NV04(push, NV20_3D(SEPARATE_SPECULAR_ENABLE), 1);
  182.         PUSH_DATAb(push, m->ColorControl == GL_SEPARATE_SPECULAR_COLOR);
  183.  
  184.         BEGIN_NV04(push, NV20_3D(LIGHT_MODEL), 1);
  185.         PUSH_DATA (push, ((m->LocalViewer ?
  186.                          NV20_3D_LIGHT_MODEL_VIEWER_LOCAL :
  187.                          NV20_3D_LIGHT_MODEL_VIEWER_NONLOCAL) |
  188.                         (_mesa_need_secondary_color(ctx) ?
  189.                          NV20_3D_LIGHT_MODEL_SEPARATE_SPECULAR :
  190.                          0)));
  191.  
  192.         BEGIN_NV04(push, NV20_3D(LIGHT_MODEL_TWO_SIDE_ENABLE), 1);
  193.         PUSH_DATAb(push, ctx->Light.Model.TwoSide);
  194. }
  195.  
  196. void
  197. nv20_emit_light_source(struct gl_context *ctx, int emit)
  198. {
  199.         const int i = emit - NOUVEAU_STATE_LIGHT_SOURCE0;
  200.         struct nouveau_pushbuf *push = context_push(ctx);
  201.         struct gl_light *l = &ctx->Light.Light[i];
  202.  
  203.         if (l->_Flags & LIGHT_POSITIONAL) {
  204.                 BEGIN_NV04(push, NV20_3D(LIGHT_POSITION_X(i)), 3);
  205.                 PUSH_DATAp(push, l->_Position, 3);
  206.  
  207.                 BEGIN_NV04(push, NV20_3D(LIGHT_ATTENUATION_CONSTANT(i)), 3);
  208.                 PUSH_DATAf(push, l->ConstantAttenuation);
  209.                 PUSH_DATAf(push, l->LinearAttenuation);
  210.                 PUSH_DATAf(push, l->QuadraticAttenuation);
  211.  
  212.         } else {
  213.                 BEGIN_NV04(push, NV20_3D(LIGHT_DIRECTION_X(i)), 3);
  214.                 PUSH_DATAp(push, l->_VP_inf_norm, 3);
  215.  
  216.                 BEGIN_NV04(push, NV20_3D(LIGHT_HALF_VECTOR_X(i)), 3);
  217.                 PUSH_DATAp(push, l->_h_inf_norm, 3);
  218.         }
  219.  
  220.         if (l->_Flags & LIGHT_SPOT) {
  221.                 float k[7];
  222.  
  223.                 nv10_get_spot_coeff(l, k);
  224.  
  225.                 BEGIN_NV04(push, NV20_3D(LIGHT_SPOT_CUTOFF(i, 0)), 7);
  226.                 PUSH_DATAp(push, k, 7);
  227.         }
  228. }
  229.  
  230. #define USE_COLOR_MATERIAL(attr, side)                                  \
  231.         (ctx->Light.ColorMaterialEnabled &&                             \
  232.          ctx->Light._ColorMaterialBitmask & (1 << MAT_ATTRIB_##attr(side)))
  233.  
  234. void
  235. nv20_emit_material_ambient(struct gl_context *ctx, int emit)
  236. {
  237.         const int side = emit - NOUVEAU_STATE_MATERIAL_FRONT_AMBIENT;
  238.         struct nouveau_pushbuf *push = context_push(ctx);
  239.         float (*mat)[4] = ctx->Light.Material.Attrib;
  240.         float c_scene[3], c_factor[3];
  241.         struct gl_light *l;
  242.  
  243.         if (USE_COLOR_MATERIAL(AMBIENT, side)) {
  244.                 COPY_3V(c_scene, mat[MAT_ATTRIB_EMISSION(side)]);
  245.                 COPY_3V(c_factor, ctx->Light.Model.Ambient);
  246.  
  247.         } else if (USE_COLOR_MATERIAL(EMISSION, side)) {
  248.                 SCALE_3V(c_scene, mat[MAT_ATTRIB_AMBIENT(side)],
  249.                          ctx->Light.Model.Ambient);
  250.                 ASSIGN_3V(c_factor, 1, 1, 1);
  251.  
  252.         } else {
  253.                 COPY_3V(c_scene, ctx->Light._BaseColor[side]);
  254.                 ZERO_3V(c_factor);
  255.         }
  256.  
  257.         BEGIN_NV04(push, SUBC_3D(LIGHT_MODEL_AMBIENT_R(side)), 3);
  258.         PUSH_DATAp(push, c_scene, 3);
  259.  
  260.         if (ctx->Light.ColorMaterialEnabled) {
  261.                 BEGIN_NV04(push, SUBC_3D(MATERIAL_FACTOR_R(side)), 3);
  262.                 PUSH_DATAp(push, c_factor, 3);
  263.         }
  264.  
  265.         foreach(l, &ctx->Light.EnabledList) {
  266.                 const int i = l - ctx->Light.Light;
  267.                 float *c_light = (USE_COLOR_MATERIAL(AMBIENT, side) ?
  268.                                   l->Ambient :
  269.                                   l->_MatAmbient[side]);
  270.  
  271.                 BEGIN_NV04(push, SUBC_3D(LIGHT_AMBIENT_R(side, i)), 3);
  272.                 PUSH_DATAp(push, c_light, 3);
  273.         }
  274. }
  275.  
  276. void
  277. nv20_emit_material_diffuse(struct gl_context *ctx, int emit)
  278. {
  279.         const int side = emit - NOUVEAU_STATE_MATERIAL_FRONT_DIFFUSE;
  280.         struct nouveau_pushbuf *push = context_push(ctx);
  281.         GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
  282.         struct gl_light *l;
  283.  
  284.         BEGIN_NV04(push, SUBC_3D(MATERIAL_FACTOR_A(side)), 1);
  285.         PUSH_DATAf(push, mat[MAT_ATTRIB_DIFFUSE(side)][3]);
  286.  
  287.         foreach(l, &ctx->Light.EnabledList) {
  288.                 const int i = l - ctx->Light.Light;
  289.                 float *c_light = (USE_COLOR_MATERIAL(DIFFUSE, side) ?
  290.                                   l->Diffuse :
  291.                                   l->_MatDiffuse[side]);
  292.  
  293.                 BEGIN_NV04(push, SUBC_3D(LIGHT_DIFFUSE_R(side, i)), 3);
  294.                 PUSH_DATAp(push, c_light, 3);
  295.         }
  296. }
  297.  
  298. void
  299. nv20_emit_material_specular(struct gl_context *ctx, int emit)
  300. {
  301.         const int side = emit - NOUVEAU_STATE_MATERIAL_FRONT_SPECULAR;
  302.         struct nouveau_pushbuf *push = context_push(ctx);
  303.         struct gl_light *l;
  304.  
  305.         foreach(l, &ctx->Light.EnabledList) {
  306.                 const int i = l - ctx->Light.Light;
  307.                 float *c_light = (USE_COLOR_MATERIAL(SPECULAR, side) ?
  308.                                   l->Specular :
  309.                                   l->_MatSpecular[side]);
  310.  
  311.                 BEGIN_NV04(push, SUBC_3D(LIGHT_SPECULAR_R(side, i)), 3);
  312.                 PUSH_DATAp(push, c_light, 3);
  313.         }
  314. }
  315.  
  316. void
  317. nv20_emit_material_shininess(struct gl_context *ctx, int emit)
  318. {
  319.         const int side = emit - NOUVEAU_STATE_MATERIAL_FRONT_SHININESS;
  320.         struct nouveau_pushbuf *push = context_push(ctx);
  321.         float (*mat)[4] = ctx->Light.Material.Attrib;
  322.         float k[6];
  323.  
  324.         nv10_get_shininess_coeff(
  325.                 CLAMP(mat[MAT_ATTRIB_SHININESS(side)][0], 0, 1024),
  326.                 k);
  327.  
  328.         BEGIN_NV04(push, SUBC_3D(MATERIAL_SHININESS(side)), 6);
  329.         PUSH_DATAp(push, k, 6);
  330. }
  331.  
  332. void
  333. nv20_emit_modelview(struct gl_context *ctx, int emit)
  334. {
  335.         struct nouveau_context *nctx = to_nouveau_context(ctx);
  336.         struct nouveau_pushbuf *push = context_push(ctx);
  337.         GLmatrix *m = ctx->ModelviewMatrixStack.Top;
  338.  
  339.         if (nctx->fallback != HWTNL)
  340.                 return;
  341.  
  342.         if (ctx->Light._NeedEyeCoords || ctx->Fog.Enabled ||
  343.             (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD)) {
  344.                 BEGIN_NV04(push, NV20_3D(MODELVIEW_MATRIX(0, 0)), 16);
  345.                 PUSH_DATAm(push, m->m);
  346.         }
  347.  
  348.         if (ctx->Light.Enabled ||
  349.             (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD)) {
  350.                 int i, j;
  351.  
  352.                 BEGIN_NV04(push, NV20_3D(INVERSE_MODELVIEW_MATRIX(0, 0)), 12);
  353.                 for (i = 0; i < 3; i++)
  354.                         for (j = 0; j < 4; j++)
  355.                                 PUSH_DATAf(push, m->inv[4*i + j]);
  356.         }
  357. }
  358.  
  359. void
  360. nv20_emit_projection(struct gl_context *ctx, int emit)
  361. {
  362.         struct nouveau_context *nctx = to_nouveau_context(ctx);
  363.         struct nouveau_pushbuf *push = context_push(ctx);
  364.         GLmatrix m;
  365.  
  366.         _math_matrix_ctr(&m);
  367.         get_viewport_scale(ctx, m.m);
  368.  
  369.         if (nctx->fallback == HWTNL)
  370.                 _math_matrix_mul_matrix(&m, &m, &ctx->_ModelProjectMatrix);
  371.  
  372.         BEGIN_NV04(push, NV20_3D(PROJECTION_MATRIX(0)), 16);
  373.         PUSH_DATAm(push, m.m);
  374.  
  375.         _math_matrix_dtr(&m);
  376. }
  377.