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 <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net> [v1]
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
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) {
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++;
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++;
}
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++;
}
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++;
}
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;
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;
*/
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);
}
/* 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;
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;
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);
}
}
--- /dev/null
+/*
+ * 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
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 )
/* _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 */
#include "program/prog_instruction.h"
#include "brw_context.h"
#include "brw_eu.h"
+#include "brw_program.h"
#define SATURATE (1<<5)
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;
};
/* 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<<i))
* temporary, otherwise writemasking of the real dst could lose some of our
* channels.
*/
- if (c->key.tex_swizzles[unit] != SWIZZLE_NOOP) {
+ if (c->key.tex.swizzles[unit] != SWIZZLE_NOOP) {
unswizzled_tmp = get_temp(c);
} else {
unswizzled_tmp = inst->DstReg;
* 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<<unit);
+ bool swap_uv = c->key.tex.yuvtex_swap_mask & (1 << unit);
/*
CONST C0 = { -.5, -.0625, -.5, 1.164 }
}
/* 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());
}