From 1df7199fc933facf2e74304976c3798e474929a1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sat, 14 Jun 2014 03:19:26 +0200 Subject: [PATCH] gallium: implement ARB_texture_query_levels The extension is always supported if GLSL 1.30 is supported. Softpipe and llvmpipe support is also added (trivial). Radeon and nouveau support is already done. Reviewed-by: Roland Scheidegger --- docs/GL3.txt | 2 +- docs/relnotes/10.3.html | 1 + src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 2 +- src/gallium/docs/source/tgsi.rst | 6 +++++- src/gallium/drivers/softpipe/sp_tex_sample.c | 3 +++ src/mesa/state_tracker/st_extensions.c | 1 + src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 25 ++++++++++++++++++------- 7 files changed, 30 insertions(+), 10 deletions(-) diff --git a/docs/GL3.txt b/docs/GL3.txt index f2fd114..375b3b5 100644 --- a/docs/GL3.txt +++ b/docs/GL3.txt @@ -172,7 +172,7 @@ GL 4.3: GL_ARB_shader_storage_buffer_object not started GL_ARB_stencil_texturing DONE (i965/gen8+, nv50, nvc0, r600, radeonsi) GL_ARB_texture_buffer_range DONE (nv50, nvc0, i965, r600, radeonsi) - GL_ARB_texture_query_levels DONE (i965) + GL_ARB_texture_query_levels DONE (all drivers that support GLSL 1.30) GL_ARB_texture_storage_multisample DONE (all drivers that support GL_ARB_texture_multisample) GL_ARB_texture_view DONE (i965) GL_ARB_vertex_attrib_binding DONE (all drivers) diff --git a/docs/relnotes/10.3.html b/docs/relnotes/10.3.html index 825eb84..9939301 100644 --- a/docs/relnotes/10.3.html +++ b/docs/relnotes/10.3.html @@ -50,6 +50,7 @@ Note: some of the new features are only available with certain drivers.
  • GL_ARB_stencil_texturing on nv50, nvc0, r600, and radeonsi
  • GL_ARB_texture_cube_map_array on radeonsi
  • GL_ARB_texture_gather on radeonsi
  • +
  • GL_ARB_texture_query_levels on nv50, nvc0, llvmpipe, r600, radeonsi, softpipe
  • GL_ARB_viewport_array on nvc0
  • diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index 0eaa020..3d7df3e 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -2445,7 +2445,7 @@ emit_size_query( struct lp_build_tgsi_soa_context *bld, bld->bld_base.base.gallivm, bld->bld_base.int_bld.type, unit, pipe_target, - is_sviewinfo, + TRUE, lod_property, explicit_lod, sizes_out); diff --git a/src/gallium/docs/source/tgsi.rst b/src/gallium/docs/source/tgsi.rst index 2ca3c3b..2130e08 100644 --- a/src/gallium/docs/source/tgsi.rst +++ b/src/gallium/docs/source/tgsi.rst @@ -964,7 +964,9 @@ XXX doesn't look like most of the opcodes really belong here. As per NV_gpu_program4, retrieve the dimensions of the texture depending on the target. For 1D (width), 2D/RECT/CUBE (width, height), 3D (width, height, - depth), 1D array (width, layers), 2D array (width, height, layers) + depth), 1D array (width, layers), 2D array (width, height, layers). + Also return the number of accessible levels (last_level - first_level + 1) + in W. .. math:: @@ -976,6 +978,8 @@ XXX doesn't look like most of the opcodes really belong here. dst.z = texture\_depth(unit, lod) + dst.w = texture\_levels(unit) + .. opcode:: TG4 - Texture Gather As per ARB_texture_gather, gathers the four texels to be used in a bi-linear diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 274e56b..6d97664 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -2911,6 +2911,9 @@ sp_get_dims(struct sp_sampler_view *sp_sview, int level, if (level > view->u.tex.last_level) return; + if (texture->target != PIPE_BUFFER) + dims[3] = view->u.tex.last_level - view->u.tex.first_level + 1; + dims[0] = u_minify(texture->width0, level); switch(texture->target) { diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index e9a74c5..e938046 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -631,6 +631,7 @@ void st_init_extensions(struct st_context *st) ctx->Extensions.ARB_shading_language_packing = GL_TRUE; ctx->Extensions.OES_depth_texture_cube_map = GL_TRUE; ctx->Extensions.ARB_shading_language_420pack = GL_TRUE; + ctx->Extensions.ARB_texture_query_levels = GL_TRUE; if (!st->options.disable_shader_bit_encoding) { ctx->Extensions.ARB_shader_bit_encoding = GL_TRUE; diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 739e108..cac1e0f 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -2779,7 +2779,9 @@ glsl_to_tgsi_visitor::visit(ir_call *ir) void glsl_to_tgsi_visitor::visit(ir_texture *ir) { - st_src_reg result_src, coord, cube_sc, lod_info, projector, dx, dy, offset[MAX_GLSL_TEXTURE_OFFSET], sample_index, component; + st_src_reg result_src, coord, cube_sc, lod_info, projector, dx, dy; + st_src_reg offset[MAX_GLSL_TEXTURE_OFFSET], sample_index, component; + st_src_reg levels_src; st_dst_reg result_dst, coord_dst, cube_sc_dst; glsl_to_tgsi_instruction *inst = NULL; unsigned opcode = TGSI_OPCODE_NOP; @@ -2860,6 +2862,11 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) ir->lod_info.lod->accept(this); lod_info = this->result; break; + case ir_query_levels: + opcode = TGSI_OPCODE_TXQ; + lod_info = st_src_reg(PROGRAM_IMMEDIATE, 0, GLSL_TYPE_INT); + levels_src = get_temp(ir->type); + break; case ir_txf: opcode = TGSI_OPCODE_TXF; ir->lod_info.lod->accept(this); @@ -2896,9 +2903,6 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) case ir_lod: opcode = TGSI_OPCODE_LODQ; break; - case ir_query_levels: - assert(!"Unexpected ir_query_levels opcode"); - break; } if (ir->projector) { @@ -2995,9 +2999,16 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) if (opcode == TGSI_OPCODE_TXD) inst = emit(ir, opcode, result_dst, coord, dx, dy); - else if (opcode == TGSI_OPCODE_TXQ) - inst = emit(ir, opcode, result_dst, lod_info); - else if (opcode == TGSI_OPCODE_TXF) { + else if (opcode == TGSI_OPCODE_TXQ) { + if (ir->op == ir_query_levels) { + /* the level is stored in W */ + inst = emit(ir, opcode, st_dst_reg(levels_src), lod_info); + result_dst.writemask = WRITEMASK_X; + levels_src.swizzle = SWIZZLE_WWWW; + emit(ir, TGSI_OPCODE_MOV, result_dst, levels_src); + } else + inst = emit(ir, opcode, result_dst, lod_info); + } else if (opcode == TGSI_OPCODE_TXF) { inst = emit(ir, opcode, result_dst, coord); } else if (opcode == TGSI_OPCODE_TXL2 || opcode == TGSI_OPCODE_TXB2) { inst = emit(ir, opcode, result_dst, coord, lod_info); -- 2.7.4