mesa: remove gl_program.Target
We are going to add mesh shader support, but there's no GL_MESH_PROGRAM_EXT. Use shader stages instead. Reviewed-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35931>
This commit is contained in:
+13
-10
@@ -77,12 +77,12 @@ lookup_or_create_program(GLuint id, GLenum target, const char* caller)
|
||||
}
|
||||
else {
|
||||
/* Bind a user program */
|
||||
unsigned stage = _mesa_program_enum_to_shader_stage(target);
|
||||
_mesa_HashLockMutex(&ctx->Shared->Programs);
|
||||
newProg = _mesa_lookup_program_locked(ctx, id);
|
||||
if (!newProg || newProg == &_mesa_DummyProgram) {
|
||||
/* allocate a new program now */
|
||||
newProg = ctx->Driver.NewProgram(ctx, _mesa_program_enum_to_shader_stage(target),
|
||||
id, true);
|
||||
newProg = ctx->Driver.NewProgram(ctx, stage, id, true);
|
||||
if (!newProg) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
|
||||
_mesa_HashUnlockMutex(&ctx->Shared->Programs);
|
||||
@@ -90,7 +90,7 @@ lookup_or_create_program(GLuint id, GLenum target, const char* caller)
|
||||
}
|
||||
_mesa_HashInsertLocked(&ctx->Shared->Programs, id, newProg);
|
||||
}
|
||||
else if (newProg->Target != target) {
|
||||
else if (newProg->info.stage != stage) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"%s(target mismatch)", caller);
|
||||
_mesa_HashUnlockMutex(&ctx->Shared->Programs);
|
||||
@@ -188,19 +188,19 @@ _mesa_DeleteProgramsARB(GLsizei n, const GLuint *ids)
|
||||
}
|
||||
else if (prog) {
|
||||
/* Unbind program if necessary */
|
||||
switch (prog->Target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
switch (prog->info.stage) {
|
||||
case MESA_SHADER_VERTEX:
|
||||
if (ctx->VertexProgram.Current &&
|
||||
ctx->VertexProgram.Current->Id == ids[i]) {
|
||||
/* unbind this currently bound program */
|
||||
_mesa_BindProgramARB(prog->Target, 0);
|
||||
_mesa_BindProgramARB(GL_VERTEX_PROGRAM_ARB, 0);
|
||||
}
|
||||
break;
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
case MESA_SHADER_FRAGMENT:
|
||||
if (ctx->FragmentProgram.Current &&
|
||||
ctx->FragmentProgram.Current->Id == ids[i]) {
|
||||
/* unbind this currently bound program */
|
||||
_mesa_BindProgramARB(prog->Target, 0);
|
||||
_mesa_BindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -306,6 +306,7 @@ get_local_param_pointer(struct gl_context *ctx, const char *func,
|
||||
else
|
||||
max = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams;
|
||||
|
||||
|
||||
/* Allocate LocalParams. */
|
||||
if (!prog->arb.LocalParams) {
|
||||
prog->arb.LocalParams = rzalloc_array_size(prog, sizeof(float[4]),
|
||||
@@ -718,14 +719,16 @@ program_local_parameters4fv(struct gl_program* prog, GLuint index, GLsizei count
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
GLfloat *dest;
|
||||
flush_vertices_for_program_constants(ctx, prog->Target);
|
||||
flush_vertices_for_program_constants(
|
||||
ctx, _mesa_shader_stage_to_program(prog->info.stage));
|
||||
|
||||
if (count <= 0) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE, "%s(count)", caller);
|
||||
}
|
||||
|
||||
if (get_local_param_pointer(ctx, caller,
|
||||
prog, prog->Target, index, count, &dest))
|
||||
prog, _mesa_shader_stage_to_program(prog->info.stage),
|
||||
index, count, &dest))
|
||||
memcpy(dest, params, count * 4 * sizeof(GLfloat));
|
||||
}
|
||||
|
||||
|
||||
@@ -480,8 +480,6 @@ struct gl_program
|
||||
GLint RefCount;
|
||||
GLubyte *String; /**< Null-terminated program text */
|
||||
|
||||
/** GL_VERTEX/FRAGMENT_PROGRAM_ARB, GL_GEOMETRY_PROGRAM_NV */
|
||||
GLenum16 Target;
|
||||
GLenum16 Format; /**< String encoding format */
|
||||
|
||||
GLboolean _Used; /**< Ever used for drawing? Used for debugging */
|
||||
|
||||
@@ -69,8 +69,7 @@ update_single_shader_texture_used(struct gl_shader_program *shProg,
|
||||
struct gl_program *prog,
|
||||
GLuint unit, GLuint target)
|
||||
{
|
||||
gl_shader_stage prog_stage =
|
||||
_mesa_program_enum_to_shader_stage(prog->Target);
|
||||
gl_shader_stage prog_stage = prog->info.stage;
|
||||
|
||||
assert(unit < ARRAY_SIZE(prog->TexturesUsed));
|
||||
assert(target < NUM_TEXTURE_TARGETS);
|
||||
@@ -103,8 +102,7 @@ _mesa_update_shader_textures_used(struct gl_shader_program *shProg,
|
||||
struct gl_program *prog)
|
||||
{
|
||||
GLbitfield mask = prog->SamplersUsed;
|
||||
ASSERTED gl_shader_stage prog_stage =
|
||||
_mesa_program_enum_to_shader_stage(prog->Target);
|
||||
ASSERTED gl_shader_stage prog_stage = prog->info.stage;
|
||||
GLuint s;
|
||||
|
||||
assert(shProg->_LinkedShaders[prog_stage]);
|
||||
|
||||
@@ -79,7 +79,7 @@ _mesa_register_file_name(gl_register_file f)
|
||||
* Return ARB_v/f_prog-style input attrib string.
|
||||
*/
|
||||
static const char *
|
||||
arb_input_attrib_string(GLuint index, GLenum progType)
|
||||
arb_input_attrib_string(GLuint index, unsigned stage)
|
||||
{
|
||||
/*
|
||||
* These strings should match the VERT_ATTRIB_x and VARYING_SLOT_x tokens.
|
||||
@@ -193,12 +193,12 @@ arb_input_attrib_string(GLuint index, GLenum progType)
|
||||
assert(strcmp(fragAttribs[VARYING_SLOT_TEX0], "fragment.texcoord[0]") == 0);
|
||||
assert(strcmp(fragAttribs[VARYING_SLOT_VAR0+15], "fragment.varying[15]") == 0);
|
||||
|
||||
if (progType == GL_VERTEX_PROGRAM_ARB) {
|
||||
if (stage == MESA_SHADER_VERTEX) {
|
||||
assert(index < ARRAY_SIZE(vertAttribs));
|
||||
return vertAttribs[index];
|
||||
}
|
||||
else {
|
||||
assert(progType == GL_FRAGMENT_PROGRAM_ARB);
|
||||
assert(stage == MESA_SHADER_FRAGMENT);
|
||||
assert(index < ARRAY_SIZE(fragAttribs));
|
||||
return fragAttribs[index];
|
||||
}
|
||||
@@ -215,8 +215,7 @@ _mesa_print_vp_inputs(GLbitfield inputs)
|
||||
printf("VP Inputs 0x%x: \n", inputs);
|
||||
while (inputs) {
|
||||
GLint attr = ffs(inputs) - 1;
|
||||
const char *name = arb_input_attrib_string(attr,
|
||||
GL_VERTEX_PROGRAM_ARB);
|
||||
const char *name = arb_input_attrib_string(attr, MESA_SHADER_VERTEX);
|
||||
printf(" %d: %s\n", attr, name);
|
||||
inputs &= ~(1 << attr);
|
||||
}
|
||||
@@ -233,8 +232,7 @@ _mesa_print_fp_inputs(GLbitfield inputs)
|
||||
printf("FP Inputs 0x%x: \n", inputs);
|
||||
while (inputs) {
|
||||
GLint attr = ffs(inputs) - 1;
|
||||
const char *name = arb_input_attrib_string(attr,
|
||||
GL_FRAGMENT_PROGRAM_ARB);
|
||||
const char *name = arb_input_attrib_string(attr, MESA_SHADER_FRAGMENT);
|
||||
printf(" %d: %s\n", attr, name);
|
||||
inputs &= ~(1 << attr);
|
||||
}
|
||||
@@ -246,7 +244,7 @@ _mesa_print_fp_inputs(GLbitfield inputs)
|
||||
* Return ARB_v/f_prog-style output attrib string.
|
||||
*/
|
||||
static const char *
|
||||
arb_output_attrib_string(GLuint index, GLenum progType)
|
||||
arb_output_attrib_string(GLuint index, unsigned stage)
|
||||
{
|
||||
/*
|
||||
* These strings should match the VARYING_SLOT_x and FRAG_RESULT_x tokens.
|
||||
@@ -339,12 +337,12 @@ arb_output_attrib_string(GLuint index, GLenum progType)
|
||||
assert(strcmp(vertResults[VARYING_SLOT_VAR0], "result.varying[0]") == 0);
|
||||
assert(strcmp(fragResults[FRAG_RESULT_DATA0], "result.color[0]") == 0);
|
||||
|
||||
if (progType == GL_VERTEX_PROGRAM_ARB) {
|
||||
if (stage == MESA_SHADER_VERTEX) {
|
||||
assert(index < ARRAY_SIZE(vertResults));
|
||||
return vertResults[index];
|
||||
}
|
||||
else {
|
||||
assert(progType == GL_FRAGMENT_PROGRAM_ARB);
|
||||
assert(stage == MESA_SHADER_FRAGMENT);
|
||||
assert(index < ARRAY_SIZE(fragResults));
|
||||
return fragResults[index];
|
||||
}
|
||||
@@ -378,10 +376,10 @@ reg_string(gl_register_file f, GLint index, gl_prog_print_mode mode,
|
||||
case PROG_PRINT_ARB:
|
||||
switch (f) {
|
||||
case PROGRAM_INPUT:
|
||||
sprintf(str, "%s", arb_input_attrib_string(index, prog->Target));
|
||||
sprintf(str, "%s", arb_input_attrib_string(index, prog->info.stage));
|
||||
break;
|
||||
case PROGRAM_OUTPUT:
|
||||
sprintf(str, "%s", arb_output_attrib_string(index, prog->Target));
|
||||
sprintf(str, "%s", arb_output_attrib_string(index, prog->info.stage));
|
||||
break;
|
||||
case PROGRAM_TEMPORARY:
|
||||
sprintf(str, "temp%d", index);
|
||||
@@ -732,21 +730,24 @@ _mesa_fprint_program_opt(FILE *f,
|
||||
{
|
||||
GLuint i, indent = 0;
|
||||
|
||||
switch (prog->Target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
switch (prog->info.stage) {
|
||||
case MESA_SHADER_VERTEX:
|
||||
if (mode == PROG_PRINT_ARB)
|
||||
fprintf(f, "!!ARBvp1.0\n");
|
||||
else
|
||||
fprintf(f, "# Vertex Program/Shader %u\n", prog->Id);
|
||||
break;
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
case MESA_SHADER_FRAGMENT:
|
||||
if (mode == PROG_PRINT_ARB)
|
||||
fprintf(f, "!!ARBfp1.0\n");
|
||||
else
|
||||
fprintf(f, "# Fragment Program/Shader %u\n", prog->Id);
|
||||
break;
|
||||
case GL_GEOMETRY_PROGRAM_NV:
|
||||
case MESA_SHADER_GEOMETRY:
|
||||
fprintf(f, "# Geometry Shader\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < prog->arb.NumInstructions; i++) {
|
||||
|
||||
@@ -89,7 +89,7 @@ ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src)
|
||||
unsigned slot = prog_src->Index;
|
||||
nir_def *input;
|
||||
|
||||
if (c->prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
|
||||
if (c->prog->info.stage == MESA_SHADER_FRAGMENT) {
|
||||
if (slot == VARYING_SLOT_POS && c->ctx->Const.GLSLFragCoordIsSysVal) {
|
||||
nir_variable *pos =
|
||||
nir_get_variable_with_location(b->shader, nir_var_system_value,
|
||||
@@ -749,7 +749,7 @@ ptn_add_output_stores(struct ptn_compile *c)
|
||||
|
||||
u_foreach_bit64(slot, b->shader->info.outputs_written) {
|
||||
nir_def *src = nir_load_reg(b, c->output_regs[slot]);
|
||||
if (c->prog->Target == GL_FRAGMENT_PROGRAM_ARB &&
|
||||
if (c->prog->info.stage == MESA_SHADER_FRAGMENT &&
|
||||
slot == FRAG_RESULT_DEPTH) {
|
||||
/* result.depth has this strange convention of being the .z component of
|
||||
* a vec4 with undefined .xyw components. We resolve it to a scalar, to
|
||||
@@ -757,7 +757,7 @@ ptn_add_output_stores(struct ptn_compile *c)
|
||||
*/
|
||||
src = nir_channel(b, src, 2);
|
||||
}
|
||||
if (c->prog->Target == GL_VERTEX_PROGRAM_ARB &&
|
||||
if (c->prog->info.stage == MESA_SHADER_VERTEX &&
|
||||
(slot == VARYING_SLOT_FOGC || slot == VARYING_SLOT_PSIZ)) {
|
||||
/* result.{fogcoord,psiz} is a single component value */
|
||||
src = nir_channel(b, src, 0);
|
||||
@@ -806,7 +806,7 @@ prog_to_nir(const struct gl_context *ctx, const struct gl_program *prog)
|
||||
st_get_nir_compiler_options(ctx->st, prog->info.stage);
|
||||
struct ptn_compile *c;
|
||||
struct nir_shader *s;
|
||||
gl_shader_stage stage = _mesa_program_enum_to_shader_stage(prog->Target);
|
||||
gl_shader_stage stage = prog->info.stage;
|
||||
|
||||
c = rzalloc(NULL, struct ptn_compile);
|
||||
if (!c)
|
||||
|
||||
@@ -193,7 +193,6 @@ _mesa_init_gl_program(struct gl_program *prog, gl_shader_stage stage,
|
||||
|
||||
memset(prog, 0, sizeof(*prog));
|
||||
prog->Id = id;
|
||||
prog->Target = _mesa_shader_stage_to_program(stage);
|
||||
prog->RefCount = 1;
|
||||
prog->Format = GL_PROGRAM_FORMAT_ASCII_ARB;
|
||||
prog->info.stage = stage;
|
||||
@@ -317,13 +316,7 @@ _mesa_reference_program_(struct gl_context *ctx,
|
||||
assert(ptr);
|
||||
if (*ptr && prog) {
|
||||
/* sanity check */
|
||||
if ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB)
|
||||
assert(prog->Target == GL_VERTEX_PROGRAM_ARB);
|
||||
else if ((*ptr)->Target == GL_FRAGMENT_PROGRAM_ARB)
|
||||
assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB ||
|
||||
prog->Target == GL_FRAGMENT_PROGRAM_NV);
|
||||
else if ((*ptr)->Target == GL_GEOMETRY_PROGRAM_NV)
|
||||
assert(prog->Target == GL_GEOMETRY_PROGRAM_NV);
|
||||
assert((*ptr)->info.stage == prog->info.stage);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -302,7 +302,7 @@ program: language optionSequence statementSequence END
|
||||
|
||||
language: ARBvp_10
|
||||
{
|
||||
if (state->prog->Target != GL_VERTEX_PROGRAM_ARB) {
|
||||
if (state->prog->info.stage != MESA_SHADER_VERTEX) {
|
||||
yyerror(& @1, state, "invalid fragment program header");
|
||||
|
||||
}
|
||||
@@ -310,7 +310,7 @@ language: ARBvp_10
|
||||
}
|
||||
| ARBfp_10
|
||||
{
|
||||
if (state->prog->Target != GL_FRAGMENT_PROGRAM_ARB) {
|
||||
if (state->prog->info.stage != MESA_SHADER_FRAGMENT) {
|
||||
yyerror(& @1, state, "invalid vertex program header");
|
||||
}
|
||||
state->mode = ARB_fragment;
|
||||
@@ -2546,9 +2546,10 @@ _mesa_parse_arb_program(struct gl_context *ctx, GLenum target, const GLubyte *st
|
||||
GLboolean result = GL_FALSE;
|
||||
void *temp;
|
||||
struct asm_symbol *sym;
|
||||
unsigned stage = _mesa_program_enum_to_shader_stage(target);
|
||||
|
||||
state->ctx = ctx;
|
||||
state->prog->Target = target;
|
||||
state->prog->info.stage = stage;
|
||||
state->prog->Parameters = _mesa_new_parameter_list();
|
||||
|
||||
/* Make a copy of the program string and force it to be newline and NUL-terminated.
|
||||
@@ -2570,9 +2571,7 @@ _mesa_parse_arb_program(struct gl_context *ctx, GLenum target, const GLubyte *st
|
||||
|
||||
state->st = _mesa_symbol_table_ctor();
|
||||
|
||||
state->limits = (target == GL_VERTEX_PROGRAM_ARB)
|
||||
? & ctx->Const.Program[MESA_SHADER_VERTEX]
|
||||
: & ctx->Const.Program[MESA_SHADER_FRAGMENT];
|
||||
state->limits = &ctx->Const.Program[stage];
|
||||
|
||||
state->MaxTextureImageUnits = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits;
|
||||
state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits;
|
||||
|
||||
@@ -118,7 +118,7 @@ st_update_fp( struct st_context *st )
|
||||
|
||||
assert(st->ctx->FragmentProgram._Current);
|
||||
fp = st->ctx->FragmentProgram._Current;
|
||||
assert(fp->Target == GL_FRAGMENT_PROGRAM_ARB);
|
||||
assert(fp->info.stage == MESA_SHADER_FRAGMENT);
|
||||
|
||||
void *shader;
|
||||
|
||||
@@ -207,7 +207,7 @@ st_update_vp( struct st_context *st )
|
||||
*/
|
||||
assert(st->ctx->VertexProgram._Current);
|
||||
vp = st->ctx->VertexProgram._Current;
|
||||
assert(vp->Target == GL_VERTEX_PROGRAM_ARB);
|
||||
assert(vp->info.stage == MESA_SHADER_VERTEX);
|
||||
|
||||
if (st->shader_has_one_variant[MESA_SHADER_VERTEX] &&
|
||||
!st->ctx->Array._PerVertexEdgeFlagsEnabled) {
|
||||
|
||||
@@ -218,10 +218,10 @@ st_set_prog_affected_state_flags(struct gl_program *prog)
|
||||
* the linked list.
|
||||
*/
|
||||
static void
|
||||
delete_variant(struct st_context *st, struct st_variant *v, GLenum target)
|
||||
delete_variant(struct st_context *st, struct st_variant *v, unsigned stage)
|
||||
{
|
||||
if (v->driver_shader) {
|
||||
if (target == GL_VERTEX_PROGRAM_ARB &&
|
||||
if (stage == MESA_SHADER_VERTEX &&
|
||||
((struct st_common_variant*)v)->key.is_draw_shader) {
|
||||
/* Draw shader. */
|
||||
draw_delete_vertex_shader(st->draw, v->driver_shader);
|
||||
@@ -229,23 +229,23 @@ delete_variant(struct st_context *st, struct st_variant *v, GLenum target)
|
||||
/* The shader's context matches the calling context, or we
|
||||
* don't care.
|
||||
*/
|
||||
switch (target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
switch (stage) {
|
||||
case MESA_SHADER_VERTEX:
|
||||
st->pipe->delete_vs_state(st->pipe, v->driver_shader);
|
||||
break;
|
||||
case GL_TESS_CONTROL_PROGRAM_NV:
|
||||
case MESA_SHADER_TESS_CTRL:
|
||||
st->pipe->delete_tcs_state(st->pipe, v->driver_shader);
|
||||
break;
|
||||
case GL_TESS_EVALUATION_PROGRAM_NV:
|
||||
case MESA_SHADER_TESS_EVAL:
|
||||
st->pipe->delete_tes_state(st->pipe, v->driver_shader);
|
||||
break;
|
||||
case GL_GEOMETRY_PROGRAM_NV:
|
||||
case MESA_SHADER_GEOMETRY:
|
||||
st->pipe->delete_gs_state(st->pipe, v->driver_shader);
|
||||
break;
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
case MESA_SHADER_FRAGMENT:
|
||||
st->pipe->delete_fs_state(st->pipe, v->driver_shader);
|
||||
break;
|
||||
case GL_COMPUTE_PROGRAM_NV:
|
||||
case MESA_SHADER_COMPUTE:
|
||||
st->pipe->delete_compute_state(st->pipe, v->driver_shader);
|
||||
break;
|
||||
default:
|
||||
@@ -255,10 +255,7 @@ delete_variant(struct st_context *st, struct st_variant *v, GLenum target)
|
||||
/* We can't delete a shader with a context different from the one
|
||||
* that created it. Add it to the creating context's zombie list.
|
||||
*/
|
||||
enum pipe_shader_type type =
|
||||
pipe_shader_type_from_mesa(_mesa_program_enum_to_shader_stage(target));
|
||||
|
||||
st_save_zombie_shader(v->st, type, v->driver_shader);
|
||||
st_save_zombie_shader(v->st, stage, v->driver_shader);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,7 +314,7 @@ st_release_variants(struct st_context *st, struct gl_program *p)
|
||||
|
||||
for (v = p->variants; v; ) {
|
||||
struct st_variant *next = v->next;
|
||||
delete_variant(st, v, p->Target);
|
||||
delete_variant(st, v, p->info.stage);
|
||||
v = next;
|
||||
}
|
||||
|
||||
@@ -1330,7 +1327,7 @@ destroy_program_variants(struct st_context *st, struct gl_program *p)
|
||||
/* unlink from list */
|
||||
*prevPtr = next;
|
||||
/* destroy this variant */
|
||||
delete_variant(st, v, p->Target);
|
||||
delete_variant(st, v, p->info.stage);
|
||||
}
|
||||
else {
|
||||
prevPtr = &v->next;
|
||||
@@ -1421,12 +1418,12 @@ st_precompile_shader_variant(struct st_context *st,
|
||||
{
|
||||
char *error = NULL;
|
||||
|
||||
switch (prog->Target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
case GL_TESS_CONTROL_PROGRAM_NV:
|
||||
case GL_TESS_EVALUATION_PROGRAM_NV:
|
||||
case GL_GEOMETRY_PROGRAM_NV:
|
||||
case GL_COMPUTE_PROGRAM_NV: {
|
||||
switch (prog->info.stage) {
|
||||
case MESA_SHADER_VERTEX:
|
||||
case MESA_SHADER_TESS_CTRL:
|
||||
case MESA_SHADER_TESS_EVAL:
|
||||
case MESA_SHADER_GEOMETRY:
|
||||
case MESA_SHADER_COMPUTE: {
|
||||
struct st_common_variant_key key;
|
||||
|
||||
memset(&key, 0, sizeof(key));
|
||||
@@ -1445,7 +1442,7 @@ st_precompile_shader_variant(struct st_context *st,
|
||||
return error;
|
||||
}
|
||||
|
||||
case GL_FRAGMENT_PROGRAM_ARB: {
|
||||
case MESA_SHADER_FRAGMENT: {
|
||||
struct st_fp_variant_key key;
|
||||
|
||||
memset(&key, 0, sizeof(key));
|
||||
|
||||
Reference in New Issue
Block a user