示例#1
0
int etna_assemble(uint32_t *out, const struct etna_inst *inst)
{
    if(inst->imm && inst->src[2].use)
        return 1; /* cannot have both src2 and imm */

    if(!check_uniforms(inst))
    {
        BUG("error: generating instruction that accesses two different uniforms");
    }

    out[0] = VIV_ISA_WORD_0_OPCODE(inst->opcode) |
             VIV_ISA_WORD_0_COND(inst->cond) |
             (inst->sat ? VIV_ISA_WORD_0_SAT : 0) |
             (inst->dst.use ? VIV_ISA_WORD_0_DST_USE : 0) |
             VIV_ISA_WORD_0_DST_AMODE(inst->dst.amode) |
             VIV_ISA_WORD_0_DST_REG(inst->dst.reg) |
             VIV_ISA_WORD_0_DST_COMPS(inst->dst.comps) |
             VIV_ISA_WORD_0_TEX_ID(inst->tex.id);
    out[1] = VIV_ISA_WORD_1_TEX_AMODE(inst->tex.amode) |
             VIV_ISA_WORD_1_TEX_SWIZ(inst->tex.swiz) |
             (inst->src[0].use ? VIV_ISA_WORD_1_SRC0_USE : 0) |
             VIV_ISA_WORD_1_SRC0_REG(inst->src[0].reg) |
             VIV_ISA_WORD_1_SRC0_SWIZ(inst->src[0].swiz) |
             (inst->src[0].neg ? VIV_ISA_WORD_1_SRC0_NEG : 0) |
             (inst->src[0].abs ? VIV_ISA_WORD_1_SRC0_ABS : 0);
    out[2] = VIV_ISA_WORD_2_SRC0_AMODE(inst->src[0].amode) |
             VIV_ISA_WORD_2_SRC0_RGROUP(inst->src[0].rgroup) |
             (inst->src[1].use ? VIV_ISA_WORD_2_SRC1_USE : 0) |
             VIV_ISA_WORD_2_SRC1_REG(inst->src[1].reg) |
             VIV_ISA_WORD_2_SRC1_SWIZ(inst->src[1].swiz) |
             (inst->src[1].neg ? VIV_ISA_WORD_2_SRC1_NEG : 0) |
             (inst->src[1].abs ? VIV_ISA_WORD_2_SRC1_ABS : 0) |
             VIV_ISA_WORD_2_SRC1_AMODE(inst->src[1].amode);
    out[3] = VIV_ISA_WORD_3_SRC1_RGROUP(inst->src[1].rgroup) |
             (inst->src[2].use ? VIV_ISA_WORD_3_SRC2_USE : 0) |
             VIV_ISA_WORD_3_SRC2_REG(inst->src[2].reg) |
             VIV_ISA_WORD_3_SRC2_SWIZ(inst->src[2].swiz) |
             (inst->src[2].neg ? VIV_ISA_WORD_3_SRC2_NEG : 0) |
             (inst->src[2].abs ? VIV_ISA_WORD_3_SRC2_ABS : 0) |
             VIV_ISA_WORD_3_SRC2_AMODE(inst->src[2].amode) |
             VIV_ISA_WORD_3_SRC2_RGROUP(inst->src[2].rgroup);
    out[3] |= VIV_ISA_WORD_3_SRC2_IMM(inst->imm);
    return 0;
}
示例#2
0
/**
 * This function gets plugged into the VBO module and is called when
 * we have something to render.
 * Basically, translate the information into the format expected by gallium.
 */
void
st_draw_vbo(struct gl_context *ctx,
            const struct _mesa_prim *prims,
            GLuint nr_prims,
            const struct _mesa_index_buffer *ib,
	    GLboolean index_bounds_valid,
            GLuint min_index,
            GLuint max_index,
            struct gl_transform_feedback_object *tfb_vertcount,
            struct gl_buffer_object *indirect)
{
   struct st_context *st = st_context(ctx);
   struct pipe_index_buffer ibuffer = {0};
   struct pipe_draw_info info;
   const struct gl_client_array **arrays = ctx->Array._DrawArrays;
   unsigned i;

   /* Mesa core state should have been validated already */
   assert(ctx->NewState == 0x0);

   /* Validate state. */
   if (st->dirty.st || ctx->NewDriverState) {
      st_validate_state(st);

#if 0
      if (MESA_VERBOSE & VERBOSE_GLSL) {
         check_uniforms(ctx);
      }
#else
      (void) check_uniforms;
#endif
   }

   if (st->vertex_array_out_of_memory) {
      return;
   }

   util_draw_init_info(&info);

   if (ib) {
      /* Get index bounds for user buffers. */
      if (!index_bounds_valid)
         if (!all_varyings_in_vbos(arrays))
            vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index,
                                   nr_prims);

