Пример #1
0
void
vec4_gs_visitor::emit_thread_end()
{
   if (c->control_data_header_size_bits > 0) {
      /* During shader execution, we only ever call emit_control_data_bits()
       * just prior to outputting a vertex.  Therefore, the control data bits
       * corresponding to the most recently output vertex still need to be
       * emitted.
       */
      current_annotation = "thread end: emit control data bits";
      emit_control_data_bits();
   }

   /* MRF 0 is reserved for the debugger, so start with message header
    * in MRF 1.
    */
   int base_mrf = 1;

   current_annotation = "thread end";
   dst_reg mrf_reg(MRF, base_mrf);
   src_reg r0(retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD));
   vec4_instruction *inst = emit(MOV(mrf_reg, r0));
   inst->force_writemask_all = true;
   emit(GS_OPCODE_SET_VERTEX_COUNT, mrf_reg, this->vertex_count);
   if (INTEL_DEBUG & DEBUG_SHADER_TIME)
      emit_shader_time_end();
   inst = emit(GS_OPCODE_THREAD_END);
   inst->base_mrf = base_mrf;
   inst->mlen = 1;
}
Пример #2
0
void
vec4_gs_visitor::emit_thread_end()
{
    if (c->control_data_header_size_bits > 0) {
        /* During shader execution, we only ever call emit_control_data_bits()
         * just prior to outputting a vertex.  Therefore, the control data bits
         * corresponding to the most recently output vertex still need to be
         * emitted.
         */
        current_annotation = "thread end: emit control data bits";
        emit_control_data_bits();
    }

    /* MRF 0 is reserved for the debugger, so start with message header
     * in MRF 1.
     */
    int base_mrf = 1;

    bool static_vertex_count = gs_prog_data->static_vertex_count != -1;

    /* If the previous instruction was a URB write, we don't need to issue
     * a second one - we can just set the EOT bit on the previous write.
     *
     * Skip this on Gen8+ unless there's a static vertex count, as we also
     * need to write the vertex count out, and combining the two may not be
     * possible (or at least not straightforward).
     */
    vec4_instruction *last = (vec4_instruction *) instructions.get_tail();
    if (last && last->opcode == GS_OPCODE_URB_WRITE &&
            !(INTEL_DEBUG & DEBUG_SHADER_TIME) &&
            devinfo->gen >= 8 && static_vertex_count) {
        last->urb_write_flags = BRW_URB_WRITE_EOT | last->urb_write_flags;
        return;
    }

    current_annotation = "thread end";
    dst_reg mrf_reg(MRF, base_mrf);
    src_reg r0(retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD));
    vec4_instruction *inst = emit(MOV(mrf_reg, r0));
    inst->force_writemask_all = true;
    if (devinfo->gen < 8 || !static_vertex_count)
        emit(GS_OPCODE_SET_VERTEX_COUNT, mrf_reg, this->vertex_count);
    if (INTEL_DEBUG & DEBUG_SHADER_TIME)
        emit_shader_time_end();
    inst = emit(GS_OPCODE_THREAD_END);
    inst->base_mrf = base_mrf;
    inst->mlen = devinfo->gen >= 8 && !static_vertex_count ? 2 : 1;
}
Пример #3
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;
}
Пример #4
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;
}