diff options
-rw-r--r-- | src/gallium/drivers/swr/swr_draw.cpp | 39 | ||||
-rw-r--r-- | src/gallium/drivers/swr/swr_shader.cpp | 32 | ||||
-rw-r--r-- | src/gallium/drivers/swr/swr_shader.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/swr/swr_state.cpp | 5 |
4 files changed, 71 insertions, 8 deletions
diff --git a/src/gallium/drivers/swr/swr_draw.cpp b/src/gallium/drivers/swr/swr_draw.cpp index 62ad3f716cf..df1c11abeb7 100644 --- a/src/gallium/drivers/swr/swr_draw.cpp +++ b/src/gallium/drivers/swr/swr_draw.cpp @@ -81,8 +81,11 @@ swr_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) offsets[output_buffer] = so->output[i].dst_offset; } + unsigned attrib_slot = so->output[i].register_index; + attrib_slot = swr_so_adjust_attrib(attrib_slot, ctx->vs); + state.stream.decl[num].bufferIndex = output_buffer; - state.stream.decl[num].attribSlot = so->output[i].register_index - 1; + state.stream.decl[num].attribSlot = attrib_slot; state.stream.decl[num].componentMask = ((1 << so->output[i].num_components) - 1) << so->output[i].start_component; @@ -129,10 +132,36 @@ swr_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) * XXX setup provokingVertex & topologyProvokingVertex */ SWR_FRONTEND_STATE feState = {0}; - feState.vsVertexSize = - VERTEX_ATTRIB_START_SLOT + - + ctx->vs->info.base.num_outputs - - (ctx->vs->info.base.writes_position ? 1 : 0); + // feState.vsVertexSize seeds the PA size that is used as an interface + // between all the shader stages, so it has to be large enough to + // incorporate all interfaces between stages + + // max of gs and vs num_outputs + feState.vsVertexSize = ctx->vs->info.base.num_outputs; + if (ctx->gs && + ctx->gs->info.base.num_outputs > feState.vsVertexSize) { + feState.vsVertexSize = ctx->gs->info.base.num_outputs; + } + + if (ctx->vs->info.base.num_outputs) { + // gs does not adjust for position in SGV slot at input from vs + if (!ctx->gs) + feState.vsVertexSize--; + } + + // other (non-SGV) slots start at VERTEX_ATTRIB_START_SLOT + feState.vsVertexSize += VERTEX_ATTRIB_START_SLOT; + + // The PA in the clipper does not handle BE vertex sizes + // different from FE. Increase vertexsize only for the cases that needed it + + // primid needs a slot + if (ctx->fs->info.base.uses_primid) + feState.vsVertexSize++; + // sprite coord enable + if (ctx->rasterizer->sprite_coord_enable) + feState.vsVertexSize++; + if (ctx->rasterizer->flatshade_first) { feState.provokingVertex = {1, 0, 0}; diff --git a/src/gallium/drivers/swr/swr_shader.cpp b/src/gallium/drivers/swr/swr_shader.cpp index 83b49c47635..0a81eaa006f 100644 --- a/src/gallium/drivers/swr/swr_shader.cpp +++ b/src/gallium/drivers/swr/swr_shader.cpp @@ -414,7 +414,10 @@ BuilderSWR::swr_gs_llvm_emit_vertex(const struct lp_build_tgsi_gs_iface *gs_base } else if (iface->info->output_semantic_name[attrib] == TGSI_SEMANTIC_POSITION) { attribSlot = VERTEX_POSITION_SLOT; } else { - attribSlot = VERTEX_ATTRIB_START_SLOT + attrib - 1; + attribSlot = VERTEX_ATTRIB_START_SLOT + attrib; + if (iface->info->writes_position) { + attribSlot--; + } } #if USE_SIMD16_FRONTEND @@ -923,6 +926,33 @@ swr_compile_vs(struct swr_context *ctx, swr_jit_vs_key &key) return func; } +unsigned +swr_so_adjust_attrib(unsigned in_attrib, + swr_vertex_shader *swr_vs) +{ + ubyte semantic_name; + unsigned attrib; + + attrib = in_attrib + VERTEX_ATTRIB_START_SLOT; + + if (swr_vs) { + semantic_name = swr_vs->info.base.output_semantic_name[in_attrib]; + if (semantic_name == TGSI_SEMANTIC_POSITION) { + attrib = VERTEX_POSITION_SLOT; + } else if (semantic_name == TGSI_SEMANTIC_PSIZE) { + attrib = VERTEX_SGV_SLOT; + } else if (semantic_name == TGSI_SEMANTIC_LAYER) { + attrib = VERTEX_SGV_SLOT; + } else { + if (swr_vs->info.base.writes_position) { + attrib--; + } + } + } + + return attrib; +} + static unsigned locate_linkage(ubyte name, ubyte index, struct tgsi_shader_info *info) { diff --git a/src/gallium/drivers/swr/swr_shader.h b/src/gallium/drivers/swr/swr_shader.h index 1ab68460569..6468874dc3f 100644 --- a/src/gallium/drivers/swr/swr_shader.h +++ b/src/gallium/drivers/swr/swr_shader.h @@ -30,6 +30,9 @@ struct swr_jit_fs_key; struct swr_jit_vs_key; struct swr_jit_gs_key; +unsigned swr_so_adjust_attrib(unsigned in_attrib, + swr_vertex_shader *swr_vs); + PFN_VERTEX_FUNC swr_compile_vs(struct swr_context *ctx, swr_jit_vs_key &key); diff --git a/src/gallium/drivers/swr/swr_state.cpp b/src/gallium/drivers/swr/swr_state.cpp index 501fdea7880..47ab4453898 100644 --- a/src/gallium/drivers/swr/swr_state.cpp +++ b/src/gallium/drivers/swr/swr_state.cpp @@ -345,13 +345,14 @@ swr_create_vs_state(struct pipe_context *pipe, // soState.streamToRasterizer not used for (uint32_t i = 0; i < stream_output->num_outputs; i++) { + unsigned attrib_slot = stream_output->output[i].register_index; + attrib_slot = swr_so_adjust_attrib(attrib_slot, swr_vs); swr_vs->soState.streamMasks[stream_output->output[i].stream] |= - 1 << (stream_output->output[i].register_index - 1); + (1 << attrib_slot); } for (uint32_t i = 0; i < MAX_SO_STREAMS; i++) { swr_vs->soState.streamNumEntries[i] = _mm_popcnt_u32(swr_vs->soState.streamMasks[i]); - swr_vs->soState.vertexAttribOffset[i] = VERTEX_ATTRIB_START_SLOT; // TODO: optimize } } |