From 65d0452bbc14c69ecd2cffdb38f711cfbaab348e Mon Sep 17 00:00:00 2001 From: Anuj Phogat Date: Thu, 24 Oct 2013 15:53:05 -0700 Subject: [PATCH] i965: Add FS backend for builtin gl_SamplePosition V2: - Update comments. - Add compute_pos_offset variable in brw_wm_prog_key. - Add variable uses_pos_offset in brw_wm_prog_data. V3: - Make changes to support simd16 mode. Signed-off-by: Anuj Phogat Reviewed-by: Paul Berry --- src/mesa/drivers/dri/i965/brw_context.h | 1 + src/mesa/drivers/dri/i965/brw_fs.cpp | 79 ++++++++++++++++++++ src/mesa/drivers/dri/i965/brw_fs.h | 2 + src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 5 ++ src/mesa/drivers/dri/i965/brw_wm.c | 6 ++ src/mesa/drivers/dri/i965/brw_wm.h | 2 + 6 files changed, 95 insertions(+) diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index d30c963ad48..665807c8bf8 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -383,6 +383,7 @@ struct brw_wm_prog_data { GLuint nr_params; /**< number of float params/constants */ GLuint nr_pull_params; bool dual_src_blend; + bool uses_pos_offset; uint32_t prog_offset_16; /** diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index 7064910281f..dfb0d15c031 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -1145,6 +1145,78 @@ fs_visitor::emit_frontfacing_interpolation(ir_variable *ir) return reg; } +void +fs_visitor::compute_sample_position(fs_reg dst, fs_reg int_sample_pos) +{ + assert(dst.type == BRW_REGISTER_TYPE_F); + + if (c->key.compute_pos_offset) { + /* Convert int_sample_pos to floating point */ + emit(MOV(dst, int_sample_pos)); + /* Scale to the range [0, 1] */ + emit(MUL(dst, dst, fs_reg(1 / 16.0f))); + } + else { + /* From ARB_sample_shading specification: + * "When rendering to a non-multisample buffer, or if multisample + * rasterization is disabled, gl_SamplePosition will always be + * (0.5, 0.5). + */ + emit(MOV(dst, fs_reg(0.5f))); + } +} + +fs_reg * +fs_visitor::emit_samplepos_setup(ir_variable *ir) +{ + assert(brw->gen >= 6); + assert(ir->type == glsl_type::vec2_type); + + this->current_annotation = "compute sample position"; + fs_reg *reg = new(this->mem_ctx) fs_reg(this, ir->type); + fs_reg pos = *reg; + fs_reg int_sample_x = fs_reg(this, glsl_type::int_type); + fs_reg int_sample_y = fs_reg(this, glsl_type::int_type); + + /* WM will be run in MSDISPMODE_PERSAMPLE. So, only one of SIMD8 or SIMD16 + * mode will be enabled. + * + * From the Ivy Bridge PRM, volume 2 part 1, page 344: + * R31.1:0 Position Offset X/Y for Slot[3:0] + * R31.3:2 Position Offset X/Y for Slot[7:4] + * ..... + * + * The X, Y sample positions come in as bytes in thread payload. So, read + * the positions using vstride=16, width=8, hstride=2. + */ + struct brw_reg sample_pos_reg = + stride(retype(brw_vec1_grf(c->sample_pos_reg, 0), + BRW_REGISTER_TYPE_B), 16, 8, 2); + + emit(MOV(int_sample_x, fs_reg(sample_pos_reg))); + if (dispatch_width == 16) { + int_sample_x.sechalf = true; + fs_inst *inst = emit(MOV(int_sample_x, + fs_reg(suboffset(sample_pos_reg, 16)))); + inst->force_sechalf = true; + int_sample_x.sechalf = false; + } + /* Compute gl_SamplePosition.x */ + compute_sample_position(pos, int_sample_x); + pos.reg_offset++; + emit(MOV(int_sample_y, fs_reg(suboffset(sample_pos_reg, 1)))); + if (dispatch_width == 16) { + int_sample_y.sechalf = true; + fs_inst *inst = emit(MOV(int_sample_y, + fs_reg(suboffset(sample_pos_reg, 17)))); + inst->force_sechalf = true; + int_sample_y.sechalf = false; + } + /* Compute gl_SamplePosition.y */ + compute_sample_position(pos, int_sample_y); + return reg; +} + fs_reg fs_visitor::fix_math_operand(fs_reg src) { @@ -3056,7 +3128,14 @@ fs_visitor::setup_payload_gen6() c->nr_payload_regs++; } } + + c->prog_data.uses_pos_offset = c->key.compute_pos_offset; /* R31: MSAA position offsets. */ + if (c->prog_data.uses_pos_offset) { + c->sample_pos_reg = c->nr_payload_regs; + c->nr_payload_regs++; + } + /* R32-: bary for 32-pixel. */ /* R58-59: interp W for 32-pixel. */ diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index 43e47617c17..7eb82fc5a3c 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -340,9 +340,11 @@ public: glsl_interp_qualifier interpolation_mode, bool is_centroid); fs_reg *emit_frontfacing_interpolation(ir_variable *ir); + fs_reg *emit_samplepos_setup(ir_variable *ir); fs_reg *emit_general_interpolation(ir_variable *ir); void emit_interpolation_setup_gen4(); void emit_interpolation_setup_gen6(); + void compute_sample_position(fs_reg dst, fs_reg int_sample_pos); fs_reg rescale_texcoord(ir_texture *ir, fs_reg coordinate, bool is_rect, int sampler, int texunit); fs_inst *emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate, diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index 0e2dfd30016..0404fffe9b8 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -125,6 +125,11 @@ fs_visitor::visit(ir_variable *ir) reg = new(this->mem_ctx) fs_reg(UNIFORM, param_index); reg->type = brw_type_for_base_type(ir->type); + + } else if (ir->mode == ir_var_system_value) { + if (ir->location == SYSTEM_VALUE_SAMPLE_POS) { + reg = emit_samplepos_setup(ir); + } } if (!reg) diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c index 0fda4900aae..d2a5a9fb3be 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.c +++ b/src/mesa/drivers/dri/i965/brw_wm.c @@ -37,6 +37,7 @@ #include "main/fbobject.h" #include "main/samplerobj.h" #include "program/prog_parameter.h" +#include "program/program.h" #include "glsl/ralloc.h" @@ -483,6 +484,11 @@ static void brw_wm_populate_key( struct brw_context *brw, key->replicate_alpha = ctx->DrawBuffer->_NumColorDrawBuffers > 1 && (ctx->Multisample.SampleAlphaToCoverage || ctx->Color.AlphaEnabled); + /* _NEW_BUFFERS _NEW_MULTISAMPLE */ + key->compute_pos_offset = + _mesa_get_min_invocations_per_fragment(ctx, &fp->program) > 1 && + fp->program.Base.SystemValuesRead & SYSTEM_BIT_SAMPLE_POS; + /* BRW_NEW_VUE_MAP_GEOM_OUT */ if (brw->gen < 6 || _mesa_bitcount_64(fp->program.Base.InputsRead & BRW_FS_VARYING_INPUT_MASK) > 16) diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index 259a4b67573..eb740adffe6 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -65,6 +65,7 @@ struct brw_wm_prog_key { GLuint replicate_alpha:1; GLuint render_to_fbo:1; GLuint clamp_fragment_color:1; + GLuint compute_pos_offset:1; GLuint line_aa:2; GLuint high_quality_derivatives:1; @@ -83,6 +84,7 @@ struct brw_wm_compile { uint8_t source_w_reg; uint8_t aa_dest_stencil_reg; uint8_t dest_depth_reg; + uint8_t sample_pos_reg; uint8_t barycentric_coord_reg[BRW_WM_BARYCENTRIC_INTERP_MODE_COUNT]; uint8_t nr_payload_regs; GLuint source_depth_to_render_target:1; -- 2.30.2