[Mesa-dev] [PATCH 1/3] glsl: Implement ARB_texture_query_lod
Matt Turner
mattst88 at gmail.com
Tue Mar 19 11:51:55 PDT 2013
From: Dave Airlie <airlied at gmail.com>
v2 [mattst88]:
- Rebase.
- #define GL_ARB_texture_query_lod to 1.
- Remove comma after ir_lod in ir.h for MSVC.
- Handled ir_lod in ir_hv_accept.cpp, ir_rvalue_visitor.cpp,
opt_tree_grafting.cpp.
- Rename textureQueryLOD to textureQueryLod, see
https://www.khronos.org/bugzilla/show_bug.cgi?id=821
- Fix ir_reader of (lod ...).
Reviewed-by: Matt Turner <mattst88 at gmail.com>
---
The current ARB_texture_query_lod spec defines textureQueryLOD
and the original 4.0 spec did as well. The most recent revision
of the 4.0 spec and all subsequent 4.x specs define textureQueryLod.
This seems to have been a typo, since it was corrected in the 4.0 spec.
Khronos bug 821 (see above link) attempts to make the same correction
to the spec.
I haven't yet run the piglit compiler tests on proprietary drivers, but
output of strings run on their binaries tells me that Nvidia only
implements textureQueryLod (while still exposing ARB_texture_query_lod)
and AMD implements both. Seems sensible to fix the spec and only
implement the name that is used by 4.0+.
The spec also states that EXT_gpu_shader4 is required, but we believe
they meant that GLSL 1.30 *or* EXT_gpu_shader4 is required.
.../builtins/profiles/ARB_texture_query_lod.frag | 38 +++++++++++++++++++
src/glsl/builtins/tools/generate_builtins.py | 1 +
src/glsl/builtins/tools/texture_builtins.py | 40 ++++++++++++++-----
src/glsl/glcpp/glcpp-parse.y | 3 +
src/glsl/glsl_parser_extras.cpp | 1 +
src/glsl/glsl_parser_extras.h | 2 +
src/glsl/ir.cpp | 5 ++-
src/glsl/ir.h | 4 +-
src/glsl/ir_clone.cpp | 1 +
src/glsl/ir_hv_accept.cpp | 1 +
src/glsl/ir_print_visitor.cpp | 1 +
src/glsl/ir_reader.cpp | 14 ++++--
src/glsl/ir_rvalue_visitor.cpp | 1 +
src/glsl/opt_tree_grafting.cpp | 1 +
src/glsl/standalone_scaffolding.cpp | 1 +
src/mesa/main/extensions.c | 1 +
src/mesa/main/mtypes.h | 1 +
17 files changed, 98 insertions(+), 18 deletions(-)
create mode 100644 src/glsl/builtins/profiles/ARB_texture_query_lod.frag
diff --git a/src/glsl/builtins/profiles/ARB_texture_query_lod.frag b/src/glsl/builtins/profiles/ARB_texture_query_lod.frag
new file mode 100644
index 0000000..99348fb
--- /dev/null
+++ b/src/glsl/builtins/profiles/ARB_texture_query_lod.frag
@@ -0,0 +1,38 @@
+#version 130
+#extension GL_ARB_texture_query_lod : enable
+#extension GL_ARB_texture_cube_map_array : enable
+
+vec2 textureQueryLod( sampler1D sampler, float coord);
+vec2 textureQueryLod(isampler1D sampler, float coord);
+vec2 textureQueryLod(usampler1D sampler, float coord);
+
+vec2 textureQueryLod( sampler2D sampler, vec2 coord);
+vec2 textureQueryLod(isampler2D sampler, vec2 coord);
+vec2 textureQueryLod(usampler2D sampler, vec2 coord);
+
+vec2 textureQueryLod( sampler3D sampler, vec3 coord);
+vec2 textureQueryLod(isampler3D sampler, vec3 coord);
+vec2 textureQueryLod(usampler3D sampler, vec3 coord);
+
+vec2 textureQueryLod( samplerCube sampler, vec3 coord);
+vec2 textureQueryLod(isamplerCube sampler, vec3 coord);
+vec2 textureQueryLod(usamplerCube sampler, vec3 coord);
+
+vec2 textureQueryLod( sampler1DArray sampler, float coord);
+vec2 textureQueryLod(isampler1DArray sampler, float coord);
+vec2 textureQueryLod(usampler1DArray sampler, float coord);
+
+vec2 textureQueryLod( sampler2DArray sampler, vec2 coord);
+vec2 textureQueryLod(isampler2DArray sampler, vec2 coord);
+vec2 textureQueryLod(usampler2DArray sampler, vec2 coord);
+
+vec2 textureQueryLod( samplerCubeArray sampler, vec3 coord);
+vec2 textureQueryLod(isamplerCubeArray sampler, vec3 coord);
+vec2 textureQueryLod(usamplerCubeArray sampler, vec3 coord);
+
+vec2 textureQueryLod(sampler1DShadow sampler, float coord);
+vec2 textureQueryLod(sampler2DShadow sampler, vec2 coord);
+vec2 textureQueryLod(samplerCubeShadow sampler, vec3 coord);
+vec2 textureQueryLod(sampler1DArrayShadow sampler, float coord);
+vec2 textureQueryLod(sampler2DArrayShadow sampler, vec2 coord);
+vec2 textureQueryLod(samplerCubeArrayShadow sampler, vec3 coord);
diff --git a/src/glsl/builtins/tools/generate_builtins.py b/src/glsl/builtins/tools/generate_builtins.py
index 6da29c0..9062f27 100755
--- a/src/glsl/builtins/tools/generate_builtins.py
+++ b/src/glsl/builtins/tools/generate_builtins.py
@@ -191,6 +191,7 @@ read_builtins(GLenum target, const char *protos, const char **functions, unsigne
st->ARB_texture_cube_map_array_enable = true;
st->ARB_shading_language_packing_enable = true;
st->ARB_texture_multisample_enable = true;
+ st->ARB_texture_query_lod_enable = true;
_mesa_glsl_initialize_types(st);
sh->ir = new(sh) exec_list;
diff --git a/src/glsl/builtins/tools/texture_builtins.py b/src/glsl/builtins/tools/texture_builtins.py
index f32391d..c50fe19 100755
--- a/src/glsl/builtins/tools/texture_builtins.py
+++ b/src/glsl/builtins/tools/texture_builtins.py
@@ -33,29 +33,29 @@ def get_sampler_dim(sampler_type):
# Get the coordinate dimension for a given sampler type.
# Array samplers also get +1 here since the layer is really an extra coordinate
-def get_coord_dim(sampler_type):
+def get_coord_dim(sampler_type, tex_inst):
coord_dim = get_sampler_dim(sampler_type)
- if sampler_type.find("Array") != -1:
+ if sampler_type.find("Array") != -1 and tex_inst != "lod":
coord_dim += 1
return coord_dim
# Get the number of extra vector components (i.e. shadow comparitor)
-def get_extra_dim(sampler_type, use_proj, unused_fields):
+def get_extra_dim(sampler_type, use_proj, unused_fields, tex_inst):
extra_dim = unused_fields
if sampler_type == "CubeArrayShadow":
return 0
- if sampler_type.find("Shadow") != -1:
+ if sampler_type.find("Shadow") != -1 and tex_inst != "lod":
extra_dim += 1
if use_proj:
extra_dim += 1
return extra_dim
-def get_txs_dim(sampler_type):
+def get_txs_dim(sampler_type, tex_inst):
if sampler_type.startswith("CubeArray"):
return 3
if sampler_type.startswith("Cube"):
return 2
- return get_coord_dim(sampler_type)
+ return get_coord_dim(sampler_type, tex_inst)
def has_lod(sampler_type):
if 'Buffer' in sampler_type: return False
@@ -64,14 +64,16 @@ def has_lod(sampler_type):
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)
+ coord_dim = get_coord_dim(sampler_type, tex_inst)
+ extra_dim = get_extra_dim(sampler_type, variant & Proj, unused_fields, tex_inst)
sampler_dim = get_sampler_dim(sampler_type)
if variant & Single:
return_type = "float"
elif tex_inst == "txs":
- return_type = vec_type("i", get_txs_dim(sampler_type))
+ return_type = vec_type("i", get_txs_dim(sampler_type, tex_inst))
+ elif tex_inst == "lod":
+ return_type = "vec2"
else:
return_type = g + "vec4"
@@ -108,14 +110,14 @@ def generate_sigs(g, tex_inst, sampler_type, variant = 0, unused_fields = 0):
else:
print "(var_ref P)",
- if tex_inst not in ['txf_ms', 'txs']:
+ if tex_inst not in ['txf_ms', 'txs', 'lod']:
# Coordinate offset
if variant & Offset:
print "(var_ref offset)",
else:
print "0",
- if tex_inst not in ['txf', 'txf_ms', 'txs']:
+ if tex_inst not in ['txf', 'txf_ms', 'txs', 'lod']:
# Projective divisor
if variant & Proj:
print "(swiz " + "xyzw"[coord_dim + extra_dim-1] + " (var_ref P))",
@@ -635,6 +637,22 @@ def generate_texture_functions(fs):
generate_sigs("", "txl", "2DShadow", Proj)
end_function(fs, "shadow2DProjLod")
+ start_function("textureQueryLod")
+ generate_fiu_sigs("lod", "1D")
+ generate_fiu_sigs("lod", "2D")
+ generate_fiu_sigs("lod", "3D")
+ generate_fiu_sigs("lod", "Cube")
+ generate_fiu_sigs("lod", "1DArray")
+ generate_fiu_sigs("lod", "2DArray")
+ generate_fiu_sigs("lod", "CubeArray")
+ generate_sigs("", "lod", "1DShadow")
+ generate_sigs("", "lod", "2DShadow")
+ generate_sigs("", "lod", "CubeShadow")
+ generate_sigs("", "lod", "1DArrayShadow")
+ generate_sigs("", "lod", "2DArrayShadow")
+ generate_sigs("", "lod", "CubeArrayShadow")
+ end_function(fs, "textureQueryLod")
+
sys.stdout = sys.__stdout__
return fs
diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y
index d6afe88..00edbbf 100644
--- a/src/glsl/glcpp/glcpp-parse.y
+++ b/src/glsl/glcpp/glcpp-parse.y
@@ -1233,6 +1233,9 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api)
if (extensions->ARB_texture_multisample)
add_builtin_define(parser, "GL_ARB_texture_multisample", 1);
+
+ if (extensions->ARB_texture_query_lod)
+ add_builtin_define(parser, "GL_ARB_texture_query_lod", 1);
}
}
diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp
index 56082f7..9740903 100644
--- a/src/glsl/glsl_parser_extras.cpp
+++ b/src/glsl/glsl_parser_extras.cpp
@@ -467,6 +467,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
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),
+ EXT(ARB_texture_query_lod, false, false, true, true, false, ARB_texture_query_lod),
};
#undef EXT
diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h
index 1765cdf..95891b5 100644
--- a/src/glsl/glsl_parser_extras.h
+++ b/src/glsl/glsl_parser_extras.h
@@ -282,6 +282,8 @@ struct _mesa_glsl_parse_state {
bool ARB_shading_language_packing_warn;
bool ARB_texture_multisample_enable;
bool ARB_texture_multisample_warn;
+ bool ARB_texture_query_lod_enable;
+ bool ARB_texture_query_lod_warn;
/*@}*/
/** Extensions supported by the OpenGL implementation. */
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index 2eb3af6..220a59d 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -1307,7 +1307,7 @@ ir_dereference::is_lvalue() const
}
-static const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txf_ms", "txs" };
+static const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txf_ms", "txs", "lod" };
const char *ir_texture::opcode_string()
{
@@ -1338,6 +1338,9 @@ ir_texture::set_sampler(ir_dereference *sampler, const glsl_type *type)
if (this->op == ir_txs) {
assert(type->base_type == GLSL_TYPE_INT);
+ } else if (this->op == ir_lod) {
+ assert(type->vector_elements == 2);
+ assert(type->base_type == GLSL_TYPE_FLOAT);
} else {
assert(sampler->type->sampler_type == (int) type->base_type);
if (sampler->type->sampler_shadow)
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 393b486..f14f5f8 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -1425,7 +1425,8 @@ enum ir_texture_opcode {
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 */
+ ir_txs, /**< Texture size */
+ ir_lod /**< Texture lod query */
};
@@ -1449,6 +1450,7 @@ enum ir_texture_opcode {
* (txf_ms
* <type> <sampler> <coordinate> <sample_index>)
* (txs <type> <sampler> <lod>)
+ * (lod <type> <sampler> <coordinate>)
*/
class ir_texture : public ir_rvalue {
public:
diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp
index 4797451..5b42935 100644
--- a/src/glsl/ir_clone.cpp
+++ b/src/glsl/ir_clone.cpp
@@ -243,6 +243,7 @@ ir_texture::clone(void *mem_ctx, struct hash_table *ht) const
switch (this->op) {
case ir_tex:
+ case ir_lod:
break;
case ir_txb:
new_tex->lod_info.bias = this->lod_info.bias->clone(mem_ctx, ht);
diff --git a/src/glsl/ir_hv_accept.cpp b/src/glsl/ir_hv_accept.cpp
index 5fa7501..559b71a 100644
--- a/src/glsl/ir_hv_accept.cpp
+++ b/src/glsl/ir_hv_accept.cpp
@@ -213,6 +213,7 @@ ir_texture::accept(ir_hierarchical_visitor *v)
switch (this->op) {
case ir_tex:
+ case ir_lod:
break;
case ir_txb:
s = this->lod_info.bias->accept(v);
diff --git a/src/glsl/ir_print_visitor.cpp b/src/glsl/ir_print_visitor.cpp
index 3bdea9b..597d281 100644
--- a/src/glsl/ir_print_visitor.cpp
+++ b/src/glsl/ir_print_visitor.cpp
@@ -278,6 +278,7 @@ void ir_print_visitor::visit(ir_texture *ir)
switch (ir->op)
{
case ir_tex:
+ case ir_lod:
break;
case ir_txb:
ir->lod_info.bias->accept(this);
diff --git a/src/glsl/ir_reader.cpp b/src/glsl/ir_reader.cpp
index 22ce03b..16fdc41 100644
--- a/src/glsl/ir_reader.cpp
+++ b/src/glsl/ir_reader.cpp
@@ -917,6 +917,8 @@ ir_reader::read_texture(s_expression *expr)
s_pattern tex_pattern[] =
{ "tex", s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow };
+ s_pattern lod_pattern[] =
+ { "lod", s_type, s_sampler, s_coord };
s_pattern txf_pattern[] =
{ "txf", s_type, s_sampler, s_coord, s_offset, s_lod };
s_pattern txf_ms_pattern[] =
@@ -926,7 +928,9 @@ ir_reader::read_texture(s_expression *expr)
s_pattern other_pattern[] =
{ tag, s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow, s_lod };
- if (MATCH(expr, tex_pattern)) {
+ if (MATCH(expr, lod_pattern)) {
+ op = ir_lod;
+ } else if (MATCH(expr, tex_pattern)) {
op = ir_tex;
} else if (MATCH(expr, txf_pattern)) {
op = ir_txf;
@@ -939,7 +943,7 @@ ir_reader::read_texture(s_expression *expr)
if (op == -1)
return NULL;
} else {
- ir_read_error(NULL, "unexpected texture pattern");
+ ir_read_error(NULL, "unexpected texture pattern %s", tag->value());
return NULL;
}
@@ -971,7 +975,7 @@ ir_reader::read_texture(s_expression *expr)
return NULL;
}
- if (op != ir_txf_ms) {
+ if (op != ir_txf_ms && op != ir_lod) {
// 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) {
@@ -984,7 +988,7 @@ ir_reader::read_texture(s_expression *expr)
}
}
- if (op != ir_txf && op != ir_txf_ms && op != ir_txs) {
+ if (op != ir_txf && op != ir_txf_ms && op != ir_txs && op != ir_lod) {
s_int *proj_as_int = SX_AS_INT(s_proj);
if (proj_as_int && proj_as_int->value() == 1) {
tex->projector = NULL;
@@ -1054,7 +1058,7 @@ ir_reader::read_texture(s_expression *expr)
break;
}
default:
- // tex doesn't have any extra parameters.
+ // tex and lod don't have any extra parameters.
break;
};
return tex;
diff --git a/src/glsl/ir_rvalue_visitor.cpp b/src/glsl/ir_rvalue_visitor.cpp
index 543c544..3504a4d 100644
--- a/src/glsl/ir_rvalue_visitor.cpp
+++ b/src/glsl/ir_rvalue_visitor.cpp
@@ -57,6 +57,7 @@ ir_rvalue_base_visitor::rvalue_visit(ir_texture *ir)
switch (ir->op) {
case ir_tex:
+ case ir_lod:
break;
case ir_txb:
handle_rvalue(&ir->lod_info.bias);
diff --git a/src/glsl/opt_tree_grafting.cpp b/src/glsl/opt_tree_grafting.cpp
index 9855401..9aceb13 100644
--- a/src/glsl/opt_tree_grafting.cpp
+++ b/src/glsl/opt_tree_grafting.cpp
@@ -274,6 +274,7 @@ ir_tree_grafting_visitor::visit_enter(ir_texture *ir)
switch (ir->op) {
case ir_tex:
+ case ir_lod:
break;
case ir_txb:
if (do_graft(&ir->lod_info.bias))
diff --git a/src/glsl/standalone_scaffolding.cpp b/src/glsl/standalone_scaffolding.cpp
index b5ef768..0c1f52f 100644
--- a/src/glsl/standalone_scaffolding.cpp
+++ b/src/glsl/standalone_scaffolding.cpp
@@ -103,6 +103,7 @@ void initialize_context_to_defaults(struct gl_context *ctx, gl_api api)
ctx->Extensions.OES_standard_derivatives = true;
ctx->Extensions.ARB_texture_cube_map_array = true;
ctx->Extensions.ARB_texture_multisample = true;
+ ctx->Extensions.ARB_texture_query_lod = true;
ctx->Const.GLSLVersion = 120;
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index e90a296..3116692 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -144,6 +144,7 @@ static const struct extension extension_table[] = {
{ "GL_ARB_texture_mirrored_repeat", o(dummy_true), GLL, 2001 },
{ "GL_ARB_texture_multisample", o(ARB_texture_multisample), GL, 2009 },
{ "GL_ARB_texture_non_power_of_two", o(ARB_texture_non_power_of_two), GL, 2003 },
+ { "GL_ARB_texture_query_lod", o(ARB_texture_query_lod), GL, 2009 },
{ "GL_ARB_texture_rectangle", o(NV_texture_rectangle), GL, 2004 },
{ "GL_ARB_texture_rgb10_a2ui", o(ARB_texture_rgb10_a2ui), GL, 2009 },
{ "GL_ARB_texture_rg", o(ARB_texture_rg), GL, 2008 },
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 4f09513..8540f1d 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -3109,6 +3109,7 @@ struct gl_extensions
GLboolean ARB_texture_float;
GLboolean ARB_texture_multisample;
GLboolean ARB_texture_non_power_of_two;
+ GLboolean ARB_texture_query_lod;
GLboolean ARB_texture_rg;
GLboolean ARB_texture_rgb10_a2ui;
GLboolean ARB_texture_storage;
--
1.7.8.6
More information about the mesa-dev
mailing list