nv50,nvc0: add new texture and render target formats
[mesa.git] / src / gallium / drivers / nv50 / nv50_shader_state.c
index 2d7572820f2a00545a621c92b47dcd0aa2009f46..82c346cb5eab340e86ad9d3bc70354fd2e8e1086 100644 (file)
@@ -76,7 +76,7 @@ nv50_constbufs_validate(struct nv50_context *nv50)
             assert(0);
 
             if (!nouveau_resource_mapped_by_gpu(&res->base)) {
-               nouveau_buffer_migrate(&nv50->pipe, res, NOUVEAU_BO_VRAM);
+               nouveau_buffer_migrate(&nv50->base, res, NOUVEAU_BO_VRAM);
 
                BEGIN_RING(chan, RING_3D(CODE_CB_FLUSH), 1);
                OUT_RING  (chan, 0);
@@ -138,6 +138,7 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog)
       return FALSE;
 
    if (prog->type == PIPE_SHADER_FRAGMENT) heap = nv50->screen->fp_code_heap;
+   else
    if (prog->type == PIPE_SHADER_GEOMETRY) heap = nv50->screen->gp_code_heap;
    else
       heap = nv50->screen->vp_code_heap;
@@ -145,12 +146,16 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog)
    size = align(prog->code_size, 0x100);
 
    ret = nouveau_resource_alloc(heap, size, prog, &prog->res);
-   if (ret)
+   if (ret) {
+      NOUVEAU_ERR("out of code space for shader type %i\n", prog->type);
       return FALSE;
+   }
    prog->code_base = prog->res->start;
 
-   nv50_sifc_linear_u8(&nv50->pipe, nv50->screen->code,
-                       (prog->type << 16) + prog->code_base,
+   nv50_relocate_program(prog, prog->code_base, 0);
+
+   nv50_sifc_linear_u8(&nv50->base, nv50->screen->code,
+                       (prog->type << NV50_CODE_BO_SIZE_LOG2) + prog->code_base,
                        NOUVEAU_BO_VRAM, prog->code_size, prog->code);
 
    BEGIN_RING(nv50->screen->base.channel, RING_3D(CODE_CB_FLUSH), 1);
@@ -222,12 +227,28 @@ nv50_gmtyprog_validate(struct nv50_context *nv50)
 }
 
 static void
-nv50_pntc_replace(struct nv50_context *nv50, uint32_t pntc[8], unsigned m)
+nv50_sprite_coords_validate(struct nv50_context *nv50)
 {
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+   uint32_t pntc[8], mode;
    struct nv50_program *fp = nv50->fragprog;
    unsigned i, c;
+   unsigned m = (nv50->state.interpolant_ctrl >> 8) & 0xff;
+
+   if (!nv50->rast->pipe.point_quad_rasterization) {
+      if (nv50->state.point_sprite) {
+         BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE_MAP(0)), 8);
+         for (i = 0; i < 8; ++i)
+            OUT_RING(chan, 0);
 
-   memset(pntc, 0, 8 * sizeof(uint32_t));
+         nv50->state.point_sprite = FALSE;
+      }
+      return;
+   } else {
+      nv50->state.point_sprite = TRUE;
+   }
+
+   memset(pntc, 0, sizeof(pntc));
 
    for (i = 0; i < fp->in_nr; i++) {
       unsigned n = util_bitcount(fp->in[i].mask);
@@ -248,6 +269,50 @@ nv50_pntc_replace(struct nv50_context *nv50, uint32_t pntc[8], unsigned m)
          }
       }
    }
+
+   if (nv50->rast->pipe.sprite_coord_mode == PIPE_SPRITE_COORD_LOWER_LEFT)
+      mode = 0x00;
+   else
+      mode = 0x10;
+
+   BEGIN_RING(chan, RING_3D(POINT_SPRITE_CTRL), 1);
+   OUT_RING  (chan, mode);
+
+   BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE_MAP(0)), 8);
+   OUT_RINGp (chan, pntc, 8);
+}
+
+/* Validate state derived from shaders and the rasterizer cso. */
+void
+nv50_validate_derived_rs(struct nv50_context *nv50)
+{
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+   uint32_t color, psize;
+
+   nv50_sprite_coords_validate(nv50);
+
+   if (nv50->dirty & NV50_NEW_FRAGPROG)
+      return;
+   psize = nv50->state.semantic_psize & ~NV50_3D_MAP_SEMANTIC_3_PTSZ_EN__MASK;
+   color = nv50->state.semantic_color & ~NV50_3D_MAP_SEMANTIC_0_CLMP_EN;
+
+   if (nv50->rast->pipe.clamp_vertex_color)
+      color |= NV50_3D_MAP_SEMANTIC_0_CLMP_EN;
+
+   if (color != nv50->state.semantic_color) {
+      nv50->state.semantic_color = color;
+      BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_0), 1);
+      OUT_RING  (chan, color);
+   }
+
+   if (nv50->rast->pipe.point_size_per_vertex)
+      psize |= NV50_3D_MAP_SEMANTIC_3_PTSZ_EN__MASK;
+
+   if (psize != nv50->state.semantic_psize) {
+      nv50->state.semantic_psize = psize;
+      BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_3), 1);
+      OUT_RING  (chan, psize);
+   }
 }
 
 static int
@@ -289,7 +354,7 @@ nv50_fp_linkage_validate(struct nv50_context *nv50)
    uint32_t psiz = 0x000;
    uint32_t interp = fp->fp.interp;
    uint32_t colors = fp->fp.colors;
-   uint32_t lin[4], pntc[8];
+   uint32_t lin[4];
    uint8_t map[64];
 
    memset(lin, 0x00, sizeof(lin));
@@ -340,6 +405,9 @@ nv50_fp_linkage_validate(struct nv50_context *nv50)
       map[m++] = vp->vp.psiz;
    }
 
+   if (nv50->rast->pipe.clamp_vertex_color)
+      colors |= NV50_3D_MAP_SEMANTIC_0_CLMP_EN;
+
    n = (m + 3) / 4;
    assert(m <= 64);
 
@@ -370,18 +438,13 @@ nv50_fp_linkage_validate(struct nv50_context *nv50)
    BEGIN_RING(chan, RING_3D(FP_INTERPOLANT_CTRL), 1);
    OUT_RING  (chan, interp);
 
-   BEGIN_RING(chan, RING_3D(NOPERSPECTIVE_BITMAP(0)), 4);
-   OUT_RINGp (chan, lin, 4);
+   nv50->state.interpolant_ctrl = interp;
 
-   if (nv50->rast->pipe.point_quad_rasterization) {
-      nv50_pntc_replace(nv50, pntc, (interp >> 8) & 0xff);
+   nv50->state.semantic_color = colors;
+   nv50->state.semantic_psize = psiz;
 
-      BEGIN_RING(chan, RING_3D(POINT_SPRITE_CTRL), 1);
-      OUT_RING  (chan, (nv50->rast->pipe.sprite_coord_mode ==
-                        PIPE_SPRITE_COORD_LOWER_LEFT) ? 0 : 0x10);
-      BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE_MAP(0)), 8);
-      OUT_RINGp (chan, pntc, 8);
-   }
+   BEGIN_RING(chan, RING_3D(NOPERSPECTIVE_BITMAP(0)), 4);
+   OUT_RINGp (chan, lin, 4);
 
    BEGIN_RING(chan, RING_3D(GP_ENABLE), 1);
    OUT_RING  (chan, nv50->gmtyprog ? 1 : 0);