glsl: Slightly change the semantic of _LinkedShaders
Previously _LinkedShaders was a compact array of the linked shaders for each shader stage. Now it is arranged such that each slot, indexed by the MESA_SHADER_* defines, refers to a specific shader stage. As a result, some slots will be NULL. This makes things a little more complex in the linker, but it simplifies things in other places. As a side effect _NumLinkedShaders is removed. NOTE: This may be a candidate for the 7.9 branch. If there are other patches that get backported to 7.9 that use _LinkedShader, this patch should be cherry picked also.
This commit is contained in:
@@ -29,9 +29,17 @@
|
||||
#include <errno.h>
|
||||
#include "glcpp.h"
|
||||
#include "main/mtypes.h"
|
||||
#include "main/shaderobj.h"
|
||||
|
||||
extern int yydebug;
|
||||
|
||||
void
|
||||
_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
|
||||
struct gl_shader *sh)
|
||||
{
|
||||
*ptr = sh;
|
||||
}
|
||||
|
||||
/* Read from fd until EOF and return a string of everything read.
|
||||
*/
|
||||
static char *
|
||||
|
@@ -80,6 +80,10 @@ extern "C" {
|
||||
#include "linker.h"
|
||||
#include "ir_optimization.h"
|
||||
|
||||
extern "C" {
|
||||
#include "main/shaderobj.h"
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor that determines whether or not a variable is ever written.
|
||||
*/
|
||||
@@ -321,6 +325,9 @@ cross_validate_globals(struct gl_shader_program *prog,
|
||||
*/
|
||||
glsl_symbol_table variables;
|
||||
for (unsigned i = 0; i < num_shaders; i++) {
|
||||
if (shader_list[i] == NULL)
|
||||
continue;
|
||||
|
||||
foreach_list(node, shader_list[i]->ir) {
|
||||
ir_variable *const var = ((ir_instruction *) node)->as_variable();
|
||||
|
||||
@@ -420,7 +427,7 @@ bool
|
||||
cross_validate_uniforms(struct gl_shader_program *prog)
|
||||
{
|
||||
return cross_validate_globals(prog, prog->_LinkedShaders,
|
||||
prog->_NumLinkedShaders, true);
|
||||
MESA_SHADER_TYPES, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -876,7 +883,10 @@ struct uniform_node {
|
||||
static void
|
||||
update_array_sizes(struct gl_shader_program *prog)
|
||||
{
|
||||
for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
|
||||
for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
|
||||
if (prog->_LinkedShaders[i] == NULL)
|
||||
continue;
|
||||
|
||||
foreach_list(node, prog->_LinkedShaders[i]->ir) {
|
||||
ir_variable *const var = ((ir_instruction *) node)->as_variable();
|
||||
|
||||
@@ -887,7 +897,10 @@ update_array_sizes(struct gl_shader_program *prog)
|
||||
continue;
|
||||
|
||||
unsigned int size = var->max_array_access;
|
||||
for (unsigned j = 0; j < prog->_NumLinkedShaders; j++) {
|
||||
for (unsigned j = 0; j < MESA_SHADER_TYPES; j++) {
|
||||
if (prog->_LinkedShaders[j] == NULL)
|
||||
continue;
|
||||
|
||||
foreach_list(node2, prog->_LinkedShaders[j]->ir) {
|
||||
ir_variable *other_var = ((ir_instruction *) node2)->as_variable();
|
||||
if (!other_var)
|
||||
@@ -999,7 +1012,10 @@ assign_uniform_locations(struct gl_shader_program *prog)
|
||||
hash_table_string_compare);
|
||||
void *mem_ctx = talloc_new(NULL);
|
||||
|
||||
for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
|
||||
for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
|
||||
if (prog->_LinkedShaders[i] == NULL)
|
||||
continue;
|
||||
|
||||
unsigned next_position = 0;
|
||||
|
||||
foreach_list(node, prog->_LinkedShaders[i]->ir) {
|
||||
@@ -1449,13 +1465,15 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||
|
||||
prog->Version = max_version;
|
||||
|
||||
for (unsigned int i = 0; i < prog->_NumLinkedShaders; i++) {
|
||||
for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) {
|
||||
if (prog->_LinkedShaders[i] != NULL)
|
||||
ctx->Driver.DeleteShader(ctx, prog->_LinkedShaders[i]);
|
||||
|
||||
prog->_LinkedShaders[i] = NULL;
|
||||
}
|
||||
|
||||
/* Link all shaders for a particular stage and validate the result.
|
||||
*/
|
||||
prog->_NumLinkedShaders = 0;
|
||||
if (num_vert_shaders > 0) {
|
||||
gl_shader *const sh =
|
||||
link_intrastage_shaders(ctx, prog, vert_shader_list, num_vert_shaders);
|
||||
@@ -1466,8 +1484,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||
if (!validate_vertex_shader_executable(prog, sh))
|
||||
goto done;
|
||||
|
||||
prog->_LinkedShaders[prog->_NumLinkedShaders] = sh;
|
||||
prog->_NumLinkedShaders++;
|
||||
_mesa_reference_shader(ctx, &prog->_LinkedShaders[MESA_SHADER_VERTEX],
|
||||
sh);
|
||||
}
|
||||
|
||||
if (num_frag_shaders > 0) {
|
||||
@@ -1480,8 +1498,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||
if (!validate_fragment_shader_executable(prog, sh))
|
||||
goto done;
|
||||
|
||||
prog->_LinkedShaders[prog->_NumLinkedShaders] = sh;
|
||||
prog->_NumLinkedShaders++;
|
||||
_mesa_reference_shader(ctx, &prog->_LinkedShaders[MESA_SHADER_FRAGMENT],
|
||||
sh);
|
||||
}
|
||||
|
||||
/* Here begins the inter-stage linking phase. Some initial validation is
|
||||
@@ -1489,14 +1507,26 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||
* varyings.
|
||||
*/
|
||||
if (cross_validate_uniforms(prog)) {
|
||||
unsigned prev;
|
||||
|
||||
for (prev = 0; prev < MESA_SHADER_TYPES; prev++) {
|
||||
if (prog->_LinkedShaders[prev] != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Validate the inputs of each stage with the output of the preceeding
|
||||
* stage.
|
||||
*/
|
||||
for (unsigned i = 1; i < prog->_NumLinkedShaders; i++) {
|
||||
for (unsigned i = prev + 1; i < MESA_SHADER_TYPES; i++) {
|
||||
if (prog->_LinkedShaders[i] == NULL)
|
||||
continue;
|
||||
|
||||
if (!cross_validate_outputs_to_inputs(prog,
|
||||
prog->_LinkedShaders[i - 1],
|
||||
prog->_LinkedShaders[prev],
|
||||
prog->_LinkedShaders[i]))
|
||||
goto done;
|
||||
|
||||
prev = i;
|
||||
}
|
||||
|
||||
prog->LinkStatus = true;
|
||||
@@ -1506,7 +1536,10 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||
* uniforms, and varyings. Later optimization could possibly make
|
||||
* some of that unused.
|
||||
*/
|
||||
for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
|
||||
for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
|
||||
if (prog->_LinkedShaders[i] == NULL)
|
||||
continue;
|
||||
|
||||
while (do_common_optimization(prog->_LinkedShaders[i]->ir, true, 32))
|
||||
;
|
||||
}
|
||||
@@ -1515,7 +1548,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||
|
||||
assign_uniform_locations(prog);
|
||||
|
||||
if (prog->_NumLinkedShaders && prog->_LinkedShaders[0]->Type == GL_VERTEX_SHADER) {
|
||||
if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) {
|
||||
/* FINISHME: The value of the max_attribute_index parameter is
|
||||
* FINISHME: implementation dependent based on the value of
|
||||
* FINISHME: GL_MAX_VERTEX_ATTRIBS. GL_MAX_VERTEX_ATTRIBS must be
|
||||
@@ -1526,14 +1559,26 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (prog->_NumLinkedShaders == 1)
|
||||
demote_unread_shader_outputs(prog->_LinkedShaders[0]);
|
||||
if ((prog->_LinkedShaders[MESA_SHADER_GEOMETRY] == NULL)
|
||||
&& (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL))
|
||||
demote_unread_shader_outputs(prog->_LinkedShaders[MESA_SHADER_VERTEX]);
|
||||
}
|
||||
|
||||
for (unsigned i = 1; i < prog->_NumLinkedShaders; i++)
|
||||
unsigned prev;
|
||||
for (prev = 0; prev < MESA_SHADER_TYPES; prev++) {
|
||||
if (prog->_LinkedShaders[prev] != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
for (unsigned i = prev + 1; i < MESA_SHADER_TYPES; i++) {
|
||||
if (prog->_LinkedShaders[i] == NULL)
|
||||
continue;
|
||||
|
||||
assign_varying_locations(prog,
|
||||
prog->_LinkedShaders[i - 1],
|
||||
prog->_LinkedShaders[prev],
|
||||
prog->_LinkedShaders[i]);
|
||||
prev = i;
|
||||
}
|
||||
|
||||
/* FINISHME: Assign fragment shader output locations. */
|
||||
|
||||
|
@@ -40,8 +40,19 @@
|
||||
extern "C" struct gl_shader *
|
||||
_mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type);
|
||||
|
||||
extern "C" void
|
||||
_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
|
||||
struct gl_shader *sh);
|
||||
|
||||
/* Copied from shader_api.c for the stand-alone compiler.
|
||||
*/
|
||||
void
|
||||
_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
|
||||
struct gl_shader *sh)
|
||||
{
|
||||
*ptr = sh;
|
||||
}
|
||||
|
||||
struct gl_shader *
|
||||
_mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type)
|
||||
{
|
||||
@@ -319,7 +330,7 @@ main(int argc, char **argv)
|
||||
printf("Info log for linking:\n%s\n", whole_program->InfoLog);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < whole_program->_NumLinkedShaders; i++)
|
||||
for (unsigned i = 0; i < MESA_SHADER_TYPES; i++)
|
||||
talloc_free(whole_program->_LinkedShaders[i]);
|
||||
|
||||
talloc_free(whole_program);
|
||||
|
@@ -91,10 +91,9 @@ brw_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||
{
|
||||
struct intel_context *intel = intel_context(ctx);
|
||||
|
||||
for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
|
||||
struct brw_shader *shader = (struct brw_shader *)prog->_LinkedShaders[i];
|
||||
|
||||
if (shader->base.Type == GL_FRAGMENT_SHADER) {
|
||||
struct brw_shader *shader =
|
||||
(struct brw_shader *)prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
|
||||
if (shader != NULL) {
|
||||
void *mem_ctx = talloc_new(NULL);
|
||||
bool progress;
|
||||
|
||||
@@ -143,7 +142,6 @@ brw_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||
reparent_ir(shader->ir, shader->ir);
|
||||
talloc_free(mem_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_mesa_ir_link_shader(ctx, prog))
|
||||
return GL_FALSE;
|
||||
@@ -3182,18 +3180,13 @@ brw_wm_fs_emit(struct brw_context *brw, struct brw_wm_compile *c)
|
||||
struct brw_compile *p = &c->func;
|
||||
struct intel_context *intel = &brw->intel;
|
||||
struct gl_context *ctx = &intel->ctx;
|
||||
struct brw_shader *shader = NULL;
|
||||
struct gl_shader_program *prog = ctx->Shader.CurrentProgram;
|
||||
|
||||
if (!prog)
|
||||
return GL_FALSE;
|
||||
|
||||
for (unsigned int i = 0; i < prog->_NumLinkedShaders; i++) {
|
||||
if (prog->_LinkedShaders[i]->Type == GL_FRAGMENT_SHADER) {
|
||||
shader = (struct brw_shader *)prog->_LinkedShaders[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
struct brw_shader *shader =
|
||||
(brw_shader *) prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
|
||||
if (!shader)
|
||||
return GL_FALSE;
|
||||
|
||||
|
@@ -148,17 +148,11 @@ static GLboolean brwProgramStringNotify( struct gl_context *ctx,
|
||||
* using the new FS backend.
|
||||
*/
|
||||
shader_program = _mesa_lookup_shader_program(ctx, prog->Id);
|
||||
if (shader_program) {
|
||||
for (i = 0; i < shader_program->_NumLinkedShaders; i++) {
|
||||
struct brw_shader *shader;
|
||||
|
||||
shader = (struct brw_shader *)shader_program->_LinkedShaders[i];
|
||||
if (shader->base.Type == GL_FRAGMENT_SHADER && shader->ir) {
|
||||
if (shader_program
|
||||
&& shader_program->_LinkedShaders[MESA_SHADER_FRAGMENT]) {
|
||||
return GL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (target == GL_VERTEX_PROGRAM_ARB) {
|
||||
struct gl_vertex_program *vprog = (struct gl_vertex_program *) prog;
|
||||
struct brw_vertex_program *newVP = brw_vertex_program(vprog);
|
||||
|
@@ -108,18 +108,13 @@ wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key)
|
||||
* 8-wide.
|
||||
*/
|
||||
if (ctx->Shader.CurrentProgram) {
|
||||
int i;
|
||||
struct brw_shader *shader = (struct brw_shader *)
|
||||
ctx->Shader.CurrentProgram->_LinkedShaders[MESA_SHADER_FRAGMENT];
|
||||
|
||||
for (i = 0; i < ctx->Shader.CurrentProgram->_NumLinkedShaders; i++) {
|
||||
struct brw_shader *shader =
|
||||
(struct brw_shader *)ctx->Shader.CurrentProgram->_LinkedShaders[i];;
|
||||
|
||||
if (shader->base.Type == GL_FRAGMENT_SHADER &&
|
||||
shader->ir != NULL) {
|
||||
if (shader != NULL && shader->ir != NULL) {
|
||||
key->is_glsl = GL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* _NEW_DEPTH */
|
||||
key->stats_wm = intel->stats_wm;
|
||||
|
@@ -1702,10 +1702,10 @@ _mesa_valid_to_render(struct gl_context *ctx, const char *where)
|
||||
_mesa_update_state(ctx);
|
||||
|
||||
if (ctx->Shader.CurrentProgram) {
|
||||
unsigned i;
|
||||
struct gl_shader_program *const prog = ctx->Shader.CurrentProgram;
|
||||
|
||||
/* using shaders */
|
||||
if (!ctx->Shader.CurrentProgram->LinkStatus) {
|
||||
if (!prog->LinkStatus) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"%s(shader not linked)", where);
|
||||
return GL_FALSE;
|
||||
@@ -1713,10 +1713,9 @@ _mesa_valid_to_render(struct gl_context *ctx, const char *where)
|
||||
#if 0 /* not normally enabled */
|
||||
{
|
||||
char errMsg[100];
|
||||
if (!_mesa_validate_shader_program(ctx, ctx->Shader.CurrentProgram,
|
||||
errMsg)) {
|
||||
if (!_mesa_validate_shader_program(ctx, prog, errMsg)) {
|
||||
_mesa_warning(ctx, "Shader program %u is invalid: %s",
|
||||
ctx->Shader.CurrentProgram->Name, errMsg);
|
||||
prog->Name, errMsg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1725,13 +1724,12 @@ _mesa_valid_to_render(struct gl_context *ctx, const char *where)
|
||||
* any stages that are not provided, the corresponding assembly shader
|
||||
* target will be validated below.
|
||||
*/
|
||||
for (i = 0; i < ctx->Shader.CurrentProgram->_NumLinkedShaders; i++) {
|
||||
switch (ctx->Shader.CurrentProgram->_LinkedShaders[i]->Type) {
|
||||
case GL_VERTEX_SHADER: vert_from_glsl_shader = true; break;
|
||||
case GL_GEOMETRY_SHADER_ARB: geom_from_glsl_shader = true; break;
|
||||
case GL_FRAGMENT_SHADER: frag_from_glsl_shader = true; break;
|
||||
}
|
||||
}
|
||||
vert_from_glsl_shader =
|
||||
prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL;
|
||||
geom_from_glsl_shader =
|
||||
prog->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL;
|
||||
frag_from_glsl_shader =
|
||||
prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -2117,11 +2117,12 @@ struct gl_shader_program
|
||||
|
||||
/**
|
||||
* Per-stage shaders resulting from the first stage of linking.
|
||||
*
|
||||
* Set of linked shaders for this program. The array is accessed using the
|
||||
* \c MESA_SHADER_* defines. Entries for non-existent stages will be
|
||||
* \c NULL.
|
||||
*/
|
||||
/*@{*/
|
||||
GLuint _NumLinkedShaders;
|
||||
struct gl_shader *_LinkedShaders[2];
|
||||
/*@}*/
|
||||
struct gl_shader *_LinkedShaders[MESA_SHADER_TYPES];
|
||||
};
|
||||
|
||||
|
||||
|
@@ -326,10 +326,12 @@ _mesa_free_shader_program_data(struct gl_context *ctx,
|
||||
shProg->TransformFeedback.NumVarying = 0;
|
||||
|
||||
|
||||
for (i = 0; i < shProg->_NumLinkedShaders; i++) {
|
||||
for (i = 0; i < MESA_SHADER_TYPES; i++) {
|
||||
if (shProg->_LinkedShaders[i] != NULL) {
|
||||
ctx->Driver.DeleteShader(ctx, shProg->_LinkedShaders[i]);
|
||||
shProg->_LinkedShaders[i] = NULL;
|
||||
}
|
||||
}
|
||||
shProg->_NumLinkedShaders = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -2238,8 +2238,12 @@ set_uniform_initializers(struct gl_context *ctx,
|
||||
{
|
||||
void *mem_ctx = NULL;
|
||||
|
||||
for (unsigned int i = 0; i < shader_program->_NumLinkedShaders; i++) {
|
||||
for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) {
|
||||
struct gl_shader *shader = shader_program->_LinkedShaders[i];
|
||||
|
||||
if (shader == NULL)
|
||||
continue;
|
||||
|
||||
foreach_iter(exec_list_iterator, iter, *shader->ir) {
|
||||
ir_instruction *ir = (ir_instruction *)iter.get();
|
||||
ir_variable *var = ir->as_variable();
|
||||
@@ -2467,7 +2471,10 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||
{
|
||||
assert(prog->LinkStatus);
|
||||
|
||||
for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
|
||||
for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
|
||||
if (prog->_LinkedShaders[i] == NULL)
|
||||
continue;
|
||||
|
||||
bool progress;
|
||||
exec_list *ir = prog->_LinkedShaders[i]->ir;
|
||||
const struct gl_shader_compiler_options *options =
|
||||
@@ -2511,10 +2518,13 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||
validate_ir_tree(ir);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
|
||||
for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
|
||||
struct gl_program *linked_prog;
|
||||
bool ok = true;
|
||||
|
||||
if (prog->_LinkedShaders[i] == NULL)
|
||||
continue;
|
||||
|
||||
linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]);
|
||||
|
||||
switch (prog->_LinkedShaders[i]->Type) {
|
||||
|
Reference in New Issue
Block a user