GLSL_SAMPLER_DIM_CUBE, 0, 1, GLSL_TYPE_UINT, "usamplerCubeArray"),
};
/*@}*/
+
+/** \name Sampler types added by GL_ARB_texture_multisample
+ */
+/*@{*/
+const glsl_type glsl_type::builtin_ARB_texture_multisample_types[] = {
+ glsl_type(GL_SAMPLER_2D_MULTISAMPLE,
+ GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_FLOAT, "sampler2DMS"),
+ glsl_type(GL_INT_SAMPLER_2D_MULTISAMPLE,
+ GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_INT, "isampler2DMS"),
+ glsl_type(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE,
+ GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_UINT, "usampler2DMS"),
+ glsl_type(GL_SAMPLER_2D_MULTISAMPLE_ARRAY,
+ GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_FLOAT, "sampler2DMSArray"),
+ glsl_type(GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY,
+ GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_INT, "isampler2DMSArray"),
+ glsl_type(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY,
+ GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_UINT, "usampler2DMSArray"),
+};
+/*@}*/
--- /dev/null
+#version 130
+#extension GL_ARB_texture_multisample : enable
+
+ivec2 textureSize( sampler2DMS sampler);
+ivec2 textureSize(isampler2DMS sampler);
+ivec2 textureSize(usampler2DMS sampler);
+
+ivec3 textureSize( sampler2DMSArray sampler);
+ivec3 textureSize(isampler2DMSArray sampler);
+ivec3 textureSize(usampler2DMSArray sampler);
+
+ vec4 texelFetch( sampler2DMS sampler, ivec2 P, int sample);
+ivec4 texelFetch(isampler2DMS sampler, ivec2 P, int sample);
+uvec4 texelFetch(usampler2DMS sampler, ivec2 P, int sample);
+
+ vec4 texelFetch( sampler2DMSArray sampler, ivec3 P, int sample);
+ivec4 texelFetch(isampler2DMSArray sampler, ivec3 P, int sample);
+uvec4 texelFetch(usampler2DMSArray sampler, ivec3 P, int sample);
st->ARB_shader_bit_encoding_enable = true;
st->ARB_texture_cube_map_array_enable = true;
st->ARB_shading_language_packing_enable = true;
+ st->ARB_texture_multisample_enable = true;
_mesa_glsl_initialize_types(st);
sh->ir = new(sh) exec_list;
return 2
return get_coord_dim(sampler_type)
+def has_lod(sampler_type):
+ if 'Buffer' in sampler_type: return False
+ if 'Rect' in sampler_type: return False
+ if 'MS' in sampler_type: return False
+ return True
+
def generate_sigs(g, tex_inst, sampler_type, variant = 0, unused_fields = 0):
coord_dim = get_coord_dim(sampler_type)
extra_dim = get_extra_dim(sampler_type, variant & Proj, unused_fields)
print " (parameters"
print " (declare (in) " + g + "sampler" + sampler_type + " sampler)",
if tex_inst != "txs":
- print "\n (declare (in) " + vec_type("i" if tex_inst == "txf" else "", coord_dim + extra_dim) + " P)",
+ print "\n (declare (in) " + vec_type("i" if tex_inst in ['txf','txf_ms'] else "", coord_dim + extra_dim) + " P)",
if tex_inst == "txl":
print "\n (declare (in) float lod)",
- elif ((tex_inst == "txf" or tex_inst == "txs") and "Buffer" not in sampler_type and "Rect" not in sampler_type):
+ elif tex_inst in ['txf', 'txs'] and has_lod(sampler_type):
print "\n (declare (in) int lod)",
+ elif tex_inst == "txf_ms":
+ print "\n (declare (in) int sample)",
elif tex_inst == "txd":
grad_type = vec_type("", sampler_dim)
print "\n (declare (in) " + grad_type + " dPdx)",
else:
print "(var_ref P)",
+ if tex_inst not in ['txf_ms', 'txs']:
+ # Coordinate offset
if variant & Offset:
print "(var_ref offset)",
else:
print "0",
- if tex_inst != "txf" and tex_inst != "txs":
+ if tex_inst not in ['txf', 'txf_ms', 'txs']:
# Projective divisor
if variant & Proj:
print "(swiz " + "xyzw"[coord_dim + extra_dim-1] + " (var_ref P))",
# Bias/explicit LOD/gradient:
if tex_inst == "txb":
print "(var_ref bias)",
- elif tex_inst == "txs" or tex_inst == "txf":
- if "Rect" not in sampler_type and "Buffer" not in sampler_type:
+ elif tex_inst in ['txs', 'txf', 'txf_ms']:
+ if has_lod(sampler_type):
print "(var_ref lod)",
+ elif tex_inst == 'txf_ms':
+ print "(var_ref sample)",
else:
- print "(constant int (0))"
+ print "(constant int (0))",
elif tex_inst == "txl":
print "(var_ref lod)",
elif tex_inst == "txd":
generate_fiu_sigs("txs", "Buffer")
generate_fiu_sigs("txs", "CubeArray")
generate_sigs("", "txs", "CubeArrayShadow")
+ generate_fiu_sigs("txs", "2DMS")
+ generate_fiu_sigs("txs", "2DMSArray")
end_function(fs, "textureSize")
start_function("texture")
generate_fiu_sigs("txf", "1DArray")
generate_fiu_sigs("txf", "2DArray")
generate_fiu_sigs("txf", "Buffer")
+ generate_fiu_sigs("txf_ms", "2DMS")
+ generate_fiu_sigs("txf_ms", "2DMSArray")
end_function(fs, "texelFetch")
start_function("texelFetchOffset")
if (extensions->ARB_shading_language_packing)
add_builtin_define(parser, "GL_ARB_shading_language_packing", 1);
+
+ if (extensions->ARB_texture_multisample)
+ add_builtin_define(parser, "GL_ARB_texture_multisample", 1);
}
}
usampler1DArray KEYWORD(130, 300, 130, 0, USAMPLER1DARRAY);
usampler2DArray KEYWORD(130, 300, 130, 300, USAMPLER2DARRAY);
+ /* additional keywords in ARB_texture_multisample, included in GLSL 1.50 */
+ /* these are reserved but not defined in GLSL 3.00 */
+sampler2DMS KEYWORD_WITH_ALT(150, 300, 150, 0, yyextra->ARB_texture_multisample_enable, SAMPLER2DMS);
+isampler2DMS KEYWORD_WITH_ALT(150, 300, 150, 0, yyextra->ARB_texture_multisample_enable, ISAMPLER2DMS);
+usampler2DMS KEYWORD_WITH_ALT(150, 300, 150, 0, yyextra->ARB_texture_multisample_enable, USAMPLER2DMS);
+sampler2DMSArray KEYWORD_WITH_ALT(150, 300, 150, 0, yyextra->ARB_texture_multisample_enable, SAMPLER2DMSARRAY);
+isampler2DMSArray KEYWORD_WITH_ALT(150, 300, 150, 0, yyextra->ARB_texture_multisample_enable, ISAMPLER2DMSARRAY);
+usampler2DMSArray KEYWORD_WITH_ALT(150, 300, 150, 0, yyextra->ARB_texture_multisample_enable, USAMPLER2DMSARRAY);
+
samplerCubeArray {
if (yyextra->ARB_texture_cube_map_array_enable)
return SAMPLERCUBEARRAY;
patch KEYWORD(0, 300, 0, 0, PATCH);
sample KEYWORD(0, 300, 0, 0, SAMPLE);
subroutine KEYWORD(0, 300, 0, 0, SUBROUTINE);
-sampler2DMS KEYWORD(0, 300, 0, 0, SAMPLER2DMS);
-isampler2DMS KEYWORD(0, 300, 0, 0, ISAMPLER2DMS);
-usampler2DMS KEYWORD(0, 300, 0, 0, USAMPLER2DMS);
-sampler2DMSArray KEYWORD(0, 300, 0, 0, SAMPLER2DMSARRAY);
-isampler2DMSArray KEYWORD(0, 300, 0, 0, ISAMPLER2DMSARRAY);
-usampler2DMSArray KEYWORD(0, 300, 0, 0, USAMPLER2DMSARRAY);
[_a-zA-Z][_a-zA-Z0-9]* {
%token USAMPLER2DARRAY USAMPLERCUBEARRAY
%token SAMPLER2DRECT ISAMPLER2DRECT USAMPLER2DRECT SAMPLER2DRECTSHADOW
%token SAMPLERBUFFER ISAMPLERBUFFER USAMPLERBUFFER
+%token SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS
+%token SAMPLER2DMSARRAY ISAMPLER2DMSARRAY USAMPLER2DMSARRAY
%token SAMPLEREXTERNALOES
%token STRUCT VOID_TOK WHILE
%token <identifier> IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
%token SAMPLER3DRECT
%token SIZEOF CAST NAMESPACE USING
%token COHERENT RESTRICT READONLY WRITEONLY RESOURCE ATOMIC_UINT PATCH SAMPLE
-%token SUBROUTINE SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS SAMPLER2DMSARRAY
-%token ISAMPLER2DMSARRAY USAMPLER2DMSARRAY
+%token SUBROUTINE
%token ERROR_TOK
| USAMPLER2DARRAY { $$ = "usampler2DArray"; }
| USAMPLERBUFFER { $$ = "usamplerBuffer"; }
| USAMPLERCUBEARRAY { $$ = "usamplerCubeArray"; }
+ | SAMPLER2DMS { $$ = "sampler2DMS"; }
+ | ISAMPLER2DMS { $$ = "isampler2DMS"; }
+ | USAMPLER2DMS { $$ = "usampler2DMS"; }
+ | SAMPLER2DMSARRAY { $$ = "sampler2DMSArray"; }
+ | ISAMPLER2DMSARRAY { $$ = "isampler2DMSArray"; }
+ | USAMPLER2DMSARRAY { $$ = "usampler2DMSArray"; }
;
precision_qualifier:
EXT(OES_standard_derivatives, false, false, true, false, true, OES_standard_derivatives),
EXT(ARB_texture_cube_map_array, true, false, true, true, false, ARB_texture_cube_map_array),
EXT(ARB_shading_language_packing, true, false, true, true, false, ARB_shading_language_packing),
+ EXT(ARB_texture_multisample, true, false, true, true, false, ARB_texture_multisample),
};
#undef EXT
bool ARB_texture_cube_map_array_warn;
bool ARB_shading_language_packing_enable;
bool ARB_shading_language_packing_warn;
+ bool ARB_texture_multisample_enable;
+ bool ARB_texture_multisample_warn;
/*@}*/
/** Extensions supported by the OpenGL implementation. */
return TEXTURE_BUFFER_INDEX;
case GLSL_SAMPLER_DIM_EXTERNAL:
return TEXTURE_EXTERNAL_INDEX;
+ case GLSL_SAMPLER_DIM_MS:
+ return (t->sampler_array) ? TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX : TEXTURE_2D_MULTISAMPLE_INDEX;
default:
assert(!"Should not get here.");
return TEXTURE_BUFFER_INDEX;
warn, skip_1d);
}
+void
+glsl_type::generate_ARB_texture_multisample_types(glsl_symbol_table *symtab,
+ bool warn)
+{
+ bool skip_1d = false;
+ add_types_to_symbol_table(symtab, builtin_ARB_texture_multisample_types,
+ Elements(builtin_ARB_texture_multisample_types),
+ warn, skip_1d);
+}
+
void
_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state)
{
glsl_type::generate_ARB_texture_cube_map_array_types(state->symbols,
state->ARB_texture_cube_map_array_warn);
}
+
+ if (state->ARB_texture_multisample_enable) {
+ glsl_type::generate_ARB_texture_multisample_types(state->symbols,
+ state->ARB_texture_multisample_warn);
+ }
}
GLSL_SAMPLER_DIM_CUBE,
GLSL_SAMPLER_DIM_RECT,
GLSL_SAMPLER_DIM_BUF,
- GLSL_SAMPLER_DIM_EXTERNAL
+ GLSL_SAMPLER_DIM_EXTERNAL,
+ GLSL_SAMPLER_DIM_MS
};
enum glsl_interface_packing {
static const glsl_type builtin_EXT_texture_buffer_object_types[];
static const glsl_type builtin_OES_EGL_image_external_types[];
static const glsl_type builtin_ARB_texture_cube_map_array_types[];
+ static const glsl_type builtin_ARB_texture_multisample_types[];
/*@}*/
/**
static void generate_OES_texture_3D_types(glsl_symbol_table *, bool);
static void generate_OES_EGL_image_external_types(glsl_symbol_table *, bool);
static void generate_ARB_texture_cube_map_array_types(glsl_symbol_table *, bool);
+ static void generate_ARB_texture_multisample_types(glsl_symbol_table *, bool);
/*@}*/
/**
}
-static const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txs" };
+static const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txf_ms", "txs" };
const char *ir_texture::opcode_string()
{
ir_txl, /**< Texture look-up with explicit LOD */
ir_txd, /**< Texture look-up with partial derivatvies */
ir_txf, /**< Texel fetch with explicit LOD */
+ ir_txf_ms, /**< Multisample texture fetch */
ir_txs /**< Texture size */
};
* (txl <type> <sampler> <coordinate> 0 1 ( ) <lod>)
* (txd <type> <sampler> <coordinate> 0 1 ( ) (dPdx dPdy))
* (txf <type> <sampler> <coordinate> 0 <lod>)
+ * (txf_ms
+ * <type> <sampler> <coordinate> <sample_index>)
* (txs <type> <sampler> <lod>)
*/
class ir_texture : public ir_rvalue {
union {
ir_rvalue *lod; /**< Floating point LOD */
ir_rvalue *bias; /**< Floating point LOD bias */
+ ir_rvalue *sample_index; /**< MSAA sample index */
struct {
ir_rvalue *dPdx; /**< Partial derivative of coordinate wrt X */
ir_rvalue *dPdy; /**< Partial derivative of coordinate wrt Y */
case ir_txs:
new_tex->lod_info.lod = this->lod_info.lod->clone(mem_ctx, ht);
break;
+ case ir_txf_ms:
+ new_tex->lod_info.sample_index = this->lod_info.sample_index->clone(mem_ctx, ht);
+ break;
case ir_txd:
new_tex->lod_info.grad.dPdx = this->lod_info.grad.dPdx->clone(mem_ctx, ht);
new_tex->lod_info.grad.dPdy = this->lod_info.grad.dPdy->clone(mem_ctx, ht);
if (s != visit_continue)
return (s == visit_continue_with_parent) ? visit_continue : s;
break;
+ case ir_txf_ms:
+ s = this->lod_info.sample_index->accept(v);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+ break;
case ir_txd:
s = this->lod_info.grad.dPdx->accept(v);
if (s != visit_continue)
printf(" ");
}
- if (ir->op != ir_txf && ir->op != ir_txs) {
+ if (ir->op != ir_txf && ir->op != ir_txf_ms && ir->op != ir_txs) {
if (ir->projector)
ir->projector->accept(this);
else
case ir_txs:
ir->lod_info.lod->accept(this);
break;
+ case ir_txf_ms:
+ ir->lod_info.sample_index->accept(this);
+ break;
case ir_txd:
printf("(");
ir->lod_info.grad.dPdx->accept(this);
s_expression *s_proj = NULL;
s_list *s_shadow = NULL;
s_expression *s_lod = NULL;
+ s_expression *s_sample_index = NULL;
ir_texture_opcode op = ir_tex; /* silence warning */
{ "tex", s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow };
s_pattern txf_pattern[] =
{ "txf", s_type, s_sampler, s_coord, s_offset, s_lod };
+ s_pattern txf_ms_pattern[] =
+ { "txf_ms", s_type, s_sampler, s_coord, s_sample_index };
s_pattern txs_pattern[] =
{ "txs", s_type, s_sampler, s_lod };
s_pattern other_pattern[] =
op = ir_tex;
} else if (MATCH(expr, txf_pattern)) {
op = ir_txf;
+ } else if (MATCH(expr, txf_ms_pattern)) {
+ op = ir_txf_ms;
} else if (MATCH(expr, txs_pattern)) {
op = ir_txs;
} else if (MATCH(expr, other_pattern)) {
return NULL;
}
- // Read texel offset - either 0 or an rvalue.
- s_int *si_offset = SX_AS_INT(s_offset);
- if (si_offset == NULL || si_offset->value() != 0) {
- tex->offset = read_rvalue(s_offset);
- if (tex->offset == NULL) {
- ir_read_error(s_offset, "expected 0 or an expression");
- return NULL;
- }
+ if (op != ir_txf_ms) {
+ // Read texel offset - either 0 or an rvalue.
+ s_int *si_offset = SX_AS_INT(s_offset);
+ if (si_offset == NULL || si_offset->value() != 0) {
+ tex->offset = read_rvalue(s_offset);
+ if (tex->offset == NULL) {
+ ir_read_error(s_offset, "expected 0 or an expression");
+ return NULL;
+ }
+ }
}
}
- if (op != ir_txf && op != ir_txs) {
+ if (op != ir_txf && op != ir_txf_ms && op != ir_txs) {
s_int *proj_as_int = SX_AS_INT(s_proj);
if (proj_as_int && proj_as_int->value() == 1) {
tex->projector = NULL;
return NULL;
}
break;
+ case ir_txf_ms:
+ tex->lod_info.sample_index = read_rvalue(s_sample_index);
+ if (tex->lod_info.sample_index == NULL) {
+ ir_read_error(NULL, "when reading sample_index in (txf_ms ...)");
+ return NULL;
+ }
+ break;
case ir_txd: {
s_expression *s_dx, *s_dy;
s_pattern dxdy_pat[] = { s_dx, s_dy };
case ir_txs:
handle_rvalue(&ir->lod_info.lod);
break;
+ case ir_txf_ms:
+ handle_rvalue(&ir->lod_info.sample_index);
+ break;
case ir_txd:
handle_rvalue(&ir->lod_info.grad.dPdx);
handle_rvalue(&ir->lod_info.grad.dPdy);
if (do_graft(&ir->lod_info.lod))
return visit_stop;
break;
+ case ir_txf_ms:
+ if (do_graft(&ir->lod_info.sample_index))
+ return visit_stop;
+ break;
case ir_txd:
if (do_graft(&ir->lod_info.grad.dPdx) ||
do_graft(&ir->lod_info.grad.dPdy))
ctx->Extensions.ARB_shading_language_packing = true;
ctx->Extensions.OES_standard_derivatives = true;
ctx->Extensions.ARB_texture_cube_map_array = true;
+ ctx->Extensions.ARB_texture_multisample = true;
ctx->Const.GLSLVersion = 120;