diff options
author | Lauri Kasanen <cand@gmx.com> | 2011-07-12 19:26:35 +0300 |
---|---|---|
committer | Lauri Kasanen <cand@gmx.com> | 2011-07-12 19:26:35 +0300 |
commit | d09865abfc571a10aa8c1d730e5bf5c5aac2ca92 (patch) | |
tree | 6b41fbf9a6e3ba101eb06fa213b0efb1499d11f3 | |
parent | 05d14eeb3824bf17b4b50f88d129a611a6e9c6e0 (diff) |
pp: Add the main post-processing queue
-rw-r--r-- | src/gallium/auxiliary/postprocess/filters.h | 55 | ||||
-rw-r--r-- | src/gallium/auxiliary/postprocess/postprocess.h | 87 | ||||
-rw-r--r-- | src/gallium/auxiliary/postprocess/pp_filters.h | 55 | ||||
-rw-r--r-- | src/gallium/auxiliary/postprocess/pp_init.c | 254 | ||||
-rw-r--r-- | src/gallium/auxiliary/postprocess/pp_program.c | 122 | ||||
-rw-r--r-- | src/gallium/auxiliary/postprocess/pp_program.h | 61 | ||||
-rw-r--r-- | src/gallium/auxiliary/postprocess/pp_run.c | 139 |
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); +} |