From: Marek Olšák <marek.ol...@amd.com> key->part.*: prolog and epilog flags only key->as_{ls,es}: special flags key->mono.*: flags for monolithic compilation only --- src/gallium/drivers/radeonsi/si_pipe.h | 4 +- src/gallium/drivers/radeonsi/si_shader.c | 194 ++++++++++++------------ src/gallium/drivers/radeonsi/si_shader.h | 65 ++++---- src/gallium/drivers/radeonsi/si_state.c | 2 +- src/gallium/drivers/radeonsi/si_state_shaders.c | 132 ++++++++-------- 5 files changed, 203 insertions(+), 194 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index df2f130..847281e 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -456,18 +456,18 @@ static inline struct si_shader* si_get_vs_state(struct si_context *sctx) return sctx->gs_shader.cso->gs_copy_shader; else if (sctx->tes_shader.current) return sctx->tes_shader.current; else return sctx->vs_shader.current; } static inline bool si_vs_exports_prim_id(struct si_shader *shader) { if (shader->selector->type == PIPE_SHADER_VERTEX) - return shader->key.vs.epilog.export_prim_id; + return shader->key.part.vs.epilog.export_prim_id; else if (shader->selector->type == PIPE_SHADER_TESS_EVAL) - return shader->key.tes.epilog.export_prim_id; + return shader->key.part.tes.epilog.export_prim_id; else return false; } #endif diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 917e148..4e73d59 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -61,21 +61,21 @@ struct si_shader_output_values static void si_init_shader_ctx(struct si_shader_context *ctx, struct si_screen *sscreen, struct si_shader *shader, LLVMTargetMachineRef tm); static void si_llvm_emit_barrier(const struct lp_build_tgsi_action *action, struct lp_build_tgsi_context *bld_base, struct lp_build_emit_data *emit_data); -static void si_dump_shader_key(unsigned shader, union si_shader_key *key, +static void si_dump_shader_key(unsigned shader, struct si_shader_key *key, FILE *f); static void si_build_vs_prolog_function(struct si_shader_context *ctx, union si_shader_part_key *key); static void si_build_vs_epilog_function(struct si_shader_context *ctx, union si_shader_part_key *key); static void si_build_tcs_epilog_function(struct si_shader_context *ctx, union si_shader_part_key *key); static void si_build_ps_prolog_function(struct si_shader_context *ctx, union si_shader_part_key *key); @@ -409,21 +409,21 @@ static void declare_input_vs( "llvm.SI.vs.load.input", ctx->v4f32, args, 3, LP_FUNC_ATTR_READNONE); /* Break up the vec4 into individual components */ for (chan = 0; chan < 4; chan++) { LLVMValueRef llvm_chan = lp_build_const_int32(gallivm, chan); out[chan] = LLVMBuildExtractElement(gallivm->builder, input, llvm_chan, ""); } - fix_fetch = (ctx->shader->key.vs.fix_fetch >> (2 * input_index)) & 3; + fix_fetch = (ctx->shader->key.mono.vs.fix_fetch >> (2 * input_index)) & 3; if (fix_fetch) { /* The hardware returns an unsigned value; convert it to a * signed one. */ LLVMValueRef tmp = out[3]; LLVMValueRef c30 = LLVMConstInt(ctx->i32, 30, 0); /* First, recover the sign-extended signed integer value. */ if (fix_fetch == SI_FIX_FETCH_A2_SSCALED) tmp = LLVMBuildFPToUI(gallivm->builder, tmp, ctx->i32, ""); @@ -1245,21 +1245,21 @@ static void interp_fs_input(struct si_shader_context *ctx, * vertices). * * Luckily, it doesn't matter, because we rely on the FLAT_SHADE state * to do the right thing. The only reason we use fs.constant is that * fs.interp cannot be used on integers, because they can be equal * to NaN. */ intr_name = interp_param ? "llvm.SI.fs.interp" : "llvm.SI.fs.constant"; if (semantic_name == TGSI_SEMANTIC_COLOR && - ctx->shader->key.ps.prolog.color_two_side) { + ctx->shader->key.part.ps.prolog.color_two_side) { LLVMValueRef args[4]; LLVMValueRef is_face_positive; LLVMValueRef back_attr_number; /* If BCOLOR0 is used, BCOLOR1 is at offset "num_inputs + 1", * otherwise it's at offset "num_inputs". */ unsigned back_attr_offset = num_interp_inputs; if (semantic_index == 1 && colors_read_mask & 0xf) back_attr_offset += 1; @@ -1353,21 +1353,21 @@ static void declare_input_fs( interp_param_idx = lookup_interp_param_index(decl->Interp.Interpolate, decl->Interp.Location); if (interp_param_idx == -1) return; else if (interp_param_idx) { interp_param = LLVMGetParam(ctx->main_fn, interp_param_idx); } if (decl->Semantic.Name == TGSI_SEMANTIC_COLOR && decl->Interp.Interpolate == TGSI_INTERPOLATE_COLOR && - ctx->shader->key.ps.prolog.flatshade_colors) + ctx->shader->key.part.ps.prolog.flatshade_colors) interp_param = NULL; /* load the constant color */ interp_fs_input(ctx, input_index, decl->Semantic.Name, decl->Semantic.Index, shader->selector->info.num_inputs, shader->selector->info.colors_read, interp_param, LLVMGetParam(main_fn, SI_PARAM_PRIM_MASK), LLVMGetParam(main_fn, SI_PARAM_FRONT_FACE), &out[0]); } @@ -1825,27 +1825,27 @@ static void si_llvm_init_export_args(struct lp_build_tgsi_context *bld_base, /* Specify whether the EXEC mask represents the valid mask */ args[1] = uint->zero; /* Specify whether this is the last export */ args[2] = uint->zero; /* Specify the target we are exporting */ args[3] = lp_build_const_int32(base->gallivm, target); if (ctx->type == PIPE_SHADER_FRAGMENT) { - const union si_shader_key *key = &ctx->shader->key; - unsigned col_formats = key->ps.epilog.spi_shader_col_format; + const struct si_shader_key *key = &ctx->shader->key; + unsigned col_formats = key->part.ps.epilog.spi_shader_col_format; int cbuf = target - V_008DFC_SQ_EXP_MRT; assert(cbuf >= 0 && cbuf < 8); spi_shader_col_format = (col_formats >> (cbuf * 4)) & 0xf; - is_int8 = (key->ps.epilog.color_is_int8 >> cbuf) & 0x1; + is_int8 = (key->part.ps.epilog.color_is_int8 >> cbuf) & 0x1; } args[4] = uint->zero; /* COMPR flag */ args[5] = base->undef; args[6] = base->undef; args[7] = base->undef; args[8] = base->undef; switch (spi_shader_col_format) { case V_028714_SPI_SHADER_ZERO: @@ -1984,27 +1984,27 @@ static void si_llvm_init_export_args(struct lp_build_tgsi_context *bld_base, break; } } static void si_alpha_test(struct lp_build_tgsi_context *bld_base, LLVMValueRef alpha) { struct si_shader_context *ctx = si_shader_context(bld_base); struct gallivm_state *gallivm = bld_base->base.gallivm; - if (ctx->shader->key.ps.epilog.alpha_func != PIPE_FUNC_NEVER) { + if (ctx->shader->key.part.ps.epilog.alpha_func != PIPE_FUNC_NEVER) { LLVMValueRef alpha_ref = LLVMGetParam(ctx->main_fn, SI_PARAM_ALPHA_REF); LLVMValueRef alpha_pass = lp_build_cmp(&bld_base->base, - ctx->shader->key.ps.epilog.alpha_func, + ctx->shader->key.part.ps.epilog.alpha_func, alpha, alpha_ref); LLVMValueRef arg = lp_build_select(&bld_base->base, alpha_pass, lp_build_const_float(gallivm, 1.0f), lp_build_const_float(gallivm, -1.0f)); lp_build_intrinsic(gallivm->builder, "llvm.AMDGPU.kill", ctx->voidt, &arg, 1, 0); } else { @@ -2433,21 +2433,21 @@ static void si_copy_tcs_inputs(struct lp_build_tgsi_context *bld_base) lp_build_const_int32(gallivm, SI_HS_RING_TESS_OFFCHIP)); buffer_offset = LLVMGetParam(ctx->main_fn, ctx->param_oc_lds); lds_vertex_stride = unpack_param(ctx, SI_PARAM_TCS_IN_LAYOUT, 13, 8); lds_vertex_offset = LLVMBuildMul(gallivm->builder, invocation_id, lds_vertex_stride, ""); lds_base = get_tcs_in_current_patch_offset(ctx); lds_base = LLVMBuildAdd(gallivm->builder, lds_base, lds_vertex_offset, ""); - inputs = ctx->shader->key.tcs.epilog.inputs_to_copy; + inputs = ctx->shader->key.mono.tcs.inputs_to_copy; while (inputs) { unsigned i = u_bit_scan64(&inputs); LLVMValueRef lds_ptr = LLVMBuildAdd(gallivm->builder, lds_base, lp_build_const_int32(gallivm, 4 * i), ""); LLVMValueRef buffer_addr = get_tcs_tes_buffer_address(ctx, invocation_id, lp_build_const_int32(gallivm, i)); @@ -2480,21 +2480,21 @@ static void si_write_tess_factors(struct lp_build_tgsi_context *bld_base, * not per-vertex. * * This can't jump, because invocation 0 executes this. It should * at least mask out the loads and stores for other invocations. */ lp_build_if(&if_ctx, gallivm, LLVMBuildICmp(gallivm->builder, LLVMIntEQ, invocation_id, bld_base->uint_bld.zero, "")); /* Determine the layout of one tess factor element in the buffer. */ - switch (shader->key.tcs.epilog.prim_mode) { + switch (shader->key.part.tcs.epilog.prim_mode) { case PIPE_PRIM_LINES: stride = 2; /* 2 dwords, 1 vec2 store */ outer_comps = 2; inner_comps = 0; break; case PIPE_PRIM_TRIANGLES: stride = 4; /* 4 dwords, 1 vec4 store */ outer_comps = 3; inner_comps = 1; break; @@ -2867,53 +2867,53 @@ static void si_export_mrt_z(struct lp_build_tgsi_context *bld_base, static void si_export_mrt_color(struct lp_build_tgsi_context *bld_base, LLVMValueRef *color, unsigned index, unsigned samplemask_param, bool is_last, struct si_ps_exports *exp) { struct si_shader_context *ctx = si_shader_context(bld_base); struct lp_build_context *base = &bld_base->base; int i; /* Clamp color */ - if (ctx->shader->key.ps.epilog.clamp_color) + if (ctx->shader->key.part.ps.epilog.clamp_color) for (i = 0; i < 4; i++) color[i] = si_llvm_saturate(bld_base, color[i]); /* Alpha to one */ - if (ctx->shader->key.ps.epilog.alpha_to_one) + if (ctx->shader->key.part.ps.epilog.alpha_to_one) color[3] = base->one; /* Alpha test */ if (index == 0 && - ctx->shader->key.ps.epilog.alpha_func != PIPE_FUNC_ALWAYS) + ctx->shader->key.part.ps.epilog.alpha_func != PIPE_FUNC_ALWAYS) si_alpha_test(bld_base, color[3]); /* Line & polygon smoothing */ - if (ctx->shader->key.ps.epilog.poly_line_smoothing) + if (ctx->shader->key.part.ps.epilog.poly_line_smoothing) color[3] = si_scale_alpha_by_sample_mask(bld_base, color[3], samplemask_param); /* If last_cbuf > 0, FS_COLOR0_WRITES_ALL_CBUFS is true. */ - if (ctx->shader->key.ps.epilog.last_cbuf > 0) { + if (ctx->shader->key.part.ps.epilog.last_cbuf > 0) { LLVMValueRef args[8][9]; int c, last = -1; /* Get the export arguments, also find out what the last one is. */ - for (c = 0; c <= ctx->shader->key.ps.epilog.last_cbuf; c++) { + for (c = 0; c <= ctx->shader->key.part.ps.epilog.last_cbuf; c++) { si_llvm_init_export_args(bld_base, color, V_008DFC_SQ_EXP_MRT + c, args[c]); if (args[c][0] != bld_base->uint_bld.zero) last = c; } /* Emit all exports. */ - for (c = 0; c <= ctx->shader->key.ps.epilog.last_cbuf; c++) { + for (c = 0; c <= ctx->shader->key.part.ps.epilog.last_cbuf; c++) { if (is_last && last == c) { args[c][1] = bld_base->uint_bld.one; /* whether the EXEC mask is valid */ args[c][2] = bld_base->uint_bld.one; /* DONE bit */ } else if (args[c][0] == bld_base->uint_bld.zero) continue; /* unnecessary NULL export */ memcpy(exp->args[exp->num++], args[c], sizeof(args[c])); } } else { LLVMValueRef args[9]; @@ -5340,23 +5340,23 @@ static void create_function(struct si_shader_context *ctx) params[SI_PARAM_SHADER_BUFFERS] = const_array(ctx->v4i32, SI_NUM_SHADER_BUFFERS); switch (ctx->type) { case PIPE_SHADER_VERTEX: params[SI_PARAM_VERTEX_BUFFERS] = const_array(ctx->v16i8, SI_NUM_VERTEX_BUFFERS); params[SI_PARAM_BASE_VERTEX] = ctx->i32; params[SI_PARAM_START_INSTANCE] = ctx->i32; params[SI_PARAM_DRAWID] = ctx->i32; num_params = SI_PARAM_DRAWID+1; - if (shader->key.vs.as_es) { + if (shader->key.as_es) { params[ctx->param_es2gs_offset = num_params++] = ctx->i32; - } else if (shader->key.vs.as_ls) { + } else if (shader->key.as_ls) { params[SI_PARAM_LS_OUT_LAYOUT] = ctx->i32; num_params = SI_PARAM_LS_OUT_LAYOUT+1; } else { if (shader->is_gs_copy_shader) { num_params = SI_PARAM_RW_BUFFERS+1; } else { params[SI_PARAM_VS_STATE_BITS] = ctx->i32; num_params = SI_PARAM_VS_STATE_BITS+1; } @@ -5376,21 +5376,21 @@ static void create_function(struct si_shader_context *ctx) if (!shader->is_gs_copy_shader) { /* Vertex load indices. */ ctx->param_vertex_index0 = num_params; for (i = 0; i < shader->selector->info.num_inputs; i++) params[num_params++] = ctx->i32; num_prolog_vgprs += shader->selector->info.num_inputs; /* PrimitiveID output. */ - if (!shader->key.vs.as_es && !shader->key.vs.as_ls) + if (!shader->key.as_es && !shader->key.as_ls) for (i = 0; i <= VS_EPILOG_PRIMID_LOC; i++) returns[num_returns++] = ctx->f32; } break; case PIPE_SHADER_TESS_CTRL: params[SI_PARAM_TCS_OFFCHIP_LAYOUT] = ctx->i32; params[SI_PARAM_TCS_OUT_OFFSETS] = ctx->i32; params[SI_PARAM_TCS_OUT_LAYOUT] = ctx->i32; params[SI_PARAM_TCS_IN_LAYOUT] = ctx->i32; @@ -5410,40 +5410,40 @@ static void create_function(struct si_shader_context *ctx) returns[num_returns++] = ctx->i32; /* SGPRs */ for (i = 0; i < 3; i++) returns[num_returns++] = ctx->f32; /* VGPRs */ break; case PIPE_SHADER_TESS_EVAL: params[SI_PARAM_TCS_OFFCHIP_LAYOUT] = ctx->i32; num_params = SI_PARAM_TCS_OFFCHIP_LAYOUT+1; - if (shader->key.tes.as_es) { + if (shader->key.as_es) { params[ctx->param_oc_lds = num_params++] = ctx->i32; params[ctx->param_tess_offchip = num_params++] = ctx->i32; params[ctx->param_es2gs_offset = num_params++] = ctx->i32; } else { params[ctx->param_tess_offchip = num_params++] = ctx->i32; declare_streamout_params(ctx, &shader->selector->so, params, ctx->i32, &num_params); params[ctx->param_oc_lds = num_params++] = ctx->i32; } last_sgpr = num_params - 1; /* VGPRs */ params[ctx->param_tes_u = num_params++] = ctx->f32; params[ctx->param_tes_v = num_params++] = ctx->f32; params[ctx->param_tes_rel_patch_id = num_params++] = ctx->i32; params[ctx->param_tes_patch_id = num_params++] = ctx->i32; /* PrimitiveID output. */ - if (!shader->key.tes.as_es) + if (!shader->key.as_es) for (i = 0; i <= VS_EPILOG_PRIMID_LOC; i++) returns[num_returns++] = ctx->f32; break; case PIPE_SHADER_GEOMETRY: params[SI_PARAM_GS2VS_OFFSET] = ctx->i32; params[SI_PARAM_GS_WAVE_ID] = ctx->i32; last_sgpr = SI_PARAM_GS_WAVE_ID; /* VGPRs */ @@ -5583,42 +5583,42 @@ static void create_function(struct si_shader_context *ctx) bld_base->info->opcode_count[TGSI_OPCODE_DDX_FINE] > 0 || bld_base->info->opcode_count[TGSI_OPCODE_DDY_FINE] > 0 || bld_base->info->opcode_count[TGSI_OPCODE_INTERP_OFFSET] > 0 || bld_base->info->opcode_count[TGSI_OPCODE_INTERP_SAMPLE] > 0)) ctx->lds = LLVMAddGlobalInAddressSpace(gallivm->module, LLVMArrayType(ctx->i32, 64), "ddxy_lds", LOCAL_ADDR_SPACE); - if ((ctx->type == PIPE_SHADER_VERTEX && shader->key.vs.as_ls) || + if ((ctx->type == PIPE_SHADER_VERTEX && shader->key.as_ls) || ctx->type == PIPE_SHADER_TESS_CTRL || ctx->type == PIPE_SHADER_TESS_EVAL) declare_tess_lds(ctx); } /** * Load ESGS and GSVS ring buffer resource descriptors and save the variables * for later use. */ static void preload_ring_buffers(struct si_shader_context *ctx) { struct gallivm_state *gallivm = ctx->soa.bld_base.base.gallivm; LLVMValueRef buf_ptr = LLVMGetParam(ctx->main_fn, SI_PARAM_RW_BUFFERS); if ((ctx->type == PIPE_SHADER_VERTEX && - ctx->shader->key.vs.as_es) || + ctx->shader->key.as_es) || (ctx->type == PIPE_SHADER_TESS_EVAL && - ctx->shader->key.tes.as_es) || + ctx->shader->key.as_es) || ctx->type == PIPE_SHADER_GEOMETRY) { unsigned ring = ctx->type == PIPE_SHADER_GEOMETRY ? SI_GS_RING_ESGS : SI_ES_RING_ESGS; LLVMValueRef offset = lp_build_const_int32(gallivm, ring); ctx->esgs_ring = build_indexed_load_const(ctx, buf_ptr, offset); } @@ -5969,30 +5969,30 @@ static void si_shader_dump_stats(struct si_screen *sscreen, conf->lds_size, conf->scratch_bytes_per_wave, max_simd_waves, conf->spilled_sgprs, conf->spilled_vgprs); } static const char *si_get_shader_name(struct si_shader *shader, unsigned processor) { switch (processor) { case PIPE_SHADER_VERTEX: - if (shader->key.vs.as_es) + if (shader->key.as_es) return "Vertex Shader as ES"; - else if (shader->key.vs.as_ls) + else if (shader->key.as_ls) return "Vertex Shader as LS"; else return "Vertex Shader as VS"; case PIPE_SHADER_TESS_CTRL: return "Tessellation Control Shader"; case PIPE_SHADER_TESS_EVAL: - if (shader->key.tes.as_es) + if (shader->key.as_es) return "Tessellation Evaluation Shader as ES"; else return "Tessellation Evaluation Shader as VS"; case PIPE_SHADER_GEOMETRY: if (shader->is_gs_copy_shader) return "GS Copy Shader as VS"; else return "Geometry Shader"; case PIPE_SHADER_FRAGMENT: return "Pixel Shader"; @@ -6214,69 +6214,69 @@ si_generate_gs_copy_shader(struct si_screen *sscreen, FREE(outputs); if (r != 0) { FREE(shader); shader = NULL; } return shader; } -static void si_dump_shader_key(unsigned shader, union si_shader_key *key, +static void si_dump_shader_key(unsigned shader, struct si_shader_key *key, FILE *f) { int i; fprintf(f, "SHADER KEY\n"); switch (shader) { case PIPE_SHADER_VERTEX: - fprintf(f, " instance_divisors = {"); - for (i = 0; i < ARRAY_SIZE(key->vs.prolog.instance_divisors); i++) + fprintf(f, " part.vs.prolog.instance_divisors = {"); + for (i = 0; i < ARRAY_SIZE(key->part.vs.prolog.instance_divisors); i++) fprintf(f, !i ? "%u" : ", %u", - key->vs.prolog.instance_divisors[i]); + key->part.vs.prolog.instance_divisors[i]); fprintf(f, "}\n"); - fprintf(f, " as_es = %u\n", key->vs.as_es); - fprintf(f, " as_ls = %u\n", key->vs.as_ls); - fprintf(f, " export_prim_id = %u\n", key->vs.epilog.export_prim_id); + fprintf(f, " part.vs.epilog.export_prim_id = %u\n", key->part.vs.epilog.export_prim_id); + fprintf(f, " as_es = %u\n", key->as_es); + fprintf(f, " as_ls = %u\n", key->as_ls); break; case PIPE_SHADER_TESS_CTRL: - fprintf(f, " prim_mode = %u\n", key->tcs.epilog.prim_mode); + fprintf(f, " part.tcs.epilog.prim_mode = %u\n", key->part.tcs.epilog.prim_mode); break; case PIPE_SHADER_TESS_EVAL: - fprintf(f, " as_es = %u\n", key->tes.as_es); - fprintf(f, " export_prim_id = %u\n", key->tes.epilog.export_prim_id); + fprintf(f, " part.tes.epilog.export_prim_id = %u\n", key->part.tes.epilog.export_prim_id); + fprintf(f, " as_es = %u\n", key->as_es); break; case PIPE_SHADER_GEOMETRY: case PIPE_SHADER_COMPUTE: break; case PIPE_SHADER_FRAGMENT: - fprintf(f, " prolog.color_two_side = %u\n", key->ps.prolog.color_two_side); - fprintf(f, " prolog.flatshade_colors = %u\n", key->ps.prolog.flatshade_colors); - fprintf(f, " prolog.poly_stipple = %u\n", key->ps.prolog.poly_stipple); - fprintf(f, " prolog.force_persp_sample_interp = %u\n", key->ps.prolog.force_persp_sample_interp); - fprintf(f, " prolog.force_linear_sample_interp = %u\n", key->ps.prolog.force_linear_sample_interp); - fprintf(f, " prolog.force_persp_center_interp = %u\n", key->ps.prolog.force_persp_center_interp); - fprintf(f, " prolog.force_linear_center_interp = %u\n", key->ps.prolog.force_linear_center_interp); - fprintf(f, " prolog.bc_optimize_for_persp = %u\n", key->ps.prolog.bc_optimize_for_persp); - fprintf(f, " prolog.bc_optimize_for_linear = %u\n", key->ps.prolog.bc_optimize_for_linear); - fprintf(f, " epilog.spi_shader_col_format = 0x%x\n", key->ps.epilog.spi_shader_col_format); - fprintf(f, " epilog.color_is_int8 = 0x%X\n", key->ps.epilog.color_is_int8); - fprintf(f, " epilog.last_cbuf = %u\n", key->ps.epilog.last_cbuf); - fprintf(f, " epilog.alpha_func = %u\n", key->ps.epilog.alpha_func); - fprintf(f, " epilog.alpha_to_one = %u\n", key->ps.epilog.alpha_to_one); - fprintf(f, " epilog.poly_line_smoothing = %u\n", key->ps.epilog.poly_line_smoothing); - fprintf(f, " epilog.clamp_color = %u\n", key->ps.epilog.clamp_color); + fprintf(f, " part.ps.prolog.color_two_side = %u\n", key->part.ps.prolog.color_two_side); + fprintf(f, " part.ps.prolog.flatshade_colors = %u\n", key->part.ps.prolog.flatshade_colors); + fprintf(f, " part.ps.prolog.poly_stipple = %u\n", key->part.ps.prolog.poly_stipple); + fprintf(f, " part.ps.prolog.force_persp_sample_interp = %u\n", key->part.ps.prolog.force_persp_sample_interp); + fprintf(f, " part.ps.prolog.force_linear_sample_interp = %u\n", key->part.ps.prolog.force_linear_sample_interp); + fprintf(f, " part.ps.prolog.force_persp_center_interp = %u\n", key->part.ps.prolog.force_persp_center_interp); + fprintf(f, " part.ps.prolog.force_linear_center_interp = %u\n", key->part.ps.prolog.force_linear_center_interp); + fprintf(f, " part.ps.prolog.bc_optimize_for_persp = %u\n", key->part.ps.prolog.bc_optimize_for_persp); + fprintf(f, " part.ps.prolog.bc_optimize_for_linear = %u\n", key->part.ps.prolog.bc_optimize_for_linear); + fprintf(f, " part.ps.epilog.spi_shader_col_format = 0x%x\n", key->part.ps.epilog.spi_shader_col_format); + fprintf(f, " part.ps.epilog.color_is_int8 = 0x%X\n", key->part.ps.epilog.color_is_int8); + fprintf(f, " part.ps.epilog.last_cbuf = %u\n", key->part.ps.epilog.last_cbuf); + fprintf(f, " part.ps.epilog.alpha_func = %u\n", key->part.ps.epilog.alpha_func); + fprintf(f, " part.ps.epilog.alpha_to_one = %u\n", key->part.ps.epilog.alpha_to_one); + fprintf(f, " part.ps.epilog.poly_line_smoothing = %u\n", key->part.ps.epilog.poly_line_smoothing); + fprintf(f, " part.ps.epilog.clamp_color = %u\n", key->part.ps.epilog.clamp_color); break; default: assert(0); } } static void si_init_shader_ctx(struct si_shader_context *ctx, struct si_screen *sscreen, struct si_shader *shader, @@ -6414,23 +6414,21 @@ struct si_vs_exports { static void si_eliminate_const_vs_outputs(struct si_shader_context *ctx) { struct si_shader *shader = ctx->shader; struct tgsi_shader_info *info = &shader->selector->info; LLVMBasicBlockRef bb; struct si_vs_exports exports; bool removed_any = false; exports.num = 0; - if ((ctx->type == PIPE_SHADER_VERTEX && - (shader->key.vs.as_es || shader->key.vs.as_ls)) || - (ctx->type == PIPE_SHADER_TESS_EVAL && shader->key.tes.as_es)) + if (shader->key.as_es || shader->key.as_ls) return; /* Process all LLVM instructions. */ bb = LLVMGetFirstBasicBlock(ctx->main_fn); while (bb) { LLVMValueRef inst = LLVMGetFirstInstruction(bb); while (inst) { LLVMValueRef cur = inst; inst = LLVMGetNextInstruction(inst); @@ -6506,36 +6504,36 @@ static void si_eliminate_const_vs_outputs(struct si_shader_context *ctx) static bool si_compile_tgsi_main(struct si_shader_context *ctx, struct si_shader *shader) { struct si_shader_selector *sel = shader->selector; struct lp_build_tgsi_context *bld_base = &ctx->soa.bld_base; switch (ctx->type) { case PIPE_SHADER_VERTEX: ctx->load_input = declare_input_vs; - if (shader->key.vs.as_ls) + if (shader->key.as_ls) bld_base->emit_epilogue = si_llvm_emit_ls_epilogue; - else if (shader->key.vs.as_es) + else if (shader->key.as_es) bld_base->emit_epilogue = si_llvm_emit_es_epilogue; else bld_base->emit_epilogue = si_llvm_emit_vs_epilogue; break; case PIPE_SHADER_TESS_CTRL: bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = fetch_input_tcs; bld_base->emit_fetch_funcs[TGSI_FILE_OUTPUT] = fetch_output_tcs; bld_base->emit_store = store_output_tcs; bld_base->emit_epilogue = si_llvm_emit_tcs_epilogue; break; case PIPE_SHADER_TESS_EVAL: bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = fetch_input_tes; - if (shader->key.tes.as_es) + if (shader->key.as_es) bld_base->emit_epilogue = si_llvm_emit_es_epilogue; else bld_base->emit_epilogue = si_llvm_emit_vs_epilogue; break; case PIPE_SHADER_GEOMETRY: bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = fetch_input_gs; bld_base->emit_epilogue = si_llvm_emit_gs_epilogue; break; case PIPE_SHADER_FRAGMENT: ctx->load_input = declare_input_fs; @@ -6574,21 +6572,21 @@ static bool si_compile_tgsi_main(struct si_shader_context *ctx, /** * Compute the VS prolog key, which contains all the information needed to * build the VS prolog function, and set shader->info bits where needed. */ static void si_get_vs_prolog_key(struct si_shader *shader, union si_shader_part_key *key) { struct tgsi_shader_info *info = &shader->selector->info; memset(key, 0, sizeof(*key)); - key->vs_prolog.states = shader->key.vs.prolog; + key->vs_prolog.states = shader->key.part.vs.prolog; key->vs_prolog.num_input_sgprs = shader->info.num_input_sgprs; key->vs_prolog.last_input = MAX2(1, info->num_inputs) - 1; /* Set the instanceID flag. */ for (unsigned i = 0; i < info->num_inputs; i++) if (key->vs_prolog.states.instance_divisors[i]) shader->info.uses_instanceid = true; } /** @@ -6596,87 +6594,87 @@ static void si_get_vs_prolog_key(struct si_shader *shader, * build the VS epilog function, and set the PrimitiveID output offset. */ static void si_get_vs_epilog_key(struct si_shader *shader, struct si_vs_epilog_bits *states, union si_shader_part_key *key) { memset(key, 0, sizeof(*key)); key->vs_epilog.states = *states; /* Set up the PrimitiveID output. */ - if (shader->key.vs.epilog.export_prim_id) { + if (shader->key.part.vs.epilog.export_prim_id) { unsigned index = shader->selector->info.num_outputs; unsigned offset = shader->info.nr_param_exports++; key->vs_epilog.prim_id_param_offset = offset; assert(index < ARRAY_SIZE(shader->info.vs_output_param_offset)); shader->info.vs_output_param_offset[index] = offset; } } /** * Compute the PS prolog key, which contains all the information needed to * build the PS prolog function, and set related bits in shader->config. */ static void si_get_ps_prolog_key(struct si_shader *shader, union si_shader_part_key *key, bool separate_prolog) { struct tgsi_shader_info *info = &shader->selector->info; memset(key, 0, sizeof(*key)); - key->ps_prolog.states = shader->key.ps.prolog; + key->ps_prolog.states = shader->key.part.ps.prolog; key->ps_prolog.colors_read = info->colors_read; key->ps_prolog.num_input_sgprs = shader->info.num_input_sgprs; key->ps_prolog.num_input_vgprs = shader->info.num_input_vgprs; key->ps_prolog.wqm = info->uses_derivatives && (key->ps_prolog.colors_read || key->ps_prolog.states.force_persp_sample_interp || key->ps_prolog.states.force_linear_sample_interp || key->ps_prolog.states.force_persp_center_interp || key->ps_prolog.states.force_linear_center_interp || key->ps_prolog.states.bc_optimize_for_persp || key->ps_prolog.states.bc_optimize_for_linear); if (info->colors_read) { unsigned *color = shader->selector->color_attr_index; - if (shader->key.ps.prolog.color_two_side) { + if (shader->key.part.ps.prolog.color_two_side) { /* BCOLORs are stored after the last input. */ key->ps_prolog.num_interp_inputs = info->num_inputs; key->ps_prolog.face_vgpr_index = shader->info.face_vgpr_index; shader->config.spi_ps_input_ena |= S_0286CC_FRONT_FACE_ENA(1); } for (unsigned i = 0; i < 2; i++) { unsigned interp = info->input_interpolate[color[i]]; unsigned location = info->input_interpolate_loc[color[i]]; if (!(info->colors_read & (0xf << i*4))) continue; key->ps_prolog.color_attr_index[i] = color[i]; - if (shader->key.ps.prolog.flatshade_colors && + if (shader->key.part.ps.prolog.flatshade_colors && interp == TGSI_INTERPOLATE_COLOR) interp = TGSI_INTERPOLATE_CONSTANT; switch (interp) { case TGSI_INTERPOLATE_CONSTANT: key->ps_prolog.color_interp_vgpr_index[i] = -1; break; case TGSI_INTERPOLATE_PERSPECTIVE: case TGSI_INTERPOLATE_COLOR: /* Force the interpolation location for colors here. */ - if (shader->key.ps.prolog.force_persp_sample_interp) + if (shader->key.part.ps.prolog.force_persp_sample_interp) location = TGSI_INTERPOLATE_LOC_SAMPLE; - if (shader->key.ps.prolog.force_persp_center_interp) + if (shader->key.part.ps.prolog.force_persp_center_interp) location = TGSI_INTERPOLATE_LOC_CENTER; switch (location) { case TGSI_INTERPOLATE_LOC_SAMPLE: key->ps_prolog.color_interp_vgpr_index[i] = 0; shader->config.spi_ps_input_ena |= S_0286CC_PERSP_SAMPLE_ENA(1); break; case TGSI_INTERPOLATE_LOC_CENTER: key->ps_prolog.color_interp_vgpr_index[i] = 2; @@ -6687,23 +6685,23 @@ static void si_get_ps_prolog_key(struct si_shader *shader, key->ps_prolog.color_interp_vgpr_index[i] = 4; shader->config.spi_ps_input_ena |= S_0286CC_PERSP_CENTROID_ENA(1); break; default: assert(0); } break; case TGSI_INTERPOLATE_LINEAR: /* Force the interpolation location for colors here. */ - if (shader->key.ps.prolog.force_linear_sample_interp) + if (shader->key.part.ps.prolog.force_linear_sample_interp) location = TGSI_INTERPOLATE_LOC_SAMPLE; - if (shader->key.ps.prolog.force_linear_center_interp) + if (shader->key.part.ps.prolog.force_linear_center_interp) location = TGSI_INTERPOLATE_LOC_CENTER; /* The VGPR assignment for non-monolithic shaders * works because InitialPSInputAddr is set on the * main shader and PERSP_PULL_MODEL is never used. */ switch (location) { case TGSI_INTERPOLATE_LOC_SAMPLE: key->ps_prolog.color_interp_vgpr_index[i] = separate_prolog ? 6 : 9; @@ -6754,21 +6752,21 @@ static bool si_need_ps_prolog(const union si_shader_part_key *key) */ static void si_get_ps_epilog_key(struct si_shader *shader, union si_shader_part_key *key) { struct tgsi_shader_info *info = &shader->selector->info; memset(key, 0, sizeof(*key)); key->ps_epilog.colors_written = info->colors_written; key->ps_epilog.writes_z = info->writes_z; key->ps_epilog.writes_stencil = info->writes_stencil; key->ps_epilog.writes_samplemask = info->writes_samplemask; - key->ps_epilog.states = shader->key.ps.epilog; + key->ps_epilog.states = shader->key.part.ps.epilog; } /** * Build the GS prolog function. Rotate the input vertices for triangle strips * with adjacency. */ static void si_build_gs_prolog_function(struct si_shader_context *ctx, union si_shader_part_key *key) { const unsigned num_sgprs = SI_GS_NUM_USER_SGPR + 2; @@ -7064,72 +7062,72 @@ int si_compile_tgsi_shader(struct si_screen *sscreen, si_llvm_dispose(&ctx); return -1; } if (is_monolithic && ctx.type == PIPE_SHADER_VERTEX) { LLVMValueRef parts[3]; bool need_prolog; bool need_epilog; need_prolog = sel->info.num_inputs; - need_epilog = !shader->key.vs.as_es && !shader->key.vs.as_ls; + need_epilog = !shader->key.as_es && !shader->key.as_ls; parts[need_prolog ? 1 : 0] = ctx.main_fn; if (need_prolog) { union si_shader_part_key prolog_key; si_get_vs_prolog_key(shader, &prolog_key); si_build_vs_prolog_function(&ctx, &prolog_key); parts[0] = ctx.main_fn; } if (need_epilog) { union si_shader_part_key epilog_key; - si_get_vs_epilog_key(shader, &shader->key.vs.epilog, &epilog_key); + si_get_vs_epilog_key(shader, &shader->key.part.vs.epilog, &epilog_key); si_build_vs_epilog_function(&ctx, &epilog_key); parts[need_prolog ? 2 : 1] = ctx.main_fn; } si_build_wrapper_function(&ctx, parts, 1 + need_prolog + need_epilog, need_prolog ? 1 : 0); } else if (is_monolithic && ctx.type == PIPE_SHADER_TESS_CTRL) { LLVMValueRef parts[2]; union si_shader_part_key epilog_key; parts[0] = ctx.main_fn; memset(&epilog_key, 0, sizeof(epilog_key)); - epilog_key.tcs_epilog.states = shader->key.tcs.epilog; + epilog_key.tcs_epilog.states = shader->key.part.tcs.epilog; si_build_tcs_epilog_function(&ctx, &epilog_key); parts[1] = ctx.main_fn; si_build_wrapper_function(&ctx, parts, 2, 0); } else if (is_monolithic && ctx.type == PIPE_SHADER_TESS_EVAL && - !shader->key.tes.as_es) { + !shader->key.as_es) { LLVMValueRef parts[2]; union si_shader_part_key epilog_key; parts[0] = ctx.main_fn; - si_get_vs_epilog_key(shader, &shader->key.tes.epilog, &epilog_key); + si_get_vs_epilog_key(shader, &shader->key.part.tes.epilog, &epilog_key); si_build_vs_epilog_function(&ctx, &epilog_key); parts[1] = ctx.main_fn; si_build_wrapper_function(&ctx, parts, 2, 0); } else if (is_monolithic && ctx.type == PIPE_SHADER_GEOMETRY) { LLVMValueRef parts[2]; union si_shader_part_key prolog_key; parts[1] = ctx.main_fn; memset(&prolog_key, 0, sizeof(prolog_key)); - prolog_key.gs_prolog.states = shader->key.gs.prolog; + prolog_key.gs_prolog.states = shader->key.part.gs.prolog; si_build_gs_prolog_function(&ctx, &prolog_key); parts[0] = ctx.main_fn; si_build_wrapper_function(&ctx, parts, 2, 1); } else if (is_monolithic && ctx.type == PIPE_SHADER_FRAGMENT) { LLVMValueRef parts[3]; union si_shader_part_key prolog_key; union si_shader_part_key epilog_key; bool need_prolog; @@ -7306,30 +7304,30 @@ si_get_shader_part(struct si_screen *sscreen, struct gallivm_state *gallivm = &ctx.gallivm; si_init_shader_ctx(&ctx, sscreen, &shader, tm); ctx.type = type; switch (type) { case PIPE_SHADER_VERTEX: break; case PIPE_SHADER_TESS_CTRL: assert(!prolog); - shader.key.tcs.epilog = key->tcs_epilog.states; + shader.key.part.tcs.epilog = key->tcs_epilog.states; break; case PIPE_SHADER_GEOMETRY: assert(prolog); break; case PIPE_SHADER_FRAGMENT: if (prolog) - shader.key.ps.prolog = key->ps_prolog.states; + shader.key.part.ps.prolog = key->ps_prolog.states; else - shader.key.ps.epilog = key->ps_epilog.states; + shader.key.part.ps.epilog = key->ps_epilog.states; break; default: unreachable("bad shader part"); } build(&ctx, key); /* Compile. */ si_llvm_finalize_module(&ctx, r600_extra_shader_checks(&sscreen->b, PIPE_SHADER_FRAGMENT)); @@ -7543,42 +7541,42 @@ static bool si_shader_select_vs_parts(struct si_screen *sscreen, si_get_shader_part(sscreen, &sscreen->vs_prologs, PIPE_SHADER_VERTEX, true, &prolog_key, tm, debug, si_build_vs_prolog_function, "Vertex Shader Prolog"); if (!shader->prolog) return false; } /* Get the epilog. */ - if (!shader->key.vs.as_es && !shader->key.vs.as_ls && + if (!shader->key.as_es && !shader->key.as_ls && !si_get_vs_epilog(sscreen, tm, shader, debug, - &shader->key.vs.epilog)) + &shader->key.part.vs.epilog)) return false; return true; } /** * Select and compile (or reuse) TES parts (epilog). */ static bool si_shader_select_tes_parts(struct si_screen *sscreen, LLVMTargetMachineRef tm, struct si_shader *shader, struct pipe_debug_callback *debug) { - if (shader->key.tes.as_es) + if (shader->key.as_es) return true; /* TES compiled as VS. */ return si_get_vs_epilog(sscreen, tm, shader, debug, - &shader->key.tes.epilog); + &shader->key.part.tes.epilog); } /** * Compile the TCS epilog function. This writes tesselation factors to memory * based on the output primitive type of the tesselator (determined by TES). */ static void si_build_tcs_epilog_function(struct si_shader_context *ctx, union si_shader_part_key *key) { struct gallivm_state *gallivm = &ctx->gallivm; @@ -7624,45 +7622,45 @@ static void si_build_tcs_epilog_function(struct si_shader_context *ctx, */ static bool si_shader_select_tcs_parts(struct si_screen *sscreen, LLVMTargetMachineRef tm, struct si_shader *shader, struct pipe_debug_callback *debug) { union si_shader_part_key epilog_key; /* Get the epilog. */ memset(&epilog_key, 0, sizeof(epilog_key)); - epilog_key.tcs_epilog.states = shader->key.tcs.epilog; + epilog_key.tcs_epilog.states = shader->key.part.tcs.epilog; shader->epilog = si_get_shader_part(sscreen, &sscreen->tcs_epilogs, PIPE_SHADER_TESS_CTRL, false, &epilog_key, tm, debug, si_build_tcs_epilog_function, "Tessellation Control Shader Epilog"); return shader->epilog != NULL; } /** * Select and compile (or reuse) GS parts (prolog). */ static bool si_shader_select_gs_parts(struct si_screen *sscreen, LLVMTargetMachineRef tm, struct si_shader *shader, struct pipe_debug_callback *debug) { union si_shader_part_key prolog_key; - if (!shader->key.gs.prolog.tri_strip_adj_fix) + if (!shader->key.part.gs.prolog.tri_strip_adj_fix) return true; memset(&prolog_key, 0, sizeof(prolog_key)); - prolog_key.gs_prolog.states = shader->key.gs.prolog; + prolog_key.gs_prolog.states = shader->key.part.gs.prolog; shader->prolog = si_get_shader_part(sscreen, &sscreen->gs_prologs, PIPE_SHADER_GEOMETRY, true, &prolog_key, tm, debug, si_build_gs_prolog_function, "Geometry Shader Prolog"); return shader->prolog != NULL; } /** @@ -8044,48 +8042,48 @@ static bool si_shader_select_ps_parts(struct si_screen *sscreen, shader->epilog = si_get_shader_part(sscreen, &sscreen->ps_epilogs, PIPE_SHADER_FRAGMENT, false, &epilog_key, tm, debug, si_build_ps_epilog_function, "Fragment Shader Epilog"); if (!shader->epilog) return false; /* Enable POS_FIXED_PT if polygon stippling is enabled. */ - if (shader->key.ps.prolog.poly_stipple) { + if (shader->key.part.ps.prolog.poly_stipple) { shader->config.spi_ps_input_ena |= S_0286CC_POS_FIXED_PT_ENA(1); assert(G_0286CC_POS_FIXED_PT_ENA(shader->config.spi_ps_input_addr)); } /* Set up the enable bits for per-sample shading if needed. */ - if (shader->key.ps.prolog.force_persp_sample_interp && + if (shader->key.part.ps.prolog.force_persp_sample_interp && (G_0286CC_PERSP_CENTER_ENA(shader->config.spi_ps_input_ena) || G_0286CC_PERSP_CENTROID_ENA(shader->config.spi_ps_input_ena))) { shader->config.spi_ps_input_ena &= C_0286CC_PERSP_CENTER_ENA; shader->config.spi_ps_input_ena &= C_0286CC_PERSP_CENTROID_ENA; shader->config.spi_ps_input_ena |= S_0286CC_PERSP_SAMPLE_ENA(1); } - if (shader->key.ps.prolog.force_linear_sample_interp && + if (shader->key.part.ps.prolog.force_linear_sample_interp && (G_0286CC_LINEAR_CENTER_ENA(shader->config.spi_ps_input_ena) || G_0286CC_LINEAR_CENTROID_ENA(shader->config.spi_ps_input_ena))) { shader->config.spi_ps_input_ena &= C_0286CC_LINEAR_CENTER_ENA; shader->config.spi_ps_input_ena &= C_0286CC_LINEAR_CENTROID_ENA; shader->config.spi_ps_input_ena |= S_0286CC_LINEAR_SAMPLE_ENA(1); } - if (shader->key.ps.prolog.force_persp_center_interp && + if (shader->key.part.ps.prolog.force_persp_center_interp && (G_0286CC_PERSP_SAMPLE_ENA(shader->config.spi_ps_input_ena) || G_0286CC_PERSP_CENTROID_ENA(shader->config.spi_ps_input_ena))) { shader->config.spi_ps_input_ena &= C_0286CC_PERSP_SAMPLE_ENA; shader->config.spi_ps_input_ena &= C_0286CC_PERSP_CENTROID_ENA; shader->config.spi_ps_input_ena |= S_0286CC_PERSP_CENTER_ENA(1); } - if (shader->key.ps.prolog.force_linear_center_interp && + if (shader->key.part.ps.prolog.force_linear_center_interp && (G_0286CC_LINEAR_SAMPLE_ENA(shader->config.spi_ps_input_ena) || G_0286CC_LINEAR_CENTROID_ENA(shader->config.spi_ps_input_ena))) { shader->config.spi_ps_input_ena &= C_0286CC_LINEAR_SAMPLE_ENA; shader->config.spi_ps_input_ena &= C_0286CC_LINEAR_CENTROID_ENA; shader->config.spi_ps_input_ena |= S_0286CC_LINEAR_CENTER_ENA(1); } /* POW_W_FLOAT requires that one of the perspective weights is enabled. */ if (G_0286CC_POS_W_FLOAT_ENA(shader->config.spi_ps_input_ena) && !(shader->config.spi_ps_input_ena & 0xf)) { @@ -8095,21 +8093,21 @@ static bool si_shader_select_ps_parts(struct si_screen *sscreen, /* At least one pair of interpolation weights must be enabled. */ if (!(shader->config.spi_ps_input_ena & 0x7f)) { shader->config.spi_ps_input_ena |= S_0286CC_LINEAR_CENTER_ENA(1); assert(G_0286CC_LINEAR_CENTER_ENA(shader->config.spi_ps_input_addr)); } /* The sample mask input is always enabled, because the API shader always * passes it through to the epilog. Disable it here if it's unused. */ - if (!shader->key.ps.epilog.poly_line_smoothing && + if (!shader->key.part.ps.epilog.poly_line_smoothing && !shader->selector->info.reads_samplemask) shader->config.spi_ps_input_ena &= C_0286CC_SAMPLE_COVERAGE_ENA; return true; } static void si_fix_num_sgprs(struct si_shader *shader) { unsigned min_sgprs = shader->info.num_input_sgprs + 2; /* VCC */ @@ -8124,28 +8122,26 @@ int si_shader_create(struct si_screen *sscreen, LLVMTargetMachineRef tm, struct si_shader *mainp = sel->main_shader_part; int r; /* LS, ES, VS are compiled on demand if the main part hasn't been * compiled for that stage. * * Vertex shaders are compiled on demand when a vertex fetch * workaround must be applied. */ if (!mainp || + shader->key.as_es != mainp->key.as_es || + shader->key.as_ls != mainp->key.as_ls || (sel->type == PIPE_SHADER_VERTEX && - (shader->key.vs.as_es != mainp->key.vs.as_es || - shader->key.vs.as_ls != mainp->key.vs.as_ls || - shader->key.vs.fix_fetch)) || - (sel->type == PIPE_SHADER_TESS_EVAL && - shader->key.tes.as_es != mainp->key.tes.as_es) || + shader->key.mono.vs.fix_fetch) || (sel->type == PIPE_SHADER_TESS_CTRL && - shader->key.tcs.epilog.inputs_to_copy) || + shader->key.mono.tcs.inputs_to_copy) || sel->type == PIPE_SHADER_COMPUTE) { /* Monolithic shader (compiled as a whole, has many variants, * may take a long time to compile). */ r = si_compile_tgsi_shader(sscreen, tm, shader, true, debug); if (r) return r; } else { /* The shader consists of 2-3 parts: * diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index 59e7bfb..bed22c1 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -323,21 +323,20 @@ struct si_vs_epilog_bits { * - skip clipdist, culldist (including clipvertex code) exports based * on which clip_plane_enable bits are set * - skip layer, viewport, clipdist, and culldist parameter exports * if PS doesn't read them */ }; /* Common TCS bits between the shader key and the epilog key. */ struct si_tcs_epilog_bits { unsigned prim_mode:3; - uint64_t inputs_to_copy; }; struct si_gs_prolog_bits { unsigned tri_strip_adj_fix:1; }; /* Common PS bits between the shader key and the prolog key. */ struct si_ps_prolog_bits { unsigned color_two_side:1; unsigned flatshade_colors:1; @@ -391,44 +390,58 @@ union si_shader_part_key { } ps_prolog; struct { struct si_ps_epilog_bits states; unsigned colors_written:8; unsigned writes_z:1; unsigned writes_stencil:1; unsigned writes_samplemask:1; } ps_epilog; }; -union si_shader_key { - struct { - struct si_ps_prolog_bits prolog; - struct si_ps_epilog_bits epilog; - } ps; - struct { - struct si_vs_prolog_bits prolog; - struct si_vs_epilog_bits epilog; - unsigned as_es:1; /* export shader */ - unsigned as_ls:1; /* local shader */ - - /* One pair of bits for every input: SI_FIX_FETCH_* enums. */ - uint32_t fix_fetch; - } vs; - struct { - struct si_tcs_epilog_bits epilog; - } tcs; /* tessellation control shader */ - struct { - struct si_vs_epilog_bits epilog; /* same as VS */ - unsigned as_es:1; /* export shader */ - } tes; /* tessellation evaluation shader */ - struct { - struct si_gs_prolog_bits prolog; - } gs; +struct si_shader_key { + /* Prolog and epilog flags. */ + union { + struct { + struct si_ps_prolog_bits prolog; + struct si_ps_epilog_bits epilog; + } ps; + struct { + struct si_vs_prolog_bits prolog; + struct si_vs_epilog_bits epilog; + } vs; + struct { + struct si_tcs_epilog_bits epilog; + } tcs; /* tessellation control shader */ + struct { + struct si_vs_epilog_bits epilog; /* same as VS */ + } tes; /* tessellation evaluation shader */ + struct { + struct si_gs_prolog_bits prolog; + } gs; + } part; + + /* These two are initially set according to the NEXT_SHADER property, + * or guessed if the property doesn't seem correct. + */ + unsigned as_es:1; /* export shader */ + unsigned as_ls:1; /* local shader */ + + /* Flags for monolithic compilation only. */ + union { + struct { + /* One pair of bits for every input: SI_FIX_FETCH_* enums. */ + uint32_t fix_fetch; + } vs; + struct { + uint64_t inputs_to_copy; /* for fixed-func TCS */ + } tcs; + } mono; }; struct si_shader_config { unsigned num_sgprs; unsigned num_vgprs; unsigned spilled_sgprs; unsigned spilled_vgprs; unsigned lds_size; unsigned spi_ps_input_ena; unsigned spi_ps_input_addr; @@ -463,21 +476,21 @@ struct si_shader_info { struct si_shader { struct si_shader_selector *selector; struct si_shader *next_variant; struct si_shader_part *prolog; struct si_shader_part *epilog; struct si_pm4_state *pm4; struct r600_resource *bo; struct r600_resource *scratch_bo; - union si_shader_key key; + struct si_shader_key key; bool is_binary_shared; bool is_gs_copy_shader; /* The following data is all that's needed for binary shaders. */ struct radeon_shader_binary binary; struct si_shader_config config; struct si_shader_info info; /* Shader key + LLVM IR + disassembly + statistics. * Generated for debug contexts only. diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 7e051a1..7d118b0 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -112,21 +112,21 @@ static void si_emit_cb_render_state(struct si_context *sctx, struct r600_atom *a sctx->ps_shader.cso && (sctx->ps_shader.cso->info.colors_written & 0x3) != 0x3) cb_target_mask = 0; radeon_set_context_reg(cs, R_028238_CB_TARGET_MASK, cb_target_mask); /* STONEY-specific register settings. */ if (sctx->b.family == CHIP_STONEY) { unsigned spi_shader_col_format = sctx->ps_shader.cso ? - sctx->ps_shader.current->key.ps.epilog.spi_shader_col_format : 0; + sctx->ps_shader.current->key.part.ps.epilog.spi_shader_col_format : 0; unsigned sx_ps_downconvert = 0; unsigned sx_blend_opt_epsilon = 0; unsigned sx_blend_opt_control = 0; for (i = 0; i < sctx->framebuffer.state.nr_cbufs; i++) { struct r600_surface *surf = (struct r600_surface*)sctx->framebuffer.state.cbufs[i]; unsigned format, swap, spi_format, colormask; bool has_alpha, has_rgb; diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index d0869e3..3323d3c 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -619,29 +619,29 @@ static void si_shader_vs(struct si_screen *sscreen, struct si_shader *shader, if (shader->selector->type == PIPE_SHADER_TESS_EVAL) si_set_tesseval_regs(sscreen, shader, pm4); } static unsigned si_get_ps_num_interp(struct si_shader *ps) { struct tgsi_shader_info *info = &ps->selector->info; unsigned num_colors = !!(info->colors_read & 0x0f) + !!(info->colors_read & 0xf0); unsigned num_interp = ps->selector->info.num_inputs + - (ps->key.ps.prolog.color_two_side ? num_colors : 0); + (ps->key.part.ps.prolog.color_two_side ? num_colors : 0); assert(num_interp <= 32); return MIN2(num_interp, 32); } static unsigned si_get_spi_shader_col_format(struct si_shader *shader) { - unsigned value = shader->key.ps.epilog.spi_shader_col_format; + unsigned value = shader->key.part.ps.epilog.spi_shader_col_format; unsigned i, num_targets = (util_last_bit(value) + 3) / 4; /* If the i-th target format is set, all previous target formats must * be non-zero to avoid hangs. */ for (i = 0; i < num_targets; i++) if (!(value & (0xf << (i * 4)))) value |= V_028714_SPI_SHADER_32_R << (i * 4); return value; @@ -698,44 +698,44 @@ static void si_shader_ps(struct si_shader *shader) G_0286CC_LINEAR_CENTROID_ENA(input_ena) || G_0286CC_LINE_STIPPLE_TEX_ENA(input_ena)); /* POS_W_FLOAT_ENA requires one of the perspective weights. */ assert(!G_0286CC_POS_W_FLOAT_ENA(input_ena) || G_0286CC_PERSP_SAMPLE_ENA(input_ena) || G_0286CC_PERSP_CENTER_ENA(input_ena) || G_0286CC_PERSP_CENTROID_ENA(input_ena) || G_0286CC_PERSP_PULL_MODEL_ENA(input_ena)); /* Validate interpolation optimization flags (read as implications). */ - assert(!shader->key.ps.prolog.bc_optimize_for_persp || + assert(!shader->key.part.ps.prolog.bc_optimize_for_persp || (G_0286CC_PERSP_CENTER_ENA(input_ena) && G_0286CC_PERSP_CENTROID_ENA(input_ena))); - assert(!shader->key.ps.prolog.bc_optimize_for_linear || + assert(!shader->key.part.ps.prolog.bc_optimize_for_linear || (G_0286CC_LINEAR_CENTER_ENA(input_ena) && G_0286CC_LINEAR_CENTROID_ENA(input_ena))); - assert(!shader->key.ps.prolog.force_persp_center_interp || + assert(!shader->key.part.ps.prolog.force_persp_center_interp || (!G_0286CC_PERSP_SAMPLE_ENA(input_ena) && !G_0286CC_PERSP_CENTROID_ENA(input_ena))); - assert(!shader->key.ps.prolog.force_linear_center_interp || + assert(!shader->key.part.ps.prolog.force_linear_center_interp || (!G_0286CC_LINEAR_SAMPLE_ENA(input_ena) && !G_0286CC_LINEAR_CENTROID_ENA(input_ena))); - assert(!shader->key.ps.prolog.force_persp_sample_interp || + assert(!shader->key.part.ps.prolog.force_persp_sample_interp || (!G_0286CC_PERSP_CENTER_ENA(input_ena) && !G_0286CC_PERSP_CENTROID_ENA(input_ena))); - assert(!shader->key.ps.prolog.force_linear_sample_interp || + assert(!shader->key.part.ps.prolog.force_linear_sample_interp || (!G_0286CC_LINEAR_CENTER_ENA(input_ena) && !G_0286CC_LINEAR_CENTROID_ENA(input_ena))); /* Validate cases when the optimizations are off (read as implications). */ - assert(shader->key.ps.prolog.bc_optimize_for_persp || + assert(shader->key.part.ps.prolog.bc_optimize_for_persp || !G_0286CC_PERSP_CENTER_ENA(input_ena) || !G_0286CC_PERSP_CENTROID_ENA(input_ena)); - assert(shader->key.ps.prolog.bc_optimize_for_linear || + assert(shader->key.part.ps.prolog.bc_optimize_for_linear || !G_0286CC_LINEAR_CENTER_ENA(input_ena) || !G_0286CC_LINEAR_CENTROID_ENA(input_ena)); pm4 = si_get_shader_pm4_state(shader); if (!pm4) return; /* SPI_BARYC_CNTL.POS_FLOAT_LOCATION * Possible vaules: * 0 -> Position = pixel center @@ -811,32 +811,32 @@ static void si_shader_ps(struct si_shader *shader) S_00B02C_EXTRA_LDS_SIZE(shader->config.lds_size) | S_00B02C_USER_SGPR(SI_PS_NUM_USER_SGPR) | S_00B32C_SCRATCH_EN(shader->config.scratch_bytes_per_wave > 0)); } static void si_shader_init_pm4_state(struct si_screen *sscreen, struct si_shader *shader) { switch (shader->selector->type) { case PIPE_SHADER_VERTEX: - if (shader->key.vs.as_ls) + if (shader->key.as_ls) si_shader_ls(shader); - else if (shader->key.vs.as_es) + else if (shader->key.as_es) si_shader_es(sscreen, shader); else si_shader_vs(sscreen, shader, NULL); break; case PIPE_SHADER_TESS_CTRL: si_shader_hs(shader); break; case PIPE_SHADER_TESS_EVAL: - if (shader->key.tes.as_es) + if (shader->key.as_es) si_shader_es(sscreen, shader); else si_shader_vs(sscreen, shader, NULL); break; case PIPE_SHADER_GEOMETRY: si_shader_gs(shader); break; case PIPE_SHADER_FRAGMENT: si_shader_ps(shader); break; @@ -850,182 +850,182 @@ static unsigned si_get_alpha_test_func(struct si_context *sctx) /* Alpha-test should be disabled if colorbuffer 0 is integer. */ if (sctx->queued.named.dsa) return sctx->queued.named.dsa->alpha_func; return PIPE_FUNC_ALWAYS; } /* Compute the key for the hw shader variant */ static inline void si_shader_selector_key(struct pipe_context *ctx, struct si_shader_selector *sel, - union si_shader_key *key) + struct si_shader_key *key) { struct si_context *sctx = (struct si_context *)ctx; unsigned i; memset(key, 0, sizeof(*key)); switch (sel->type) { case PIPE_SHADER_VERTEX: if (sctx->vertex_elements) { unsigned count = MIN2(sel->info.num_inputs, sctx->vertex_elements->count); for (i = 0; i < count; ++i) - key->vs.prolog.instance_divisors[i] = + key->part.vs.prolog.instance_divisors[i] = sctx->vertex_elements->elements[i].instance_divisor; - key->vs.fix_fetch = + key->mono.vs.fix_fetch = sctx->vertex_elements->fix_fetch & u_bit_consecutive(0, 2 * count); } if (sctx->tes_shader.cso) - key->vs.as_ls = 1; + key->as_ls = 1; else if (sctx->gs_shader.cso) - key->vs.as_es = 1; + key->as_es = 1; if (!sctx->gs_shader.cso && sctx->ps_shader.cso && sctx->ps_shader.cso->info.uses_primid) - key->vs.epilog.export_prim_id = 1; + key->part.vs.epilog.export_prim_id = 1; break; case PIPE_SHADER_TESS_CTRL: - key->tcs.epilog.prim_mode = + key->part.tcs.epilog.prim_mode = sctx->tes_shader.cso->info.properties[TGSI_PROPERTY_TES_PRIM_MODE]; if (sel == sctx->fixed_func_tcs_shader.cso) - key->tcs.epilog.inputs_to_copy = sctx->vs_shader.cso->outputs_written; + key->mono.tcs.inputs_to_copy = sctx->vs_shader.cso->outputs_written; break; case PIPE_SHADER_TESS_EVAL: if (sctx->gs_shader.cso) - key->tes.as_es = 1; + key->as_es = 1; else if (sctx->ps_shader.cso && sctx->ps_shader.cso->info.uses_primid) - key->tes.epilog.export_prim_id = 1; + key->part.tes.epilog.export_prim_id = 1; break; case PIPE_SHADER_GEOMETRY: - key->gs.prolog.tri_strip_adj_fix = sctx->gs_tri_strip_adj_fix; + key->part.gs.prolog.tri_strip_adj_fix = sctx->gs_tri_strip_adj_fix; break; case PIPE_SHADER_FRAGMENT: { struct si_state_rasterizer *rs = sctx->queued.named.rasterizer; struct si_state_blend *blend = sctx->queued.named.blend; if (sel->info.properties[TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS] && sel->info.colors_written == 0x1) - key->ps.epilog.last_cbuf = MAX2(sctx->framebuffer.state.nr_cbufs, 1) - 1; + key->part.ps.epilog.last_cbuf = MAX2(sctx->framebuffer.state.nr_cbufs, 1) - 1; if (blend) { /* Select the shader color format based on whether * blending or alpha are needed. */ - key->ps.epilog.spi_shader_col_format = + key->part.ps.epilog.spi_shader_col_format = (blend->blend_enable_4bit & blend->need_src_alpha_4bit & sctx->framebuffer.spi_shader_col_format_blend_alpha) | (blend->blend_enable_4bit & ~blend->need_src_alpha_4bit & sctx->framebuffer.spi_shader_col_format_blend) | (~blend->blend_enable_4bit & blend->need_src_alpha_4bit & sctx->framebuffer.spi_shader_col_format_alpha) | (~blend->blend_enable_4bit & ~blend->need_src_alpha_4bit & sctx->framebuffer.spi_shader_col_format); /* The output for dual source blending should have * the same format as the first output. */ if (blend->dual_src_blend) - key->ps.epilog.spi_shader_col_format |= - (key->ps.epilog.spi_shader_col_format & 0xf) << 4; + key->part.ps.epilog.spi_shader_col_format |= + (key->part.ps.epilog.spi_shader_col_format & 0xf) << 4; } else - key->ps.epilog.spi_shader_col_format = sctx->framebuffer.spi_shader_col_format; + key->part.ps.epilog.spi_shader_col_format = sctx->framebuffer.spi_shader_col_format; /* If alpha-to-coverage is enabled, we have to export alpha * even if there is no color buffer. */ - if (!(key->ps.epilog.spi_shader_col_format & 0xf) && + if (!(key->part.ps.epilog.spi_shader_col_format & 0xf) && blend && blend->alpha_to_coverage) - key->ps.epilog.spi_shader_col_format |= V_028710_SPI_SHADER_32_AR; + key->part.ps.epilog.spi_shader_col_format |= V_028710_SPI_SHADER_32_AR; /* On SI and CIK except Hawaii, the CB doesn't clamp outputs * to the range supported by the type if a channel has less * than 16 bits and the export format is 16_ABGR. */ if (sctx->b.chip_class <= CIK && sctx->b.family != CHIP_HAWAII) - key->ps.epilog.color_is_int8 = sctx->framebuffer.color_is_int8; + key->part.ps.epilog.color_is_int8 = sctx->framebuffer.color_is_int8; /* Disable unwritten outputs (if WRITE_ALL_CBUFS isn't enabled). */ - if (!key->ps.epilog.last_cbuf) { - key->ps.epilog.spi_shader_col_format &= sel->colors_written_4bit; - key->ps.epilog.color_is_int8 &= sel->info.colors_written; + if (!key->part.ps.epilog.last_cbuf) { + key->part.ps.epilog.spi_shader_col_format &= sel->colors_written_4bit; + key->part.ps.epilog.color_is_int8 &= sel->info.colors_written; } if (rs) { bool is_poly = (sctx->current_rast_prim >= PIPE_PRIM_TRIANGLES && sctx->current_rast_prim <= PIPE_PRIM_POLYGON) || sctx->current_rast_prim >= PIPE_PRIM_TRIANGLES_ADJACENCY; bool is_line = !is_poly && sctx->current_rast_prim != PIPE_PRIM_POINTS; - key->ps.prolog.color_two_side = rs->two_side && sel->info.colors_read; - key->ps.prolog.flatshade_colors = rs->flatshade && sel->info.colors_read; + key->part.ps.prolog.color_two_side = rs->two_side && sel->info.colors_read; + key->part.ps.prolog.flatshade_colors = rs->flatshade && sel->info.colors_read; if (sctx->queued.named.blend) { - key->ps.epilog.alpha_to_one = sctx->queued.named.blend->alpha_to_one && + key->part.ps.epilog.alpha_to_one = sctx->queued.named.blend->alpha_to_one && rs->multisample_enable; } - key->ps.prolog.poly_stipple = rs->poly_stipple_enable && is_poly; - key->ps.epilog.poly_line_smoothing = ((is_poly && rs->poly_smooth) || + key->part.ps.prolog.poly_stipple = rs->poly_stipple_enable && is_poly; + key->part.ps.epilog.poly_line_smoothing = ((is_poly && rs->poly_smooth) || (is_line && rs->line_smooth)) && sctx->framebuffer.nr_samples <= 1; - key->ps.epilog.clamp_color = rs->clamp_fragment_color; + key->part.ps.epilog.clamp_color = rs->clamp_fragment_color; if (rs->force_persample_interp && rs->multisample_enable && sctx->framebuffer.nr_samples > 1 && sctx->ps_iter_samples > 1) { - key->ps.prolog.force_persp_sample_interp = + key->part.ps.prolog.force_persp_sample_interp = sel->info.uses_persp_center || sel->info.uses_persp_centroid; - key->ps.prolog.force_linear_sample_interp = + key->part.ps.prolog.force_linear_sample_interp = sel->info.uses_linear_center || sel->info.uses_linear_centroid; } else if (rs->multisample_enable && sctx->framebuffer.nr_samples > 1) { - key->ps.prolog.bc_optimize_for_persp = + key->part.ps.prolog.bc_optimize_for_persp = sel->info.uses_persp_center && sel->info.uses_persp_centroid; - key->ps.prolog.bc_optimize_for_linear = + key->part.ps.prolog.bc_optimize_for_linear = sel->info.uses_linear_center && sel->info.uses_linear_centroid; } else { /* Make sure SPI doesn't compute more than 1 pair * of (i,j), which is the optimization here. */ - key->ps.prolog.force_persp_center_interp = + key->part.ps.prolog.force_persp_center_interp = sel->info.uses_persp_center + sel->info.uses_persp_centroid + sel->info.uses_persp_sample > 1; - key->ps.prolog.force_linear_center_interp = + key->part.ps.prolog.force_linear_center_interp = sel->info.uses_linear_center + sel->info.uses_linear_centroid + sel->info.uses_linear_sample > 1; } } - key->ps.epilog.alpha_func = si_get_alpha_test_func(sctx); + key->part.ps.epilog.alpha_func = si_get_alpha_test_func(sctx); break; } default: assert(0); } } /* Select the hw shader variant depending on the current state. */ static int si_shader_select_with_key(struct si_screen *sscreen, struct si_shader_ctx_state *state, - union si_shader_key *key, + struct si_shader_key *key, LLVMTargetMachineRef tm, struct pipe_debug_callback *debug, bool wait, bool is_debug_context) { struct si_shader_selector *sel = state->cso; struct si_shader *current = state->current; struct si_shader *iter, *shader = NULL; int r; @@ -1094,56 +1094,56 @@ static int si_shader_select_with_key(struct si_screen *sscreen, } state->current = shader; pipe_mutex_unlock(sel->mutex); return 0; } static int si_shader_select(struct pipe_context *ctx, struct si_shader_ctx_state *state) { struct si_context *sctx = (struct si_context *)ctx; - union si_shader_key key; + struct si_shader_key key; si_shader_selector_key(ctx, state->cso, &key); return si_shader_select_with_key(sctx->screen, state, &key, sctx->tm, &sctx->b.debug, true, sctx->is_debug); } static void si_parse_next_shader_property(const struct tgsi_shader_info *info, - union si_shader_key *key) + struct si_shader_key *key) { unsigned next_shader = info->properties[TGSI_PROPERTY_NEXT_SHADER]; switch (info->processor) { case PIPE_SHADER_VERTEX: switch (next_shader) { case PIPE_SHADER_GEOMETRY: - key->vs.as_es = 1; + key->as_es = 1; break; case PIPE_SHADER_TESS_CTRL: case PIPE_SHADER_TESS_EVAL: - key->vs.as_ls = 1; + key->as_ls = 1; break; default: /* If POSITION isn't written, it can't be a HW VS. * Assume that it's a HW LS. (the next shader is TCS) * This heuristic is needed for separate shader objects. */ if (!info->writes_position) key->as_ls = 1; } break; case PIPE_SHADER_TESS_EVAL: if (next_shader == PIPE_SHADER_GEOMETRY) - key->tes.as_es = 1; + key->as_es = 1; break; } } /** * Compile the main shader part or the monolithic shader as part of * si_shader_selector initialization. Since it can be done asynchronously, * there is no way to report compile failures to applications. */ void si_init_shader_selector_async(void *job, int thread_index) @@ -1207,43 +1207,43 @@ void si_init_shader_selector_async(void *job, int thread_index) pipe_mutex_unlock(sscreen->shader_cache_mutex); } } sel->main_shader_part = shader; } /* Pre-compilation. */ if (sscreen->b.debug_flags & DBG_PRECOMPILE) { struct si_shader_ctx_state state = {sel}; - union si_shader_key key; + struct si_shader_key key; memset(&key, 0, sizeof(key)); si_parse_next_shader_property(&sel->info, &key); /* Set reasonable defaults, so that the shader key doesn't * cause any code to be eliminated. */ switch (sel->type) { case PIPE_SHADER_TESS_CTRL: - key.tcs.epilog.prim_mode = PIPE_PRIM_TRIANGLES; + key.part.tcs.epilog.prim_mode = PIPE_PRIM_TRIANGLES; break; case PIPE_SHADER_FRAGMENT: - key.ps.prolog.bc_optimize_for_persp = + key.part.ps.prolog.bc_optimize_for_persp = sel->info.uses_persp_center && sel->info.uses_persp_centroid; - key.ps.prolog.bc_optimize_for_linear = + key.part.ps.prolog.bc_optimize_for_linear = sel->info.uses_linear_center && sel->info.uses_linear_centroid; - key.ps.epilog.alpha_func = PIPE_FUNC_ALWAYS; + key.part.ps.epilog.alpha_func = PIPE_FUNC_ALWAYS; for (i = 0; i < 8; i++) if (sel->info.colors_written & (1 << i)) - key.ps.epilog.spi_shader_col_format |= + key.part.ps.epilog.spi_shader_col_format |= V_028710_SPI_SHADER_FP16_ABGR << (i * 4); break; } if (si_shader_select_with_key(sscreen, &state, &key, tm, debug, false, sel->is_debug_context)) fprintf(stderr, "radeonsi: can't create a monolithic shader\n"); } /* The GS copy shader is always pre-compiled. */ @@ -1514,32 +1514,32 @@ static void si_bind_ps_shader(struct pipe_context *ctx, void *state) sctx->ps_shader.current = sel ? sel->first_variant : NULL; sctx->do_update_shaders = true; si_mark_atom_dirty(sctx, &sctx->cb_render_state); } static void si_delete_shader(struct si_context *sctx, struct si_shader *shader) { if (shader->pm4) { switch (shader->selector->type) { case PIPE_SHADER_VERTEX: - if (shader->key.vs.as_ls) + if (shader->key.as_ls) si_pm4_delete_state(sctx, ls, shader->pm4); - else if (shader->key.vs.as_es) + else if (shader->key.as_es) si_pm4_delete_state(sctx, es, shader->pm4); else si_pm4_delete_state(sctx, vs, shader->pm4); break; case PIPE_SHADER_TESS_CTRL: si_pm4_delete_state(sctx, hs, shader->pm4); break; case PIPE_SHADER_TESS_EVAL: - if (shader->key.tes.as_es) + if (shader->key.as_es) si_pm4_delete_state(sctx, es, shader->pm4); else si_pm4_delete_state(sctx, vs, shader->pm4); break; case PIPE_SHADER_GEOMETRY: if (shader->is_gs_copy_shader) si_pm4_delete_state(sctx, vs, shader->pm4); else si_pm4_delete_state(sctx, gs, shader->pm4); break; @@ -1666,21 +1666,21 @@ static void si_emit_spi_map(struct si_context *sctx, struct r600_atom *atom) radeon_emit(cs, si_get_ps_input_cntl(sctx, vs, name, index, interpolate)); num_written++; if (name == TGSI_SEMANTIC_COLOR) { assert(index < ARRAY_SIZE(bcol_interp)); bcol_interp[index] = interpolate; } } - if (ps->key.ps.prolog.color_two_side) { + if (ps->key.part.ps.prolog.color_two_side) { unsigned bcol = TGSI_SEMANTIC_BCOLOR; for (i = 0; i < 2; i++) { if (!(psinfo->colors_read & (0xf << (i * 4)))) continue; radeon_emit(cs, si_get_ps_input_cntl(sctx, vs, bcol, i, bcol_interp[i])); num_written++; } @@ -2274,22 +2274,22 @@ bool si_update_shaders(struct si_context *sctx) } if (sctx->b.family == CHIP_STONEY && si_pm4_state_changed(sctx, ps)) si_mark_atom_dirty(sctx, &sctx->cb_render_state); if (sctx->ps_db_shader_control != db_shader_control) { sctx->ps_db_shader_control = db_shader_control; si_mark_atom_dirty(sctx, &sctx->db_render_state); } - if (sctx->smoothing_enabled != sctx->ps_shader.current->key.ps.epilog.poly_line_smoothing) { - sctx->smoothing_enabled = sctx->ps_shader.current->key.ps.epilog.poly_line_smoothing; + if (sctx->smoothing_enabled != sctx->ps_shader.current->key.part.ps.epilog.poly_line_smoothing) { + sctx->smoothing_enabled = sctx->ps_shader.current->key.part.ps.epilog.poly_line_smoothing; si_mark_atom_dirty(sctx, &sctx->msaa_config); if (sctx->b.chip_class == SI) si_mark_atom_dirty(sctx, &sctx->db_render_state); if (sctx->framebuffer.nr_samples <= 1) si_mark_atom_dirty(sctx, &sctx->msaa_sample_locs.atom); } } -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev