summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLauri Kasanen <cand@gmx.com>2011-07-12 19:26:35 +0300
committerLauri Kasanen <cand@gmx.com>2011-07-12 19:26:35 +0300
commitd09865abfc571a10aa8c1d730e5bf5c5aac2ca92 (patch)
tree6b41fbf9a6e3ba101eb06fa213b0efb1499d11f3
parent05d14eeb3824bf17b4b50f88d129a611a6e9c6e0 (diff)
pp: Add the main post-processing queue
-rw-r--r--src/gallium/auxiliary/postprocess/filters.h55
-rw-r--r--src/gallium/auxiliary/postprocess/postprocess.h87
-rw-r--r--src/gallium/auxiliary/postprocess/pp_filters.h55
-rw-r--r--src/gallium/auxiliary/postprocess/pp_init.c254
-rw-r--r--src/gallium/auxiliary/postprocess/pp_program.c122
-rw-r--r--src/gallium/auxiliary/postprocess/pp_program.h61
-rw-r--r--src/gallium/auxiliary/postprocess/pp_run.c139
7 files changed, 773 insertions, 0 deletions
diff --git a/src/gallium/auxiliary/postprocess/filters.h b/src/gallium/auxiliary/postprocess/filters.h
new file mode 100644
index 0000000000..3936ec379f
--- /dev/null
+++ b/src/gallium/auxiliary/postprocess/filters.h
@@ -0,0 +1,55 @@
+/**************************************************************************
+ *
+ * Copyright 2011 Lauri Kasanen
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef PP_EXTERNAL_FILTERS_H
+#define PP_EXTERNAL_FILTERS_H
+
+#include "postprocess/postprocess.h"
+
+typedef void (*pp_init_func)(struct pp_queue_t *, unsigned int, unsigned int);
+
+struct pp_filter_t {
+ const char *name; // Config name
+ unsigned int inner_tmps; // Request how many inner temps
+ unsigned int shaders; // Request how many shaders
+ unsigned int verts; // How many are vertex shaders
+ pp_init_func init; // Init function
+ pp_func main; // Run function
+};
+
+// Order matters. Put new filters in a suitable place.
+//
+static const struct pp_filter_t pp_filters[PP_FILTERS] = {
+// name inner shaders verts init run
+ { "pp_noblue", 0, 2, 1, pp_noblue_init, pp_nocolor },
+ { "pp_nogreen", 0, 2, 1, pp_nogreen_init, pp_nocolor },
+ { "pp_nored", 0, 2, 1, pp_nored_init, pp_nocolor },
+ { "pp_jimenezmlaa", 2, 5, 2, pp_jimenezmlaa_init, pp_jimenezmlaa },
+ { "pp_jimenezmlaa_color",2, 5, 2, pp_jimenezmlaa_init_color, pp_jimenezmlaa_color },
+};
+
+#endif
diff --git a/src/gallium/auxiliary/postprocess/postprocess.h b/src/gallium/auxiliary/postprocess/postprocess.h
new file mode 100644
index 0000000000..cf43ffa9dc
--- /dev/null
+++ b/src/gallium/auxiliary/postprocess/postprocess.h
@@ -0,0 +1,87 @@
+/**************************************************************************
+ *
+ * Copyright 2011 Lauri Kasanen
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef POSTPROCESS_H
+#define POSTPROCESS_H
+
+#include "postprocess/pp_program.h"
+
+#define PP_FILTERS 5 // Increment this if you add filters
+#define PP_MAX_PASSES 6
+
+struct pp_queue_t; // Forward definition
+
+// Less typing later on
+typedef void (*pp_func)(struct pp_queue_t *, struct pipe_resource *, struct pipe_resource *, unsigned int);
+
+struct pp_queue_t {
+ pp_func *pp_queue; // An array of pp_funcs
+ unsigned int n_filters; // Number of enabled filters
+
+ struct pipe_resource *tmp[2]; // Two temp FBOs for the queue, just color
+ struct pipe_resource *inner_tmp[3]; // Three temp FBOs for filter use, sharing a stencil
+
+ unsigned int n_tmp, n_inner_tmp;
+
+ struct pipe_resource *depth; // FBO containing the depth of original input
+ struct pipe_resource *stencil; // FBO containing the stencil shared by inner_tmps
+
+ struct pipe_surface *tmps[2], *inner_tmps[3], *stencils;
+
+ void ***shaders; // Shaders in TGSI form
+ unsigned int *verts;
+ struct program *p;
+
+ bool fbos_init;
+};
+
+// Main functions
+
+struct pp_queue_t *pp_init(struct pipe_screen *, const unsigned int *);
+void pp_run(struct pp_queue_t *, struct pipe_resource *, struct pipe_resource *, struct pipe_resource *);
+void pp_free(struct pp_queue_t *);
+void pp_free_fbos(struct pp_queue_t *);
+void pp_debug(const char *, ...);
+struct program *pp_init_prog(struct pp_queue_t *, struct pipe_screen *);
+void pp_init_fbos(struct pp_queue_t *, unsigned int, unsigned int, struct pipe_resource *);
+
+// The filters
+
+void pp_nocolor(struct pp_queue_t *, struct pipe_resource *, struct pipe_resource *, unsigned int);
+void pp_jimenezmlaa(struct pp_queue_t *, struct pipe_resource *, struct pipe_resource *, unsigned int);
+void pp_jimenezmlaa_color(struct pp_queue_t *, struct pipe_resource *,
+ struct pipe_resource *, unsigned int);
+
+// The filter init functions
+
+void pp_nored_init(struct pp_queue_t *, unsigned int, unsigned int);
+void pp_nogreen_init(struct pp_queue_t *, unsigned int, unsigned int);
+void pp_noblue_init(struct pp_queue_t *, unsigned int, unsigned int);
+void pp_jimenezmlaa_init(struct pp_queue_t *, unsigned int, unsigned int);
+void pp_jimenezmlaa_init_color(struct pp_queue_t *, unsigned int, unsigned int);
+
+#endif
diff --git a/src/gallium/auxiliary/postprocess/pp_filters.h b/src/gallium/auxiliary/postprocess/pp_filters.h
new file mode 100644
index 0000000000..d0ed9ab7f4
--- /dev/null
+++ b/src/gallium/auxiliary/postprocess/pp_filters.h
@@ -0,0 +1,55 @@
+/**************************************************************************
+ *
+ * Copyright 2011 Lauri Kasanen
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef PP_FILTERS_H
+#define PP_FILTERS_H
+
+// Internal include mainly for the filters
+
+#include "cso_cache/cso_context.h"
+#include "pipe/p_context.h"
+#include "pipe/p_shader_tokens.h"
+#include "pipe/p_state.h"
+#include "tgsi/tgsi_text.h"
+#include "util/u_memory.h"
+#include "util/u_draw_quad.h"
+
+#define PP_MAX_TOKENS 2048
+
+
+// Helper functions for the filters
+
+void pp_filter_setup_in(struct program *, struct pipe_resource *);
+void pp_filter_setup_out(struct program *, struct pipe_resource *);
+void pp_filter_end_pass(struct program *);
+void *pp_tgsi_to_state(struct pipe_context *, const char *, bool, const char *);
+void pp_filter_misc_state(struct program *);
+void pp_filter_draw(struct program *);
+void pp_filter_set_clear_fb(struct program *);
+
+
+#endif
diff --git a/src/gallium/auxiliary/postprocess/pp_init.c b/src/gallium/auxiliary/postprocess/pp_init.c
new file mode 100644
index 0000000000..6f599ff2cf
--- /dev/null
+++ b/src/gallium/auxiliary/postprocess/pp_init.c
@@ -0,0 +1,254 @@
+/**************************************************************************
+ *
+ * Copyright 2011 Lauri Kasanen
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "postprocess/filters.h"
+
+#include "pipe/p_screen.h"
+#include "util/u_inlines.h"
+#include "util/u_blit.h"
+#include "cso_cache/cso_context.h"
+
+
+static unsigned int pp_umax(unsigned int a, unsigned int b) {
+ return (a < b ? b : a);
+}
+
+
+struct pp_queue_t *pp_init(struct pipe_screen *pscreen, const unsigned int *enabled) {
+
+ pp_debug("Initializing the post-processing queue.\n");
+
+ unsigned int curpos = 0, i, tmp_req = 0;
+
+ // How many filters were requested?
+ for (i = 0; i < PP_FILTERS; i++) {
+ if (enabled[i]) curpos++;
+ }
+ if (!curpos) return NULL;
+
+ struct pp_queue_t *ppq = calloc(1, sizeof(struct pp_queue_t));
+ pp_func *tmp_q = calloc(curpos, sizeof(pp_func));
+ ppq->shaders = calloc(curpos, sizeof(void *));
+ ppq->verts = calloc(curpos, sizeof(unsigned int));
+
+ if (!tmp_q || !ppq || !ppq->shaders || !ppq->verts) goto error;
+
+ ppq->p = pp_init_prog(ppq, pscreen);
+ if (!ppq->p) goto error;
+
+ // Add the enabled filters to the queue, in order
+ curpos = 0;
+ ppq->pp_queue = tmp_q;
+ for (i = 0; i < PP_FILTERS; i++) {
+ if (enabled[i]) {
+ ppq->pp_queue[curpos] = pp_filters[i].main;
+ tmp_req = pp_umax(tmp_req, pp_filters[i].inner_tmps);
+
+ if (pp_filters[i].shaders) {
+ ppq->shaders[curpos] = calloc(pp_filters[i].shaders +1,
+ sizeof(void *));
+ ppq->verts[curpos] = pp_filters[i].verts;
+ if (!ppq->shaders[curpos]) goto error;
+ }
+ pp_filters[i].init(ppq, curpos, enabled[i]);
+
+ curpos++;
+ }
+ }
+
+ ppq->p->blitctx = util_create_blit(ppq->p->pipe, ppq->p->cso);
+ if (!ppq->p->blitctx) goto error;
+
+ ppq->n_filters = curpos;
+ ppq->n_tmp = (curpos > 2 ? 2 : 1);
+ ppq->n_inner_tmp = tmp_req;
+
+ ppq->fbos_init = false;
+
+ for (i = 0; i < curpos; i++) ppq->shaders[i][0] = ppq->p->passvs;
+
+ pp_debug("Queue successfully allocated. %u filter(s).\n", curpos);
+
+ return ppq;
+
+ error:
+ pp_debug("Error setting up pp\n");
+
+ if (ppq) free(ppq->p);
+ free(ppq);
+ free(tmp_q);
+
+ return NULL;
+}
+
+void pp_free_fbos(struct pp_queue_t *ppq) {
+
+ if (!ppq->fbos_init) return;
+
+ unsigned int i;
+
+ for (i = 0; i < ppq->n_tmp; i++) {
+ pipe_surface_reference(&ppq->tmps[i], NULL);
+ pipe_resource_reference(&ppq->tmp[i], NULL);
+ }
+ for (i = 0; i < ppq->n_inner_tmp; i++) {
+ pipe_surface_reference(&ppq->inner_tmps[i], NULL);
+ pipe_resource_reference(&ppq->inner_tmp[i], NULL);
+ }
+ pipe_surface_reference(&ppq->stencils, NULL);
+ pipe_resource_reference(&ppq->stencil, NULL);
+
+ ppq->fbos_init = false;
+}
+
+void pp_free(struct pp_queue_t *ppq) {
+
+ unsigned int i, j;
+
+ pp_free_fbos(ppq);
+
+ util_destroy_blit(ppq->p->blitctx);
+
+ cso_set_fragment_sampler_views(ppq->p->cso, 0, NULL);
+ cso_release_all(ppq->p->cso);
+
+ for (i = 0; i < ppq->n_filters; i++) {
+ for (j = 0; j < PP_MAX_PASSES && ppq->shaders[i][j]; j++) {
+ if (j >= ppq->verts[i]) {
+ ppq->p->pipe->delete_fs_state(ppq->p->pipe, ppq->shaders[i][j]);
+ ppq->shaders[i][j] = NULL;
+ }
+ else if (ppq->shaders[i][j] != ppq->p->passvs) {
+ ppq->p->pipe->delete_vs_state(ppq->p->pipe, ppq->shaders[i][j]);
+ ppq->shaders[i][j] = NULL;
+ }
+ }
+ }
+
+ cso_destroy_context(ppq->p->cso);
+ ppq->p->pipe->destroy(ppq->p->pipe);
+
+ free(ppq->p);
+ free(ppq->pp_queue);
+ free(ppq);
+
+ pp_debug("Queue taken down.\n");
+}
+
+void pp_debug(const char *fmt, ...) {
+ if (!getenv("PP_DEBUG")) return;
+
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+}
+
+void pp_init_fbos(struct pp_queue_t *ppq, const unsigned int w, const unsigned int h,
+ struct pipe_resource *indepth) {
+ if (ppq->fbos_init) return;
+
+ pp_debug("Initializing FBOs, size %ux%u\n", w, h);
+ pp_debug("Requesting %u temps and %u inner temps\n", ppq->n_tmp, ppq->n_inner_tmp);
+
+ struct program *p = ppq->p; // The lazy will inherit the earth
+
+ unsigned int i;
+ struct pipe_resource tmp_res;
+ memset(&tmp_res, 0, sizeof(tmp_res));
+ tmp_res.target = PIPE_TEXTURE_2D;
+ tmp_res.format = p->surf.format = PIPE_FORMAT_B8G8R8A8_UNORM;
+ tmp_res.width0 = w;
+ tmp_res.height0 = h;
+ tmp_res.depth0 = 1;
+ tmp_res.array_size = 1;
+ tmp_res.last_level = 0;
+ tmp_res.bind = p->surf.usage = PIPE_BIND_RENDER_TARGET;
+
+ if (!p->screen->is_format_supported(p->screen, tmp_res.format, tmp_res.target,
+ 1, tmp_res.bind)) pp_debug("Temp buffers' format fail\n");
+
+ for (i = 0; i < ppq->n_tmp; i++) {
+ ppq->tmp[i] = p->screen->resource_create(p->screen, &tmp_res);
+ ppq->tmps[i] = p->pipe->create_surface(p->pipe, ppq->tmp[i], &p->surf);
+
+ if (!ppq->tmp[i] || !ppq->tmps[i]) goto error;
+ }
+
+ for (i = 0; i < ppq->n_inner_tmp; i++) {
+ ppq->inner_tmp[i] = p->screen->resource_create(p->screen, &tmp_res);
+ ppq->inner_tmps[i] = p->pipe->create_surface(p->pipe, ppq->inner_tmp[i],
+ &p->surf);
+
+ if (!ppq->inner_tmp[i] || !ppq->inner_tmps[i]) goto error;
+ }
+
+ tmp_res.format = p->surf.format = indepth->format;
+ tmp_res.bind = p->surf.usage = PIPE_BIND_DEPTH_STENCIL;
+ ppq->depth = indepth;
+ if (!ppq->depth) goto error;
+
+ tmp_res.format = p->surf.format = PIPE_FORMAT_S8_USCALED_Z24_UNORM;
+
+ if (!p->screen->is_format_supported(p->screen, tmp_res.format, tmp_res.target,
+ 1, tmp_res.bind)) {
+
+ tmp_res.format = p->surf.format = PIPE_FORMAT_Z24_UNORM_S8_USCALED;
+
+ if (!p->screen->is_format_supported(p->screen, tmp_res.format, tmp_res.target,
+ 1, tmp_res.bind))
+ pp_debug("Temp Sbuffer format fail\n");
+ }
+
+ ppq->stencil = p->screen->resource_create(p->screen, &tmp_res);
+ ppq->stencils = p->pipe->create_surface(p->pipe, ppq->stencil, &p->surf);
+ if (!ppq->stencil || !ppq->stencils) goto error;
+
+
+ p->framebuffer.width = w;
+ p->framebuffer.height = h;
+
+ float half_depth = (1000.0 - 30.0) / 2.0;
+
+ p->viewport.scale[0] = p->viewport.translate[0] = (float) w / 2.0;
+ p->viewport.scale[1] = p->viewport.translate[1] = (float) h / 2.0;
+ p->viewport.scale[2] = half_depth;
+ p->viewport.translate[2] = half_depth + 1000;
+ p->viewport.scale[3] = 1.0f;
+ p->viewport.translate[3] = 0.0f;
+
+ ppq->fbos_init = true;
+
+ return;
+
+ error:
+ pp_debug("Failed to allocate temp buffers!\n");
+}
diff --git a/src/gallium/auxiliary/postprocess/pp_program.c b/src/gallium/auxiliary/postprocess/pp_program.c
new file mode 100644
index 0000000000..b862c934c8
--- /dev/null
+++ b/src/gallium/auxiliary/postprocess/pp_program.c
@@ -0,0 +1,122 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Jakob Bornecrantz
+ * Copyright 2011 Lauri Kasanen
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "postprocess/postprocess.h"
+#include "cso_cache/cso_context.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "pipe/p_shader_tokens.h"
+#include "util/u_inlines.h"
+#include "util/u_simple_shaders.h"
+
+struct program *pp_init_prog(struct pp_queue_t *ppq, struct pipe_screen *pscreen) {
+ pp_debug("Initializing program\n");
+ if (!pscreen) return NULL;
+
+ struct program *p = calloc(1, sizeof(struct program));
+ if (!p) return NULL;
+
+ p->screen = pscreen;
+ p->pipe = pscreen->context_create(pscreen, NULL);
+ p->cso = cso_create_context(p->pipe);
+
+ {
+ float verts[4][2][4] = {
+ {
+ { 1.0f, 1.0f, 0.0f, 1.0f },
+ { 1.0f, 1.0f, 0.0f, 1.0f }
+ },
+ {
+ { -1.0f, 1.0f, 0.0f, 1.0f },
+ { 0.0f, 1.0f, 0.0f, 1.0f }
+ },
+ {
+ { -1.0f, -1.0f, 0.0f, 1.0f },
+ { 0.0f, 0.0f, 0.0f, 1.0f }
+ },
+ {
+ { 1.0f, -1.0f, 0.0f, 1.0f },
+ { 1.0f, 0.0f, 0.0f, 1.0f }
+ }
+ };
+
+ p->vbuf = pipe_buffer_create(pscreen, PIPE_BIND_VERTEX_BUFFER,
+ PIPE_USAGE_STATIC, sizeof(verts));
+ pipe_buffer_write(p->pipe, p->vbuf, 0, sizeof(verts), verts);
+ }
+
+ p->blend.rt[0].colormask = PIPE_MASK_RGBA;
+ p->blend.rt[0].rgb_src_factor = p->blend.rt[0].alpha_src_factor =
+ PIPE_BLENDFACTOR_SRC_ALPHA;
+ p->blend.rt[0].rgb_dst_factor = p->blend.rt[0].alpha_dst_factor =
+ PIPE_BLENDFACTOR_INV_SRC_ALPHA;
+
+ p->rasterizer.cull_face = PIPE_FACE_NONE;
+ p->rasterizer.gl_rasterization_rules = 1;
+
+ p->sampler.wrap_s = p->sampler.wrap_t = p->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ p->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+ p->sampler.min_img_filter = p->sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
+ p->sampler.normalized_coords = 1;
+
+ p->sampler_point.wrap_s = p->sampler_point.wrap_t = p->sampler_point.wrap_r =
+ PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ p->sampler_point.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+ p->sampler_point.min_img_filter = p->sampler_point.mag_img_filter =
+ PIPE_TEX_FILTER_NEAREST;
+ p->sampler_point.normalized_coords = 1;
+
+ p->velem[0].src_offset = 0;
+ p->velem[0].instance_divisor = 0;
+ p->velem[0].vertex_buffer_index = 0;
+ p->velem[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ p->velem[1].src_offset = 1 * 4 * sizeof(float);
+ p->velem[1].instance_divisor = 0;
+ p->velem[1].vertex_buffer_index = 0;
+ p->velem[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+
+ if (!p->screen->is_format_supported(p->screen, PIPE_FORMAT_R32G32B32A32_FLOAT,
+ PIPE_BUFFER, 1, PIPE_BIND_VERTEX_BUFFER)) pp_debug("Vertex buf format fail\n");
+
+
+ {
+ const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
+ TGSI_SEMANTIC_GENERIC };
+ const uint semantic_indexes[] = { 0, 0 };
+ p->passvs = util_make_vertex_passthrough_shader(p->pipe, 2, semantic_names,
+ semantic_indexes);
+ }
+
+ p->framebuffer.nr_cbufs = 1;
+
+ p->surf.usage = PIPE_BIND_RENDER_TARGET;
+ p->surf.format = PIPE_FORMAT_B8G8R8A8_UNORM;
+
+ return p;
+}
diff --git a/src/gallium/auxiliary/postprocess/pp_program.h b/src/gallium/auxiliary/postprocess/pp_program.h
new file mode 100644
index 0000000000..7865e1a3ab
--- /dev/null
+++ b/src/gallium/auxiliary/postprocess/pp_program.h
@@ -0,0 +1,61 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Jakob Bornecrantz
+ * Copyright 2011 Lauri Kasanen
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef PP_PROGRAM_H
+#define PP_PROGRAM_H
+
+#include "pipe/p_state.h"
+
+struct program
+{
+ struct pipe_screen *screen;
+ struct pipe_context *pipe;
+ struct cso_context *cso;
+
+ struct pipe_blend_state blend;
+ struct pipe_depth_stencil_alpha_state depthstencil;
+ struct pipe_rasterizer_state rasterizer;
+ struct pipe_sampler_state sampler; // bilinear
+ struct pipe_sampler_state sampler_point; // point
+ struct pipe_viewport_state viewport;
+ struct pipe_framebuffer_state framebuffer;
+ struct pipe_vertex_element velem[2];
+
+ float clear_color[4];
+
+ void *passvs;
+
+ struct pipe_resource *vbuf;
+ struct pipe_surface surf;
+ struct pipe_sampler_view *view;
+
+ struct blit_state *blitctx;
+};
+
+
+#endif
diff --git a/src/gallium/auxiliary/postprocess/pp_run.c b/src/gallium/auxiliary/postprocess/pp_run.c
new file mode 100644
index 0000000000..48c2256915
--- /dev/null
+++ b/src/gallium/auxiliary/postprocess/pp_run.c
@@ -0,0 +1,139 @@
+/**************************************************************************
+ *
+ * Copyright 2011 Lauri Kasanen
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "postprocess.h"
+
+#include "postprocess/pp_filters.h"
+#include "util/u_blit.h"
+#include "util/u_inlines.h"
+#include "util/u_sampler.h"
+
+void pp_run(struct pp_queue_t *ppq, struct pipe_resource *in, struct pipe_resource *out,
+ struct pipe_resource *indepth) {
+
+ if (in->width0 != ppq->p->framebuffer.width || in->height0 != ppq->p->framebuffer.height) {
+ pp_debug("Resizing the temp pp buffers\n");
+ pp_free_fbos(ppq);
+ pp_init_fbos(ppq, in->width0, in->height0, indepth);
+ }
+
+ if (in == out && ppq->n_filters == 1) {
+ // Make a copy of in to tmp[0] in this case.
+ unsigned int w = ppq->p->framebuffer.width;
+ unsigned int h = ppq->p->framebuffer.height;
+
+ util_blit_pixels(ppq->p->blitctx, in, 0, 0, 0,
+ w, h, 0, ppq->tmps[0],
+ 0, 0, w, h, 0, PIPE_TEX_MIPFILTER_NEAREST);
+
+ in = ppq->tmp[0];
+ }
+
+ switch (ppq->n_filters) {
+ case 1: // No temp buf
+ ppq->pp_queue[0](ppq, in, out, 0);
+ break;
+ case 2: // One temp buf
+
+ ppq->pp_queue[0](ppq, in, ppq->tmp[0], 0);
+ ppq->pp_queue[1](ppq, ppq->tmp[0], out, 1);
+
+ break;
+ default: // Two temp bufs
+ ppq->pp_queue[0](ppq, in, ppq->tmp[0], 0);
+ unsigned int i;
+
+ for (i = 1; i < (ppq->n_filters - 1); i++) {
+ if (i % 2 == 0) ppq->pp_queue[i](ppq, ppq->tmp[1], ppq->tmp[0], i);
+ else ppq->pp_queue[i](ppq, ppq->tmp[0], ppq->tmp[1], i);
+ }
+ if (i % 2 == 0) ppq->pp_queue[i](ppq, ppq->tmp[1], out, i);
+ else ppq->pp_queue[i](ppq, ppq->tmp[0], out, i);
+
+ break;
+ }
+}
+
+
+// Utility functions for the filters. You're not forced to use these if your filter
+// is more complicated.
+
+
+void pp_filter_setup_in(struct program *p, struct pipe_resource *in) {
+ struct pipe_sampler_view v_tmp;
+ u_sampler_view_default_template(&v_tmp, in, in->format);
+ p->view = p->pipe->create_sampler_view(p->pipe, in, &v_tmp);
+}
+
+void pp_filter_setup_out(struct program *p, struct pipe_resource *out) {
+ p->surf.format = out->format;
+ p->surf.usage = PIPE_BIND_RENDER_TARGET;
+
+ p->framebuffer.cbufs[0] = p->pipe->create_surface(p->pipe, out, &p->surf);
+}
+
+void pp_filter_end_pass(struct program *p) {
+ pipe_surface_reference(&p->framebuffer.cbufs[0], NULL);
+ pipe_sampler_view_reference(&p->view, NULL);
+}
+
+// We need not care about geometry shaders. All we have is screen quads.
+void *pp_tgsi_to_state(struct pipe_context *pipe, const char *text, bool isvs,
+ const char *name) {
+ struct pipe_shader_state state;
+ struct tgsi_token tokens[PP_MAX_TOKENS];
+
+ if (tgsi_text_translate(text, tokens, Elements(tokens)) == FALSE) {
+ pp_debug("Failed to translate %s\n", name);
+ return NULL;
+ }
+
+ state.tokens = tokens;
+
+ if (isvs) return pipe->create_vs_state(pipe, &state);
+ else return pipe->create_fs_state(pipe, &state);
+}
+
+void pp_filter_misc_state(struct program *p) {
+ cso_set_blend(p->cso, &p->blend);
+ cso_set_depth_stencil_alpha(p->cso, &p->depthstencil);
+ cso_set_rasterizer(p->cso, &p->rasterizer);
+ cso_set_viewport(p->cso, &p->viewport);
+
+ cso_set_vertex_elements(p->cso, 2, p->velem);
+}
+
+void pp_filter_draw(struct program *p) {
+ util_draw_vertex_buffer(p->pipe, p->cso, p->vbuf, 0,
+ PIPE_PRIM_QUADS, 4, 2);
+ p->pipe->flush(p->pipe, NULL);
+}
+
+void pp_filter_set_clear_fb(struct program *p) {
+ cso_set_framebuffer(p->cso, &p->framebuffer);
+ p->pipe->clear(p->pipe, PIPE_CLEAR_COLOR, p->clear_color, 0, 0);
+}