i965: Represent depth surfaces with isl
[mesa.git] / src / mesa / drivers / dri / nouveau / nv04_state_frag.c
index 34ee2962023ca2ee6a6238a0831b35fe91857cea..248a7d2b5220bb7b3777418789d3e20382387442 100644 (file)
 #include "nouveau_driver.h"
 #include "nouveau_context.h"
 #include "nouveau_util.h"
-#include "nouveau_class.h"
+#include "nv_object.xml.h"
+#include "nv04_3d.xml.h"
 #include "nv04_driver.h"
 
 #define COMBINER_SHIFT(in)                                             \
-       (NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ARGUMENT##in##_SHIFT      \
-        - NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ARGUMENT0_SHIFT)
+       (NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ARGUMENT##in##__SHIFT     \
+        - NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ARGUMENT0__SHIFT)
 #define COMBINER_SOURCE(reg)                                   \
        NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ARGUMENT0_##reg
 #define COMBINER_INVERT                                        \
        NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ALPHA0
 
 struct combiner_state {
+       struct gl_context *ctx;
        int unit;
        GLboolean alpha;
+       GLboolean premodulate;
 
        /* GL state */
        GLenum mode;
@@ -59,11 +62,13 @@ struct combiner_state {
 
 /* Initialize a combiner_state struct from the texture unit
  * context. */
-#define INIT_COMBINER(chan, rc, i) do {                                \
+#define INIT_COMBINER(chan, ctx, rc, i) do {                   \
                struct gl_tex_env_combine_state *c =            \
                        ctx->Texture.Unit[i]._CurrentCombine;   \
-               (rc)->alpha = __INIT_COMBINER_ALPHA_##chan;     \
+               (rc)->ctx = ctx;                                \
                (rc)->unit = i;                                 \
+               (rc)->alpha = __INIT_COMBINER_ALPHA_##chan;     \
+               (rc)->premodulate = c->_NumArgs##chan == 4;     \
                (rc)->mode = c->Mode##chan;                     \
                (rc)->source = c->Source##chan;                 \
                (rc)->operand = c->Operand##chan;               \
@@ -72,11 +77,14 @@ struct combiner_state {
        } while (0)
 
 /* Get the combiner source for the specified EXT_texture_env_combine
- * argument. */
+ * source. */
 static uint32_t
-get_arg_source(struct combiner_state *rc, int arg)
+get_input_source(struct combiner_state *rc, int source)
 {
-       switch (rc->source[arg]) {
+       switch (source) {
+       case GL_ZERO:
+               return COMBINER_SOURCE(ZERO);
+
        case GL_TEXTURE:
                return rc->unit ? COMBINER_SOURCE(TEXTURE1) :
                        COMBINER_SOURCE(TEXTURE0);
@@ -103,38 +111,53 @@ get_arg_source(struct combiner_state *rc, int arg)
 }
 
 /* Get the (possibly inverted) combiner input mapping for the
- * specified argument. */
+ * specified EXT_texture_env_combine operand. */
 #define INVERT 0x1
 
 static uint32_t
-get_arg_mapping(struct combiner_state *rc, int arg, int flags)
+get_input_mapping(struct combiner_state *rc, int operand, int flags)
 {
        int map = 0;
 
-       switch (rc->operand[arg]) {
-       case GL_SRC_COLOR:
-       case GL_ONE_MINUS_SRC_COLOR:
-               break;
+       if (!is_color_operand(operand) && !rc->alpha)
+               map |= COMBINER_ALPHA;
 
-       case GL_SRC_ALPHA:
-       case GL_ONE_MINUS_SRC_ALPHA:
-               map |= rc->alpha ? 0 : COMBINER_ALPHA;
-               break;
-       }
+       if (is_negative_operand(operand) == !(flags & INVERT))
+               map |= COMBINER_INVERT;
 
-       switch (rc->operand[arg]) {
-       case GL_SRC_COLOR:
-       case GL_SRC_ALPHA:
-               map |= flags & INVERT ? COMBINER_INVERT : 0;
-               break;
+       return map;
+}
 
-       case GL_ONE_MINUS_SRC_COLOR:
-       case GL_ONE_MINUS_SRC_ALPHA:
-               map |= flags & INVERT ? 0 : COMBINER_INVERT;
-               break;
+static uint32_t
+get_input_arg(struct combiner_state *rc, int arg, int flags)
+{
+       int source = rc->source[arg];
+       int operand = rc->operand[arg];
+
+       /* Fake several unsupported texture formats. */
+       if (is_texture_source(source)) {
+               int i = (source == GL_TEXTURE ?
+                        rc->unit : source - GL_TEXTURE0);
+               struct gl_texture_object *t = rc->ctx->Texture.Unit[i]._Current;
+               mesa_format format = t->Image[0][t->BaseLevel]->TexFormat;
+
+               if (format == MESA_FORMAT_A_UNORM8) {
+                       /* Emulated using I8. */
+                       if (is_color_operand(operand))
+                               return COMBINER_SOURCE(ZERO) |
+                                       get_input_mapping(rc, operand, flags);
+
+               } else if (format == MESA_FORMAT_L_UNORM8) {
+                       /* Emulated using I8. */
+                       if (!is_color_operand(operand))
+                               return COMBINER_SOURCE(ZERO) |
+                                       get_input_mapping(rc, operand,
+                                                         flags ^ INVERT);
+               }
        }
 
-       return map;
+       return get_input_source(rc, source) |
+               get_input_mapping(rc, operand, flags);
 }
 
 /* Bind the combiner input <in> to the combiner source <src>,
@@ -146,8 +169,7 @@ get_arg_mapping(struct combiner_state *rc, int arg, int flags)
 /* Bind the combiner input <in> to the EXT_texture_env_combine
  * argument <arg>, possibly inverted. */
 #define INPUT_ARG(rc, in, arg, flags)                                  \
-       (rc)->hw |= (get_arg_source(rc, arg) |                          \
-                    get_arg_mapping(rc, arg, flags)) << COMBINER_SHIFT(in)
+       (rc)->hw |= get_input_arg(rc, arg, flags) << COMBINER_SHIFT(in)
 
 #define UNSIGNED_OP(rc)                                                        \
        (rc)->hw |= ((rc)->logscale ?                                   \
@@ -179,11 +201,24 @@ setup_combiner(struct combiner_state *rc)
                break;
 
        case GL_ADD:
-               INPUT_ARG(rc, 0, 0, 0);
-               INPUT_SRC(rc, 1, ZERO, INVERT);
-               INPUT_ARG(rc, 2, 1, 0);
-               INPUT_SRC(rc, 3, ZERO, INVERT);
-               UNSIGNED_OP(rc);
+       case GL_ADD_SIGNED:
+               if (rc->premodulate) {
+                       INPUT_ARG(rc, 0, 0, 0);
+                       INPUT_ARG(rc, 1, 1, 0);
+                       INPUT_ARG(rc, 2, 2, 0);
+                       INPUT_ARG(rc, 3, 3, 0);
+               } else {
+                       INPUT_ARG(rc, 0, 0, 0);
+                       INPUT_SRC(rc, 1, ZERO, INVERT);
+                       INPUT_ARG(rc, 2, 1, 0);
+                       INPUT_SRC(rc, 3, ZERO, INVERT);
+               }
+
+               if (rc->mode == GL_ADD_SIGNED)
+                       SIGNED_OP(rc);
+               else
+                       UNSIGNED_OP(rc);
+
                break;
 
        case GL_INTERPOLATE:
@@ -194,38 +229,39 @@ setup_combiner(struct combiner_state *rc)
                UNSIGNED_OP(rc);
                break;
 
-       case GL_ADD_SIGNED:
-               INPUT_ARG(rc, 0, 0, 0);
-               INPUT_SRC(rc, 1, ZERO, INVERT);
-               INPUT_ARG(rc, 2, 1, 0);
-               INPUT_SRC(rc, 3, ZERO, INVERT);
-               SIGNED_OP(rc);
-               break;
+       default:
+               assert(0);
+       }
+}
 
+static unsigned
+get_texenv_mode(unsigned mode)
+{
+       switch (mode) {
+       case GL_REPLACE:
+               return 0x1;
+       case GL_DECAL:
+               return 0x3;
+       case GL_MODULATE:
+               return 0x4;
        default:
                assert(0);
        }
 }
 
 void
-nv04_emit_tex_env(GLcontext *ctx, int emit)
+nv04_emit_tex_env(struct gl_context *ctx, int emit)
 {
+       struct nv04_context *nv04 = to_nv04_context(ctx);
        const int i = emit - NOUVEAU_STATE_TEX_ENV0;
-       struct nouveau_channel *chan = context_chan(ctx);
-       struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx);
        struct combiner_state rc_a = {}, rc_c = {};
 
-       if (!nv04_mtex_engine(fahrenheit)) {
-               context_dirty(ctx, BLEND);
-               return;
-       }
-
        /* Compute the new combiner state. */
-       if (ctx->Texture.Unit[i]._ReallyEnabled) {
-               INIT_COMBINER(A, &rc_a, i);
+       if (ctx->Texture.Unit[i]._Current) {
+               INIT_COMBINER(A, ctx, &rc_a, i);
                setup_combiner(&rc_a);
 
-               INIT_COMBINER(RGB, &rc_c, i);
+               INIT_COMBINER(RGB, ctx, &rc_c, i);
                setup_combiner(&rc_c);
 
        } else {
@@ -248,14 +284,16 @@ nv04_emit_tex_env(GLcontext *ctx, int emit)
                UNSIGNED_OP(&rc_c);
        }
 
-       /* Write the register combiner state out to the hardware. */
-       BEGIN_RING(chan, fahrenheit,
-                  NV04_MULTITEX_TRIANGLE_COMBINE_ALPHA(i), 2);
-       OUT_RING(chan, rc_a.hw);
-       OUT_RING(chan, rc_c.hw);
-
-       BEGIN_RING(chan, fahrenheit,
-                  NV04_MULTITEX_TRIANGLE_COMBINE_FACTOR, 1);
-       OUT_RING(chan, pack_rgba_f(MESA_FORMAT_ARGB8888,
-                                  ctx->Texture.Unit[0].EnvColor));
+       /* calculate non-multitex state */
+       nv04->blend &= ~NV04_TEXTURED_TRIANGLE_BLEND_TEXTURE_MAP__MASK;
+       if (ctx->Texture._MaxEnabledTexImageUnit != -1)
+               nv04->blend |= get_texenv_mode(ctx->Texture.Unit[0].EnvMode);
+       else
+               nv04->blend |= get_texenv_mode(GL_MODULATE);
+
+       /* update calculated multitex state */
+       nv04->alpha[i] = rc_a.hw;
+       nv04->color[i] = rc_c.hw;
+       nv04->factor   = pack_rgba_f(MESA_FORMAT_B8G8R8A8_UNORM,
+                                    ctx->Texture.Unit[0].EnvColor);
 }