From 1b05fc7cdd0e5d77b50bc8ee2f2c851da5884d72 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 6 Dec 2011 15:36:21 -0800 Subject: [PATCH] i965/fs: Factor out texturing related data from brw_wm_prog_key. The idea is to reuse this for the VS and (in the future) GS as well. v2: Include yuvtex data since we're not dropping GL_MESA_ycbycr. Signed-off-by: Kenneth Graunke Reviewed-by: Eric Anholt [v1] Reviewed-by: Ian Romanick --- src/mesa/drivers/dri/i965/brw_fs.cpp | 4 +- src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 26 +-- src/mesa/drivers/dri/i965/brw_program.h | 60 +++++++ src/mesa/drivers/dri/i965/brw_wm.c | 162 ++++++++++--------- src/mesa/drivers/dri/i965/brw_wm.h | 19 +-- src/mesa/drivers/dri/i965/brw_wm_emit.c | 2 +- src/mesa/drivers/dri/i965/brw_wm_fp.c | 10 +- 7 files changed, 168 insertions(+), 115 deletions(-) create mode 100644 src/mesa/drivers/dri/i965/brw_program.h diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index 339044ca11a..8ca4a8735d0 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -1904,10 +1904,10 @@ brw_fs_precompile(struct gl_context *ctx, struct gl_shader_program *prog) for (int i = 0; i < BRW_MAX_TEX_UNIT; i++) { if (fp->Base.ShadowSamplers & (1 << i)) - key.compare_funcs[i] = GL_LESS; + key.tex.compare_funcs[i] = GL_LESS; /* FINISHME: depth compares might use (0,0,0,W) for example */ - key.tex_swizzles[i] = SWIZZLE_XYZW; + key.tex.swizzles[i] = SWIZZLE_XYZW; } if (fp->Base.InputsRead & FRAG_BIT_WPOS) { diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index 1143951385d..9f8a44a4742 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -623,7 +623,7 @@ fs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate, for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i), coordinate); - if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler)) + if (i < 3 && c->key.tex.gl_clamp_mask[i] & (1 << sampler)) inst->saturate = true; coordinate.reg_offset++; @@ -655,7 +655,7 @@ fs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate, for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i), coordinate); - if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler)) + if (i < 3 && c->key.tex.gl_clamp_mask[i] & (1 << sampler)) inst->saturate = true; coordinate.reg_offset++; } @@ -718,7 +718,7 @@ fs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate, base_mrf + mlen + i * 2, coordinate.type), coordinate); - if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler)) + if (i < 3 && c->key.tex.gl_clamp_mask[i] & (1 << sampler)) inst->saturate = true; coordinate.reg_offset++; } @@ -830,7 +830,7 @@ fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate, fs_reg(MRF, base_mrf + mlen + i * reg_width, coordinate.type), coordinate); - if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler)) + if (i < 3 && c->key.tex.gl_clamp_mask[i] & (1 << sampler)) inst->saturate = true; coordinate.reg_offset++; } @@ -978,7 +978,7 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), coordinate); - if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler)) + if (i < 3 && c->key.tex.gl_clamp_mask[i] & (1 << sampler)) inst->saturate = true; coordinate.reg_offset++; mlen += reg_width; @@ -1023,7 +1023,7 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), coordinate); - if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler)) + if (i < 3 && c->key.tex.gl_clamp_mask[i] & (1 << sampler)) inst->saturate = true; coordinate.reg_offset++; mlen += reg_width; @@ -1064,11 +1064,11 @@ fs_visitor::visit(ir_texture *ir) */ bool hw_compare_supported = ir->op != ir_txd; if (ir->shadow_comparitor && !hw_compare_supported) { - assert(c->key.compare_funcs[sampler] != GL_NONE); + assert(c->key.tex.compare_funcs[sampler] != GL_NONE); /* No need to even sample for GL_ALWAYS or GL_NEVER...bail early */ - if (c->key.compare_funcs[sampler] == GL_ALWAYS) + if (c->key.tex.compare_funcs[sampler] == GL_ALWAYS) return swizzle_result(ir, fs_reg(1.0f), sampler); - else if (c->key.compare_funcs[sampler] == GL_NEVER) + else if (c->key.tex.compare_funcs[sampler] == GL_NEVER) return swizzle_result(ir, fs_reg(0.0f), sampler); } @@ -1177,7 +1177,7 @@ fs_visitor::visit(ir_texture *ir) /* FINISHME: This needs to be done pre-filtering. */ uint32_t conditional = 0; - switch (c->key.compare_funcs[sampler]) { + switch (c->key.tex.compare_funcs[sampler]) { /* GL_ALWAYS and GL_NEVER were handled at the top of the function */ case GL_LESS: conditional = BRW_CONDITIONAL_L; break; case GL_GREATER: conditional = BRW_CONDITIONAL_G; break; @@ -1224,11 +1224,11 @@ fs_visitor::swizzle_result(ir_texture *ir, fs_reg orig_val, int sampler) if (ir->type == glsl_type::float_type) { /* Ignore DEPTH_TEXTURE_MODE swizzling. */ assert(ir->sampler->type->sampler_shadow); - } else if (c->key.tex_swizzles[sampler] != SWIZZLE_NOOP) { + } else if (c->key.tex.swizzles[sampler] != SWIZZLE_NOOP) { fs_reg swizzled_result = fs_reg(this, glsl_type::vec4_type); for (int i = 0; i < 4; i++) { - int swiz = GET_SWZ(c->key.tex_swizzles[sampler], i); + int swiz = GET_SWZ(c->key.tex.swizzles[sampler], i); fs_reg l = swizzled_result; l.reg_offset += i; @@ -1238,7 +1238,7 @@ fs_visitor::swizzle_result(ir_texture *ir, fs_reg orig_val, int sampler) emit(BRW_OPCODE_MOV, l, fs_reg(1.0f)); } else { fs_reg r = orig_val; - r.reg_offset += GET_SWZ(c->key.tex_swizzles[sampler], i); + r.reg_offset += GET_SWZ(c->key.tex.swizzles[sampler], i); emit(BRW_OPCODE_MOV, l, r); } } diff --git a/src/mesa/drivers/dri/i965/brw_program.h b/src/mesa/drivers/dri/i965/brw_program.h new file mode 100644 index 00000000000..a2698cf2e29 --- /dev/null +++ b/src/mesa/drivers/dri/i965/brw_program.h @@ -0,0 +1,60 @@ +/* + * Copyright © 2011 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef BRW_PROGRAM_H +#define BRW_PROGRAM_H + +/** + * Sampler information needed by VS, WM, and GS program cache keys. + */ +struct brw_sampler_prog_key_data { + /** + * Per-sampler comparison functions: + * + * If comparison mode is GL_COMPARE_R_TO_TEXTURE, then this is set to one + * of GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL, + * GL_GEQUAL, or GL_ALWAYS. Otherwise (comparison mode is GL_NONE), this + * field is irrelevant so it's left as GL_NONE (0). + * + * While this is a GLenum, all possible values fit in 16-bits. + */ + uint16_t compare_funcs[BRW_MAX_TEX_UNIT]; + + /** + * EXT_texture_swizzle and DEPTH_TEXTURE_MODE swizzles. + */ + uint16_t swizzles[BRW_MAX_TEX_UNIT]; + + uint16_t gl_clamp_mask[3]; + + /** + * YUV conversions, needed for the GL_MESA_ycbcr extension. + */ + uint16_t yuvtex_mask; + uint16_t yuvtex_swap_mask; /**< UV swaped */ +}; + +void brw_populate_sampler_prog_key_data(struct gl_context *ctx, + struct brw_sampler_prog_key_data *key, int i); + +#endif diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c index 207ffd6c639..f23edfa798b 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.c +++ b/src/mesa/drivers/dri/i965/brw_wm.c @@ -320,7 +320,90 @@ bool do_wm_prog(struct brw_context *brw, return true; } +void +brw_populate_sampler_prog_key_data(struct gl_context *ctx, + struct brw_sampler_prog_key_data *key, + int i) +{ + const struct gl_texture_unit *unit = &ctx->Texture.Unit[i]; + + if (unit->_ReallyEnabled) { + const struct gl_texture_object *t = unit->_Current; + const struct gl_texture_image *img = t->Image[0][t->BaseLevel]; + struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, i); + int swizzles[SWIZZLE_NIL + 1] = { + SWIZZLE_X, + SWIZZLE_Y, + SWIZZLE_Z, + SWIZZLE_W, + SWIZZLE_ZERO, + SWIZZLE_ONE, + SWIZZLE_NIL + }; + + if (img->_BaseFormat == GL_DEPTH_COMPONENT || + img->_BaseFormat == GL_DEPTH_STENCIL) { + if (sampler->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) + key->compare_funcs[i] = sampler->CompareFunc; + + /* We handle GL_DEPTH_TEXTURE_MODE here instead of as surface format + * overrides because shadow comparison always returns the result of + * the comparison in all channels anyway. + */ + switch (sampler->DepthMode) { + case GL_ALPHA: + swizzles[0] = SWIZZLE_ZERO; + swizzles[1] = SWIZZLE_ZERO; + swizzles[2] = SWIZZLE_ZERO; + swizzles[3] = SWIZZLE_X; + break; + case GL_LUMINANCE: + swizzles[0] = SWIZZLE_X; + swizzles[1] = SWIZZLE_X; + swizzles[2] = SWIZZLE_X; + swizzles[3] = SWIZZLE_ONE; + break; + case GL_INTENSITY: + swizzles[0] = SWIZZLE_X; + swizzles[1] = SWIZZLE_X; + swizzles[2] = SWIZZLE_X; + swizzles[3] = SWIZZLE_X; + break; + case GL_RED: + swizzles[0] = SWIZZLE_X; + swizzles[1] = SWIZZLE_ZERO; + swizzles[2] = SWIZZLE_ZERO; + swizzles[3] = SWIZZLE_ONE; + break; + } + } + if (img->InternalFormat == GL_YCBCR_MESA) { + key->yuvtex_mask |= 1 << i; + if (img->TexFormat == MESA_FORMAT_YCBCR) + key->yuvtex_swap_mask |= 1 << i; + } + + key->swizzles[i] = + MAKE_SWIZZLE4(swizzles[GET_SWZ(t->_Swizzle, 0)], + swizzles[GET_SWZ(t->_Swizzle, 1)], + swizzles[GET_SWZ(t->_Swizzle, 2)], + swizzles[GET_SWZ(t->_Swizzle, 3)]); + + if (sampler->MinFilter != GL_NEAREST && + sampler->MagFilter != GL_NEAREST) { + if (sampler->WrapS == GL_CLAMP) + key->gl_clamp_mask[0] |= 1 << i; + if (sampler->WrapT == GL_CLAMP) + key->gl_clamp_mask[1] |= 1 << i; + if (sampler->WrapR == GL_CLAMP) + key->gl_clamp_mask[2] |= 1 << i; + } + } + else { + key->swizzles[i] = SWIZZLE_NOOP; + } +} static void brw_wm_populate_key( struct brw_context *brw, struct brw_wm_prog_key *key ) @@ -404,84 +487,7 @@ static void brw_wm_populate_key( struct brw_context *brw, /* _NEW_TEXTURE */ for (i = 0; i < BRW_MAX_TEX_UNIT; i++) { - const struct gl_texture_unit *unit = &ctx->Texture.Unit[i]; - - if (unit->_ReallyEnabled) { - const struct gl_texture_object *t = unit->_Current; - const struct gl_texture_image *img = t->Image[0][t->BaseLevel]; - struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, i); - int swizzles[SWIZZLE_NIL + 1] = { - SWIZZLE_X, - SWIZZLE_Y, - SWIZZLE_Z, - SWIZZLE_W, - SWIZZLE_ZERO, - SWIZZLE_ONE, - SWIZZLE_NIL - }; - - if (img->_BaseFormat == GL_DEPTH_COMPONENT || - img->_BaseFormat == GL_DEPTH_STENCIL) { - if (sampler->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) - key->compare_funcs[i] = sampler->CompareFunc; - - /* We handle GL_DEPTH_TEXTURE_MODE here instead of as surface format - * overrides because shadow comparison always returns the result of - * the comparison in all channels anyway. - */ - switch (sampler->DepthMode) { - case GL_ALPHA: - swizzles[0] = SWIZZLE_ZERO; - swizzles[1] = SWIZZLE_ZERO; - swizzles[2] = SWIZZLE_ZERO; - swizzles[3] = SWIZZLE_X; - break; - case GL_LUMINANCE: - swizzles[0] = SWIZZLE_X; - swizzles[1] = SWIZZLE_X; - swizzles[2] = SWIZZLE_X; - swizzles[3] = SWIZZLE_ONE; - break; - case GL_INTENSITY: - swizzles[0] = SWIZZLE_X; - swizzles[1] = SWIZZLE_X; - swizzles[2] = SWIZZLE_X; - swizzles[3] = SWIZZLE_X; - break; - case GL_RED: - swizzles[0] = SWIZZLE_X; - swizzles[1] = SWIZZLE_ZERO; - swizzles[2] = SWIZZLE_ZERO; - swizzles[3] = SWIZZLE_ONE; - break; - } - } - - if (img->InternalFormat == GL_YCBCR_MESA) { - key->yuvtex_mask |= 1 << i; - if (img->TexFormat == MESA_FORMAT_YCBCR) - key->yuvtex_swap_mask |= 1 << i; - } - - key->tex_swizzles[i] = - MAKE_SWIZZLE4(swizzles[GET_SWZ(t->_Swizzle, 0)], - swizzles[GET_SWZ(t->_Swizzle, 1)], - swizzles[GET_SWZ(t->_Swizzle, 2)], - swizzles[GET_SWZ(t->_Swizzle, 3)]); - - if (sampler->MinFilter != GL_NEAREST && - sampler->MagFilter != GL_NEAREST) { - if (sampler->WrapS == GL_CLAMP) - key->gl_clamp_mask[0] |= 1 << i; - if (sampler->WrapT == GL_CLAMP) - key->gl_clamp_mask[1] |= 1 << i; - if (sampler->WrapR == GL_CLAMP) - key->gl_clamp_mask[2] |= 1 << i; - } - } - else { - key->tex_swizzles[i] = SWIZZLE_NOOP; - } + brw_populate_sampler_prog_key_data(ctx, &key->tex, i); } /* _NEW_BUFFERS */ diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index 596759269ad..3bce1f3dd8f 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -38,6 +38,7 @@ #include "program/prog_instruction.h" #include "brw_context.h" #include "brw_eu.h" +#include "brw_program.h" #define SATURATE (1<<5) @@ -68,27 +69,13 @@ struct brw_wm_prog_key { GLuint clamp_fragment_color:1; GLuint line_aa:2; - /** - * Per-sampler comparison functions: - * - * If comparison mode is GL_COMPARE_R_TO_TEXTURE, then this is set to one - * of GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL, - * GL_GEQUAL, or GL_ALWAYS. Otherwise (comparison mode is GL_NONE), this - * field is irrelevant so it's left as GL_NONE (0). - * - * While this is a GLenum, all possible values fit in 16-bits. - */ - uint16_t compare_funcs[BRW_MAX_TEX_UNIT]; - GLbitfield proj_attrib_mask; /**< one bit per fragment program attribute */ - GLuint yuvtex_mask:16; - GLuint yuvtex_swap_mask:16; /* UV swaped */ - uint16_t gl_clamp_mask[3]; - GLushort tex_swizzles[BRW_MAX_TEX_UNIT]; GLushort drawable_height; GLbitfield64 vp_outputs_written; GLuint program_string_id:32; + + struct brw_sampler_prog_key_data tex; }; diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c index 5905ba9cd40..4f2054656fa 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_emit.c +++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c @@ -1109,7 +1109,7 @@ void emit_tex(struct brw_wm_compile *c, /* Emit the texcoords. */ for (i = 0; i < nr_texcoords; i++) { - if (c->key.gl_clamp_mask[i] & (1 << sampler)) + if (c->key.tex.gl_clamp_mask[i] & (1 << sampler)) brw_set_saturate(p, true); if (emit & (1<key.tex_swizzles[unit] != SWIZZLE_NOOP) { + if (c->key.tex.swizzles[unit] != SWIZZLE_NOOP) { unswizzled_tmp = get_temp(c); } else { unswizzled_tmp = inst->DstReg; @@ -771,9 +771,9 @@ static void precalc_tex( struct brw_wm_compile *c, * conversion requires allocating a temporary variable which we * don't have the facility to do that late in the compilation. */ - if (c->key.yuvtex_mask & (1 << unit)) { + if (c->key.tex.yuvtex_mask & (1 << unit)) { /* convert ycbcr to RGBA */ - bool swap_uv = c->key.yuvtex_swap_mask & (1<key.tex.yuvtex_swap_mask & (1 << unit); /* CONST C0 = { -.5, -.0625, -.5, 1.164 } @@ -868,13 +868,13 @@ static void precalc_tex( struct brw_wm_compile *c, } /* For GL_EXT_texture_swizzle: */ - if (c->key.tex_swizzles[unit] != SWIZZLE_NOOP) { + if (c->key.tex.swizzles[unit] != SWIZZLE_NOOP) { /* swizzle the result of the TEX instruction */ struct prog_src_register tmpsrc = src_reg_from_dst(unswizzled_tmp); emit_op(c, OPCODE_SWZ, inst->DstReg, SATURATE_OFF, /* saturate already done above */ - src_swizzle4(tmpsrc, c->key.tex_swizzles[unit]), + src_swizzle4(tmpsrc, c->key.tex.swizzles[unit]), src_undef(), src_undef()); } -- 2.30.2