void vec4_vs_visitor::emit_thread_end() { setup_uniform_clipplane_values(); /* Lower legacy ff and ClipVertex clipping to clip distances */ if (key->nr_userclip_plane_consts > 0) { current_annotation = "user clip distances"; output_reg[VARYING_SLOT_CLIP_DIST0][0] = dst_reg(this, glsl_type::vec4_type); output_reg[VARYING_SLOT_CLIP_DIST1][0] = dst_reg(this, glsl_type::vec4_type); output_num_components[VARYING_SLOT_CLIP_DIST0][0] = 4; output_num_components[VARYING_SLOT_CLIP_DIST1][0] = 4; emit_clip_distances(output_reg[VARYING_SLOT_CLIP_DIST0][0], 0); emit_clip_distances(output_reg[VARYING_SLOT_CLIP_DIST1][0], 4); } /* For VS, we always end the thread by emitting a single vertex. * emit_urb_write_opcode() will take care of setting the eot flag on the * SEND instruction. */ emit_vertex(); }
static void emit_elt32(struct push_context *ctx, unsigned start, unsigned count) { uint32_t *idxbuf = ctx->idxbuf; while (count--) emit_vertex(ctx, idxbuf[start++]); }
static void emit_elt32_biased(void *priv, unsigned start, unsigned count) { struct push_context *ctx = priv; uint32_t *idxbuf = ctx->idxbuf; while (count--) emit_vertex(ctx, idxbuf[start++] + ctx->idxbias); }
void vec4_vs_visitor::emit_thread_end() { /* For VS, we always end the thread by emitting a single vertex. * emit_urb_write_opcode() will take care of setting the eot flag on the * SEND instruction. */ emit_vertex(); }
static void vbuf_point( struct draw_stage *stage, struct prim_header *prim ) { struct vbuf_stage *vbuf = vbuf_stage( stage ); check_space( vbuf, 1 ); vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[0] ); }
static void vbuf_line( struct draw_stage *stage, struct prim_header *prim ) { struct vbuf_stage *vbuf = vbuf_stage( stage ); unsigned i; check_space( vbuf, 2 ); for (i = 0; i < 2; i++) { vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] ); } }
/** * Emit GLX DrawArrays protocol using a GLXRender packet. */ static void emit_Render_DrawArrays(__GLXcontext * gc, const struct array_info * arrays, GLsizei first, GLsizei count, GLsizei num_arrays, GLenum mode, GLsizei cmdlen, GLsizei total_vertex_size) { GLubyte * pc = gc->pc; GLsizei offset; GLsizei i; __GLX_BEGIN_VARIABLE(X_GLrop_DrawArrays, cmdlen); emit_header(pc + 4, arrays, num_arrays, count, mode); /* Write the actual array data. */ offset = __GLX_DRAWARRAYS_CMD_HDR_SIZE + (num_arrays * __GLX_COMPONENT_HDR_SIZE); for ( i = 0 ; i < count ; i++ ) { offset = emit_vertex(pc, arrays, num_arrays, i + first, offset); } __GLX_END(cmdlen); }
void gen2_render_copyfunc(struct intel_batchbuffer *batch, drm_intel_context *context, struct igt_buf *src, unsigned src_x, unsigned src_y, unsigned width, unsigned height, struct igt_buf *dst, unsigned dst_x, unsigned dst_y) { gen2_emit_invariant(batch); gen2_emit_copy_pipeline(batch); gen2_emit_target(batch, dst); gen2_emit_texture(batch, src, 0); OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | I1_LOAD_S(3) | I1_LOAD_S(8) | 2); OUT_BATCH(1<<12); OUT_BATCH(S3_CULLMODE_NONE | S3_VERTEXHAS_XY); OUT_BATCH(S8_ENABLE_COLOR_BUFFER_WRITE); OUT_BATCH(_3DSTATE_VERTEX_FORMAT_2_CMD | TEXCOORDFMT_2D << 0); OUT_BATCH(PRIM3D_INLINE | PRIM3D_RECTLIST | (3*4 -1)); emit_vertex(batch, dst_x + width); emit_vertex(batch, dst_y + height); emit_vertex_normalized(batch, src_x + width, igt_buf_width(src)); emit_vertex_normalized(batch, src_y + height, igt_buf_height(src)); emit_vertex(batch, dst_x); emit_vertex(batch, dst_y + height); emit_vertex_normalized(batch, src_x, igt_buf_width(src)); emit_vertex_normalized(batch, src_y + height, igt_buf_height(src)); emit_vertex(batch, dst_x); emit_vertex(batch, dst_y); emit_vertex_normalized(batch, src_x, igt_buf_width(src)); emit_vertex_normalized(batch, src_y, igt_buf_height(src)); intel_batchbuffer_flush(batch); }
static void emit_seq(struct push_context *ctx, unsigned start, unsigned count) { while (count--) emit_vertex(ctx, start++); }
static void emit_verts(void *priv, unsigned start, unsigned count) { while (count--) emit_vertex(priv, start++); }
void vec4_gs_visitor::visit(ir_emit_vertex *ir) { this->current_annotation = "emit vertex: safety check"; /* To ensure that we don't output more vertices than the shader specified * using max_vertices, do the logic inside a conditional of the form "if * (vertex_count < MAX)" */ unsigned num_output_vertices = c->gp->program.VerticesOut; emit(CMP(dst_null_d(), this->vertex_count, src_reg(num_output_vertices), BRW_CONDITIONAL_L)); emit(IF(BRW_PREDICATE_NORMAL)); { /* If we're outputting 32 control data bits or less, then we can wait * until the shader is over to output them all. Otherwise we need to * output them as we go. Now is the time to do it, since we're about to * output the vertex_count'th vertex, so it's guaranteed that the * control data bits associated with the (vertex_count - 1)th vertex are * correct. */ if (c->control_data_header_size_bits > 32) { this->current_annotation = "emit vertex: emit control data bits"; /* Only emit control data bits if we've finished accumulating a batch * of 32 bits. This is the case when: * * (vertex_count * bits_per_vertex) % 32 == 0 * * (in other words, when the last 5 bits of vertex_count * * bits_per_vertex are 0). Assuming bits_per_vertex == 2^n for some * integer n (which is always the case, since bits_per_vertex is * always 1 or 2), this is equivalent to requiring that the last 5-n * bits of vertex_count are 0: * * vertex_count & (2^(5-n) - 1) == 0 * * 2^(5-n) == 2^5 / 2^n == 32 / bits_per_vertex, so this is * equivalent to: * * vertex_count & (32 / bits_per_vertex - 1) == 0 */ vec4_instruction *inst = emit(AND(dst_null_d(), this->vertex_count, (uint32_t) (32 / c->control_data_bits_per_vertex - 1))); inst->conditional_mod = BRW_CONDITIONAL_Z; emit(IF(BRW_PREDICATE_NORMAL)); { emit_control_data_bits(); /* Reset control_data_bits to 0 so we can start accumulating a new * batch. * * Note: in the case where vertex_count == 0, this neutralizes the * effect of any call to EndPrimitive() that the shader may have * made before outputting its first vertex. */ inst = emit(MOV(dst_reg(this->control_data_bits), 0u)); inst->force_writemask_all = true; } emit(BRW_OPCODE_ENDIF); } this->current_annotation = "emit vertex: vertex data"; emit_vertex(); /* In stream mode we have to set control data bits for all vertices * unless we have disabled control data bits completely (which we do * do for GL_POINTS outputs that don't use streams). */ if (c->control_data_header_size_bits > 0 && c->prog_data.control_data_format == GEN7_GS_CONTROL_DATA_FORMAT_GSCTL_SID) { this->current_annotation = "emit vertex: Stream control data bits"; set_stream_control_data_bits(ir->stream_id()); } this->current_annotation = "emit vertex: increment vertex count"; emit(ADD(dst_reg(this->vertex_count), this->vertex_count, src_reg(1u))); } emit(BRW_OPCODE_ENDIF); this->current_annotation = NULL; }
/** * Emit GLX DrawArrays protocol using a GLXRenderLarge packet. */ static void emit_RenderLarge_DrawArrays(__GLXcontext * gc, const struct array_info * arrays, GLsizei first, GLsizei count, GLsizei num_arrays, GLenum mode, GLsizei cmdlen, GLsizei total_vertex_size) { GLubyte * pc = gc->pc; GLsizei offset; GLsizei i; GLint maxSize; GLint totalRequests; GLint requestNumber; GLsizei elements_per_request; /* Calculate the maximum amount of data can be stuffed into a single * packet. sz_xGLXRenderReq is added because bufSize is the maximum * packet size minus sz_xGLXRenderReq. * * The important value here is elements_per_request. This is the number * of complete array elements that will fit in a single buffer. There * may be some wasted space at the end of the buffer, but splitting * elements across buffer boundries would be painful. */ maxSize = (gc->bufSize + sz_xGLXRenderReq) - sz_xGLXRenderLargeReq; elements_per_request = maxSize / total_vertex_size; totalRequests = ((count + (elements_per_request - 1)) / elements_per_request) + 1; /* Fill in the header data and send it away. */ __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_DrawArrays, cmdlen+4); emit_header(pc + 8, arrays, num_arrays, count, mode); gc->pc = pc + (__GLX_DRAWARRAYS_CMD_HDR_SIZE + 4) + (__GLX_COMPONENT_HDR_SIZE * num_arrays); __glXSendLargeChunk(gc, 1, totalRequests, gc->buf, gc->pc - gc->buf); /* Write the actual array data. */ offset = 0; requestNumber = 2; for ( i = 0 ; i < count ; i++ ) { if ( i == elements_per_request ) { __glXSendLargeChunk(gc, requestNumber, totalRequests, gc->buf, offset); requestNumber++; offset = 0; count -= i; first += i; i = 0; } offset = emit_vertex(gc->buf, arrays, num_arrays, i + first, offset); } /* If the buffer isn't empty, emit the last, partial request. */ if ( offset != 0 ) { assert(requestNumber == totalRequests); __glXSendLargeChunk(gc, requestNumber, totalRequests, gc->buf, offset); } gc->pc = gc->buf; }
void vec4_gs_visitor::gs_emit_vertex(int stream_id) { this->current_annotation = "emit vertex: safety check"; /* Haswell and later hardware ignores the "Render Stream Select" bits * from the 3DSTATE_STREAMOUT packet when the SOL stage is disabled, * and instead sends all primitives down the pipeline for rasterization. * If the SOL stage is enabled, "Render Stream Select" is honored and * primitives bound to non-zero streams are discarded after stream output. * * Since the only purpose of primives sent to non-zero streams is to * be recorded by transform feedback, we can simply discard all geometry * bound to these streams when transform feedback is disabled. */ if (stream_id > 0 && !nir->info->has_transform_feedback_varyings) return; /* If we're outputting 32 control data bits or less, then we can wait * until the shader is over to output them all. Otherwise we need to * output them as we go. Now is the time to do it, since we're about to * output the vertex_count'th vertex, so it's guaranteed that the * control data bits associated with the (vertex_count - 1)th vertex are * correct. */ if (c->control_data_header_size_bits > 32) { this->current_annotation = "emit vertex: emit control data bits"; /* Only emit control data bits if we've finished accumulating a batch * of 32 bits. This is the case when: * * (vertex_count * bits_per_vertex) % 32 == 0 * * (in other words, when the last 5 bits of vertex_count * * bits_per_vertex are 0). Assuming bits_per_vertex == 2^n for some * integer n (which is always the case, since bits_per_vertex is * always 1 or 2), this is equivalent to requiring that the last 5-n * bits of vertex_count are 0: * * vertex_count & (2^(5-n) - 1) == 0 * * 2^(5-n) == 2^5 / 2^n == 32 / bits_per_vertex, so this is * equivalent to: * * vertex_count & (32 / bits_per_vertex - 1) == 0 */ vec4_instruction *inst = emit(AND(dst_null_ud(), this->vertex_count, brw_imm_ud(32 / c->control_data_bits_per_vertex - 1))); inst->conditional_mod = BRW_CONDITIONAL_Z; emit(IF(BRW_PREDICATE_NORMAL)); { /* If vertex_count is 0, then no control data bits have been * accumulated yet, so we skip emitting them. */ emit(CMP(dst_null_ud(), this->vertex_count, brw_imm_ud(0u), BRW_CONDITIONAL_NEQ)); emit(IF(BRW_PREDICATE_NORMAL)); emit_control_data_bits(); emit(BRW_OPCODE_ENDIF); /* Reset control_data_bits to 0 so we can start accumulating a new * batch. * * Note: in the case where vertex_count == 0, this neutralizes the * effect of any call to EndPrimitive() that the shader may have * made before outputting its first vertex. */ inst = emit(MOV(dst_reg(this->control_data_bits), brw_imm_ud(0u))); inst->force_writemask_all = true; } emit(BRW_OPCODE_ENDIF); } this->current_annotation = "emit vertex: vertex data"; emit_vertex(); /* In stream mode we have to set control data bits for all vertices * unless we have disabled control data bits completely (which we do * do for GL_POINTS outputs that don't use streams). */ if (c->control_data_header_size_bits > 0 && gs_prog_data->control_data_format == GEN7_GS_CONTROL_DATA_FORMAT_GSCTL_SID) { this->current_annotation = "emit vertex: Stream control data bits"; set_stream_control_data_bits(stream_id); } this->current_annotation = NULL; }