Esempio n. 1
0
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();
}
Esempio n. 2
0
static void
emit_elt32(struct push_context *ctx, unsigned start, unsigned count)
{
   uint32_t *idxbuf = ctx->idxbuf;

   while (count--)
      emit_vertex(ctx, idxbuf[start++]);
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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();
}
Esempio n. 5
0
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] );
}
Esempio n. 6
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] );
   }   
}
Esempio n. 7
0
/**
 * 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);
}
Esempio n. 9
0
static void
emit_seq(struct push_context *ctx, unsigned start, unsigned count)
{
   while (count--)
      emit_vertex(ctx, start++);
}
Esempio n. 10
0
static void
emit_verts(void *priv, unsigned start, unsigned count)
{
   while (count--)
      emit_vertex(priv, start++);
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
/**
 * 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;
}
Esempio n. 13
0
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;
}