mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-21 18:00:13 +01:00
glsl: support compilation of geometry shaders
This commit adds all of the parsing and semantics for GLSL 150 style
geometry shaders.
v2 (Paul Berry <stereotype441@gmail.com>): Add a few missing calls to
get_pipeline_stage(). Fix some signed/unsigned comparison warnings.
Fix handling of NULL consumer in assign_varying_locations().
v3 (Bryan Cain <bryancain3@gmail.com>): fix indexing order of 2D
arrays. Also, allow interpolation qualifiers in geometry shaders.
v4 (Paul Berry <stereotype441@gmail.com>): Eliminate
get_pipeline_stage()--it is no longer needed thanks to 030ca23 (mesa:
renumber shader indices according to their placement in pipeline).
Remove 2D stuff. Move vertices_per_prim() to ir.h, so that it will be
accessible from outside the linker. Remove
inject_num_vertices_visitor. Rework for GLSL 1.50.
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
v5 (Paul Berry <stereotype441@gmail.com>): Split out
do_set_program_inouts() argument refactoring to a separate patch.
Move geom_array_resizing_visitor to later in the series.
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
parent
844bd71736
commit
2548092ad8
5 changed files with 103 additions and 11 deletions
|
|
@ -2056,11 +2056,11 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
|
||||||
var->interpolation = INTERP_QUALIFIER_NONE;
|
var->interpolation = INTERP_QUALIFIER_NONE;
|
||||||
|
|
||||||
if (var->interpolation != INTERP_QUALIFIER_NONE &&
|
if (var->interpolation != INTERP_QUALIFIER_NONE &&
|
||||||
!(state->target == vertex_shader && var->mode == ir_var_shader_out) &&
|
((state->target == vertex_shader && var->mode == ir_var_shader_in) ||
|
||||||
!(state->target == fragment_shader && var->mode == ir_var_shader_in)) {
|
(state->target == fragment_shader && var->mode == ir_var_shader_out))) {
|
||||||
_mesa_glsl_error(loc, state,
|
_mesa_glsl_error(loc, state,
|
||||||
"interpolation qualifier `%s' can only be applied to "
|
"interpolation qualifier `%s' cannot be applied to "
|
||||||
"vertex shader outputs and fragment shader inputs",
|
"vertex shader inputs or fragment shader outputs",
|
||||||
var->interpolation_string());
|
var->interpolation_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2662,6 +2662,26 @@ ast_declarator_list::hir(exec_list *instructions,
|
||||||
|
|
||||||
var = new(ctx) ir_variable(var_type, decl->identifier, ir_var_auto);
|
var = new(ctx) ir_variable(var_type, decl->identifier, ir_var_auto);
|
||||||
|
|
||||||
|
/* The 'varying in' and 'varying out' qualifiers can only be used with
|
||||||
|
* ARB_geometry_shader4 and EXT_geometry_shader4, which we don't support
|
||||||
|
* yet.
|
||||||
|
*/
|
||||||
|
if (this->type->qualifier.flags.q.varying) {
|
||||||
|
if (this->type->qualifier.flags.q.in) {
|
||||||
|
_mesa_glsl_error(& loc, state,
|
||||||
|
"`varying in' qualifier in declaration of "
|
||||||
|
"`%s' only valid for geometry shaders using "
|
||||||
|
"ARB_geometry_shader4 or EXT_geometry_shader4",
|
||||||
|
decl->identifier);
|
||||||
|
} else if (this->type->qualifier.flags.q.out) {
|
||||||
|
_mesa_glsl_error(& loc, state,
|
||||||
|
"`varying out' qualifier in declaration of "
|
||||||
|
"`%s' only valid for geometry shaders using "
|
||||||
|
"ARB_geometry_shader4 or EXT_geometry_shader4",
|
||||||
|
decl->identifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* From page 22 (page 28 of the PDF) of the GLSL 1.10 specification;
|
/* From page 22 (page 28 of the PDF) of the GLSL 1.10 specification;
|
||||||
*
|
*
|
||||||
* "Global variables can only use the qualifiers const,
|
* "Global variables can only use the qualifiers const,
|
||||||
|
|
@ -2906,7 +2926,7 @@ ast_declarator_list::hir(exec_list *instructions,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1778,3 +1778,24 @@ ir_rvalue::as_rvalue_to_saturate()
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
vertices_per_prim(GLenum prim)
|
||||||
|
{
|
||||||
|
switch (prim) {
|
||||||
|
case GL_POINTS:
|
||||||
|
return 1;
|
||||||
|
case GL_LINES:
|
||||||
|
return 2;
|
||||||
|
case GL_TRIANGLES:
|
||||||
|
return 3;
|
||||||
|
case GL_LINES_ADJACENCY:
|
||||||
|
return 4;
|
||||||
|
case GL_TRIANGLES_ADJACENCY:
|
||||||
|
return 6;
|
||||||
|
default:
|
||||||
|
assert(!"Bad primitive");
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2128,4 +2128,7 @@ extern void _mesa_print_ir(struct exec_list *instructions,
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
vertices_per_prim(GLenum prim);
|
||||||
|
|
||||||
#endif /* IR_H */
|
#endif /* IR_H */
|
||||||
|
|
|
||||||
|
|
@ -73,11 +73,14 @@
|
||||||
#include "linker.h"
|
#include "linker.h"
|
||||||
#include "link_varyings.h"
|
#include "link_varyings.h"
|
||||||
#include "ir_optimization.h"
|
#include "ir_optimization.h"
|
||||||
|
#include "ir_rvalue_visitor.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "main/shaderobj.h"
|
#include "main/shaderobj.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void linker_error(gl_shader_program *, const char *, ...);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Visitor that determines whether or not a variable is ever written.
|
* Visitor that determines whether or not a variable is ever written.
|
||||||
*/
|
*/
|
||||||
|
|
@ -402,6 +405,24 @@ validate_fragment_shader_executable(struct gl_shader_program *prog,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify that a geometry shader executable meets all semantic requirements
|
||||||
|
*
|
||||||
|
* Also sets prog->Geom.VerticesIn as a side effect.
|
||||||
|
*
|
||||||
|
* \param shader Geometry shader executable to be verified
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
validate_geometry_shader_executable(struct gl_shader_program *prog,
|
||||||
|
struct gl_shader *shader)
|
||||||
|
{
|
||||||
|
if (shader == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
unsigned num_vertices = vertices_per_prim(prog->Geom.InputType);
|
||||||
|
prog->Geom.VerticesIn = num_vertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a string describing the mode of a variable
|
* Generate a string describing the mode of a variable
|
||||||
|
|
@ -1613,11 +1634,15 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||||
unsigned num_vert_shaders = 0;
|
unsigned num_vert_shaders = 0;
|
||||||
struct gl_shader **frag_shader_list;
|
struct gl_shader **frag_shader_list;
|
||||||
unsigned num_frag_shaders = 0;
|
unsigned num_frag_shaders = 0;
|
||||||
|
struct gl_shader **geom_shader_list;
|
||||||
|
unsigned num_geom_shaders = 0;
|
||||||
|
|
||||||
vert_shader_list = (struct gl_shader **)
|
vert_shader_list = (struct gl_shader **)
|
||||||
calloc(prog->NumShaders, sizeof(struct gl_shader *));
|
calloc(prog->NumShaders, sizeof(struct gl_shader *));
|
||||||
frag_shader_list = (struct gl_shader **)
|
frag_shader_list = (struct gl_shader **)
|
||||||
calloc(prog->NumShaders, sizeof(struct gl_shader *));
|
calloc(prog->NumShaders, sizeof(struct gl_shader *));
|
||||||
|
geom_shader_list = (struct gl_shader **)
|
||||||
|
calloc(prog->NumShaders, sizeof(struct gl_shader *));
|
||||||
|
|
||||||
unsigned min_version = UINT_MAX;
|
unsigned min_version = UINT_MAX;
|
||||||
unsigned max_version = 0;
|
unsigned max_version = 0;
|
||||||
|
|
@ -1643,8 +1668,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||||
num_frag_shaders++;
|
num_frag_shaders++;
|
||||||
break;
|
break;
|
||||||
case GL_GEOMETRY_SHADER:
|
case GL_GEOMETRY_SHADER:
|
||||||
/* FINISHME: Support geometry shaders. */
|
geom_shader_list[num_geom_shaders] = prog->Shaders[i];
|
||||||
assert(prog->Shaders[i]->Type != GL_GEOMETRY_SHADER);
|
num_geom_shaders++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1706,6 +1731,22 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||||
sh);
|
sh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (num_geom_shaders > 0) {
|
||||||
|
gl_shader *const sh =
|
||||||
|
link_intrastage_shaders(mem_ctx, ctx, prog, geom_shader_list,
|
||||||
|
num_geom_shaders);
|
||||||
|
|
||||||
|
if (!prog->LinkStatus)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
validate_geometry_shader_executable(prog, sh);
|
||||||
|
if (!prog->LinkStatus)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
_mesa_reference_shader(ctx, &prog->_LinkedShaders[MESA_SHADER_GEOMETRY],
|
||||||
|
sh);
|
||||||
|
}
|
||||||
|
|
||||||
/* Here begins the inter-stage linking phase. Some initial validation is
|
/* Here begins the inter-stage linking phase. Some initial validation is
|
||||||
* performed, then locations are assigned for uniforms, attributes, and
|
* performed, then locations are assigned for uniforms, attributes, and
|
||||||
* varyings.
|
* varyings.
|
||||||
|
|
@ -1792,7 +1833,11 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||||
prog->_LinkedShaders[MESA_SHADER_VERTEX],
|
prog->_LinkedShaders[MESA_SHADER_VERTEX],
|
||||||
VERT_ATTRIB_GENERIC0, VARYING_SLOT_VAR0);
|
VERT_ATTRIB_GENERIC0, VARYING_SLOT_VAR0);
|
||||||
}
|
}
|
||||||
/* FINISHME: Geometry shaders not implemented yet */
|
if (prog->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) {
|
||||||
|
link_invalidate_variable_locations(
|
||||||
|
prog->_LinkedShaders[MESA_SHADER_GEOMETRY],
|
||||||
|
VARYING_SLOT_VAR0, VARYING_SLOT_VAR0);
|
||||||
|
}
|
||||||
if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL) {
|
if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL) {
|
||||||
link_invalidate_variable_locations(
|
link_invalidate_variable_locations(
|
||||||
prog->_LinkedShaders[MESA_SHADER_FRAGMENT],
|
prog->_LinkedShaders[MESA_SHADER_FRAGMENT],
|
||||||
|
|
@ -1826,7 +1871,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||||
* non-zero, but the program object has no vertex or geometry
|
* non-zero, but the program object has no vertex or geometry
|
||||||
* shader;
|
* shader;
|
||||||
*/
|
*/
|
||||||
if (first >= MESA_SHADER_FRAGMENT) {
|
if (first == MESA_SHADER_FRAGMENT) {
|
||||||
linker_error(prog, "Transform feedback varyings specified, but "
|
linker_error(prog, "Transform feedback varyings specified, but "
|
||||||
"no vertex or geometry shader is present.");
|
"no vertex or geometry shader is present.");
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -1950,6 +1995,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||||
done:
|
done:
|
||||||
free(vert_shader_list);
|
free(vert_shader_list);
|
||||||
free(frag_shader_list);
|
free(frag_shader_list);
|
||||||
|
free(geom_shader_list);
|
||||||
|
|
||||||
for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
|
for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
|
||||||
if (prog->_LinkedShaders[i] == NULL)
|
if (prog->_LinkedShaders[i] == NULL)
|
||||||
|
|
|
||||||
|
|
@ -1852,7 +1852,7 @@ struct gl_program
|
||||||
GLuint Id;
|
GLuint Id;
|
||||||
GLubyte *String; /**< Null-terminated program text */
|
GLubyte *String; /**< Null-terminated program text */
|
||||||
GLint RefCount;
|
GLint RefCount;
|
||||||
GLenum Target; /**< GL_VERTEX/FRAGMENT_PROGRAM_ARB */
|
GLenum Target; /**< GL_VERTEX/FRAGMENT_PROGRAM_ARB, GL_GEOMETRY_PROGRAM_NV */
|
||||||
GLenum Format; /**< String encoding format */
|
GLenum Format; /**< String encoding format */
|
||||||
|
|
||||||
struct prog_instruction *Instructions;
|
struct prog_instruction *Instructions;
|
||||||
|
|
@ -1919,6 +1919,7 @@ struct gl_geometry_program
|
||||||
{
|
{
|
||||||
struct gl_program Base; /**< base class */
|
struct gl_program Base; /**< base class */
|
||||||
|
|
||||||
|
GLint VerticesIn;
|
||||||
GLint VerticesOut;
|
GLint VerticesOut;
|
||||||
GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB,
|
GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB,
|
||||||
GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */
|
GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */
|
||||||
|
|
@ -2321,6 +2322,7 @@ struct gl_shader_program
|
||||||
|
|
||||||
/** Geometry shader state - copied into gl_geometry_program at link time */
|
/** Geometry shader state - copied into gl_geometry_program at link time */
|
||||||
struct {
|
struct {
|
||||||
|
GLint VerticesIn;
|
||||||
GLint VerticesOut;
|
GLint VerticesOut;
|
||||||
GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB,
|
GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB,
|
||||||
GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */
|
GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue