summaryrefslogtreecommitdiffstats
path: root/src/mesa/state_tracker
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/state_tracker')
-rw-r--r--src/mesa/state_tracker/st_atom.c4
-rw-r--r--src/mesa/state_tracker/st_atom.h2
-rw-r--r--src/mesa/state_tracker/st_atom_clip.c2
-rw-r--r--src/mesa/state_tracker/st_atom_constbuf.c28
-rw-r--r--src/mesa/state_tracker/st_atom_pixeltransfer.c8
-rw-r--r--src/mesa/state_tracker/st_atom_sampler.c3
-rw-r--r--src/mesa/state_tracker/st_atom_shader.c44
-rw-r--r--src/mesa/state_tracker/st_atom_texture.c98
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.c6
-rw-r--r--src/mesa/state_tracker/st_cb_clear.c2
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c6
-rw-r--r--src/mesa/state_tracker/st_cb_drawtex.c4
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.c26
-rw-r--r--src/mesa/state_tracker/st_cb_program.c60
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c2
-rw-r--r--src/mesa/state_tracker/st_context.c17
-rw-r--r--src/mesa/state_tracker/st_context.h9
-rw-r--r--src/mesa/state_tracker/st_debug.c2
-rw-r--r--src/mesa/state_tracker/st_draw.c89
-rw-r--r--src/mesa/state_tracker/st_extensions.c9
-rw-r--r--src/mesa/state_tracker/st_gl_api.h4
-rw-r--r--src/mesa/state_tracker/st_manager.c103
-rw-r--r--src/mesa/state_tracker/st_manager.h3
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.c46
-rw-r--r--src/mesa/state_tracker/st_program.c245
-rw-r--r--src/mesa/state_tracker/st_program.h50
26 files changed, 736 insertions, 136 deletions
diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c
index 6f293128d3a..e389e57346b 100644
--- a/src/mesa/state_tracker/st_atom.c
+++ b/src/mesa/state_tracker/st_atom.c
@@ -47,6 +47,7 @@ static const struct st_tracked_state *atoms[] =
&st_finalize_textures,
&st_update_fp,
+ &st_update_gp,
&st_update_vp,
&st_update_rasterizer,
@@ -59,6 +60,7 @@ static const struct st_tracked_state *atoms[] =
&st_update_framebuffer,
&st_update_msaa,
&st_update_vs_constants,
+ &st_update_gs_constants,
&st_update_fs_constants,
&st_update_pixel_transfer
};
@@ -115,6 +117,8 @@ static void check_program_state( struct st_context *st )
if (ctx->FragmentProgram._Current != &st->fp->Base)
st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
+ if (ctx->GeometryProgram._Current != &st->gp->Base)
+ st->dirty.st |= ST_NEW_GEOMETRY_PROGRAM;
}
diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h
index 0c25269e0a4..1f0fef63df5 100644
--- a/src/mesa/state_tracker/st_atom.h
+++ b/src/mesa/state_tracker/st_atom.h
@@ -48,6 +48,7 @@ extern const struct st_tracked_state st_update_framebuffer;
extern const struct st_tracked_state st_update_clip;
extern const struct st_tracked_state st_update_depth_stencil_alpha;
extern const struct st_tracked_state st_update_fp;
+extern const struct st_tracked_state st_update_gp;
extern const struct st_tracked_state st_update_vp;
extern const struct st_tracked_state st_update_rasterizer;
extern const struct st_tracked_state st_update_polygon_stipple;
@@ -59,6 +60,7 @@ extern const struct st_tracked_state st_update_sampler;
extern const struct st_tracked_state st_update_texture;
extern const struct st_tracked_state st_finalize_textures;
extern const struct st_tracked_state st_update_fs_constants;
+extern const struct st_tracked_state st_update_gs_constants;
extern const struct st_tracked_state st_update_vs_constants;
extern const struct st_tracked_state st_update_pixel_transfer;
diff --git a/src/mesa/state_tracker/st_atom_clip.c b/src/mesa/state_tracker/st_atom_clip.c
index 80c0e921398..16f7aaae6f4 100644
--- a/src/mesa/state_tracker/st_atom_clip.c
+++ b/src/mesa/state_tracker/st_atom_clip.c
@@ -55,6 +55,8 @@ static void update_clip( struct st_context *st )
clip.nr++;
}
}
+
+ clip.depth_clamp = st->ctx->Transform.DepthClamp != GL_FALSE;
if (memcmp(&clip, &st->state.clip, sizeof(clip)) != 0) {
st->state.clip = clip;
diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c
index 28439103b23..6f9d71e845b 100644
--- a/src/mesa/state_tracker/st_atom_constbuf.c
+++ b/src/mesa/state_tracker/st_atom_constbuf.c
@@ -32,8 +32,8 @@
*/
#include "main/imports.h"
-#include "shader/prog_parameter.h"
-#include "shader/prog_print.h"
+#include "program/prog_parameter.h"
+#include "program/prog_print.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
@@ -59,7 +59,8 @@ void st_upload_constants( struct st_context *st,
struct pipe_resource **cbuf = &st->state.constants[shader_type];
assert(shader_type == PIPE_SHADER_VERTEX ||
- shader_type == PIPE_SHADER_FRAGMENT);
+ shader_type == PIPE_SHADER_FRAGMENT ||
+ shader_type == PIPE_SHADER_GEOMETRY);
/* update constants */
if (params && params->NumParameters) {
@@ -139,3 +140,24 @@ const struct st_tracked_state st_update_fs_constants = {
update_fs_constants /* update */
};
+/* Geometry shader:
+ */
+static void update_gs_constants(struct st_context *st )
+{
+ struct st_geometry_program *gp = st->gp;
+ struct gl_program_parameter_list *params;
+
+ if (gp) {
+ params = gp->Base.Base.Parameters;
+ st_upload_constants( st, params, PIPE_SHADER_GEOMETRY );
+ }
+}
+
+const struct st_tracked_state st_update_gs_constants = {
+ "st_update_gs_constants", /* name */
+ { /* dirty */
+ (_NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS), /* mesa */
+ ST_NEW_GEOMETRY_PROGRAM, /* st */
+ },
+ update_gs_constants /* update */
+};
diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c
index b8644faaf83..b88c74fa03a 100644
--- a/src/mesa/state_tracker/st_atom_pixeltransfer.c
+++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c
@@ -36,10 +36,10 @@
#include "main/imports.h"
#include "main/image.h"
#include "main/macros.h"
-#include "shader/program.h"
-#include "shader/prog_instruction.h"
-#include "shader/prog_parameter.h"
-#include "shader/prog_print.h"
+#include "program/program.h"
+#include "program/prog_instruction.h"
+#include "program/prog_parameter.h"
+#include "program/prog_print.h"
#include "st_context.h"
#include "st_format.h"
diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c
index 92fe72d4df6..f147d768084 100644
--- a/src/mesa/state_tracker/st_atom_sampler.c
+++ b/src/mesa/state_tracker/st_atom_sampler.c
@@ -199,7 +199,8 @@ update_samplers(struct st_context *st)
if (sampler->min_lod < texobj->BaseLevel)
sampler->min_lod = texobj->BaseLevel;
- sampler->max_lod = MIN2((GLfloat) texobj->MaxLevel, texobj->MaxLod);
+ sampler->max_lod = MIN2((GLfloat) texobj->MaxLevel,
+ (texobj->MaxLod + texobj->BaseLevel));
if (sampler->max_lod < sampler->min_lod) {
/* The GL spec doesn't seem to specify what to do in this case.
* Swap the values.
diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c
index ad151edf3bd..cebaad5f000 100644
--- a/src/mesa/state_tracker/st_atom_shader.c
+++ b/src/mesa/state_tracker/st_atom_shader.c
@@ -37,7 +37,7 @@
#include "main/imports.h"
#include "main/mtypes.h"
-#include "shader/program.h"
+#include "program/program.h"
#include "pipe/p_context.h"
#include "pipe/p_shader_tokens.h"
@@ -66,7 +66,19 @@ translate_fp(struct st_context *st,
}
}
+/*
+ * Translate geometry program if needed.
+ */
+static void
+translate_gp(struct st_context *st,
+ struct st_geometry_program *stgp)
+{
+ if (!stgp->tgsi.tokens) {
+ assert(stgp->Base.Base.NumInstructions > 1);
+ st_translate_geometry_program(st, stgp);
+ }
+}
/**
* Find a translated vertex program that corresponds to stvp and
@@ -222,3 +234,33 @@ const struct st_tracked_state st_update_vp = {
},
update_vp /* update */
};
+
+static void
+update_gp( struct st_context *st )
+{
+
+ struct st_geometry_program *stgp;
+
+ if (!st->ctx->GeometryProgram._Current) {
+ cso_set_geometry_shader_handle(st->cso_context, NULL);
+ return;
+ }
+
+ stgp = st_geometry_program(st->ctx->GeometryProgram._Current);
+ assert(stgp->Base.Base.Target == MESA_GEOMETRY_PROGRAM);
+
+ translate_gp(st, stgp);
+
+ st_reference_geomprog(st, &st->gp, stgp);
+
+ cso_set_geometry_shader_handle(st->cso_context, stgp->driver_shader);
+}
+
+const struct st_tracked_state st_update_gp = {
+ "st_update_gp", /* name */
+ { /* dirty */
+ 0, /* mesa */
+ ST_NEW_GEOMETRY_PROGRAM /* st */
+ },
+ update_gp /* update */
+};
diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c
index 895681cb230..981129621c7 100644
--- a/src/mesa/state_tracker/st_atom_texture.c
+++ b/src/mesa/state_tracker/st_atom_texture.c
@@ -33,7 +33,7 @@
#include "main/macros.h"
-#include "shader/prog_instruction.h"
+#include "program/prog_instruction.h"
#include "st_context.h"
#include "st_atom.h"
@@ -41,16 +41,84 @@
#include "st_format.h"
#include "st_cb_texture.h"
#include "pipe/p_context.h"
+#include "util/u_format.h"
#include "util/u_inlines.h"
#include "cso_cache/cso_context.h"
+/**
+ * Combine depth texture mode with "swizzle" so that depth mode swizzling
+ * takes place before texture swizzling, and return the resulting swizzle.
+ * If the format is not a depth format, return "swizzle" unchanged.
+ *
+ * \param format PIPE_FORMAT_*.
+ * \param swizzle Texture swizzle, a bitmask computed using MAKE_SWIZZLE4.
+ * \param depthmode One of GL_LUMINANCE, GL_INTENSITY, GL_ALPHA.
+ */
+static GLuint apply_depthmode(enum pipe_format format,
+ GLuint swizzle, GLenum depthmode)
+{
+ const struct util_format_description *desc =
+ util_format_description(format);
+ unsigned char swiz[4];
+ unsigned i;
+
+ if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS ||
+ desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_NONE) {
+ /* Not a depth format. */
+ return swizzle;
+ }
+
+ for (i = 0; i < 4; i++)
+ swiz[i] = GET_SWZ(swizzle, i);
+
+ switch (depthmode) {
+ case GL_LUMINANCE:
+ /* Rewrite reads from W to ONE, and reads from XYZ to XXX. */
+ for (i = 0; i < 4; i++)
+ if (swiz[i] == SWIZZLE_W)
+ swiz[i] = SWIZZLE_ONE;
+ else if (swiz[i] < SWIZZLE_W)
+ swiz[i] = SWIZZLE_X;
+ break;
+
+ case GL_INTENSITY:
+ /* Rewrite reads from XYZW to XXXX. */
+ for (i = 0; i < 4; i++)
+ if (swiz[i] <= SWIZZLE_W)
+ swiz[i] = SWIZZLE_X;
+ break;
+
+ case GL_ALPHA:
+ /* Rewrite reads from W to X, and reads from XYZ to 000. */
+ for (i = 0; i < 4; i++)
+ if (swiz[i] == SWIZZLE_W)
+ swiz[i] = SWIZZLE_X;
+ else if (swiz[i] < SWIZZLE_W)
+ swiz[i] = SWIZZLE_ZERO;
+ break;
+ }
+
+ return MAKE_SWIZZLE4(swiz[0], swiz[1], swiz[2], swiz[3]);
+}
+
+/**
+ * Return TRUE if the swizzling described by "swizzle" and
+ * "depthmode" (for depth textures only) is different from the swizzling
+ * set in the given sampler view.
+ *
+ * \param sv A sampler view.
+ * \param swizzle Texture swizzle, a bitmask computed using MAKE_SWIZZLE4.
+ * \param depthmode One of GL_LUMINANCE, GL_INTENSITY, GL_ALPHA.
+ */
static boolean check_sampler_swizzle(struct pipe_sampler_view *sv,
- uint32_t _swizzle)
+ GLuint swizzle, GLenum depthmode)
{
- if ((sv->swizzle_r != GET_SWZ(_swizzle, 0)) ||
- (sv->swizzle_g != GET_SWZ(_swizzle, 1)) ||
- (sv->swizzle_b != GET_SWZ(_swizzle, 2)) ||
- (sv->swizzle_a != GET_SWZ(_swizzle, 3)))
+ swizzle = apply_depthmode(sv->texture->format, swizzle, depthmode);
+
+ if ((sv->swizzle_r != GET_SWZ(swizzle, 0)) ||
+ (sv->swizzle_g != GET_SWZ(swizzle, 1)) ||
+ (sv->swizzle_b != GET_SWZ(swizzle, 2)) ||
+ (sv->swizzle_a != GET_SWZ(swizzle, 3)))
return true;
return false;
}
@@ -62,16 +130,19 @@ st_create_texture_sampler_view_from_stobj(struct pipe_context *pipe,
{
struct pipe_sampler_view templ;
+ GLuint swizzle = apply_depthmode(stObj->pt->format,
+ stObj->base._Swizzle,
+ stObj->base.DepthMode);
u_sampler_view_default_template(&templ,
stObj->pt,
format);
- if (stObj->base._Swizzle != SWIZZLE_NOOP) {
- templ.swizzle_r = GET_SWZ(stObj->base._Swizzle, 0);
- templ.swizzle_g = GET_SWZ(stObj->base._Swizzle, 1);
- templ.swizzle_b = GET_SWZ(stObj->base._Swizzle, 2);
- templ.swizzle_a = GET_SWZ(stObj->base._Swizzle, 3);
+ if (swizzle != SWIZZLE_NOOP) {
+ templ.swizzle_r = GET_SWZ(swizzle, 0);
+ templ.swizzle_g = GET_SWZ(swizzle, 1);
+ templ.swizzle_b = GET_SWZ(swizzle, 2);
+ templ.swizzle_a = GET_SWZ(swizzle, 3);
}
return pipe->create_sampler_view(pipe, stObj->pt, &templ);
@@ -150,7 +221,10 @@ update_textures(struct st_context *st)
/* if sampler view has changed dereference it */
if (stObj->sampler_view)
- if (check_sampler_swizzle(stObj->sampler_view, stObj->base._Swizzle) || (st_view_format != stObj->sampler_view->format))
+ if (check_sampler_swizzle(stObj->sampler_view,
+ stObj->base._Swizzle,
+ stObj->base.DepthMode) ||
+ (st_view_format != stObj->sampler_view->format))
pipe_sampler_view_reference(&stObj->sampler_view, NULL);
sampler_view = st_get_texture_sampler_view_from_stobj(stObj, pipe, st_view_format);
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index 5aca1105eeb..ba600ccef6d 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -34,8 +34,8 @@
#include "main/image.h"
#include "main/bufferobj.h"
#include "main/macros.h"
-#include "shader/program.h"
-#include "shader/prog_print.h"
+#include "program/program.h"
+#include "program/prog_print.h"
#include "st_context.h"
#include "st_atom.h"
@@ -49,7 +49,7 @@
#include "util/u_inlines.h"
#include "util/u_draw_quad.h"
#include "util/u_simple_shaders.h"
-#include "shader/prog_instruction.h"
+#include "program/prog_instruction.h"
#include "cso_cache/cso_context.h"
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index b15792504af..ea2414c4a00 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -36,7 +36,7 @@
#include "main/glheader.h"
#include "main/formats.h"
#include "main/macros.h"
-#include "shader/prog_instruction.h"
+#include "program/prog_instruction.h"
#include "st_context.h"
#include "st_atom.h"
#include "st_cb_accum.h"
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index f74d8cd42d0..69a3dd45e80 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -36,8 +36,8 @@
#include "main/macros.h"
#include "main/texformat.h"
#include "main/texstore.h"
-#include "shader/program.h"
-#include "shader/prog_print.h"
+#include "program/program.h"
+#include "program/prog_print.h"
#include "st_debug.h"
#include "st_context.h"
@@ -58,7 +58,7 @@
#include "util/u_draw_quad.h"
#include "util/u_format.h"
#include "util/u_math.h"
-#include "shader/prog_instruction.h"
+#include "program/prog_instruction.h"
#include "cso_cache/cso_context.h"
diff --git a/src/mesa/state_tracker/st_cb_drawtex.c b/src/mesa/state_tracker/st_cb_drawtex.c
index 3d99d6c8a11..b191a7f8902 100644
--- a/src/mesa/state_tracker/st_cb_drawtex.c
+++ b/src/mesa/state_tracker/st_cb_drawtex.c
@@ -16,8 +16,8 @@
#include "main/image.h"
#include "main/bufferobj.h"
#include "main/macros.h"
-#include "shader/program.h"
-#include "shader/prog_print.h"
+#include "program/program.h"
+#include "program/prog_print.h"
#include "st_context.h"
#include "st_atom.h"
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index 46f27ced6c3..13119ce2037 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -458,25 +458,37 @@ st_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
{
struct st_context *st = st_context(ctx);
struct pipe_screen *screen = st->pipe->screen;
- const struct gl_renderbuffer *depthRb =
- fb->Attachment[BUFFER_DEPTH].Renderbuffer;
- const struct gl_renderbuffer *stencilRb =
- fb->Attachment[BUFFER_STENCIL].Renderbuffer;
+ const struct gl_renderbuffer_attachment *depth =
+ &fb->Attachment[BUFFER_DEPTH];
+ const struct gl_renderbuffer_attachment *stencil =
+ &fb->Attachment[BUFFER_STENCIL];
GLuint i;
- if (stencilRb && depthRb && stencilRb != depthRb) {
+ if (depth->Type && stencil->Type && depth->Type != stencil->Type) {
+ fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
+ return;
+ }
+ if (depth->Type == GL_RENDERBUFFER_EXT &&
+ stencil->Type == GL_RENDERBUFFER_EXT &&
+ depth->Renderbuffer != stencil->Renderbuffer) {
+ fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
+ return;
+ }
+ if (depth->Type == GL_TEXTURE &&
+ stencil->Type == GL_TEXTURE &&
+ depth->Texture != stencil->Texture) {
fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
return;
}
if (!st_validate_attachment(screen,
- &fb->Attachment[BUFFER_DEPTH],
+ depth,
PIPE_BIND_DEPTH_STENCIL)) {
fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
return;
}
if (!st_validate_attachment(screen,
- &fb->Attachment[BUFFER_STENCIL],
+ stencil,
PIPE_BIND_DEPTH_STENCIL)) {
fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
return;
diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
index 2361b2eddfe..6aa7e79af95 100644
--- a/src/mesa/state_tracker/st_cb_program.c
+++ b/src/mesa/state_tracker/st_cb_program.c
@@ -33,10 +33,9 @@
#include "main/glheader.h"
#include "main/macros.h"
#include "main/enums.h"
-#include "shader/prog_instruction.h"
-#include "shader/prog_parameter.h"
-#include "shader/program.h"
-#include "shader/shader_api.h"
+#include "main/shaderapi.h"
+#include "program/prog_instruction.h"
+#include "program/program.h"
#include "cso_cache/cso_context.h"
#include "draw/draw_context.h"
@@ -67,6 +66,9 @@ static void st_bind_program( GLcontext *ctx,
case GL_FRAGMENT_PROGRAM_ARB:
st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
break;
+ case MESA_GEOMETRY_PROGRAM:
+ st->dirty.st |= ST_NEW_GEOMETRY_PROGRAM;
+ break;
}
}
@@ -75,15 +77,13 @@ static void st_bind_program( GLcontext *ctx,
* Called via ctx->Driver.UseProgram() to bind a linked GLSL program
* (vertex shader + fragment shader).
*/
-static void st_use_program( GLcontext *ctx,
- GLuint program )
+static void st_use_program( GLcontext *ctx, struct gl_shader_program *shProg)
{
struct st_context *st = st_context(ctx);
st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
-
- _mesa_use_program(ctx, program);
+ st->dirty.st |= ST_NEW_GEOMETRY_PROGRAM;
}
@@ -120,6 +120,17 @@ static struct gl_program *st_new_program( GLcontext *ctx,
id );
}
+ case MESA_GEOMETRY_PROGRAM: {
+ struct st_geometry_program *prog = ST_CALLOC_STRUCT(st_geometry_program);
+
+ prog->serialNo = SerialNo++;
+
+ return _mesa_init_geometry_program( ctx,
+ &prog->Base,
+ target,
+ id );
+ }
+
default:
assert(0);
return NULL;
@@ -139,6 +150,21 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog)
st_vp_release_varients( st, stvp );
}
break;
+ case MESA_GEOMETRY_PROGRAM:
+ {
+ struct st_geometry_program *stgp = (struct st_geometry_program *) prog;
+
+ if (stgp->driver_shader) {
+ cso_delete_geometry_shader(st->cso_context, stgp->driver_shader);
+ stgp->driver_shader = NULL;
+ }
+
+ if (stgp->tgsi.tokens) {
+ st_free_tokens((void *) stgp->tgsi.tokens);
+ stgp->tgsi.tokens = NULL;
+ }
+ }
+ break;
case GL_FRAGMENT_PROGRAM_ARB:
{
struct st_fragment_program *stfp = (struct st_fragment_program *) prog;
@@ -201,6 +227,24 @@ static GLboolean st_program_string_notify( GLcontext *ctx,
if (st->fp == stfp)
st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
}
+ else if (target == MESA_GEOMETRY_PROGRAM) {
+ struct st_geometry_program *stgp = (struct st_geometry_program *) prog;
+
+ stgp->serialNo++;
+
+ if (stgp->driver_shader) {
+ cso_delete_geometry_shader(st->cso_context, stgp->driver_shader);
+ stgp->driver_shader = NULL;
+ }
+
+ if (stgp->tgsi.tokens) {
+ st_free_tokens((void *) stgp->tgsi.tokens);
+ stgp->tgsi.tokens = NULL;
+ }
+
+ if (st->gp == stgp)
+ st->dirty.st |= ST_NEW_GEOMETRY_PROGRAM;
+ }
else if (target == GL_VERTEX_PROGRAM_ARB) {
struct st_vertex_program *stvp = (struct st_vertex_program *) prog;
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 8f7ebeed976..4c3e3688dd8 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -112,7 +112,7 @@ st_NewTextureObject(GLcontext * ctx, GLuint name, GLenum target)
return &obj->base;
}
-/** called via ctx->Driver.DeleteTextureImage() */
+/** called via ctx->Driver.DeleteTextureObject() */
static void
st_DeleteTextureObject(GLcontext *ctx,
struct gl_texture_object *texObj)
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index 0bf030e9876..7eb5f32611d 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -27,8 +27,8 @@
#include "main/imports.h"
#include "main/context.h"
+#include "main/shaderobj.h"
#include "vbo/vbo.h"
-#include "shader/shader_api.h"
#include "glapi/glapi.h"
#include "st_context.h"
#include "st_debug.h"
@@ -153,7 +153,7 @@ st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe )
}
-struct st_context *st_create_context(struct pipe_context *pipe,
+struct st_context *st_create_context(gl_api api, struct pipe_context *pipe,
const __GLcontextModes *visual,
struct st_context *share)
{
@@ -164,16 +164,7 @@ struct st_context *st_create_context(struct pipe_context *pipe,
memset(&funcs, 0, sizeof(funcs));
st_init_driver_functions(&funcs);
-#if FEATURE_GL
- ctx = _mesa_create_context_for_api(API_OPENGL,
- visual, shareCtx, &funcs, NULL);
-#elif FEATURE_ES1
- ctx = _mesa_create_context_for_api(API_OPENGLES,
- visual, shareCtx, &funcs, NULL);
-#elif FEATURE_ES2
- ctx = _mesa_create_context_for_api(API_OPENGLES2,
- visual, shareCtx, &funcs, NULL);
-#endif
+ ctx = _mesa_create_context_for_api(api, visual, shareCtx, &funcs, NULL);
/* XXX: need a capability bit in gallium to query if the pipe
* driver prefers DP4 or MUL/MAD for vertex transformation.
@@ -254,7 +245,7 @@ void st_destroy_context( struct st_context *st )
void st_init_driver_functions(struct dd_function_table *functions)
{
- _mesa_init_glsl_driver_functions(functions);
+ _mesa_init_shader_object_functions(functions);
st_init_accum_functions(functions);
st_init_blit_functions(functions);
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index efff55a9057..a147a021176 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -29,7 +29,7 @@
#define ST_CONTEXT_H
#include "main/mtypes.h"
-#include "shader/prog_cache.h"
+#include "program/prog_cache.h"
#include "pipe/p_state.h"
#include "state_tracker/st_api.h"
@@ -51,6 +51,7 @@ struct bitmap_cache;
#define ST_NEW_VERTEX_PROGRAM 0x4
#define ST_NEW_FRAMEBUFFER 0x8
#define ST_NEW_EDGEFLAGS_DATA 0x10
+#define ST_NEW_GEOMETRY_PROGRAM 0x20
struct st_state_flags {
@@ -95,7 +96,7 @@ struct st_context
struct pipe_sampler_state samplers[PIPE_MAX_SAMPLERS];
struct pipe_sampler_state *sampler_list[PIPE_MAX_SAMPLERS];
struct pipe_clip_state clip;
- struct pipe_resource *constants[2];
+ struct pipe_resource *constants[PIPE_SHADER_TYPES];
struct pipe_framebuffer_state framebuffer;
struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
struct pipe_scissor_state scissor;
@@ -130,6 +131,7 @@ struct st_context
struct st_vertex_program *vp; /**< Currently bound vertex program */
struct st_fragment_program *fp; /**< Currently bound fragment program */
+ struct st_geometry_program *gp; /**< Currently bound geometry program */
struct st_vp_varient *vp_varient;
@@ -259,7 +261,8 @@ extern int
st_get_msaa(void);
extern struct st_context *
-st_create_context(struct pipe_context *pipe, const __GLcontextModes *visual,
+st_create_context(gl_api api, struct pipe_context *pipe,
+ const __GLcontextModes *visual,
struct st_context *share);
extern void
diff --git a/src/mesa/state_tracker/st_debug.c b/src/mesa/state_tracker/st_debug.c
index 0b3768341ef..ebf6ec6e7e2 100644
--- a/src/mesa/state_tracker/st_debug.c
+++ b/src/mesa/state_tracker/st_debug.c
@@ -27,7 +27,7 @@
#include "main/context.h"
-#include "shader/prog_print.h"
+#include "program/prog_print.h"
#include "pipe/p_state.h"
#include "pipe/p_shader_tokens.h"
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index eb2e5b2bbf7..5821da4889d 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -43,7 +43,7 @@
#include "main/imports.h"
#include "main/image.h"
#include "main/macros.h"
-#include "shader/prog_uniform.h"
+#include "program/prog_uniform.h"
#include "vbo/vbo.h"
@@ -57,6 +57,7 @@
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
#include "util/u_format.h"
+#include "util/u_prim.h"
#include "draw/draw_context.h"
#include "cso_cache/cso_context.h"
@@ -517,10 +518,21 @@ check_uniforms(GLcontext *ctx)
}
-static unsigned translate_prim( GLcontext *ctx,
- unsigned prim )
+/**
+ * Translate OpenGL primtive type (GL_POINTS, GL_TRIANGLE_STRIP, etc) to
+ * the corresponding Gallium type.
+ */
+static unsigned
+translate_prim(const GLcontext *ctx, unsigned prim)
{
+ /* GL prims should match Gallium prims, spot-check a few */
+ assert(GL_POINTS == PIPE_PRIM_POINTS);
+ assert(GL_QUADS == PIPE_PRIM_QUADS);
+ assert(GL_TRIANGLE_STRIP_ADJACENCY == PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY);
+
/* Avoid quadstrips if it's easy to do so:
+ * Note: it's imporant to do the correct trimming if we change the prim type!
+ * We do that wherever this function is called.
*/
if (prim == GL_QUAD_STRIP &&
ctx->Light.ShadeModel != GL_FLAT &&
@@ -531,6 +543,8 @@ static unsigned translate_prim( GLcontext *ctx,
return prim;
}
+
+
/**
* This function gets plugged into the VBO module and is called when
* we have something to render.
@@ -639,7 +653,6 @@ st_draw_vbo(GLcontext *ctx,
struct gl_buffer_object *bufobj = ib->obj;
struct pipe_resource *indexBuf = NULL;
unsigned indexSize, indexOffset, i;
- unsigned prim;
switch (ib->type) {
case GL_UNSIGNED_INT:
@@ -678,27 +691,41 @@ st_draw_vbo(GLcontext *ctx,
* need a bit of work...
*/
for (i = 0; i < nr_prims; i++) {
- prim = translate_prim( ctx, prims[i].mode );
-
- pipe->draw_range_elements(pipe, indexBuf, indexSize, 0,
- min_index, max_index, prim,
- prims[i].start + indexOffset, prims[i].count);
+ unsigned vcount = prims[i].count;
+ unsigned prim = translate_prim(ctx, prims[i].mode);
+
+ if (u_trim_pipe_prim(prims[i].mode, &vcount)) {
+ pipe->draw_range_elements(pipe, indexBuf, indexSize,
+ prims[i].basevertex,
+ min_index, max_index, prim,
+ prims[i].start + indexOffset, vcount);
+ }
}
}
else {
for (i = 0; i < nr_prims; i++) {
- prim = translate_prim( ctx, prims[i].mode );
+ unsigned vcount = prims[i].count;
+ unsigned prim = translate_prim(ctx, prims[i].mode);
- if (prims[i].num_instances == 1) {
- pipe->draw_elements(pipe, indexBuf, indexSize, 0, prim,
- prims[i].start + indexOffset,
- prims[i].count);
- }
- else {
- pipe->draw_elements_instanced(pipe, indexBuf, indexSize, 0, prim,
- prims[i].start + indexOffset,
- prims[i].count,
- 0, prims[i].num_instances);
+ if (u_trim_pipe_prim(prims[i].mode, &vcount)) {
+ if (prims[i].num_instances == 1) {
+ pipe->draw_elements(pipe, indexBuf,
+ indexSize,
+ prims[i].basevertex,
+ prim,
+ prims[i].start + indexOffset,
+ vcount);
+ }
+ else {
+ pipe->draw_elements_instanced(pipe, indexBuf,
+ indexSize,
+ prims[i].basevertex,
+ prim,
+ prims[i].start + indexOffset,
+ vcount,
+ 0, /* startInstance */
+ prims[i].num_instances);
+ }
}
}
}
@@ -708,18 +735,22 @@ st_draw_vbo(GLcontext *ctx,
else {
/* non-indexed */
GLuint i;
- GLuint prim;
for (i = 0; i < nr_prims; i++) {
- prim = translate_prim( ctx, prims[i].mode );
+ unsigned vcount = prims[i].count;
+ unsigned prim = translate_prim(ctx, prims[i].mode);
- if (prims[i].num_instances == 1) {
- pipe->draw_arrays(pipe, prim, prims[i].start, prims[i].count);
- }
- else {
- pipe->draw_arrays_instanced(pipe, prim, prims[i].start,
- prims[i].count,
- 0, prims[i].num_instances);
+ if (u_trim_pipe_prim(prims[i].mode, &vcount)) {
+ if (prims[i].num_instances == 1) {
+ pipe->draw_arrays(pipe, prim, prims[i].start, vcount);
+ }
+ else {
+ pipe->draw_arrays_instanced(pipe, prim,
+ prims[i].start,
+ vcount,
+ 0, /* startInstance */
+ prims[i].num_instances);
+ }
}
}
}
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index d0ea89f4f4f..90e78679e47 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -180,6 +180,7 @@ void st_init_extensions(struct st_context *st)
* Extensions that are supported by all Gallium drivers:
*/
ctx->Extensions.ARB_copy_buffer = GL_TRUE;
+ ctx->Extensions.ARB_draw_elements_base_vertex = GL_TRUE;
ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE;
ctx->Extensions.ARB_fragment_program = GL_TRUE;
ctx->Extensions.ARB_map_buffer_range = GL_TRUE;
@@ -392,4 +393,12 @@ void st_init_extensions(struct st_context *st)
ctx->Extensions.ARB_draw_buffers_blend = GL_TRUE;
}
#endif
+
+ if (screen->get_param(screen, PIPE_CAP_GEOMETRY_SHADER4)) {
+ ctx->Extensions.ARB_geometry_shader4 = GL_TRUE;
+ }
+
+ if (screen->get_param(screen, PIPE_CAP_DEPTH_CLAMP)) {
+ ctx->Extensions.ARB_depth_clamp = GL_TRUE;
+ }
}
diff --git a/src/mesa/state_tracker/st_gl_api.h b/src/mesa/state_tracker/st_gl_api.h
index 52c3fa0b417..fe1aec207ea 100644
--- a/src/mesa/state_tracker/st_gl_api.h
+++ b/src/mesa/state_tracker/st_gl_api.h
@@ -4,6 +4,8 @@
#include "state_tracker/st_api.h"
-struct st_api * st_gl_api_create(void);
+struct st_api *st_gl_api_create(void);
+struct st_api *st_gl_api_create_es1(void);
+struct st_api *st_gl_api_create_es2(void);
#endif
diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c
index ccfb1f4a520..2afc682e0b1 100644
--- a/src/mesa/state_tracker/st_manager.c
+++ b/src/mesa/state_tracker/st_manager.c
@@ -48,17 +48,9 @@
#include "st_context.h"
#include "st_format.h"
#include "st_cb_fbo.h"
+#include "st_cb_flush.h"
#include "st_manager.h"
-/* these functions are defined in st_context.c */
-struct st_context *
-st_create_context(struct pipe_context *pipe,
- const __GLcontextModes *visual,
- struct st_context *share);
-void st_destroy_context(struct st_context *st);
-void st_flush(struct st_context *st, uint pipeFlushFlags,
- struct pipe_fence_handle **fence);
-
/**
* Cast wrapper to convert a GLframebuffer to an st_framebuffer.
* Return NULL if the GLframebuffer is a user-created framebuffer.
@@ -603,9 +595,9 @@ st_context_destroy(struct st_context_iface *stctxi)
}
static struct st_context_iface *
-st_api_create_context(struct st_api *stapi, struct st_manager *smapi,
- const struct st_visual *visual,
- struct st_context_iface *shared_stctxi)
+create_context(gl_api api, struct st_manager *smapi,
+ const struct st_visual *visual,
+ struct st_context_iface *shared_stctxi)
{
struct st_context *shared_ctx = (struct st_context *) shared_stctxi;
struct st_context *st;
@@ -617,7 +609,7 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi,
return NULL;
st_visual_to_context_mode(visual, &mode);
- st = st_create_context(pipe, &mode, shared_ctx);
+ st = st_create_context(api, pipe, &mode, shared_ctx);
if (!st) {
pipe->destroy(pipe);
return NULL;
@@ -637,6 +629,30 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi,
return &st->iface;
}
+static struct st_context_iface *
+st_api_create_context(struct st_api *stapi, struct st_manager *smapi,
+ const struct st_visual *visual,
+ struct st_context_iface *shared_stctxi)
+{
+ return create_context(API_OPENGL, smapi, visual, shared_stctxi);
+}
+
+static struct st_context_iface *
+st_api_create_context_es1(struct st_api *stapi, struct st_manager *smapi,
+ const struct st_visual *visual,
+ struct st_context_iface *shared_stctxi)
+{
+ return create_context(API_OPENGLES, smapi, visual, shared_stctxi);
+}
+
+static struct st_context_iface *
+st_api_create_context_es2(struct st_api *stapi, struct st_manager *smapi,
+ const struct st_visual *visual,
+ struct st_context_iface *shared_stctxi)
+{
+ return create_context(API_OPENGLES2, smapi, visual, shared_stctxi);
+}
+
static boolean
st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi,
struct st_framebuffer_iface *stdrawi,
@@ -707,13 +723,6 @@ st_api_get_current(struct st_api *stapi)
return (st) ? &st->iface : NULL;
}
-static boolean
-st_api_is_visual_supported(struct st_api *stapi,
- const struct st_visual *visual)
-{
- return TRUE;
-}
-
static st_proc_t
st_api_get_proc_address(struct st_api *stapi, const char *procname)
{
@@ -819,22 +828,60 @@ st_manager_add_color_renderbuffer(struct st_context *st, GLframebuffer *fb,
return TRUE;
}
-struct st_api st_gl_api = {
+static const struct st_api st_gl_api = {
st_api_destroy,
st_api_get_proc_address,
- st_api_is_visual_supported,
st_api_create_context,
st_api_make_current,
st_api_get_current,
};
-/**
- * Return the st_api for this state tracker. This might either be GL, GLES1,
- * GLES2 that mostly depends on the build and link options. But these
- * functions remain the same either way.
- */
+static const struct st_api st_gl_api_es1 = {
+ st_api_destroy,
+ st_api_get_proc_address,
+ st_api_create_context_es1,
+ st_api_make_current,
+ st_api_get_current,
+};
+
+static const struct st_api st_gl_api_es2 = {
+ st_api_destroy,
+ st_api_get_proc_address,
+ st_api_create_context_es2,
+ st_api_make_current,
+ st_api_get_current,
+};
+
struct st_api *
st_gl_api_create(void)
{
- return &st_gl_api;
+ (void) st_gl_api;
+ (void) st_gl_api_es1;
+ (void) st_gl_api_es2;
+
+#if FEATURE_GL
+ return (struct st_api *) &st_gl_api;
+#else
+ return NULL;
+#endif
+}
+
+struct st_api *
+st_gl_api_create_es1(void)
+{
+#if FEATURE_ES1
+ return (struct st_api *) &st_gl_api_es1;
+#else
+ return NULL;
+#endif
+}
+
+struct st_api *
+st_gl_api_create_es2(void)
+{
+#if FEATURE_ES2
+ return (struct st_api *) &st_gl_api_es2;
+#else
+ return NULL;
+#endif
}
diff --git a/src/mesa/state_tracker/st_manager.h b/src/mesa/state_tracker/st_manager.h
index dabede4d64a..cd2887b1e0f 100644
--- a/src/mesa/state_tracker/st_manager.h
+++ b/src/mesa/state_tracker/st_manager.h
@@ -46,7 +46,4 @@ boolean
st_manager_add_color_renderbuffer(struct st_context *st, GLframebuffer *fb,
gl_buffer_index idx);
-struct st_api *
-st_manager_create_api(void);
-
#endif /* ST_MANAGER_H */
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c
index 35016d80e6b..97186f8dadf 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -38,8 +38,8 @@
#include "tgsi/tgsi_ureg.h"
#include "st_mesa_to_tgsi.h"
#include "st_context.h"
-#include "shader/prog_instruction.h"
-#include "shader/prog_parameter.h"
+#include "program/prog_instruction.h"
+#include "program/prog_parameter.h"
#include "util/u_debug.h"
#include "util/u_math.h"
#include "util/u_memory.h"
@@ -176,7 +176,7 @@ dst_register( struct st_translate *t,
else if (t->procType == TGSI_PROCESSOR_FRAGMENT)
assert(index < FRAG_RESULT_MAX);
else
- assert(0 && "geom shaders not handled in dst_register() yet");
+ assert(index < GEOM_RESULT_MAX);
assert(t->outputMapping[index] < Elements(t->outputs));
@@ -305,6 +305,15 @@ translate_src( struct st_translate *t,
{
struct ureg_src src = src_register( t, SrcReg->File, SrcReg->Index );
+ if (t->procType == TGSI_PROCESSOR_GEOMETRY && SrcReg->HasIndex2) {
+ src = src_register( t, SrcReg->File, SrcReg->Index2 );
+ if (SrcReg->RelAddr2)
+ src = ureg_src_dimension_indirect( src, ureg_src(t->address[0]),
+ SrcReg->Index);
+ else
+ src = ureg_src_dimension( src, SrcReg->Index);
+ }
+
src = ureg_swizzle( src,
GET_SWZ( SrcReg->Swizzle, 0 ) & 0x3,
GET_SWZ( SrcReg->Swizzle, 1 ) & 0x3,
@@ -522,6 +531,10 @@ translate_opcode( unsigned op )
return TGSI_OPCODE_DST;
case OPCODE_ELSE:
return TGSI_OPCODE_ELSE;
+ case OPCODE_EMIT_VERTEX:
+ return TGSI_OPCODE_EMIT;
+ case OPCODE_END_PRIMITIVE:
+ return TGSI_OPCODE_ENDPRIM;
case OPCODE_ENDIF:
return TGSI_OPCODE_ENDIF;
case OPCODE_ENDLOOP:
@@ -725,9 +738,11 @@ emit_adjusted_wpos( struct st_translate *t,
struct ureg_dst wpos_temp = ureg_DECL_temporary(ureg);
struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]];
- ureg_ADD(ureg,
- ureg_writemask(wpos_temp, TGSI_WRITEMASK_X | TGSI_WRITEMASK_Y),
- wpos_input, ureg_imm1f(ureg, value));
+ /* Note that we bias X and Y and pass Z and W through unchanged.
+ * The shader might also use gl_FragCoord.w and .z.
+ */
+ ureg_ADD(ureg, wpos_temp, wpos_input,
+ ureg_imm4f(ureg, value, value, 0.0f, 0.0f));
t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]] = ureg_src(wpos_temp);
}
@@ -918,6 +933,9 @@ st_translate_mesa_program(
unsigned i;
enum pipe_error ret = PIPE_OK;
+ assert(numInputs <= Elements(t->inputs));
+ assert(numOutputs <= Elements(t->outputs));
+
t = &translate;
memset(t, 0, sizeof *t);
@@ -985,7 +1003,23 @@ st_translate_mesa_program(
}
}
}
+ else if (procType == TGSI_PROCESSOR_GEOMETRY) {
+ for (i = 0; i < numInputs; i++) {
+ t->inputs[i] = ureg_DECL_gs_input(ureg,
+ i,
+ inputSemanticName[i],
+ inputSemanticIndex[i]);
+ }
+
+ for (i = 0; i < numOutputs; i++) {
+ t->outputs[i] = ureg_DECL_output( ureg,
+ outputSemanticName[i],
+ outputSemanticIndex[i] );
+ }
+ }
else {
+ assert(procType == TGSI_PROCESSOR_VERTEX);
+
for (i = 0; i < numInputs; i++) {
t->inputs[i] = ureg_DECL_vs_input(ureg, i);
}
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index 3c865028a7a..6f3ecdbce11 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -33,8 +33,8 @@
#include "main/imports.h"
#include "main/mtypes.h"
-#include "shader/prog_print.h"
-#include "shader/programopt.h"
+#include "program/prog_print.h"
+#include "program/programopt.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
@@ -459,6 +459,247 @@ st_translate_fragment_program(struct st_context *st,
}
}
+void
+st_translate_geometry_program(struct st_context *st,
+ struct st_geometry_program *stgp)
+{
+ GLuint inputMapping[GEOM_ATTRIB_MAX];
+ GLuint outputMapping[GEOM_RESULT_MAX];
+ struct pipe_context *pipe = st->pipe;
+ enum pipe_error error;
+ GLuint attr;
+ const GLbitfield inputsRead = stgp->Base.Base.InputsRead;
+ GLuint vslot = 0;
+ GLuint num_generic = 0;
+
+ uint gs_num_inputs = 0;
+ uint gs_builtin_inputs = 0;
+ uint gs_array_offset = 0;
+
+ ubyte gs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
+ ubyte gs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
+ uint gs_num_outputs = 0;
+
+ GLint i;
+ GLuint maxSlot = 0;
+ struct ureg_program *ureg;
+
+ ureg = ureg_create( TGSI_PROCESSOR_GEOMETRY );
+ if (ureg == NULL) {
+ return;
+ }
+
+ /* which vertex output goes to the first geometry input */
+ vslot = 0;
+
+ memset(inputMapping, 0, sizeof(inputMapping));
+ memset(outputMapping, 0, sizeof(outputMapping));
+
+ /*
+ * Convert Mesa program inputs to TGSI input register semantics.
+ */
+ for (attr = 0; attr < GEOM_ATTRIB_MAX; attr++) {
+ if (inputsRead & (1 << attr)) {
+ const GLuint slot = gs_num_inputs;
+
+ gs_num_inputs++;
+
+ inputMapping[attr] = slot;
+
+ stgp->input_map[slot + gs_array_offset] = vslot - gs_builtin_inputs;
+ stgp->input_to_index[attr] = vslot;
+ stgp->index_to_input[vslot] = attr;
+ ++vslot;
+
+ if (attr != GEOM_ATTRIB_PRIMITIVE_ID) {
+ gs_array_offset += 2;
+ } else
+ ++gs_builtin_inputs;
+
+#if 1
+ debug_printf("input map at %d = %d\n",
+ slot + gs_array_offset, stgp->input_map[slot + gs_array_offset]);
+#endif
+
+ switch (attr) {
+ case GEOM_ATTRIB_PRIMITIVE_ID:
+ stgp->input_semantic_name[slot] = TGSI_SEMANTIC_PRIMID;
+ stgp->input_semantic_index[slot] = 0;
+ break;
+ case GEOM_ATTRIB_POSITION:
+ stgp->input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
+ stgp->input_semantic_index[slot] = 0;
+ break;
+ case GEOM_ATTRIB_COLOR0:
+ stgp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+ stgp->input_semantic_index[slot] = 0;
+ break;
+ case GEOM_ATTRIB_COLOR1:
+ stgp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+ stgp->input_semantic_index[slot] = 1;
+ break;
+ case GEOM_ATTRIB_FOG_FRAG_COORD:
+ stgp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
+ stgp->input_semantic_index[slot] = 0;
+ break;
+ case GEOM_ATTRIB_TEX_COORD:
+ stgp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+ stgp->input_semantic_index[slot] = num_generic++;
+ break;
+ case GEOM_ATTRIB_VAR0:
+ /* fall-through */
+ default:
+ stgp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+ stgp->input_semantic_index[slot] = num_generic++;
+ }
+ }
+ }
+
+ /* initialize output semantics to defaults */
+ for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
+ gs_output_semantic_name[i] = TGSI_SEMANTIC_GENERIC;
+ gs_output_semantic_index[i] = 0;
+ }
+
+ num_generic = 0;
+ /*
+ * Determine number of outputs, the (default) output register
+ * mapping and the semantic information for each output.
+ */
+ for (attr = 0; attr < GEOM_RESULT_MAX; attr++) {
+ if (stgp->Base.Base.OutputsWritten & (1 << attr)) {
+ GLuint slot;
+
+ slot = gs_num_outputs;
+ gs_num_outputs++;
+ outputMapping[attr] = slot;
+
+ switch (attr) {
+ case GEOM_RESULT_POS:
+ assert(slot == 0);
+ gs_output_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
+ gs_output_semantic_index[slot] = 0;
+ break;
+ case GEOM_RESULT_COL0:
+ gs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+ gs_output_semantic_index[slot] = 0;
+ break;
+ case GEOM_RESULT_COL1:
+ gs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+ gs_output_semantic_index[slot] = 1;
+ break;
+ case GEOM_RESULT_SCOL0:
+ gs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
+ gs_output_semantic_index[slot] = 0;
+ break;
+ case GEOM_RESULT_SCOL1:
+ gs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
+ gs_output_semantic_index[slot] = 1;
+ break;
+ case GEOM_RESULT_FOGC:
+ gs_output_semantic_name[slot] = TGSI_SEMANTIC_FOG;
+ gs_output_semantic_index[slot] = 0;
+ break;
+ case GEOM_RESULT_PSIZ:
+ gs_output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
+ gs_output_semantic_index[slot] = 0;
+ break;
+ case GEOM_RESULT_TEX0:
+ case GEOM_RESULT_TEX1:
+ case GEOM_RESULT_TEX2:
+ case GEOM_RESULT_TEX3:
+ case GEOM_RESULT_TEX4:
+ case GEOM_RESULT_TEX5:
+ case GEOM_RESULT_TEX6:
+ case GEOM_RESULT_TEX7:
+ /* fall-through */
+ case GEOM_RESULT_VAR0:
+ /* fall-through */
+ default:
+ assert(slot < Elements(gs_output_semantic_name));
+ /* use default semantic info */
+ gs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+ gs_output_semantic_index[slot] = num_generic++;
+ }
+ }
+ }
+
+ assert(gs_output_semantic_name[0] == TGSI_SEMANTIC_POSITION);
+
+ /* find max output slot referenced to compute gs_num_outputs */
+ for (attr = 0; attr < GEOM_RESULT_MAX; attr++) {
+ if (outputMapping[attr] != ~0 && outputMapping[attr] > maxSlot)
+ maxSlot = outputMapping[attr];
+ }
+ gs_num_outputs = maxSlot + 1;
+
+#if 0 /* debug */
+ {
+ GLuint i;
+ printf("outputMapping? %d\n", outputMapping ? 1 : 0);
+ if (outputMapping) {
+ printf("attr -> slot\n");
+ for (i = 0; i < 16; i++) {
+ printf(" %2d %3d\n", i, outputMapping[i]);
+ }
+ }
+ printf("slot sem_name sem_index\n");
+ for (i = 0; i < gs_num_outputs; i++) {
+ printf(" %2d %d %d\n",
+ i,
+ gs_output_semantic_name[i],
+ gs_output_semantic_index[i]);
+ }
+ }
+#endif
+
+ /* free old shader state, if any */
+ if (stgp->tgsi.tokens) {
+ st_free_tokens(stgp->tgsi.tokens);
+ stgp->tgsi.tokens = NULL;
+ }
+ if (stgp->driver_shader) {
+ cso_delete_geometry_shader(st->cso_context, stgp->driver_shader);
+ stgp->driver_shader = NULL;
+ }
+
+ ureg_property_gs_input_prim(ureg, stgp->Base.InputType);
+ ureg_property_gs_output_prim(ureg, stgp->Base.OutputType);
+ ureg_property_gs_max_vertices(ureg, stgp->Base.VerticesOut);
+
+ error = st_translate_mesa_program(st->ctx,
+ TGSI_PROCESSOR_GEOMETRY,
+ ureg,
+ &stgp->Base.Base,
+ /* inputs */
+ gs_num_inputs,
+ inputMapping,
+ stgp->input_semantic_name,
+ stgp->input_semantic_index,
+ NULL,
+ /* outputs */
+ gs_num_outputs,
+ outputMapping,
+ gs_output_semantic_name,
+ gs_output_semantic_index,
+ FALSE);
+
+
+ stgp->num_inputs = gs_num_inputs;
+ stgp->tgsi.tokens = ureg_get_tokens( ureg, NULL );
+ ureg_destroy( ureg );
+ stgp->driver_shader = pipe->create_gs_state(pipe, &stgp->tgsi);
+
+ if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) {
+ _mesa_print_program(&stgp->Base.Base);
+ debug_printf("\n");
+ }
+
+ if (ST_DEBUG & DEBUG_TGSI) {
+ tgsi_dump(stgp->tgsi.tokens, 0);
+ debug_printf("\n");
+ }
+}
/**
* Debug- print current shader text
diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h
index 1b3f75ca27c..d779d5a6dde 100644
--- a/src/mesa/state_tracker/st_program.h
+++ b/src/mesa/state_tracker/st_program.h
@@ -35,13 +35,12 @@
#define ST_PROGRAM_H
#include "main/mtypes.h"
-#include "shader/program.h"
+#include "program/program.h"
#include "pipe/p_shader_tokens.h"
struct cso_fragment_shader;
struct cso_vertex_shader;
-struct translated_vertex_program;
/**
@@ -99,8 +98,6 @@ struct st_vp_varient
};
-
-
/**
* Derived from Mesa gl_fragment_program:
*/
@@ -126,6 +123,33 @@ struct st_vertex_program
struct st_vp_varient *varients;
};
+/**
+ * Derived from Mesa gl_geometry_program:
+ */
+struct st_geometry_program
+{
+ struct gl_geometry_program Base; /**< The Mesa geometry program */
+ GLuint serialNo;
+
+ /** map GP input back to VP output */
+ GLuint input_map[PIPE_MAX_SHADER_INPUTS];
+
+ /** maps a Mesa GEOM_ATTRIB_x to a packed TGSI input index */
+ GLuint input_to_index[GEOM_ATTRIB_MAX];
+ /** maps a TGSI input index back to a Mesa GEOM_ATTRIB_x */
+ GLuint index_to_input[PIPE_MAX_SHADER_INPUTS];
+
+ GLuint num_inputs;
+
+ GLuint input_to_slot[GEOM_ATTRIB_MAX]; /**< Maps GEOM_ATTRIB_x to slot */
+ GLuint num_input_slots;
+
+ ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS];
+ ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS];
+
+ struct pipe_shader_state tgsi;
+ void *driver_shader;
+};
static INLINE struct st_fragment_program *
st_fragment_program( struct gl_fragment_program *fp )
@@ -140,6 +164,11 @@ st_vertex_program( struct gl_vertex_program *vp )
return (struct st_vertex_program *)vp;
}
+static INLINE struct st_geometry_program *
+st_geometry_program( struct gl_geometry_program *vp )
+{
+ return (struct st_geometry_program *)vp;
+}
static INLINE void
st_reference_vertprog(struct st_context *st,
@@ -152,6 +181,16 @@ st_reference_vertprog(struct st_context *st,
}
static INLINE void
+st_reference_geomprog(struct st_context *st,
+ struct st_geometry_program **ptr,
+ struct st_geometry_program *prog)
+{
+ _mesa_reference_program(st->ctx,
+ (struct gl_program **) ptr,
+ (struct gl_program *) prog);
+}
+
+static INLINE void
st_reference_fragprog(struct st_context *st,
struct st_fragment_program **ptr,
struct st_fragment_program *prog)
@@ -166,6 +205,9 @@ extern void
st_translate_fragment_program(struct st_context *st,
struct st_fragment_program *fp);
+extern void
+st_translate_geometry_program(struct st_context *st,
+ struct st_geometry_program *stgp);
/* Called after program string change, discard all previous
* compilation results.