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; }
/** * 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); } }
/** * 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); } }