diff options
-rw-r--r-- | src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp | 67 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/gen6_gs_visitor.h | 2 |
2 files changed, 69 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp b/src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp index 34cd59be52c..0da95e56011 100644 --- a/src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp @@ -31,6 +31,8 @@ #include "gen6_gs_visitor.h" +const unsigned MAX_GS_INPUT_VERTICES = 6; + namespace brw { void @@ -94,6 +96,30 @@ gen6_gs_visitor::emit_prolog() */ this->prim_count = src_reg(this, glsl_type::uint_type); emit(MOV(dst_reg(this->prim_count), 0u)); + + /* PrimitveID is delivered in r0.1 of the thread payload. If the program + * needs it we have to move it to a separate register where we can map + * the atttribute. + * + * Notice that we cannot use a virtual register for this, because we need to + * map all input attributes to hardware registers in setup_payload(), + * which happens before virtual registers are mapped to hardware registers. + * We could work around that issue if we were able to compute the first + * non-payload register here and move the PrimitiveID information to that + * register, but we can't because at this point we don't know the final + * number uniforms that will be included in the payload. + * + * So, what we do is to place PrimitiveID information in r1, which is always + * delivered as part of the payload, but its only populated with data + * relevant for transform feedback when we set GEN6_GS_SVBI_PAYLOAD_ENABLE + * in the 3DSTATE_GS state packet. That information can be obtained by other + * means though, so we can safely use r1 for this purpose. + */ + if (c->prog_data.include_primitive_id) { + this->primitive_id = + src_reg(retype(brw_vec8_grf(1, 0), BRW_REGISTER_TYPE_UD)); + emit(GS_OPCODE_SET_PRIMITIVE_ID, dst_reg(this->primitive_id)); + } } void @@ -411,4 +437,45 @@ gen6_gs_visitor::emit_thread_end() inst->mlen = 1; } +void +gen6_gs_visitor::setup_payload() +{ + int attribute_map[BRW_VARYING_SLOT_COUNT * MAX_GS_INPUT_VERTICES]; + + /* Attributes are going to be interleaved, so one register contains two + * attribute slots. + */ + int attributes_per_reg = 2; + + /* If a geometry shader tries to read from an input that wasn't written by + * the vertex shader, that produces undefined results, but it shouldn't + * crash anything. So initialize attribute_map to zeros--that ensures that + * these undefined results are read from r0. + */ + memset(attribute_map, 0, sizeof(attribute_map)); + + int reg = 0; + + /* The payload always contains important data in r0. */ + reg++; + + /* r1 is always part of the payload and it holds information relevant + * for transform feedback when we set the GEN6_GS_SVBI_PAYLOAD_ENABLE bit in + * the 3DSTATE_GS packet. We will overwrite it with the PrimitiveID + * information (and move the original value to a virtual register if + * necessary). + */ + if (c->prog_data.include_primitive_id) + attribute_map[VARYING_SLOT_PRIMITIVE_ID] = attributes_per_reg * reg; + reg++; + + reg = setup_uniforms(reg); + + reg = setup_varying_inputs(reg, attribute_map, attributes_per_reg); + + lower_attributes_to_hw_regs(attribute_map, true); + + this->first_non_payload_grf = reg; +} + } /* namespace brw */ diff --git a/src/mesa/drivers/dri/i965/gen6_gs_visitor.h b/src/mesa/drivers/dri/i965/gen6_gs_visitor.h index 7af6405a282..8d2386cc9ab 100644 --- a/src/mesa/drivers/dri/i965/gen6_gs_visitor.h +++ b/src/mesa/drivers/dri/i965/gen6_gs_visitor.h @@ -52,6 +52,7 @@ protected: int base_mrf, int last_mrf, int urb_offset); + virtual void setup_payload(); private: src_reg vertex_output; @@ -59,6 +60,7 @@ private: src_reg temp; src_reg first_vertex; src_reg prim_count; + src_reg primitive_id; }; } /* namespace brw */ |