[Mesa-dev] [PATCH] mesa: Use GL_RED for DEPTH_TEXTURE_MODE for #version 300 es shaders.

Kenneth Graunke kenneth at whitecape.org
Mon Jan 21 11:16:22 PST 2013


According to page 163 of the ES 3.0 spec:

"Texture lookups involving textures with depth component data generate
 a texture base color C_b either using depth data directly or by
 performing a comparison with the D_ref value used to perform the
 lookup, as described in section 3.8.15.  The resulting value R_t is
 then expanded to a color C_b = (R_t,0,0,1), ..."

In other words, depth textures are supposed to be treated as GL_RED.

Sadly, the GL_OES_depth_texture extension (for ES 2.0) says:
"Therefore, this extension treats depth textures always as luminance
 textures and no longer supports DEPTH_TEXTURE_MODE."

ES 3.0 is supposed to be backwards compatible with ES 2.0, which means
that we can transparently give applications a ES 3.0 context when they
ask for an ES 2.0 context.  This means that we can't decide the texture
swizzle based on the context version: it would break ES 2.0 applications
that used GL_OES_depth_texture.

Instead, we use the shading language version.  #version 300 es shaders
will use GL_RED, and everything else will use GL_LUMINANCE.  This should
work in both modes.

Unfortunately, this means that our SURFACE_STATE entries for textures
depend on the active shader program, which could mean reuploading all of
them.  However, this was already the case for other reasons, so we
should be no worse off than we already were.

Fixes 4 es3conform tests:
- depth_texture_fbo
- depth_texture_fbo_clear
- depth_texture_teximage
- depth_texture_texsubimage

Cc: Ian Romanick <idr at freedesktop.org>
Cc: Eric Anholt <eric at anholt.net>
---
 src/mesa/drivers/dri/i965/brw_state.h             | 3 ++-
 src/mesa/drivers/dri/i965/brw_wm.c                | 2 +-
 src/mesa/drivers/dri/i965/brw_wm_surface_state.c  | 8 ++++++--
 src/mesa/drivers/dri/i965/gen7_wm_surface_state.c | 4 ++--
 4 files changed, 11 insertions(+), 6 deletions(-)

I believe the BRW_NEW_VERTEX_PROGRAM/BRW_NEW_FRAGMENT_PROGRAM dirty bits
on the brw_texture_surfaces atom should cover my new usage of shProg.
Eric, can you confirm?  I always get confused by _NEW_PROGRAM vs.
CACHE_NEW_WM/VS_PROG vs. BRW_NEW_VERTEX/FRAGMENT_PROGRAM.  Thanks!

diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index c6b8219..d50f35b 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -202,7 +202,8 @@ GLuint translate_tex_format(gl_format mesa_format,
 			    GLenum depth_mode,
 			    GLenum srgb_decode);
 
-int brw_get_texture_swizzle(const struct gl_texture_object *t);
+int brw_get_texture_swizzle(struct gl_context *ctx,
+                            const struct gl_texture_object *t);
 
 /* gen7_wm_surface_state.c */
 uint32_t gen7_surface_tiling_mode(uint32_t tiling);
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index 2891567..4b04465 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -316,7 +316,7 @@ brw_populate_sampler_prog_key_data(struct gl_context *ctx,
           * (except for GL_ALPHA); all other platforms need MOVs in the shader.
           */
          if (!intel->is_haswell || alpha_depth)
-            key->swizzles[s] = brw_get_texture_swizzle(t);
+            key->swizzles[s] = brw_get_texture_swizzle(ctx, t);
 
 	 if (img->InternalFormat == GL_YCBCR_MESA) {
 	    key->yuvtex_mask |= 1 << s;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index 5e99592..b609b09 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -685,8 +685,10 @@ brw_get_surface_num_multisamples(unsigned num_samples)
  * swizzling.
  */
 int
-brw_get_texture_swizzle(const struct gl_texture_object *t)
+brw_get_texture_swizzle(struct gl_context *ctx,
+                        const struct gl_texture_object *t)
 {
+   const struct gl_shader_program *shProg = ctx->Shader._CurrentFragmentProgram;
    const struct gl_texture_image *img = t->Image[0][t->BaseLevel];
 
    int swizzles[SWIZZLE_NIL + 1] = {
@@ -699,9 +701,11 @@ brw_get_texture_swizzle(const struct gl_texture_object *t)
       SWIZZLE_NIL
    };
 
+   GLenum depth_mode = shProg->Version == 300 ? GL_RED : t->DepthMode;
+
    if (img->_BaseFormat == GL_DEPTH_COMPONENT ||
        img->_BaseFormat == GL_DEPTH_STENCIL) {
-      switch (t->DepthMode) {
+      switch (depth_mode) {
       case GL_ALPHA:
          swizzles[0] = SWIZZLE_ZERO;
          swizzles[1] = SWIZZLE_ZERO;
diff --git a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
index 05e9e75..b7258b4 100644
--- a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
@@ -344,8 +344,8 @@ gen7_update_texture_surface(struct gl_context *ctx,
          (firstImage->_BaseFormat == GL_DEPTH_COMPONENT ||
           firstImage->_BaseFormat == GL_DEPTH_STENCIL);
 
-      const int swizzle =
-         unlikely(alpha_depth) ? SWIZZLE_XYZW : brw_get_texture_swizzle(tObj);
+      const int swizzle = unlikely(alpha_depth)
+         ? SWIZZLE_XYZW : brw_get_texture_swizzle(ctx, tObj);
 
 
       surf[7] =
-- 
1.8.1.1



More information about the mesa-dev mailing list