gallium: be smarter about picking the sampler unit for pstipple, aaalines
authorBrian <brian.paul@tungstengraphics.com>
Tue, 25 Mar 2008 01:36:44 +0000 (19:36 -0600)
committerBrian <brian.paul@tungstengraphics.com>
Tue, 25 Mar 2008 01:36:44 +0000 (19:36 -0600)
Also, if the app really uses all available sampler/texture units, don't just
die.  Just use the last sampler for the pstipple or aaline texture.

src/gallium/auxiliary/draw/draw_aaline.c
src/gallium/auxiliary/draw/draw_pstipple.c

index cc1873abada63a4146fdee1a1e79c1ae2898a98b..a999ef12279f3d21b42ae7d899bd1d861841df55 100644 (file)
@@ -61,6 +61,7 @@ struct aaline_fragment_shader
    void *aaline_fs;
    void *aapoint_fs; /* not yet */
    void *sprite_fs; /* not yet */
+   uint sampler_unit;
 };
 
 
@@ -117,7 +118,8 @@ struct aa_transform_context {
    struct tgsi_transform_context base;
    uint tempsUsed;  /**< bitmask */
    int colorOutput; /**< which output is the primary color */
-   int maxSampler;  /**< max sampler index found */
+   uint samplersUsed;  /**< bitfield of samplers used */
+   int freeSampler;  /** an available sampler for the pstipple */
    int maxInput, maxGeneric;  /**< max input index found */
    int colorTemp, texTemp;  /**< temp registers */
    boolean firstInstruction;
@@ -140,8 +142,11 @@ aa_transform_decl(struct tgsi_transform_context *ctx,
       aactx->colorOutput = decl->u.DeclarationRange.First;
    }
    else if (decl->Declaration.File == TGSI_FILE_SAMPLER) {
-      if ((int) decl->u.DeclarationRange.Last > aactx->maxSampler)
-         aactx->maxSampler = decl->u.DeclarationRange.Last + 1;
+      uint i;
+      for (i = decl->u.DeclarationRange.First;
+           i <= decl->u.DeclarationRange.Last; i++) {
+         aactx->samplersUsed |= 1 << i;
+      }
    }
    else if (decl->Declaration.File == TGSI_FILE_INPUT) {
       if ((int) decl->u.DeclarationRange.Last > aactx->maxInput)
@@ -163,6 +168,21 @@ aa_transform_decl(struct tgsi_transform_context *ctx,
 }
 
 
+/**
+ * Find the lowest zero bit in the given word, or -1 if bitfield is all ones.
+ */
+static int
+free_bit(uint bitfield)
+{
+   int i;
+   for (i = 0; i < 32; i++) {
+      if ((bitfield & (1 << i)) == 0)
+         return i;
+   }
+   return -1;
+}
+
+
 /**
  * TGSI instruction transform callback.
  * Replace writes to result.color w/ a temp reg.
@@ -180,6 +200,11 @@ aa_transform_inst(struct tgsi_transform_context *ctx,
       struct tgsi_full_declaration decl;
       uint i;
 
+      /* find free sampler */
+      aactx->freeSampler = free_bit(aactx->samplersUsed);
+      if (aactx->freeSampler >= PIPE_MAX_SAMPLERS)
+         aactx->freeSampler = PIPE_MAX_SAMPLERS - 1;
+
       /* find two free temp regs */
       for (i = 0; i < 32; i++) {
          if ((aactx->tempsUsed & (1 << i)) == 0) {
@@ -212,7 +237,7 @@ aa_transform_inst(struct tgsi_transform_context *ctx,
       decl = tgsi_default_full_declaration();
       decl.Declaration.File = TGSI_FILE_SAMPLER;
       decl.u.DeclarationRange.First = 
-      decl.u.DeclarationRange.Last = aactx->maxSampler + 1;
+      decl.u.DeclarationRange.Last = aactx->freeSampler;
       ctx->emit_declaration(ctx, &decl);
 
       /* declare new temp regs */
@@ -246,7 +271,7 @@ aa_transform_inst(struct tgsi_transform_context *ctx,
       newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
       newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->maxInput + 1;
       newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->maxSampler + 1;
+      newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->freeSampler;
 
       ctx->emit_instruction(ctx, &newInst);
 
@@ -322,7 +347,6 @@ generate_aaline_fs(struct aaline_stage *aaline)
 
    memset(&transform, 0, sizeof(transform));
    transform.colorOutput = -1;
-   transform.maxSampler = -1;
    transform.maxInput = -1;
    transform.maxGeneric = -1;
    transform.colorTemp = -1;
@@ -340,6 +364,8 @@ generate_aaline_fs(struct aaline_stage *aaline)
    tgsi_dump(aaline_fs.tokens, 0);
 #endif
 
+   aaline->fs->sampler_unit = transform.freeSampler;
+
    aaline->fs->aaline_fs
       = aaline->driver_create_fs_state(aaline->pipe, &aaline_fs);
 
@@ -602,7 +628,7 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header)
    auto struct aaline_stage *aaline = aaline_stage(stage);
    struct draw_context *draw = stage->draw;
    struct pipe_context *pipe = aaline->pipe;
-   uint num = MAX2(aaline->num_textures, aaline->num_samplers);
+   uint num_samplers;
 
    assert(draw->rasterizer->line_smooth);
 
@@ -620,11 +646,17 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header)
     */
    bind_aaline_fragment_shader(aaline);
 
-   aaline->state.sampler[num] = aaline->sampler_cso;
-   pipe_texture_reference(&aaline->state.texture[num], aaline->texture);
+   /* how many samplers? */
+   /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
+   num_samplers = MAX2(aaline->num_textures, aaline->num_samplers);
+   num_samplers = MAX2(num_samplers, aaline->fs->sampler_unit + 1);
+
+   aaline->state.sampler[aaline->fs->sampler_unit] = aaline->sampler_cso;
+   pipe_texture_reference(&aaline->state.texture[aaline->fs->sampler_unit],
+                          aaline->texture);
 
-   aaline->driver_bind_sampler_states(pipe, num + 1, aaline->state.sampler);
-   aaline->driver_set_sampler_textures(pipe, num + 1, aaline->state.texture);
+   aaline->driver_bind_sampler_states(pipe, num_samplers, aaline->state.sampler);
+   aaline->driver_set_sampler_textures(pipe, num_samplers, aaline->state.texture);
 
    /* now really draw first line */
    stage->line = aaline_line;
index 9cec98664082f9732d62745b23fcb97e945716d2..4dddb72906f4cb6d378245e5468561032dc6abfe 100644 (file)
@@ -112,7 +112,8 @@ struct pstip_transform_context {
    uint tempsUsed;  /**< bitmask */
    int wincoordInput;
    int maxInput;
-   int maxSampler;  /**< max sampler index found */
+   uint samplersUsed;  /**< bitfield of samplers used */
+   int freeSampler;  /** an available sampler for the pstipple */
    int texTemp;  /**< temp registers */
    int numImmed;
    boolean firstInstruction;
@@ -130,8 +131,11 @@ pstip_transform_decl(struct tgsi_transform_context *ctx,
    struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx;
 
    if (decl->Declaration.File == TGSI_FILE_SAMPLER) {
-      if ((int) decl->u.DeclarationRange.Last > pctx->maxSampler)
-         pctx->maxSampler = (int) decl->u.DeclarationRange.Last;
+      uint i;
+      for (i = decl->u.DeclarationRange.First;
+           i <= decl->u.DeclarationRange.Last; i++) {
+         pctx->samplersUsed |= 1 << i;
+      }
    }
    else if (decl->Declaration.File == TGSI_FILE_INPUT) {
       pctx->maxInput = MAX2(pctx->maxInput, (int) decl->u.DeclarationRange.Last);
@@ -159,6 +163,21 @@ pstip_transform_immed(struct tgsi_transform_context *ctx,
 }
 
 
+/**
+ * Find the lowest zero bit in the given word, or -1 if bitfield is all ones.
+ */
+static int
+free_bit(uint bitfield)
+{
+   int i;
+   for (i = 0; i < 32; i++) {
+      if ((bitfield & (1 << i)) == 0)
+         return i;
+   }
+   return -1;
+}
+
+
 /**
  * TGSI instruction transform callback.
  * Replace writes to result.color w/ a temp reg.
@@ -177,7 +196,11 @@ pstip_transform_inst(struct tgsi_transform_context *ctx,
       struct tgsi_full_instruction newInst;
       uint i;
       int wincoordInput;
-      const int sampler = pctx->maxSampler + 1;
+
+      /* find free sampler */
+      pctx->freeSampler = free_bit(pctx->samplersUsed);
+      if (pctx->freeSampler >= PIPE_MAX_SAMPLERS)
+         pctx->freeSampler = PIPE_MAX_SAMPLERS - 1;
 
       if (pctx->wincoordInput < 0)
          wincoordInput = pctx->maxInput + 1;
@@ -214,7 +237,7 @@ pstip_transform_inst(struct tgsi_transform_context *ctx,
       decl = tgsi_default_full_declaration();
       decl.Declaration.File = TGSI_FILE_SAMPLER;
       decl.u.DeclarationRange.First = 
-      decl.u.DeclarationRange.Last = sampler;
+      decl.u.DeclarationRange.Last = pctx->freeSampler;
       ctx->emit_declaration(ctx, &decl);
 
       /* declare new temp regs */
@@ -274,7 +297,7 @@ pstip_transform_inst(struct tgsi_transform_context *ctx,
       newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
       newInst.FullSrcRegisters[0].SrcRegister.Index = pctx->texTemp;
       newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = sampler;
+      newInst.FullSrcRegisters[1].SrcRegister.Index = pctx->freeSampler;
       ctx->emit_instruction(ctx, &newInst);
 
       /* KILP texTemp;   # if texTemp < 0, KILL fragment */
@@ -313,7 +336,6 @@ generate_pstip_fs(struct pstip_stage *pstip)
    memset(&transform, 0, sizeof(transform));
    transform.wincoordInput = -1;
    transform.maxInput = -1;
-   transform.maxSampler = -1;
    transform.texTemp = -1;
    transform.firstInstruction = TRUE;
    transform.base.transform_instruction = pstip_transform_inst;
@@ -329,7 +351,8 @@ generate_pstip_fs(struct pstip_stage *pstip)
    tgsi_dump(pstip_fs.tokens, 0);
 #endif
 
-   pstip->fs->sampler_unit = transform.maxSampler + 1;
+   pstip->fs->sampler_unit = transform.freeSampler;
+   assert(pstip->fs->sampler_unit < PIPE_MAX_SAMPLERS);
 
    pstip->fs->pstip_fs = pstip->driver_create_fs_state(pstip->pipe, &pstip_fs);
 }
@@ -399,8 +422,6 @@ pstip_create_texture(struct pstip_stage *pstip)
 
    pstip->texture = screen->texture_create(screen, &texTemp);
    assert(pstip->texture->refcount == 1);
-
-   //pstip_update_texture(pstip);
 }