Merge branch 'gallium-nopointsizeminmax'
[mesa.git] / src / gallium / drivers / r300 / r300_state.c
index b1c9aebd28029a32304d6a77401d48d099231702..d07e90860c28e2f2b61a093045044eb3dfd556bd 100644 (file)
@@ -155,23 +155,33 @@ static boolean blend_discard_if_src_alpha_color_1(unsigned srcRGB, unsigned srcA
             dstA == PIPE_BLENDFACTOR_ONE);
 }
 
+static unsigned bgra_cmask(unsigned mask)
+{
+    /* Gallium uses RGBA color ordering while R300 expects BGRA. */
+
+    return ((mask & PIPE_MASK_R) << 2) |
+           ((mask & PIPE_MASK_B) >> 2) |
+           (mask & (PIPE_MASK_G | PIPE_MASK_A));
+}
+
 /* Create a new blend state based on the CSO blend state.
  *
  * This encompasses alpha blending, logic/raster ops, and blend dithering. */
 static void* r300_create_blend_state(struct pipe_context* pipe,
                                      const struct pipe_blend_state* state)
 {
+    struct r300_screen* r300screen = r300_screen(pipe->screen);
     struct r300_blend_state* blend = CALLOC_STRUCT(r300_blend_state);
 
-    if (state->blend_enable)
+    if (state->rt[0].blend_enable)
     {
-        unsigned eqRGB = state->rgb_func;
-        unsigned srcRGB = state->rgb_src_factor;
-        unsigned dstRGB = state->rgb_dst_factor;
+        unsigned eqRGB = state->rt[0].rgb_func;
+        unsigned srcRGB = state->rt[0].rgb_src_factor;
+        unsigned dstRGB = state->rt[0].rgb_dst_factor;
 
-        unsigned eqA = state->alpha_func;
-        unsigned srcA = state->alpha_src_factor;
-        unsigned dstA = state->alpha_dst_factor;
+        unsigned eqA = state->rt[0].alpha_func;
+        unsigned srcA = state->rt[0].alpha_src_factor;
+        unsigned dstA = state->rt[0].alpha_dst_factor;
 
         /* despite the name, ALPHA_BLEND_ENABLE has nothing to do with alpha,
          * this is just the crappy D3D naming */
@@ -288,18 +298,18 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
                 (state->logicop_func) << R300_RB3D_ROPCNTL_ROP_SHIFT;
     }
 
-    /* Color Channel Mask */
-    if (state->colormask & PIPE_MASK_R) {
-        blend->color_channel_mask |= RB3D_COLOR_CHANNEL_MASK_RED_MASK0;
-    }
-    if (state->colormask & PIPE_MASK_G) {
-        blend->color_channel_mask |= RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0;
-    }
-    if (state->colormask & PIPE_MASK_B) {
-        blend->color_channel_mask |= RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0;
-    }
-    if (state->colormask & PIPE_MASK_A) {
-        blend->color_channel_mask |= RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0;
+    /* Color channel masks for all MRTs. */
+    blend->color_channel_mask = bgra_cmask(state->rt[0].colormask);
+    if (r300screen->caps->is_r500 && state->independent_blend_enable) {
+        if (state->rt[1].blend_enable) {
+            blend->color_channel_mask |= bgra_cmask(state->rt[1].colormask) << 4;
+        }
+        if (state->rt[2].blend_enable) {
+            blend->color_channel_mask |= bgra_cmask(state->rt[2].colormask) << 8;
+        }
+        if (state->rt[3].blend_enable) {
+            blend->color_channel_mask |= bgra_cmask(state->rt[3].colormask) << 12;
+        }
     }
 
     if (state->dither) {
@@ -431,7 +441,6 @@ static void*
             (r300_translate_stencil_op(state->stencil[1].zfail_op) <<
                 R300_S_BACK_ZFAIL_OP_SHIFT);
 
-            /* XXX it seems r3xx doesn't support STENCILREFMASK_BF */
             if (caps->is_r500)
             {
                 dsa->z_buffer_control |= R500_STENCIL_REFMASK_FRONT_BACK;
@@ -450,8 +459,7 @@ static void*
             r300_translate_alpha_function(state->alpha.func) |
             R300_FG_ALPHA_FUNC_ENABLE;
 
-        /* XXX figure out why emitting 10bit alpha ref causes CS to dump */
-        /* always use 8bit alpha ref */
+        /* We could use 10bit alpha ref but who needs that? */
         dsa->alpha_function |= float_to_ubyte(state->alpha.ref_value);
 
         if (caps->is_r500)
@@ -487,20 +495,30 @@ static void
     struct r300_context* r300 = r300_context(pipe);
     uint32_t zbuffer_bpp = 0;
 
+    r300->fb_state.size = (10 * state->nr_cbufs) +
+        (2 * (4 - state->nr_cbufs)) +
+        (state->zsbuf ? 10 : 0) + 6;
+
+    if (state->nr_cbufs > 4) {
+        debug_printf("r300: Implementation error: Too many MRTs in %s, "
+            "refusing to bind framebuffer state!\n", __FUNCTION__);
+        return;
+    }
+
     if (r300->draw) {
         draw_flush(r300->draw);
     }
 
-    r300->framebuffer_state = *state;
+    memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state));
 
     /* Don't rely on the order of states being set for the first time. */
-    r300->dirty_state |= R300_NEW_FRAMEBUFFERS;
-
+    /* XXX wait what */
     r300->blend_state.dirty = TRUE;
     r300->dsa_state.dirty = TRUE;
+    r300->fb_state.dirty = TRUE;
     r300->scissor_state.dirty = TRUE;
 
-    /* Polyfon offset depends on the zbuffer bit depth. */
+    /* Polygon offset depends on the zbuffer bit depth. */
     if (state->zsbuf && r300->polygon_offset_enabled) {
         switch (util_format_get_blocksize(state->zsbuf->texture->format)) {
             case 2:
@@ -610,10 +628,12 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
     rs->point_size = pack_float_16_6x(state->point_size) |
         (pack_float_16_6x(state->point_size) << R300_POINTSIZE_X_SHIFT);
 
-    rs->point_minmax =
-        ((int)(state->point_size_min * 6.0) <<
+        /* set hw limits - clamping done by state tracker in vs or point_size
+           XXX always need to emit this? */
+        rs->point_minmax =
+        ((int)(0.0 * 6.0) <<
          R300_GA_POINT_MINMAX_MIN_SHIFT) |
-        ((int)(state->point_size_max * 6.0) <<
+        ((int)(4096.0 * 6.0) <<
          R300_GA_POINT_MINMAX_MAX_SHIFT);
 
     rs->line_control = pack_float_16_6x(state->line_width) |