S_008F04_BASE_ADDRESS_HI(va >> 32);
}
+/* INTERNAL CONST BUFFERS */
+
+static void si_set_polygon_stipple(struct pipe_context *ctx,
+ const struct pipe_poly_stipple *state)
+{
+ struct si_context *sctx = (struct si_context *)ctx;
+ struct pipe_constant_buffer cb = {};
+ unsigned stipple[32];
+ int i;
+
+ for (i = 0; i < 32; i++)
+ stipple[i] = util_bitreverse(state->stipple[i]);
+
+ cb.user_buffer = stipple;
+ cb.buffer_size = sizeof(stipple);
+
+ si_set_constant_buffer(sctx, &sctx->rw_buffers,
+ SI_PS_CONST_POLY_STIPPLE, &cb);
+}
+
/* TEXTURE METADATA ENABLE/DISABLE */
/* CMASK can be enabled (for fast clear) and disabled (for texture export)
}
if (sctx->rw_buffers.desc.pointer_dirty) {
+ si_emit_shader_pointer(sctx, &sctx->rw_buffers.desc,
+ R_00B030_SPI_SHADER_USER_DATA_PS_0, true);
si_emit_shader_pointer(sctx, &sctx->rw_buffers.desc,
R_00B130_SPI_SHADER_USER_DATA_VS_0, true);
si_emit_shader_pointer(sctx, &sctx->rw_buffers.desc,
sctx->b.b.bind_sampler_states = si_bind_sampler_states;
sctx->b.b.set_shader_images = si_set_shader_images;
sctx->b.b.set_constant_buffer = si_pipe_set_constant_buffer;
+ sctx->b.b.set_polygon_stipple = si_set_polygon_stipple;
sctx->b.b.set_shader_buffers = si_set_shader_buffers;
sctx->b.b.set_sampler_views = si_set_sampler_views;
sctx->b.b.set_stream_output_targets = si_set_streamout_targets;
}
static void si_llvm_emit_polygon_stipple(struct si_shader_context *ctx,
- LLVMValueRef param_sampler_views,
+ LLVMValueRef param_rw_buffers,
unsigned param_pos_fixed_pt)
{
struct lp_build_tgsi_context *bld_base =
&ctx->radeon_bld.soa.bld_base;
struct gallivm_state *gallivm = bld_base->base.gallivm;
- struct lp_build_emit_data result = {};
- struct tgsi_full_instruction inst = {};
- LLVMValueRef desc, sampler_index, address[2], pix;
+ LLVMBuilderRef builder = gallivm->builder;
+ LLVMValueRef slot, desc, offset, row, bit, address[2];
/* Use the fixed-point gl_FragCoord input.
* Since the stipple pattern is 32x32 and it repeats, just get 5 bits
address[0] = unpack_param(ctx, param_pos_fixed_pt, 0, 5);
address[1] = unpack_param(ctx, param_pos_fixed_pt, 16, 5);
- /* Load the sampler view descriptor. */
- sampler_index = lp_build_const_int32(gallivm, SI_POLY_STIPPLE_SAMPLER);
- desc = get_sampler_desc_custom(ctx, param_sampler_views,
- sampler_index, DESC_IMAGE);
-
- /* Load the texel. */
- inst.Instruction.Opcode = TGSI_OPCODE_TXF;
- inst.Texture.Texture = TGSI_TEXTURE_2D_MSAA; /* = use load, not load_mip */
- result.inst = &inst;
- set_tex_fetch_args(ctx, &result, TGSI_OPCODE_TXF,
- inst.Texture.Texture,
- desc, NULL, address, ARRAY_SIZE(address), 0xf);
- build_tex_intrinsic(&tex_action, bld_base, &result);
-
- /* Kill the thread accordingly. */
- pix = LLVMBuildExtractElement(gallivm->builder, result.output[0],
- lp_build_const_int32(gallivm, 3), "");
- pix = bitcast(bld_base, TGSI_TYPE_FLOAT, pix);
- pix = LLVMBuildFNeg(gallivm->builder, pix, "");
+ /* Load the buffer descriptor. */
+ slot = lp_build_const_int32(gallivm, SI_PS_CONST_POLY_STIPPLE);
+ desc = build_indexed_load_const(ctx, param_rw_buffers, slot);
- lp_build_intrinsic(gallivm->builder, "llvm.AMDGPU.kill",
- LLVMVoidTypeInContext(gallivm->context),
- &pix, 1, 0);
+ /* The stipple pattern is 32x32, each row has 32 bits. */
+ offset = LLVMBuildMul(builder, address[1],
+ LLVMConstInt(ctx->i32, 4, 0), "");
+ row = buffer_load_const(builder, desc, offset, ctx->i32);
+ bit = LLVMBuildLShr(builder, row, address[0], "");
+ bit = LLVMBuildTrunc(builder, bit, ctx->i1, "");
+
+ /* The intrinsic kills the thread if arg < 0. */
+ bit = LLVMBuildSelect(builder, bit, LLVMConstReal(ctx->f32, 0),
+ LLVMConstReal(ctx->f32, -1), "");
+ lp_build_intrinsic(builder, "llvm.AMDGPU.kill", ctx->voidt, &bit, 1, 0);
}
void si_shader_binary_read_config(struct radeon_shader_binary *binary,
if (ctx.is_monolithic && sel->type == PIPE_SHADER_FRAGMENT &&
shader->key.ps.prolog.poly_stipple) {
- LLVMValueRef views = LLVMGetParam(ctx.radeon_bld.main_fn,
- SI_PARAM_SAMPLERS);
- si_llvm_emit_polygon_stipple(&ctx, views,
+ LLVMValueRef list = LLVMGetParam(ctx.radeon_bld.main_fn,
+ SI_PARAM_RW_BUFFERS);
+ si_llvm_emit_polygon_stipple(&ctx, list,
SI_PARAM_POS_FIXED_PT);
}
/* POS_FIXED_PT is always last. */
unsigned pos = key->ps_prolog.num_input_sgprs +
key->ps_prolog.num_input_vgprs - 1;
- LLVMValueRef ptr[2], views;
+ LLVMValueRef ptr[2], list;
- /* Get the pointer to sampler views. */
- ptr[0] = LLVMGetParam(func, SI_SGPR_SAMPLERS);
- ptr[1] = LLVMGetParam(func, SI_SGPR_SAMPLERS+1);
- views = lp_build_gather_values(gallivm, ptr, 2);
- views = LLVMBuildBitCast(gallivm->builder, views, ctx.i64, "");
- views = LLVMBuildIntToPtr(gallivm->builder, views,
- const_array(ctx.v8i32, SI_NUM_SAMPLERS), "");
+ /* Get the pointer to rw buffers. */
+ ptr[0] = LLVMGetParam(func, SI_SGPR_RW_BUFFERS);
+ ptr[1] = LLVMGetParam(func, SI_SGPR_RW_BUFFERS_HI);
+ list = lp_build_gather_values(gallivm, ptr, 2);
+ list = LLVMBuildBitCast(gallivm->builder, list, ctx.i64, "");
+ list = LLVMBuildIntToPtr(gallivm->builder, list,
+ const_array(ctx.v16i8, SI_NUM_RW_BUFFERS), "");
- si_llvm_emit_polygon_stipple(&ctx, views, pos);
+ si_llvm_emit_polygon_stipple(&ctx, list, pos);
}
/* Interpolate colors. */
/*
* Misc
*/
-static void si_set_polygon_stipple(struct pipe_context *ctx,
- const struct pipe_poly_stipple *state)
-{
- struct si_context *sctx = (struct si_context *)ctx;
- struct pipe_resource *tex;
- struct pipe_sampler_view *view;
- bool is_zero = true;
- bool is_one = true;
- int i;
-
- /* The hardware obeys 0 and 1 swizzles in the descriptor even if
- * the resource is NULL/invalid. Take advantage of this fact and skip
- * texture allocation if the stipple pattern is constant.
- *
- * This is an optimization for the common case when stippling isn't
- * used but set_polygon_stipple is still called by st/mesa.
- */
- for (i = 0; i < Elements(state->stipple); i++) {
- is_zero = is_zero && state->stipple[i] == 0;
- is_one = is_one && state->stipple[i] == 0xffffffff;
- }
-
- if (is_zero || is_one) {
- struct pipe_sampler_view templ = {{0}};
-
- templ.swizzle_r = PIPE_SWIZZLE_ZERO;
- templ.swizzle_g = PIPE_SWIZZLE_ZERO;
- templ.swizzle_b = PIPE_SWIZZLE_ZERO;
- /* The pattern should be inverted in the texture. */
- templ.swizzle_a = is_zero ? PIPE_SWIZZLE_ONE : PIPE_SWIZZLE_ZERO;
-
- view = ctx->create_sampler_view(ctx, NULL, &templ);
- } else {
- /* Create a new texture. */
- tex = util_pstipple_create_stipple_texture(ctx, state->stipple);
- if (!tex)
- return;
-
- view = util_pstipple_create_sampler_view(ctx, tex);
- pipe_resource_reference(&tex, NULL);
- }
-
- ctx->set_sampler_views(ctx, PIPE_SHADER_FRAGMENT,
- SI_POLY_STIPPLE_SAMPLER, 1, &view);
- pipe_sampler_view_reference(&view, NULL);
-
- /* Bind the sampler state if needed. */
- if (!sctx->pstipple_sampler_state) {
- sctx->pstipple_sampler_state = util_pstipple_create_sampler(ctx);
- ctx->bind_sampler_states(ctx, PIPE_SHADER_FRAGMENT,
- SI_POLY_STIPPLE_SAMPLER, 1,
- &sctx->pstipple_sampler_state);
- }
-}
static void si_set_tess_state(struct pipe_context *ctx,
const float default_outer_level[4],
sctx->b.b.texture_barrier = si_texture_barrier;
sctx->b.b.memory_barrier = si_memory_barrier;
- sctx->b.b.set_polygon_stipple = si_set_polygon_stipple;
sctx->b.b.set_min_samples = si_set_min_samples;
sctx->b.b.set_tess_state = si_set_tess_state;