1a9ffcceee9214342dab2085a35452acaa41003c5Christian König/************************************************************************** 2a9ffcceee9214342dab2085a35452acaa41003c5Christian König * 3a9ffcceee9214342dab2085a35452acaa41003c5Christian König * Copyright 2012 Christian König. 4a9ffcceee9214342dab2085a35452acaa41003c5Christian König * All Rights Reserved. 5a9ffcceee9214342dab2085a35452acaa41003c5Christian König * 6a9ffcceee9214342dab2085a35452acaa41003c5Christian König * Permission is hereby granted, free of charge, to any person obtaining a 7a9ffcceee9214342dab2085a35452acaa41003c5Christian König * copy of this software and associated documentation files (the 8a9ffcceee9214342dab2085a35452acaa41003c5Christian König * "Software"), to deal in the Software without restriction, including 9a9ffcceee9214342dab2085a35452acaa41003c5Christian König * without limitation the rights to use, copy, modify, merge, publish, 10a9ffcceee9214342dab2085a35452acaa41003c5Christian König * distribute, sub license, and/or sell copies of the Software, and to 11a9ffcceee9214342dab2085a35452acaa41003c5Christian König * permit persons to whom the Software is furnished to do so, subject to 12a9ffcceee9214342dab2085a35452acaa41003c5Christian König * the following conditions: 13a9ffcceee9214342dab2085a35452acaa41003c5Christian König * 14a9ffcceee9214342dab2085a35452acaa41003c5Christian König * The above copyright notice and this permission notice (including the 15a9ffcceee9214342dab2085a35452acaa41003c5Christian König * next paragraph) shall be included in all copies or substantial portions 16a9ffcceee9214342dab2085a35452acaa41003c5Christian König * of the Software. 17a9ffcceee9214342dab2085a35452acaa41003c5Christian König * 18a9ffcceee9214342dab2085a35452acaa41003c5Christian König * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19a9ffcceee9214342dab2085a35452acaa41003c5Christian König * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20a9ffcceee9214342dab2085a35452acaa41003c5Christian König * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22a9ffcceee9214342dab2085a35452acaa41003c5Christian König * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23a9ffcceee9214342dab2085a35452acaa41003c5Christian König * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24a9ffcceee9214342dab2085a35452acaa41003c5Christian König * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25a9ffcceee9214342dab2085a35452acaa41003c5Christian König * 26a9ffcceee9214342dab2085a35452acaa41003c5Christian König **************************************************************************/ 27a9ffcceee9214342dab2085a35452acaa41003c5Christian König 28a9ffcceee9214342dab2085a35452acaa41003c5Christian König#include "pipe/p_context.h" 29a9ffcceee9214342dab2085a35452acaa41003c5Christian König 30a9ffcceee9214342dab2085a35452acaa41003c5Christian König#include "tgsi/tgsi_ureg.h" 31a9ffcceee9214342dab2085a35452acaa41003c5Christian König 32a9ffcceee9214342dab2085a35452acaa41003c5Christian König#include "util/u_draw.h" 33a9ffcceee9214342dab2085a35452acaa41003c5Christian König#include "util/u_memory.h" 34a9ffcceee9214342dab2085a35452acaa41003c5Christian König#include "util/u_math.h" 35a9ffcceee9214342dab2085a35452acaa41003c5Christian König 36a9ffcceee9214342dab2085a35452acaa41003c5Christian König#include "vl_types.h" 37a9ffcceee9214342dab2085a35452acaa41003c5Christian König#include "vl_vertex_buffers.h" 38a9ffcceee9214342dab2085a35452acaa41003c5Christian König#include "vl_median_filter.h" 39a9ffcceee9214342dab2085a35452acaa41003c5Christian König 40a9ffcceee9214342dab2085a35452acaa41003c5Christian Königenum VS_OUTPUT 41a9ffcceee9214342dab2085a35452acaa41003c5Christian König{ 4295594bae47d8b3302be188e6f0be2d69c5507bb3Christian König VS_O_VPOS = 0, 4395594bae47d8b3302be188e6f0be2d69c5507bb3Christian König VS_O_VTEX = 0 44a9ffcceee9214342dab2085a35452acaa41003c5Christian König}; 45a9ffcceee9214342dab2085a35452acaa41003c5Christian König 46a9ffcceee9214342dab2085a35452acaa41003c5Christian Königstatic void * 47a9ffcceee9214342dab2085a35452acaa41003c5Christian Königcreate_vert_shader(struct vl_median_filter *filter) 48a9ffcceee9214342dab2085a35452acaa41003c5Christian König{ 49a9ffcceee9214342dab2085a35452acaa41003c5Christian König struct ureg_program *shader; 50a9ffcceee9214342dab2085a35452acaa41003c5Christian König struct ureg_src i_vpos; 51a9ffcceee9214342dab2085a35452acaa41003c5Christian König struct ureg_dst o_vpos, o_vtex; 52a9ffcceee9214342dab2085a35452acaa41003c5Christian König 53af249a7da9bf2621ab836d5074ef692677b11bbfMarek Olšák shader = ureg_create(PIPE_SHADER_VERTEX); 54a9ffcceee9214342dab2085a35452acaa41003c5Christian König if (!shader) 55a9ffcceee9214342dab2085a35452acaa41003c5Christian König return NULL; 56a9ffcceee9214342dab2085a35452acaa41003c5Christian König 57a9ffcceee9214342dab2085a35452acaa41003c5Christian König i_vpos = ureg_DECL_vs_input(shader, 0); 58a9ffcceee9214342dab2085a35452acaa41003c5Christian König o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS); 59a9ffcceee9214342dab2085a35452acaa41003c5Christian König o_vtex = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX); 60a9ffcceee9214342dab2085a35452acaa41003c5Christian König 61a9ffcceee9214342dab2085a35452acaa41003c5Christian König ureg_MOV(shader, o_vpos, i_vpos); 62a9ffcceee9214342dab2085a35452acaa41003c5Christian König ureg_MOV(shader, o_vtex, i_vpos); 63a9ffcceee9214342dab2085a35452acaa41003c5Christian König 64a9ffcceee9214342dab2085a35452acaa41003c5Christian König ureg_END(shader); 65a9ffcceee9214342dab2085a35452acaa41003c5Christian König 66a9ffcceee9214342dab2085a35452acaa41003c5Christian König return ureg_create_shader_and_destroy(shader, filter->pipe); 67a9ffcceee9214342dab2085a35452acaa41003c5Christian König} 68a9ffcceee9214342dab2085a35452acaa41003c5Christian König 69a9ffcceee9214342dab2085a35452acaa41003c5Christian Königstatic inline bool 70a9ffcceee9214342dab2085a35452acaa41003c5Christian Königis_vec_zero(struct vertex2f v) 71a9ffcceee9214342dab2085a35452acaa41003c5Christian König{ 72a9ffcceee9214342dab2085a35452acaa41003c5Christian König return v.x == 0.0f && v.y == 0.0f; 73a9ffcceee9214342dab2085a35452acaa41003c5Christian König} 74a9ffcceee9214342dab2085a35452acaa41003c5Christian König 75a9ffcceee9214342dab2085a35452acaa41003c5Christian Königstatic void * 76a9ffcceee9214342dab2085a35452acaa41003c5Christian Königcreate_frag_shader(struct vl_median_filter *filter, 77a9ffcceee9214342dab2085a35452acaa41003c5Christian König struct vertex2f *offsets, 78a9ffcceee9214342dab2085a35452acaa41003c5Christian König unsigned num_offsets) 79a9ffcceee9214342dab2085a35452acaa41003c5Christian König{ 80a9ffcceee9214342dab2085a35452acaa41003c5Christian König struct pipe_screen *screen = filter->pipe->screen; 81a9ffcceee9214342dab2085a35452acaa41003c5Christian König struct ureg_program *shader; 82a9ffcceee9214342dab2085a35452acaa41003c5Christian König struct ureg_src i_vtex; 83a9ffcceee9214342dab2085a35452acaa41003c5Christian König struct ureg_src sampler; 84a9ffcceee9214342dab2085a35452acaa41003c5Christian König struct ureg_dst *t_array = MALLOC(sizeof(struct ureg_dst) * num_offsets); 8520be2867096b984823e4b18939fc855b377c5c95Christian König struct ureg_dst o_fragment; 86a9ffcceee9214342dab2085a35452acaa41003c5Christian König const unsigned median = num_offsets >> 1; 871fb4179f927442354f93dfc8494f0236e50af838Jan Vesely unsigned i, j; 88a9ffcceee9214342dab2085a35452acaa41003c5Christian König 89a9ffcceee9214342dab2085a35452acaa41003c5Christian König assert(num_offsets & 1); /* we need an odd number of offsets */ 90a9ffcceee9214342dab2085a35452acaa41003c5Christian König if (!(num_offsets & 1)) { /* yeah, we REALLY need an odd number of offsets!!! */ 91a9ffcceee9214342dab2085a35452acaa41003c5Christian König FREE(t_array); 92a9ffcceee9214342dab2085a35452acaa41003c5Christian König return NULL; 93a9ffcceee9214342dab2085a35452acaa41003c5Christian König } 94a9ffcceee9214342dab2085a35452acaa41003c5Christian König 95a9ffcceee9214342dab2085a35452acaa41003c5Christian König if (num_offsets > screen->get_shader_param( 96af249a7da9bf2621ab836d5074ef692677b11bbfMarek Olšák screen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_TEMPS)) { 97a9ffcceee9214342dab2085a35452acaa41003c5Christian König 98a9ffcceee9214342dab2085a35452acaa41003c5Christian König FREE(t_array); 99a9ffcceee9214342dab2085a35452acaa41003c5Christian König return NULL; 100a9ffcceee9214342dab2085a35452acaa41003c5Christian König } 101a9ffcceee9214342dab2085a35452acaa41003c5Christian König 102af249a7da9bf2621ab836d5074ef692677b11bbfMarek Olšák shader = ureg_create(PIPE_SHADER_FRAGMENT); 103a9ffcceee9214342dab2085a35452acaa41003c5Christian König if (!shader) { 104a9ffcceee9214342dab2085a35452acaa41003c5Christian König FREE(t_array); 105a9ffcceee9214342dab2085a35452acaa41003c5Christian König return NULL; 106a9ffcceee9214342dab2085a35452acaa41003c5Christian König } 107a9ffcceee9214342dab2085a35452acaa41003c5Christian König 108a9ffcceee9214342dab2085a35452acaa41003c5Christian König i_vtex = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX, TGSI_INTERPOLATE_LINEAR); 109a9ffcceee9214342dab2085a35452acaa41003c5Christian König sampler = ureg_DECL_sampler(shader, 0); 110a9ffcceee9214342dab2085a35452acaa41003c5Christian König 11120be2867096b984823e4b18939fc855b377c5c95Christian König for (i = 0; i < num_offsets; ++i) 11220be2867096b984823e4b18939fc855b377c5c95Christian König t_array[i] = ureg_DECL_temporary(shader); 11320be2867096b984823e4b18939fc855b377c5c95Christian König o_fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); 114a9ffcceee9214342dab2085a35452acaa41003c5Christian König 115a9ffcceee9214342dab2085a35452acaa41003c5Christian König /* 116a9ffcceee9214342dab2085a35452acaa41003c5Christian König * t_array[0..*] = vtex + offset[0..*] 117a9ffcceee9214342dab2085a35452acaa41003c5Christian König * t_array[0..*] = tex(t_array[0..*], sampler) 118a9ffcceee9214342dab2085a35452acaa41003c5Christian König * result = partial_bubblesort(t_array)[mid] 119a9ffcceee9214342dab2085a35452acaa41003c5Christian König */ 120a9ffcceee9214342dab2085a35452acaa41003c5Christian König 121a9ffcceee9214342dab2085a35452acaa41003c5Christian König for (i = 0; i < num_offsets; ++i) { 122a9ffcceee9214342dab2085a35452acaa41003c5Christian König if (!is_vec_zero(offsets[i])) { 123a9ffcceee9214342dab2085a35452acaa41003c5Christian König ureg_ADD(shader, ureg_writemask(t_array[i], TGSI_WRITEMASK_XY), 124a9ffcceee9214342dab2085a35452acaa41003c5Christian König i_vtex, ureg_imm2f(shader, offsets[i].x, offsets[i].y)); 125a9ffcceee9214342dab2085a35452acaa41003c5Christian König ureg_MOV(shader, ureg_writemask(t_array[i], TGSI_WRITEMASK_ZW), 126a9ffcceee9214342dab2085a35452acaa41003c5Christian König ureg_imm1f(shader, 0.0f)); 127a9ffcceee9214342dab2085a35452acaa41003c5Christian König } 128a9ffcceee9214342dab2085a35452acaa41003c5Christian König } 129a9ffcceee9214342dab2085a35452acaa41003c5Christian König 130a9ffcceee9214342dab2085a35452acaa41003c5Christian König for (i = 0; i < num_offsets; ++i) { 131a9ffcceee9214342dab2085a35452acaa41003c5Christian König struct ureg_src src = is_vec_zero(offsets[i]) ? i_vtex : ureg_src(t_array[i]); 132a9ffcceee9214342dab2085a35452acaa41003c5Christian König ureg_TEX(shader, t_array[i], TGSI_TEXTURE_2D, src, sampler); 133a9ffcceee9214342dab2085a35452acaa41003c5Christian König } 134a9ffcceee9214342dab2085a35452acaa41003c5Christian König 135a9ffcceee9214342dab2085a35452acaa41003c5Christian König // TODO: Couldn't this be improved even more? 136a9ffcceee9214342dab2085a35452acaa41003c5Christian König for (i = 0; i <= median; ++i) { 137a9ffcceee9214342dab2085a35452acaa41003c5Christian König for (j = 1; j < (num_offsets - i - 1); ++j) { 138a9ffcceee9214342dab2085a35452acaa41003c5Christian König struct ureg_dst tmp = ureg_DECL_temporary(shader); 139a9ffcceee9214342dab2085a35452acaa41003c5Christian König ureg_MOV(shader, tmp, ureg_src(t_array[j])); 140a9ffcceee9214342dab2085a35452acaa41003c5Christian König ureg_MAX(shader, t_array[j], ureg_src(t_array[j]), ureg_src(t_array[j - 1])); 141a9ffcceee9214342dab2085a35452acaa41003c5Christian König ureg_MIN(shader, t_array[j - 1], ureg_src(tmp), ureg_src(t_array[j - 1])); 142a9ffcceee9214342dab2085a35452acaa41003c5Christian König ureg_release_temporary(shader, tmp); 143a9ffcceee9214342dab2085a35452acaa41003c5Christian König } 144a9ffcceee9214342dab2085a35452acaa41003c5Christian König if (i == median) 145a9ffcceee9214342dab2085a35452acaa41003c5Christian König ureg_MAX(shader, t_array[j], ureg_src(t_array[j]), ureg_src(t_array[j - 1])); 146a9ffcceee9214342dab2085a35452acaa41003c5Christian König else 147a9ffcceee9214342dab2085a35452acaa41003c5Christian König ureg_MIN(shader, t_array[j - 1], ureg_src(t_array[j]), ureg_src(t_array[j - 1])); 148a9ffcceee9214342dab2085a35452acaa41003c5Christian König } 14920be2867096b984823e4b18939fc855b377c5c95Christian König ureg_MOV(shader, o_fragment, ureg_src(t_array[median])); 150a9ffcceee9214342dab2085a35452acaa41003c5Christian König 151a9ffcceee9214342dab2085a35452acaa41003c5Christian König ureg_END(shader); 152a9ffcceee9214342dab2085a35452acaa41003c5Christian König 153a9ffcceee9214342dab2085a35452acaa41003c5Christian König FREE(t_array); 154a9ffcceee9214342dab2085a35452acaa41003c5Christian König return ureg_create_shader_and_destroy(shader, filter->pipe); 155a9ffcceee9214342dab2085a35452acaa41003c5Christian König} 156a9ffcceee9214342dab2085a35452acaa41003c5Christian König 157a9ffcceee9214342dab2085a35452acaa41003c5Christian Königstatic void 158a9ffcceee9214342dab2085a35452acaa41003c5Christian Königgenerate_offsets(enum vl_median_filter_shape shape, unsigned size, 159a9ffcceee9214342dab2085a35452acaa41003c5Christian König struct vertex2f **offsets, unsigned *num_offsets) 160a9ffcceee9214342dab2085a35452acaa41003c5Christian König{ 1611fb4179f927442354f93dfc8494f0236e50af838Jan Vesely unsigned i = 0; 1621fb4179f927442354f93dfc8494f0236e50af838Jan Vesely int half_size; 163a9ffcceee9214342dab2085a35452acaa41003c5Christian König struct vertex2f v; 164a9ffcceee9214342dab2085a35452acaa41003c5Christian König 165a9ffcceee9214342dab2085a35452acaa41003c5Christian König assert(offsets && num_offsets); 166a9ffcceee9214342dab2085a35452acaa41003c5Christian König 167a9ffcceee9214342dab2085a35452acaa41003c5Christian König /* size needs to be odd */ 168553e8203879d163e6fe2f3a8f6b80a44749514c1Christian König size = align(size + 1, 2) - 1; 169a9ffcceee9214342dab2085a35452acaa41003c5Christian König half_size = size >> 1; 170a9ffcceee9214342dab2085a35452acaa41003c5Christian König 171a9ffcceee9214342dab2085a35452acaa41003c5Christian König switch(shape) { 172a9ffcceee9214342dab2085a35452acaa41003c5Christian König case VL_MEDIAN_FILTER_BOX: 173a9ffcceee9214342dab2085a35452acaa41003c5Christian König *num_offsets = size*size; 174a9ffcceee9214342dab2085a35452acaa41003c5Christian König break; 175a9ffcceee9214342dab2085a35452acaa41003c5Christian König 176a9ffcceee9214342dab2085a35452acaa41003c5Christian König case VL_MEDIAN_FILTER_CROSS: 177a9ffcceee9214342dab2085a35452acaa41003c5Christian König case VL_MEDIAN_FILTER_X: 178a9ffcceee9214342dab2085a35452acaa41003c5Christian König *num_offsets = size + size - 1; 179a9ffcceee9214342dab2085a35452acaa41003c5Christian König break; 180a9ffcceee9214342dab2085a35452acaa41003c5Christian König 181a9ffcceee9214342dab2085a35452acaa41003c5Christian König case VL_MEDIAN_FILTER_HORIZONTAL: 182a9ffcceee9214342dab2085a35452acaa41003c5Christian König case VL_MEDIAN_FILTER_VERTICAL: 183a9ffcceee9214342dab2085a35452acaa41003c5Christian König *num_offsets = size; 184a9ffcceee9214342dab2085a35452acaa41003c5Christian König break; 185a9ffcceee9214342dab2085a35452acaa41003c5Christian König 186a9ffcceee9214342dab2085a35452acaa41003c5Christian König default: 187a9ffcceee9214342dab2085a35452acaa41003c5Christian König *num_offsets = 0; 188a9ffcceee9214342dab2085a35452acaa41003c5Christian König return; 189a9ffcceee9214342dab2085a35452acaa41003c5Christian König } 190a9ffcceee9214342dab2085a35452acaa41003c5Christian König 191a9ffcceee9214342dab2085a35452acaa41003c5Christian König *offsets = MALLOC(sizeof(struct vertex2f) * *num_offsets); 192a9ffcceee9214342dab2085a35452acaa41003c5Christian König if (!*offsets) 193a9ffcceee9214342dab2085a35452acaa41003c5Christian König return; 194a9ffcceee9214342dab2085a35452acaa41003c5Christian König 195a9ffcceee9214342dab2085a35452acaa41003c5Christian König switch(shape) { 196a9ffcceee9214342dab2085a35452acaa41003c5Christian König case VL_MEDIAN_FILTER_BOX: 197a9ffcceee9214342dab2085a35452acaa41003c5Christian König for (v.x = -half_size; v.x <= half_size; ++v.x) 198a9ffcceee9214342dab2085a35452acaa41003c5Christian König for (v.y = -half_size; v.y <= half_size; ++v.y) 199a9ffcceee9214342dab2085a35452acaa41003c5Christian König (*offsets)[i++] = v; 200a9ffcceee9214342dab2085a35452acaa41003c5Christian König break; 201a9ffcceee9214342dab2085a35452acaa41003c5Christian König 202a9ffcceee9214342dab2085a35452acaa41003c5Christian König case VL_MEDIAN_FILTER_CROSS: 203a9ffcceee9214342dab2085a35452acaa41003c5Christian König v.y = 0.0f; 204a9ffcceee9214342dab2085a35452acaa41003c5Christian König for (v.x = -half_size; v.x <= half_size; ++v.x) 205a9ffcceee9214342dab2085a35452acaa41003c5Christian König (*offsets)[i++] = v; 206a9ffcceee9214342dab2085a35452acaa41003c5Christian König 207a9ffcceee9214342dab2085a35452acaa41003c5Christian König v.x = 0.0f; 208a9ffcceee9214342dab2085a35452acaa41003c5Christian König for (v.y = -half_size; v.y <= half_size; ++v.y) 209a9ffcceee9214342dab2085a35452acaa41003c5Christian König if (v.y != 0.0f) 210a9ffcceee9214342dab2085a35452acaa41003c5Christian König (*offsets)[i++] = v; 211a9ffcceee9214342dab2085a35452acaa41003c5Christian König break; 212a9ffcceee9214342dab2085a35452acaa41003c5Christian König 213a9ffcceee9214342dab2085a35452acaa41003c5Christian König case VL_MEDIAN_FILTER_X: 214a9ffcceee9214342dab2085a35452acaa41003c5Christian König for (v.x = v.y = -half_size; v.x <= half_size; ++v.x, ++v.y) 215a9ffcceee9214342dab2085a35452acaa41003c5Christian König (*offsets)[i++] = v; 216a9ffcceee9214342dab2085a35452acaa41003c5Christian König 217a9ffcceee9214342dab2085a35452acaa41003c5Christian König for (v.x = -half_size, v.y = half_size; v.x <= half_size; ++v.x, --v.y) 218a9ffcceee9214342dab2085a35452acaa41003c5Christian König if (v.y != 0.0f) 219a9ffcceee9214342dab2085a35452acaa41003c5Christian König (*offsets)[i++] = v; 220a9ffcceee9214342dab2085a35452acaa41003c5Christian König break; 221a9ffcceee9214342dab2085a35452acaa41003c5Christian König 222a9ffcceee9214342dab2085a35452acaa41003c5Christian König case VL_MEDIAN_FILTER_HORIZONTAL: 223a9ffcceee9214342dab2085a35452acaa41003c5Christian König v.y = 0.0f; 224a9ffcceee9214342dab2085a35452acaa41003c5Christian König for (v.x = -half_size; v.x <= half_size; ++v.x) 225a9ffcceee9214342dab2085a35452acaa41003c5Christian König (*offsets)[i++] = v; 226a9ffcceee9214342dab2085a35452acaa41003c5Christian König break; 227a9ffcceee9214342dab2085a35452acaa41003c5Christian König 228a9ffcceee9214342dab2085a35452acaa41003c5Christian König case VL_MEDIAN_FILTER_VERTICAL: 229a9ffcceee9214342dab2085a35452acaa41003c5Christian König v.x = 0.0f; 230a9ffcceee9214342dab2085a35452acaa41003c5Christian König for (v.y = -half_size; v.y <= half_size; ++v.y) 231a9ffcceee9214342dab2085a35452acaa41003c5Christian König (*offsets)[i++] = v; 232a9ffcceee9214342dab2085a35452acaa41003c5Christian König break; 233a9ffcceee9214342dab2085a35452acaa41003c5Christian König } 234a9ffcceee9214342dab2085a35452acaa41003c5Christian König 235a9ffcceee9214342dab2085a35452acaa41003c5Christian König assert(i == *num_offsets); 236a9ffcceee9214342dab2085a35452acaa41003c5Christian König} 237a9ffcceee9214342dab2085a35452acaa41003c5Christian König 238a9ffcceee9214342dab2085a35452acaa41003c5Christian Königbool 239a9ffcceee9214342dab2085a35452acaa41003c5Christian Königvl_median_filter_init(struct vl_median_filter *filter, struct pipe_context *pipe, 240a9ffcceee9214342dab2085a35452acaa41003c5Christian König unsigned width, unsigned height, unsigned size, 241a9ffcceee9214342dab2085a35452acaa41003c5Christian König enum vl_median_filter_shape shape) 242a9ffcceee9214342dab2085a35452acaa41003c5Christian König{ 243a9ffcceee9214342dab2085a35452acaa41003c5Christian König struct pipe_rasterizer_state rs_state; 244a9ffcceee9214342dab2085a35452acaa41003c5Christian König struct pipe_blend_state blend; 245a9ffcceee9214342dab2085a35452acaa41003c5Christian König struct pipe_sampler_state sampler; 246a9ffcceee9214342dab2085a35452acaa41003c5Christian König struct vertex2f *offsets = NULL; 247a9ffcceee9214342dab2085a35452acaa41003c5Christian König struct pipe_vertex_element ve; 248a9ffcceee9214342dab2085a35452acaa41003c5Christian König unsigned i, num_offsets = 0; 249a9ffcceee9214342dab2085a35452acaa41003c5Christian König 250a9ffcceee9214342dab2085a35452acaa41003c5Christian König assert(filter && pipe); 251a9ffcceee9214342dab2085a35452acaa41003c5Christian König assert(width && height); 252553e8203879d163e6fe2f3a8f6b80a44749514c1Christian König assert(size > 1 && size < 20); 253a9ffcceee9214342dab2085a35452acaa41003c5Christian König 254a9ffcceee9214342dab2085a35452acaa41003c5Christian König memset(filter, 0, sizeof(*filter)); 255a9ffcceee9214342dab2085a35452acaa41003c5Christian König filter->pipe = pipe; 256a9ffcceee9214342dab2085a35452acaa41003c5Christian König 257a9ffcceee9214342dab2085a35452acaa41003c5Christian König memset(&rs_state, 0, sizeof(rs_state)); 2582737abb44efebfa10ac84b183c20fc5818d1514eJosé Fonseca rs_state.half_pixel_center = true; 2592737abb44efebfa10ac84b183c20fc5818d1514eJosé Fonseca rs_state.bottom_edge_rule = true; 260a9ffcceee9214342dab2085a35452acaa41003c5Christian König rs_state.depth_clip = 1; 261a9ffcceee9214342dab2085a35452acaa41003c5Christian König filter->rs_state = pipe->create_rasterizer_state(pipe, &rs_state); 262a9ffcceee9214342dab2085a35452acaa41003c5Christian König if (!filter->rs_state) 263a9ffcceee9214342dab2085a35452acaa41003c5Christian König goto error_rs_state; 264a9ffcceee9214342dab2085a35452acaa41003c5Christian König 265a9ffcceee9214342dab2085a35452acaa41003c5Christian König memset(&blend, 0, sizeof blend); 266a9ffcceee9214342dab2085a35452acaa41003c5Christian König blend.rt[0].rgb_func = PIPE_BLEND_ADD; 267a9ffcceee9214342dab2085a35452acaa41003c5Christian König blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; 268a9ffcceee9214342dab2085a35452acaa41003c5Christian König blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; 269a9ffcceee9214342dab2085a35452acaa41003c5Christian König blend.rt[0].alpha_func = PIPE_BLEND_ADD; 270a9ffcceee9214342dab2085a35452acaa41003c5Christian König blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; 271a9ffcceee9214342dab2085a35452acaa41003c5Christian König blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; 272a9ffcceee9214342dab2085a35452acaa41003c5Christian König blend.logicop_func = PIPE_LOGICOP_CLEAR; 273a9ffcceee9214342dab2085a35452acaa41003c5Christian König blend.rt[0].colormask = PIPE_MASK_RGBA; 274a9ffcceee9214342dab2085a35452acaa41003c5Christian König filter->blend = pipe->create_blend_state(pipe, &blend); 275a9ffcceee9214342dab2085a35452acaa41003c5Christian König if (!filter->blend) 276a9ffcceee9214342dab2085a35452acaa41003c5Christian König goto error_blend; 277a9ffcceee9214342dab2085a35452acaa41003c5Christian König 278a9ffcceee9214342dab2085a35452acaa41003c5Christian König memset(&sampler, 0, sizeof(sampler)); 279a9ffcceee9214342dab2085a35452acaa41003c5Christian König sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 280a9ffcceee9214342dab2085a35452acaa41003c5Christian König sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 281a9ffcceee9214342dab2085a35452acaa41003c5Christian König sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 282a9ffcceee9214342dab2085a35452acaa41003c5Christian König sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; 283a9ffcceee9214342dab2085a35452acaa41003c5Christian König sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; 284a9ffcceee9214342dab2085a35452acaa41003c5Christian König sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; 285a9ffcceee9214342dab2085a35452acaa41003c5Christian König sampler.compare_mode = PIPE_TEX_COMPARE_NONE; 286a9ffcceee9214342dab2085a35452acaa41003c5Christian König sampler.compare_func = PIPE_FUNC_ALWAYS; 287a9ffcceee9214342dab2085a35452acaa41003c5Christian König sampler.normalized_coords = 1; 288a9ffcceee9214342dab2085a35452acaa41003c5Christian König filter->sampler = pipe->create_sampler_state(pipe, &sampler); 289a9ffcceee9214342dab2085a35452acaa41003c5Christian König if (!filter->sampler) 290a9ffcceee9214342dab2085a35452acaa41003c5Christian König goto error_sampler; 291a9ffcceee9214342dab2085a35452acaa41003c5Christian König 292a9ffcceee9214342dab2085a35452acaa41003c5Christian König filter->quad = vl_vb_upload_quads(pipe); 293a9ffcceee9214342dab2085a35452acaa41003c5Christian König if(!filter->quad.buffer) 294a9ffcceee9214342dab2085a35452acaa41003c5Christian König goto error_quad; 295a9ffcceee9214342dab2085a35452acaa41003c5Christian König 296a9ffcceee9214342dab2085a35452acaa41003c5Christian König memset(&ve, 0, sizeof(ve)); 297a9ffcceee9214342dab2085a35452acaa41003c5Christian König ve.src_offset = 0; 298a9ffcceee9214342dab2085a35452acaa41003c5Christian König ve.instance_divisor = 0; 299a9ffcceee9214342dab2085a35452acaa41003c5Christian König ve.vertex_buffer_index = 0; 300a9ffcceee9214342dab2085a35452acaa41003c5Christian König ve.src_format = PIPE_FORMAT_R32G32_FLOAT; 301a9ffcceee9214342dab2085a35452acaa41003c5Christian König filter->ves = pipe->create_vertex_elements_state(pipe, 1, &ve); 302a9ffcceee9214342dab2085a35452acaa41003c5Christian König if (!filter->ves) 303a9ffcceee9214342dab2085a35452acaa41003c5Christian König goto error_ves; 304a9ffcceee9214342dab2085a35452acaa41003c5Christian König 305a9ffcceee9214342dab2085a35452acaa41003c5Christian König generate_offsets(shape, size, &offsets, &num_offsets); 306a9ffcceee9214342dab2085a35452acaa41003c5Christian König if (!offsets) 307a9ffcceee9214342dab2085a35452acaa41003c5Christian König goto error_offsets; 308a9ffcceee9214342dab2085a35452acaa41003c5Christian König 309a9ffcceee9214342dab2085a35452acaa41003c5Christian König for (i = 0; i < num_offsets; ++i) { 310a9ffcceee9214342dab2085a35452acaa41003c5Christian König offsets[i].x /= width; 311a9ffcceee9214342dab2085a35452acaa41003c5Christian König offsets[i].y /= height; 312a9ffcceee9214342dab2085a35452acaa41003c5Christian König } 313a9ffcceee9214342dab2085a35452acaa41003c5Christian König 314a9ffcceee9214342dab2085a35452acaa41003c5Christian König filter->vs = create_vert_shader(filter); 315a9ffcceee9214342dab2085a35452acaa41003c5Christian König if (!filter->vs) 316a9ffcceee9214342dab2085a35452acaa41003c5Christian König goto error_vs; 317a9ffcceee9214342dab2085a35452acaa41003c5Christian König 318a9ffcceee9214342dab2085a35452acaa41003c5Christian König filter->fs = create_frag_shader(filter, offsets, num_offsets); 319a9ffcceee9214342dab2085a35452acaa41003c5Christian König if (!filter->fs) 320a9ffcceee9214342dab2085a35452acaa41003c5Christian König goto error_fs; 321a9ffcceee9214342dab2085a35452acaa41003c5Christian König 322a9ffcceee9214342dab2085a35452acaa41003c5Christian König FREE(offsets); 323a9ffcceee9214342dab2085a35452acaa41003c5Christian König return true; 324a9ffcceee9214342dab2085a35452acaa41003c5Christian König 325a9ffcceee9214342dab2085a35452acaa41003c5Christian Königerror_fs: 326a9ffcceee9214342dab2085a35452acaa41003c5Christian König pipe->delete_vs_state(pipe, filter->vs); 327a9ffcceee9214342dab2085a35452acaa41003c5Christian König 328a9ffcceee9214342dab2085a35452acaa41003c5Christian Königerror_vs: 329a9ffcceee9214342dab2085a35452acaa41003c5Christian König FREE(offsets); 330a9ffcceee9214342dab2085a35452acaa41003c5Christian König 331a9ffcceee9214342dab2085a35452acaa41003c5Christian Königerror_offsets: 332a9ffcceee9214342dab2085a35452acaa41003c5Christian König pipe->delete_vertex_elements_state(pipe, filter->ves); 333a9ffcceee9214342dab2085a35452acaa41003c5Christian König 334a9ffcceee9214342dab2085a35452acaa41003c5Christian Königerror_ves: 335a9ffcceee9214342dab2085a35452acaa41003c5Christian König pipe_resource_reference(&filter->quad.buffer, NULL); 336a9ffcceee9214342dab2085a35452acaa41003c5Christian König 337a9ffcceee9214342dab2085a35452acaa41003c5Christian Königerror_quad: 338a9ffcceee9214342dab2085a35452acaa41003c5Christian König pipe->delete_sampler_state(pipe, filter->sampler); 339a9ffcceee9214342dab2085a35452acaa41003c5Christian König 340a9ffcceee9214342dab2085a35452acaa41003c5Christian Königerror_sampler: 341a9ffcceee9214342dab2085a35452acaa41003c5Christian König pipe->delete_blend_state(pipe, filter->blend); 342a9ffcceee9214342dab2085a35452acaa41003c5Christian König 343a9ffcceee9214342dab2085a35452acaa41003c5Christian Königerror_blend: 344a9ffcceee9214342dab2085a35452acaa41003c5Christian König pipe->delete_rasterizer_state(pipe, filter->rs_state); 345a9ffcceee9214342dab2085a35452acaa41003c5Christian König 346a9ffcceee9214342dab2085a35452acaa41003c5Christian Königerror_rs_state: 347a9ffcceee9214342dab2085a35452acaa41003c5Christian König return false; 348a9ffcceee9214342dab2085a35452acaa41003c5Christian König} 349a9ffcceee9214342dab2085a35452acaa41003c5Christian König 350a9ffcceee9214342dab2085a35452acaa41003c5Christian Königvoid 351a9ffcceee9214342dab2085a35452acaa41003c5Christian Königvl_median_filter_cleanup(struct vl_median_filter *filter) 352a9ffcceee9214342dab2085a35452acaa41003c5Christian König{ 353a9ffcceee9214342dab2085a35452acaa41003c5Christian König assert(filter); 354a9ffcceee9214342dab2085a35452acaa41003c5Christian König 355a9ffcceee9214342dab2085a35452acaa41003c5Christian König filter->pipe->delete_sampler_state(filter->pipe, filter->sampler); 356a9ffcceee9214342dab2085a35452acaa41003c5Christian König filter->pipe->delete_blend_state(filter->pipe, filter->blend); 357a9ffcceee9214342dab2085a35452acaa41003c5Christian König filter->pipe->delete_rasterizer_state(filter->pipe, filter->rs_state); 358a9ffcceee9214342dab2085a35452acaa41003c5Christian König filter->pipe->delete_vertex_elements_state(filter->pipe, filter->ves); 359a9ffcceee9214342dab2085a35452acaa41003c5Christian König pipe_resource_reference(&filter->quad.buffer, NULL); 360a9ffcceee9214342dab2085a35452acaa41003c5Christian König 361a9ffcceee9214342dab2085a35452acaa41003c5Christian König filter->pipe->delete_vs_state(filter->pipe, filter->vs); 362a9ffcceee9214342dab2085a35452acaa41003c5Christian König filter->pipe->delete_fs_state(filter->pipe, filter->fs); 363a9ffcceee9214342dab2085a35452acaa41003c5Christian König} 364a9ffcceee9214342dab2085a35452acaa41003c5Christian König 365a9ffcceee9214342dab2085a35452acaa41003c5Christian Königvoid 366a9ffcceee9214342dab2085a35452acaa41003c5Christian Königvl_median_filter_render(struct vl_median_filter *filter, 367a9ffcceee9214342dab2085a35452acaa41003c5Christian König struct pipe_sampler_view *src, 368a9ffcceee9214342dab2085a35452acaa41003c5Christian König struct pipe_surface *dst) 369a9ffcceee9214342dab2085a35452acaa41003c5Christian König{ 370a9ffcceee9214342dab2085a35452acaa41003c5Christian König struct pipe_viewport_state viewport; 371a9ffcceee9214342dab2085a35452acaa41003c5Christian König struct pipe_framebuffer_state fb_state; 372a9ffcceee9214342dab2085a35452acaa41003c5Christian König 373a9ffcceee9214342dab2085a35452acaa41003c5Christian König assert(filter && src && dst); 374a9ffcceee9214342dab2085a35452acaa41003c5Christian König 375a9ffcceee9214342dab2085a35452acaa41003c5Christian König memset(&viewport, 0, sizeof(viewport)); 376a9ffcceee9214342dab2085a35452acaa41003c5Christian König viewport.scale[0] = dst->width; 377a9ffcceee9214342dab2085a35452acaa41003c5Christian König viewport.scale[1] = dst->height; 378a9ffcceee9214342dab2085a35452acaa41003c5Christian König viewport.scale[2] = 1; 379a9ffcceee9214342dab2085a35452acaa41003c5Christian König 380a9ffcceee9214342dab2085a35452acaa41003c5Christian König memset(&fb_state, 0, sizeof(fb_state)); 381a9ffcceee9214342dab2085a35452acaa41003c5Christian König fb_state.width = dst->width; 382a9ffcceee9214342dab2085a35452acaa41003c5Christian König fb_state.height = dst->height; 383a9ffcceee9214342dab2085a35452acaa41003c5Christian König fb_state.nr_cbufs = 1; 384a9ffcceee9214342dab2085a35452acaa41003c5Christian König fb_state.cbufs[0] = dst; 385a9ffcceee9214342dab2085a35452acaa41003c5Christian König 386a9ffcceee9214342dab2085a35452acaa41003c5Christian König filter->pipe->bind_rasterizer_state(filter->pipe, filter->rs_state); 387a9ffcceee9214342dab2085a35452acaa41003c5Christian König filter->pipe->bind_blend_state(filter->pipe, filter->blend); 388d0520d5bf6fb8dec8434d6b68dd014227a1bdaa3Brian Paul filter->pipe->bind_sampler_states(filter->pipe, PIPE_SHADER_FRAGMENT, 389d0520d5bf6fb8dec8434d6b68dd014227a1bdaa3Brian Paul 0, 1, &filter->sampler); 390a3ed98f7aa85636579a5696bf036ec13e5c9104aBrian Paul filter->pipe->set_sampler_views(filter->pipe, PIPE_SHADER_FRAGMENT, 391a3ed98f7aa85636579a5696bf036ec13e5c9104aBrian Paul 0, 1, &src); 392a9ffcceee9214342dab2085a35452acaa41003c5Christian König filter->pipe->bind_vs_state(filter->pipe, filter->vs); 393a9ffcceee9214342dab2085a35452acaa41003c5Christian König filter->pipe->bind_fs_state(filter->pipe, filter->fs); 394a9ffcceee9214342dab2085a35452acaa41003c5Christian König filter->pipe->set_framebuffer_state(filter->pipe, &fb_state); 395eaabb4ead07ae043ecc789024028e225ebd0f318Zack Rusin filter->pipe->set_viewport_states(filter->pipe, 0, 1, &viewport); 396e73bf3b805de78299f1a652668ba4e6eab9bac94Marek Olšák filter->pipe->set_vertex_buffers(filter->pipe, 0, 1, &filter->quad); 397a9ffcceee9214342dab2085a35452acaa41003c5Christian König filter->pipe->bind_vertex_elements_state(filter->pipe, filter->ves); 398a9ffcceee9214342dab2085a35452acaa41003c5Christian König 399a9ffcceee9214342dab2085a35452acaa41003c5Christian König util_draw_arrays(filter->pipe, PIPE_PRIM_QUADS, 0, 4); 400a9ffcceee9214342dab2085a35452acaa41003c5Christian König} 401