      if (!setup_index_buffer(st, ib, &ibuffer)) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBegin/DrawElements/DrawArray");
         return;
      }

      info.indexed = TRUE;
      if (min_index != ~0 && max_index != ~0) {
         info.min_index = min_index;
         info.max_index = max_index;
      }

      /* The VBO module handles restart for the non-indexed GLDrawArrays
       * so we only set these fields for indexed drawing:
       */
      info.primitive_restart = ctx->Array._PrimitiveRestart;
      info.restart_index = ctx->Array.RestartIndex;
   }
   else {
      /* Transform feedback drawing is always non-indexed. */
      /* Set info.count_from_stream_output. */
      if (tfb_vertcount) {
         st_transform_feedback_draw_init(tfb_vertcount, &info);
      }
   }

   /* do actual drawing */
   for (i = 0; i < nr_prims; i++) {
      info.mode = translate_prim(ctx, prims[i].mode);
      info.start = prims[i].start;
      info.count = prims[i].count;
      info.start_instance = prims[i].base_instance;
      info.instance_count = prims[i].num_instances;
      info.index_bias = prims[i].basevertex;
      if (!ib) {
         info.min_index = info.start;
         info.max_index = info.start + info.count - 1;
      }

      if (ST_DEBUG & DEBUG_DRAW) {
         debug_printf("st/draw: mode %s  start %u  count %u  indexed %d\n",
                      u_prim_name(info.mode),
                      info.start,
                      info.count,
                      info.indexed);
      }

      if (info.count_from_stream_output) {
         cso_draw_vbo(st->cso_context, &info);
      }
      else if (info.primitive_restart) {
         /* don't trim, restarts might be inside index list */
         cso_draw_vbo(st->cso_context, &info);
      }
      else if (u_trim_pipe_prim(prims[i].mode, &info.count)) {
         cso_draw_vbo(st->cso_context, &info);
      }
   }

   if (ib && st->indexbuf_uploader && !_mesa_is_bufferobj(ib->obj)) {
      pipe_resource_reference(&ibuffer.buffer, NULL);
   }
}
示例#3
0
/**
 * This function gets plugged into the VBO module and is called when
 * we have something to render.
 * Basically, translate the information into the format expected by gallium.
 */
void
st_draw_vbo(struct gl_context *ctx,
            const struct _mesa_prim *prims,
            GLuint nr_prims,
            const struct _mesa_index_buffer *ib,
	    GLboolean index_bounds_valid,
            GLuint min_index,
            GLuint max_index,
            struct gl_transform_feedback_object *tfb_vertcount)
{
   struct st_context *st = st_context(ctx);
   struct pipe_index_buffer ibuffer = {0};
   struct pipe_draw_info info;
   const struct gl_client_array **arrays = ctx->Array._DrawArrays;
   unsigned i;
   GLboolean new_array;

   /* Mesa core state should have been validated already */
   assert(ctx->NewState == 0x0);

   /* Get Mesa driver state. */
   st->dirty.st |= ctx->NewDriverState;
   ctx->NewDriverState = 0;

   new_array =
      (st->dirty.st & (ST_NEW_VERTEX_ARRAYS | ST_NEW_VERTEX_PROGRAM)) ||
      (st->dirty.mesa & (_NEW_PROGRAM | _NEW_BUFFER_OBJECT)) != 0;

   /* Validate state. */
   if (st->dirty.st) {
      GLboolean vertDataEdgeFlags;

      vertDataEdgeFlags = arrays[VERT_ATTRIB_EDGEFLAG]->BufferObj &&
                          arrays[VERT_ATTRIB_EDGEFLAG]->BufferObj->Name;
      if (vertDataEdgeFlags != st->vertdata_edgeflags) {
         st->vertdata_edgeflags = vertDataEdgeFlags;
         st->dirty.st |= ST_NEW_EDGEFLAGS_DATA;
      }

      st_validate_state(st);

      if (new_array) {
         if (!st_validate_varrays(ctx, arrays)) {
            /* probably out of memory, no-op the draw call */
            return;
         }
      }

#if 0
      if (MESA_VERBOSE & VERBOSE_GLSL) {
         check_uniforms(ctx);
      }
#else
      (void) check_uniforms;
#endif
   }

   util_draw_init_info(&info);
   if (ib) {
      /* Get index bounds for user buffers. */
      if (!index_bounds_valid)
         if (!all_varyings_in_vbos(arrays))
            vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index,
                                   nr_prims);

      setup_index_buffer(st, ib, &ibuffer);

      info.indexed = TRUE;
      if (min_index != ~0 && max_index != ~0) {
         info.min_index = min_index;
         info.max_index = max_index;
      }

      /* The VBO module handles restart for the non-indexed GLDrawArrays
       * so we only set these fields for indexed drawing:
       */
      info.primitive_restart = ctx->Array.PrimitiveRestart;
      info.restart_index = ctx->Array.RestartIndex;
   }
   else {
      /* Transform feedback drawing is always non-indexed. */
      /* Set info.count_from_stream_output. */
      if (tfb_vertcount) {
         st_transform_feedback_draw_init(tfb_vertcount, &info);
      }
   }

   /* do actual drawing */
   for (i = 0; i < nr_prims; i++) {
      info.mode = translate_prim( ctx, prims[i].mode );
      info.start = prims[i].start;
      info.count = prims[i].count;
      info.instance_count = prims[i].num_instances;
      info.index_bias = prims[i].basevertex;
      if (!ib) {
         info.min_index = info.start;
         info.max_index = info.start + info.count - 1;
      }

      if (info.count_from_stream_output) {
         cso_draw_vbo(st->cso_context, &info);
      }
      else if (info.primitive_restart) {
         /* don't trim, restarts might be inside index list */
         cso_draw_vbo(st->cso_context, &info);
      }
      else if (u_trim_pipe_prim(info.mode, &info.count))
         cso_draw_vbo(st->cso_context, &info);
   }

   if (ib && st->indexbuf_uploader && !_mesa_is_bufferobj(ib->obj)) {
      pipe_resource_reference(&ibuffer.buffer, NULL);
   }
}