summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Versace <chad.versace@linux.intel.com>2012-01-25 19:38:10 -0800
committerIan Romanick <ian.d.romanick@intel.com>2012-02-07 10:20:07 -0800
commit20da01fecdd2379bd6df1407d1c344aa8ddd5c45 (patch)
treeb320b89d4730c00171a20d698abfaf6d6d5ddb08
parent203ef2a12b8e8fa520decf9e9024329f4dc96996 (diff)
swrast: Fix fixed-function fragment processing
On i965, _mesa_ir_link_shader is never called. As a consequence, the current fragment program (ctx->FragmentProgram->_Current) exists but is invalid because it has no instructions. Yet swrast continued to attempt to use the empty program. To avoid using the empty program, this patch 1) defines a new function, _swrast_use_fragment_program, which checks if the current fragment program exists and differs from the fixed function fragment program, and, when appropriate, 2) replaces checks of the form if (ctx->FragmentProgram->_Current == NULL) with if (_swrast_use_fragment_program(ctx)) Fixes the following oglconform regressions on i965/gen6: api-fogcoord(basic.allCases.log) api-mtexcoord(basic.allCases.log) api-seccolor(basic.allCases.log) api-texcoord(basic.allCases.log) blend-separate(basic.allCases) colorsum(basic.allCases.log) The tests were ran with the GLXFBConfig: visual x bf lv rg d st colorbuffer sr ax dp st accumbuffer ms cav id dep cl sp sz l ci b ro r g b a F gb bf th cl r g b a ns b eat ---------------------------------------------------------------------------- 0x021 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None (Note: I originally believed that the hunk in _swrast_update_fragment_program was unnecessary. But it is required to fix blend-separate.) Note: This is a candidate for the 8.0 branch. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=43327 Reveiwed-by: Eric Anholt <eric@anholt.net> Reviewed-by: Ian Romanick <idr@freedesktop.org> Signed-off-by: Chad Versace <chad.versace@linux.intel.com> (cherry picked from commit 1c0f1dd42a50464eeb81de4aad8eecf24b3d6c89)
-rw-r--r--src/mesa/swrast/s_aaline.c2
-rw-r--r--src/mesa/swrast/s_aalinetemp.h2
-rw-r--r--src/mesa/swrast/s_aatriangle.c2
-rw-r--r--src/mesa/swrast/s_context.c25
-rw-r--r--src/mesa/swrast/s_fragprog.c12
-rw-r--r--src/mesa/swrast/s_fragprog.h2
-rw-r--r--src/mesa/swrast/s_lines.c2
-rw-r--r--src/mesa/swrast/s_span.c38
-rw-r--r--src/mesa/swrast/s_triangle.c4
9 files changed, 45 insertions, 44 deletions
diff --git a/src/mesa/swrast/s_aaline.c b/src/mesa/swrast/s_aaline.c
index d4b1805d9ec..d36d876974e 100644
--- a/src/mesa/swrast/s_aaline.c
+++ b/src/mesa/swrast/s_aaline.c
@@ -479,7 +479,7 @@ _swrast_choose_aa_line_function(struct gl_context *ctx)
ASSERT(ctx->Line.SmoothFlag);
if (ctx->Texture._EnabledCoordUnits != 0
- || ctx->FragmentProgram._Current
+ || _swrast_use_fragment_program(ctx)
|| (ctx->Light.Enabled &&
ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
|| ctx->Fog.ColorSumEnabled
diff --git a/src/mesa/swrast/s_aalinetemp.h b/src/mesa/swrast/s_aalinetemp.h
index 376ef32d06e..ba9f8abb9c3 100644
--- a/src/mesa/swrast/s_aalinetemp.h
+++ b/src/mesa/swrast/s_aalinetemp.h
@@ -67,7 +67,7 @@ NAME(plot)(struct gl_context *ctx, struct LineInfo *line, int ix, int iy)
ATTRIB_LOOP_BEGIN
GLfloat (*attribArray)[4] = line->span.array->attribs[attr];
if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0
- && !ctx->FragmentProgram._Current) {
+ && !_swrast_use_fragment_program(ctx)) {
/* texcoord w/ divide by Q */
const GLuint unit = attr - FRAG_ATTRIB_TEX0;
const GLfloat invQ = solve_plane_recip(fx, fy, line->attrPlane[attr][3]);
diff --git a/src/mesa/swrast/s_aatriangle.c b/src/mesa/swrast/s_aatriangle.c
index c68fdf63b68..b59177fa762 100644
--- a/src/mesa/swrast/s_aatriangle.c
+++ b/src/mesa/swrast/s_aatriangle.c
@@ -299,7 +299,7 @@ _swrast_set_aa_triangle_function(struct gl_context *ctx)
ASSERT(ctx->Polygon.SmoothFlag);
if (ctx->Texture._EnabledCoordUnits != 0
- || ctx->FragmentProgram._Current
+ || _swrast_use_fragment_program(ctx)
|| swrast->_FogEnabled
|| _mesa_need_secondary_color(ctx)) {
SWRAST_CONTEXT(ctx)->Triangle = general_aa_tri;
diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c
index 14cb9b180c3..cc304d70c06 100644
--- a/src/mesa/swrast/s_context.c
+++ b/src/mesa/swrast/s_context.c
@@ -105,7 +105,7 @@ _swrast_update_rasterflags( struct gl_context *ctx )
}
- if (ctx->FragmentProgram._Current) {
+ if (_swrast_use_fragment_program(ctx)) {
rasterMask |= FRAGPROG_BIT;
}
@@ -170,7 +170,7 @@ _swrast_update_fog_hint( struct gl_context *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
swrast->_PreferPixelFog = (!swrast->AllowVertexFog ||
- ctx->FragmentProgram._Current ||
+ _swrast_use_fragment_program(ctx) ||
(ctx->Hint.Fog == GL_NICEST &&
swrast->AllowPixelFog));
}
@@ -220,13 +220,14 @@ _swrast_update_deferred_texture(struct gl_context *ctx)
swrast->_DeferredTexture = GL_FALSE;
}
else {
+ GLboolean use_fprog = _swrast_use_fragment_program(ctx);
const struct gl_fragment_program *fprog
= ctx->FragmentProgram._Current;
- if (fprog && (fprog->Base.OutputsWritten & (1 << FRAG_RESULT_DEPTH))) {
+ if (use_fprog && (fprog->Base.OutputsWritten & (1 << FRAG_RESULT_DEPTH))) {
/* Z comes from fragment program/shader */
swrast->_DeferredTexture = GL_FALSE;
}
- else if (fprog && fprog->UsesKill) {
+ else if (use_fprog && fprog->UsesKill) {
swrast->_DeferredTexture = GL_FALSE;
}
else if (ctx->Query.CurrentOcclusionObject) {
@@ -254,7 +255,8 @@ _swrast_update_fog_state( struct gl_context *ctx )
(fp->Base.Target == GL_FRAGMENT_PROGRAM_NV));
/* determine if fog is needed, and if so, which fog mode */
- swrast->_FogEnabled = (fp == NULL && ctx->Fog.Enabled);
+ swrast->_FogEnabled = (!_swrast_use_fragment_program(ctx) &&
+ ctx->Fog.Enabled);
}
@@ -265,10 +267,11 @@ _swrast_update_fog_state( struct gl_context *ctx )
static void
_swrast_update_fragment_program(struct gl_context *ctx, GLbitfield newState)
{
- const struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
- if (fp) {
- _mesa_load_state_parameters(ctx, fp->Base.Parameters);
- }
+ if (!_swrast_use_fragment_program(ctx))
+ return;
+
+ _mesa_load_state_parameters(ctx,
+ ctx->FragmentProgram._Current->Base.Parameters);
}
@@ -286,7 +289,7 @@ _swrast_update_specular_vertex_add(struct gl_context *ctx)
swrast->SpecularVertexAdd = (separateSpecular
&& ctx->Texture._EnabledUnits == 0x0
- && !ctx->FragmentProgram._Current
+ && !_swrast_use_fragment_program(ctx)
&& !ctx->ATIFragmentShader._Enabled);
}
@@ -497,7 +500,7 @@ _swrast_update_active_attribs(struct gl_context *ctx)
/*
* Compute _ActiveAttribsMask = which fragment attributes are needed.
*/
- if (ctx->FragmentProgram._Current) {
+ if (_swrast_use_fragment_program(ctx)) {
/* fragment program/shader */
attribsMask = ctx->FragmentProgram._Current->Base.InputsRead;
attribsMask &= ~FRAG_BIT_WPOS; /* WPOS is always handled specially */
diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c
index 1caa0ebc226..cd20d8e3647 100644
--- a/src/mesa/swrast/s_fragprog.c
+++ b/src/mesa/swrast/s_fragprog.c
@@ -30,6 +30,18 @@
#include "s_fragprog.h"
#include "s_span.h"
+/**
+ * \brief Should swrast use a fragment program?
+ *
+ * \return true if the current fragment program exists and is not the fixed
+ * function fragment program
+ */
+GLboolean
+_swrast_use_fragment_program(struct gl_context *ctx)
+{
+ struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
+ return fp && fp != ctx->FragmentProgram._TexEnvProgram;
+}
/**
* Apply texture object's swizzle (X/Y/Z/W/0/1) to incoming 'texel'
diff --git a/src/mesa/swrast/s_fragprog.h b/src/mesa/swrast/s_fragprog.h
index 62a68361769..ac1f5ff4cf4 100644
--- a/src/mesa/swrast/s_fragprog.h
+++ b/src/mesa/swrast/s_fragprog.h
@@ -31,6 +31,8 @@
struct gl_context;
+GLboolean
+_swrast_use_fragment_program(struct gl_context *ctx);
extern void
_swrast_exec_fragment_program(struct gl_context *ctx, SWspan *span);
diff --git a/src/mesa/swrast/s_lines.c b/src/mesa/swrast/s_lines.c
index 95a2a5d96fc..ee997b08a7b 100644
--- a/src/mesa/swrast/s_lines.c
+++ b/src/mesa/swrast/s_lines.c
@@ -236,7 +236,7 @@ _swrast_choose_line( struct gl_context *ctx )
ASSERT(swrast->Line);
}
else if (ctx->Texture._EnabledCoordUnits
- || ctx->FragmentProgram._Current
+ || _swrast_use_fragment_program(ctx)
|| swrast->_FogEnabled
|| specular) {
USE(general_line);
diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c
index 51666ba0411..6d6538c965e 100644
--- a/src/mesa/swrast/s_span.c
+++ b/src/mesa/swrast/s_span.c
@@ -139,7 +139,8 @@ _swrast_span_default_attribs(struct gl_context *ctx, SWspan *span)
for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
const GLuint attr = FRAG_ATTRIB_TEX0 + i;
const GLfloat *tc = ctx->Current.RasterTexCoords[i];
- if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) {
+ if (_swrast_use_fragment_program(ctx) ||
+ ctx->ATIFragmentShader._Enabled) {
COPY_4V(span->attrStart[attr], tc);
}
else if (tc[3] > 0.0F) {
@@ -498,7 +499,7 @@ interpolate_texcoords(struct gl_context *ctx, SWspan *span)
swrast_texture_image_const(img);
needLambda = (obj->Sampler.MinFilter != obj->Sampler.MagFilter)
- || ctx->FragmentProgram._Current;
+ || _swrast_use_fragment_program(ctx);
/* LOD is calculated directly in the ansiotropic filter, we can
* skip the normal lambda function as the result is ignored.
*/
@@ -518,7 +519,7 @@ interpolate_texcoords(struct gl_context *ctx, SWspan *span)
if (needLambda) {
GLuint i;
- if (ctx->FragmentProgram._Current
+ if (_swrast_use_fragment_program(ctx)
|| ctx->ATIFragmentShader._Enabled) {
/* do perspective correction but don't divide s, t, r by q */
const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3];
@@ -559,7 +560,7 @@ interpolate_texcoords(struct gl_context *ctx, SWspan *span)
}
else {
GLuint i;
- if (ctx->FragmentProgram._Current ||
+ if (_swrast_use_fragment_program(ctx) ||
ctx->ATIFragmentShader._Enabled) {
/* do perspective correction but don't divide s, t, r by q */
const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3];
@@ -833,7 +834,7 @@ add_specular(struct gl_context *ctx, SWspan *span)
GLfloat (*col1)[4] = span->array->attribs[FRAG_ATTRIB_COL1];
GLuint i;
- ASSERT(!ctx->FragmentProgram._Current);
+ ASSERT(!_swrast_use_fragment_program(ctx));
ASSERT(span->arrayMask & SPAN_RGBA);
ASSERT(swrast->_ActiveAttribMask & FRAG_BIT_COL1);
(void) swrast; /* silence warning */
@@ -971,25 +972,7 @@ convert_color_type(SWspan *span, GLenum newType, GLuint output)
static inline void
shade_texture_span(struct gl_context *ctx, SWspan *span)
{
- /* This is a hack to work around drivers such as i965 that:
- *
- * - Set _MaintainTexEnvProgram to generate GLSL IR for
- * fixed-function fragment processing.
- * - Don't call _mesa_ir_link_shader to generate Mesa IR from
- * the GLSL IR.
- * - May use swrast to handle glDrawPixels.
- *
- * Since _mesa_ir_link_shader is never called, there is no Mesa IR
- * to execute. Instead do regular fixed-function processing.
- *
- * It is also worth noting that the software fixed-function path is
- * much faster than the software shader path.
- */
- const bool use_fragment_program =
- ctx->FragmentProgram._Current
- && ctx->FragmentProgram._Current != ctx->FragmentProgram._TexEnvProgram;
-
- if (use_fragment_program ||
+ if (_swrast_use_fragment_program(ctx) ||
ctx->ATIFragmentShader._Enabled) {
/* programmable shading */
if (span->primitive == GL_BITMAP && span->array->ChanType != GL_FLOAT) {
@@ -1018,7 +1001,7 @@ shade_texture_span(struct gl_context *ctx, SWspan *span)
interpolate_wpos(ctx, span);
/* Run fragment program/shader now */
- if (use_fragment_program) {
+ if (_swrast_use_fragment_program(ctx)) {
_swrast_exec_fragment_program(ctx, span);
}
else {
@@ -1151,7 +1134,7 @@ _swrast_write_rgba_span( struct gl_context *ctx, SWspan *span)
const GLbitfield64 origArrayAttribs = span->arrayAttribs;
const GLenum origChanType = span->array->ChanType;
void * const origRgba = span->array->rgba;
- const GLboolean shader = (ctx->FragmentProgram._Current
+ const GLboolean shader = (_swrast_use_fragment_program(ctx)
|| ctx->ATIFragmentShader._Enabled);
const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledCoordUnits;
struct gl_framebuffer *fb = ctx->DrawBuffer;
@@ -1326,7 +1309,8 @@ _swrast_write_rgba_span( struct gl_context *ctx, SWspan *span)
const GLuint numBuffers = fb->_NumColorDrawBuffers;
const struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
const GLboolean multiFragOutputs =
- (fp && fp->Base.OutputsWritten >= (1 << FRAG_RESULT_DATA0));
+ _swrast_use_fragment_program(ctx)
+ && fp->Base.OutputsWritten >= (1 << FRAG_RESULT_DATA0);
GLuint buf;
for (buf = 0; buf < numBuffers; buf++) {
diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c
index 124aa5f8edd..ddb4792f7e9 100644
--- a/src/mesa/swrast/s_triangle.c
+++ b/src/mesa/swrast/s_triangle.c
@@ -1038,7 +1038,7 @@ _swrast_choose_triangle( struct gl_context *ctx )
* needs to be interpolated.
*/
if (ctx->Texture._EnabledCoordUnits ||
- ctx->FragmentProgram._Current ||
+ _swrast_use_fragment_program(ctx) ||
ctx->ATIFragmentShader._Enabled ||
_mesa_need_secondary_color(ctx) ||
swrast->_FogEnabled) {
@@ -1060,7 +1060,7 @@ _swrast_choose_triangle( struct gl_context *ctx )
/* First see if we can use an optimized 2-D texture function */
if (ctx->Texture._EnabledCoordUnits == 0x1
- && !ctx->FragmentProgram._Current
+ && !_swrast_use_fragment_program(ctx)
&& !ctx->ATIFragmentShader._Enabled
&& ctx->Texture._EnabledUnits == 0x1
&& ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT