X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=blobdiff_plain;f=src%2Ffreedreno%2Fvulkan%2Ftu_pipeline.c;h=3362945728928880de0c449b5874f918ea10a130;hp=d9ffa2411fec1d46c5311f7b248d75fa90f27c76;hb=6d513eb0db25a272da65822f35907456b544f172;hpb=a92d2e11095d9f1f8bc1188fd3d2b8391acc4591 diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c index d9ffa2411fe..33629457289 100644 --- a/src/freedreno/vulkan/tu_pipeline.c +++ b/src/freedreno/vulkan/tu_pipeline.c @@ -648,7 +648,7 @@ tu6_emit_gs_config(struct tu_cs *cs, struct tu_shader *shader, const struct ir3_shader_variant *gs) { bool has_gs = gs->type != MESA_SHADER_NONE; - tu_cs_emit_pkt4(cs, REG_A6XX_SP_GS_UNKNOWN_A871, 1); + tu_cs_emit_pkt4(cs, REG_A6XX_SP_GS_PRIM_SIZE, 1); tu_cs_emit(cs, 0); tu_cs_emit_pkt4(cs, REG_A6XX_SP_GS_CONFIG, 2); @@ -732,7 +732,8 @@ tu6_emit_cs_config(struct tu_cs *cs, const struct tu_shader *shader, static void tu6_emit_vs_system_values(struct tu_cs *cs, const struct ir3_shader_variant *vs, - const struct ir3_shader_variant *gs) + const struct ir3_shader_variant *gs, + bool primid_passthru) { const uint32_t vertexid_regid = ir3_find_sysval_regid(vs, SYSTEM_VALUE_VERTEX_ID); @@ -755,7 +756,7 @@ tu6_emit_vs_system_values(struct tu_cs *cs, tu_cs_emit(cs, 0x000000fc); /* VFD_CONTROL_4 */ tu_cs_emit(cs, A6XX_VFD_CONTROL_5_REGID_GSHEADER(gsheader_regid) | 0xfc00); /* VFD_CONTROL_5 */ - tu_cs_emit(cs, 0x00000000); /* VFD_CONTROL_6 */ + tu_cs_emit(cs, COND(primid_passthru, A6XX_VFD_CONTROL_6_PRIMID_PASSTHRU)); /* VFD_CONTROL_6 */ } /* Add any missing varyings needed for stream-out. Otherwise varyings not @@ -827,6 +828,10 @@ tu6_setup_streamout(const struct ir3_shader_variant *v, unsigned k = out->register_index; unsigned idx; + /* Skip it, if there's an unused reg in the middle of outputs. */ + if (v->outputs[k].regid == INVALID_REG) + continue; + tf->ncomp[out->output_buffer] += out->num_components; /* linkage map sorted by order frag shader wants things, so @@ -893,6 +898,8 @@ tu6_emit_link_map(struct tu_cs *cs, int size = DIV_ROUND_UP(num_loc, 4); size = (MIN2(size + base, consumer->constlen) - base) * 4; + if (size <= 0) + return; tu6_emit_const(cs, CP_LOAD_STATE6_GEOM, base, SB6_GS_SHADER, 0, size, patch_locs); @@ -923,23 +930,22 @@ tu6_emit_vpc(struct tu_cs *cs, bool has_gs = gs->type != MESA_SHADER_NONE; const struct ir3_shader_variant *last_shader = has_gs ? gs : vs; struct ir3_shader_linkage linkage = { 0 }; - ir3_link_shaders(&linkage, last_shader, fs); + ir3_link_shaders(&linkage, last_shader, fs, true); if (last_shader->shader->stream_output.num_outputs) tu6_link_streamout(&linkage, last_shader); - BITSET_DECLARE(vpc_var_enables, 128) = { 0 }; - for (uint32_t i = 0; i < linkage.cnt; i++) { - const uint32_t comp_count = util_last_bit(linkage.var[i].compmask); - for (uint32_t j = 0; j < comp_count; j++) - BITSET_SET(vpc_var_enables, linkage.var[i].loc + j); - } + /* We do this after linking shaders in order to know whether PrimID + * passthrough needs to be enabled. + */ + bool primid_passthru = linkage.primid_loc != 0xff; + tu6_emit_vs_system_values(cs, vs, gs, primid_passthru); tu_cs_emit_pkt4(cs, REG_A6XX_VPC_VAR_DISABLE(0), 4); - tu_cs_emit(cs, ~vpc_var_enables[0]); - tu_cs_emit(cs, ~vpc_var_enables[1]); - tu_cs_emit(cs, ~vpc_var_enables[2]); - tu_cs_emit(cs, ~vpc_var_enables[3]); + tu_cs_emit(cs, ~linkage.varmask[0]); + tu_cs_emit(cs, ~linkage.varmask[1]); + tu_cs_emit(cs, ~linkage.varmask[2]); + tu_cs_emit(cs, ~linkage.varmask[3]); /* a6xx finds position/pointsize at the end */ const uint32_t position_regid = @@ -992,10 +998,14 @@ tu6_emit_vpc(struct tu_cs *cs, tu_cs_emit_pkt4(cs, REG_A6XX_SP_VS_VPC_DST_REG(0), sp_vpc_dst_count); tu_cs_emit_array(cs, sp_vpc_dst, sp_vpc_dst_count); + tu_cs_emit_pkt4(cs, REG_A6XX_PC_PRIMID_CNTL, 1); + tu_cs_emit(cs, COND(primid_passthru, A6XX_PC_PRIMID_CNTL_PRIMID_PASSTHRU)); + tu_cs_emit_pkt4(cs, REG_A6XX_VPC_CNTL_0, 1); tu_cs_emit(cs, A6XX_VPC_CNTL_0_NUMNONPOSVAR(fs->total_in) | (fs->total_in > 0 ? A6XX_VPC_CNTL_0_VARYING : 0) | - 0xff00ff00); + A6XX_VPC_CNTL_0_PRIMIDLOC(linkage.primid_loc) | + A6XX_VPC_CNTL_0_UNKLOC(0xff)); tu_cs_emit_pkt4(cs, REG_A6XX_VPC_PACK, 1); tu_cs_emit(cs, A6XX_VPC_PACK_POSITIONLOC(position_loc) | @@ -1070,7 +1080,7 @@ tu6_emit_vpc(struct tu_cs *cs, tu_cs_emit_pkt4(cs, REG_A6XX_PC_UNKNOWN_9B07, 1); tu_cs_emit(cs, 0); - tu_cs_emit_pkt4(cs, REG_A6XX_SP_GS_UNKNOWN_A871, 1); + tu_cs_emit_pkt4(cs, REG_A6XX_SP_GS_PRIM_SIZE, 1); tu_cs_emit(cs, vs->shader->output_size); } @@ -1548,7 +1558,6 @@ tu6_emit_program(struct tu_cs *cs, tu6_emit_gs_config(cs, builder->shaders[MESA_SHADER_GEOMETRY], gs); tu6_emit_fs_config(cs, builder->shaders[MESA_SHADER_FRAGMENT], fs); - tu6_emit_vs_system_values(cs, vs, gs); tu6_emit_vpc(cs, vs, gs, fs, binning_pass, tf); tu6_emit_vpc_varying_modes(cs, fs, binning_pass); tu6_emit_fs_inputs(cs, fs); @@ -2107,7 +2116,7 @@ tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder) for (gl_shader_stage stage = MESA_SHADER_STAGES - 1; stage > MESA_SHADER_NONE; stage--) { const VkPipelineShaderStageCreateInfo *stage_info = stage_infos[stage]; - if (!stage_info) + if (!stage_info && stage != MESA_SHADER_FRAGMENT) continue; struct tu_shader *shader = @@ -2448,7 +2457,7 @@ tu_pipeline_builder_parse_multisample_and_color_blend( : &dummy_blend_info; struct tu_cs blend_cs; - tu_cs_begin_sub_stream(&pipeline->cs, MAX_RTS * 3 + 9, &blend_cs); + tu_cs_begin_sub_stream(&pipeline->cs, MAX_RTS * 3 + 18, &blend_cs); uint32_t blend_enable_mask; tu6_emit_rb_mrt_controls(&blend_cs, blend_info,