[Mesa-dev] [PATCH 3/3] mesa: Track fixed-function fragment shader as a shader
Ian Romanick
idr at freedesktop.org
Wed Nov 16 11:08:23 PST 2011
From: Ian Romanick <ian.d.romanick at intel.com>
Previously the fixed-function fragment shader was tracked as a
gl_program. This means that it shows up in the driver as a Mesa IR
program instead of as a GLSL IR program. If a driver doesn't generate
Mesa IR from the GLSL IR, that program is empty. If the program is
empty there is either no rendering or a GPU hang.
Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
Cc: Eric Anholt <eric at anholt.net>
---
src/mesa/drivers/dri/i965/brw_wm.c | 2 +-
src/mesa/drivers/dri/i965/brw_wm_state.c | 4 ++--
src/mesa/drivers/dri/i965/gen6_wm_state.c | 4 +++-
src/mesa/drivers/dri/i965/gen7_wm_state.c | 4 +++-
src/mesa/main/mtypes.h | 2 ++
src/mesa/main/shaderapi.c | 29 +++++++++++++++++++++++++++++
src/mesa/main/state.c | 10 ++++++++++
7 files changed, 50 insertions(+), 5 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index 377b8ba..4eccea3 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -520,7 +520,7 @@ brw_upload_wm_prog(struct brw_context *brw)
if (!brw_search_cache(&brw->cache, BRW_WM_PROG,
&key, sizeof(key),
&brw->wm.prog_offset, &brw->wm.prog_data)) {
- bool success = do_wm_prog(brw, ctx->Shader.CurrentFragmentProgram, fp,
+ bool success = do_wm_prog(brw, ctx->Shader._CurrentFragmentProgram, fp,
&key);
(void) success;
assert(success);
diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c
index e1791c2..dd67795 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_state.c
@@ -169,9 +169,9 @@ brw_upload_wm_unit(struct brw_context *brw)
* If using the fragment shader backend, the program is always
* 8-wide. If not, it's always 16.
*/
- if (ctx->Shader.CurrentFragmentProgram) {
+ if (ctx->Shader._CurrentFragmentProgram) {
struct brw_shader *shader = (struct brw_shader *)
- ctx->Shader.CurrentFragmentProgram->_LinkedShaders[MESA_SHADER_FRAGMENT];
+ ctx->Shader._CurrentFragmentProgram->_LinkedShaders[MESA_SHADER_FRAGMENT];
if (shader != NULL && shader->ir != NULL) {
wm->wm5.enable_8_pix = 1;
diff --git a/src/mesa/drivers/dri/i965/gen6_wm_state.c b/src/mesa/drivers/dri/i965/gen6_wm_state.c
index 271a9ae..5312f21 100644
--- a/src/mesa/drivers/dri/i965/gen6_wm_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_wm_state.c
@@ -135,7 +135,9 @@ upload_wm_state(struct brw_context *brw)
dw5 |= GEN6_WM_LINE_END_CAP_AA_WIDTH_0_5;
/* Use ALT floating point mode for ARB fragment programs, because they
- * require 0^0 == 1.
+ * require 0^0 == 1. Even though _CurrentFragmentProgram is used for
+ * rendering, CurrentFragmentProgram is used for this check to
+ * differentiate between the GLSL and non-GLSL cases.
*/
if (ctx->Shader.CurrentFragmentProgram == NULL)
dw2 |= GEN6_WM_FLOATING_POINT_MODE_ALT;
diff --git a/src/mesa/drivers/dri/i965/gen7_wm_state.c b/src/mesa/drivers/dri/i965/gen7_wm_state.c
index f38d2f1..3d34c51 100644
--- a/src/mesa/drivers/dri/i965/gen7_wm_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_wm_state.c
@@ -147,7 +147,9 @@ upload_ps_state(struct brw_context *brw)
dw2 |= (ALIGN(brw->sampler.count, 4) / 4) << GEN7_PS_SAMPLER_COUNT_SHIFT;
/* Use ALT floating point mode for ARB fragment programs, because they
- * require 0^0 == 1.
+ * require 0^0 == 1. Even though _CurrentFragmentProgram is used for
+ * rendering, CurrentFragmentProgram is used for this check to
+ * differentiate between the GLSL and non-GLSL cases.
*/
if (intel->ctx.Shader.CurrentFragmentProgram == NULL)
dw2 |= GEN7_PS_FLOATING_POINT_MODE_ALT;
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 285ec07..3abc2b3 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2301,6 +2301,8 @@ struct gl_shader_state
struct gl_shader_program *CurrentGeometryProgram;
struct gl_shader_program *CurrentFragmentProgram;
+ struct gl_shader_program *_CurrentFragmentProgram;
+
/**
* Program used by glUniform calls.
*
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index c4d01ab..85e3406 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -124,6 +124,8 @@ _mesa_free_shader_state(struct gl_context *ctx)
NULL);
_mesa_reference_shader_program(ctx, &ctx->Shader.CurrentFragmentProgram,
NULL);
+ _mesa_reference_shader_program(ctx, &ctx->Shader._CurrentFragmentProgram,
+ NULL);
_mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL);
}
@@ -876,6 +878,33 @@ use_shader_program(struct gl_context *ctx, GLenum type,
if (*target != shProg) {
FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
+
+ /* If the shader is also bound as the current rendering shader, unbind
+ * it from that binding point as well. This ensures that the correct
+ * semantics of glDeleteProgram are maintained.
+ */
+ switch (type) {
+#if FEATURE_ARB_vertex_shader
+ case GL_VERTEX_SHADER:
+ /* Empty for now. */
+ break;
+#endif
+#if FEATURE_ARB_geometry_shader4
+ case GL_GEOMETRY_SHADER_ARB:
+ /* Empty for now. */
+ break;
+#endif
+#if FEATURE_ARB_fragment_shader
+ case GL_FRAGMENT_SHADER:
+ if (*target == ctx->Shader._CurrentFragmentProgram) {
+ _mesa_reference_shader_program(ctx,
+ &ctx->Shader._CurrentFragmentProgram,
+ NULL);
+ }
+ break;
+#endif
+ }
+
_mesa_reference_shader_program(ctx, target, shProg);
return true;
}
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index 80fd03b..e91350e 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -43,6 +43,7 @@
#include "pixel.h"
#include "program/program.h"
#include "program/prog_parameter.h"
+#include "shaderobj.h"
#include "state.h"
#include "stencil.h"
#include "texenvprogram.h"
@@ -249,12 +250,18 @@ update_program(struct gl_context *ctx)
if (fsProg && fsProg->LinkStatus
&& fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]) {
/* Use GLSL fragment shader */
+ _mesa_reference_shader_program(ctx,
+ &ctx->Shader._CurrentFragmentProgram,
+ fsProg);
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
(struct gl_fragment_program *)
fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program);
}
else if (ctx->FragmentProgram._Enabled) {
/* Use user-defined fragment program */
+ _mesa_reference_shader_program(ctx,
+ &ctx->Shader._CurrentFragmentProgram,
+ NULL);
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
ctx->FragmentProgram.Current);
}
@@ -262,6 +269,9 @@ update_program(struct gl_context *ctx)
/* Use fragment program generated from fixed-function state */
struct gl_shader_program *f = _mesa_get_fixed_func_fragment_program(ctx);
+ _mesa_reference_shader_program(ctx,
+ &ctx->Shader._CurrentFragmentProgram,
+ f);
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
(struct gl_fragment_program *)
f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program);
--
1.7.6.4
More information about the mesa-dev
mailing list