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 <anuj.phogat@gmail.com>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
This commit is contained in:
Anuj Phogat 2013-10-24 15:53:05 -07:00
parent 81f5fb352a
commit 65d0452bbc
6 changed files with 95 additions and 0 deletions

View file

@ -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;
/**

View file

@ -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. */

View file

@ -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,

View file

@ -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)

View file

@ -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)

View file

@ -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;