mesa: Track fixed-function fragment shader as a shader
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@intel.com> Reviewed-by: Eric Anholt <eric@anholt.net> Acked-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
parent
ca5b30bf81
commit
b527dd65c8
|
@ -543,7 +543,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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -166,7 +166,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;
|
||||
|
|
|
@ -2350,6 +2350,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.
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
@ -252,12 +253,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);
|
||||
}
|
||||
|
@ -265,6 +272,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);
|
||||
|
|
Loading…
Reference in New Issue