~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/gallium/auxiliary/vl/vl_matrix_filter.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**************************************************************************
2
 
 *
3
 
 * Copyright 2012 Christian König.
4
 
 * All Rights Reserved.
5
 
 *
6
 
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 
 * copy of this software and associated documentation files (the
8
 
 * "Software"), to deal in the Software without restriction, including
9
 
 * without limitation the rights to use, copy, modify, merge, publish,
10
 
 * distribute, sub license, and/or sell copies of the Software, and to
11
 
 * permit persons to whom the Software is furnished to do so, subject to
12
 
 * the following conditions:
13
 
 *
14
 
 * The above copyright notice and this permission notice (including the
15
 
 * next paragraph) shall be included in all copies or substantial portions
16
 
 * of the Software.
17
 
 *
18
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
 
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
 
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21
 
 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22
 
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
 
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
 
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
 
 *
26
 
 **************************************************************************/
27
 
 
28
 
#include <stdio.h>
29
 
 
30
 
#include "pipe/p_context.h"
31
 
 
32
 
#include "tgsi/tgsi_ureg.h"
33
 
 
34
 
#include "util/u_draw.h"
35
 
#include "util/u_memory.h"
36
 
#include "util/u_math.h"
37
 
 
38
 
#include "vl_types.h"
39
 
#include "vl_vertex_buffers.h"
40
 
#include "vl_matrix_filter.h"
41
 
 
42
 
enum VS_OUTPUT
43
 
{
44
 
   VS_O_VPOS = 0,
45
 
   VS_O_VTEX = 0
46
 
};
47
 
 
48
 
static void *
49
 
create_vert_shader(struct vl_matrix_filter *filter)
50
 
{
51
 
   struct ureg_program *shader;
52
 
   struct ureg_src i_vpos;
53
 
   struct ureg_dst o_vpos, o_vtex;
54
 
 
55
 
   shader = ureg_create(PIPE_SHADER_VERTEX);
56
 
   if (!shader)
57
 
      return NULL;
58
 
 
59
 
   i_vpos = ureg_DECL_vs_input(shader, 0);
60
 
   o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS);
61
 
   o_vtex = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX);
62
 
 
63
 
   ureg_MOV(shader, o_vpos, i_vpos);
64
 
   ureg_MOV(shader, o_vtex, i_vpos);
65
 
 
66
 
   ureg_END(shader);
67
 
 
68
 
   return ureg_create_shader_and_destroy(shader, filter->pipe);
69
 
}
70
 
 
71
 
static inline bool
72
 
is_vec_zero(struct vertex2f v)
73
 
{
74
 
   return v.x == 0.0f && v.y == 0.0f;
75
 
}
76
 
 
77
 
static void *
78
 
create_frag_shader(struct vl_matrix_filter *filter, unsigned num_offsets,
79
 
                   struct vertex2f *offsets, const float *matrix_values)
80
 
{
81
 
   struct ureg_program *shader;
82
 
   struct ureg_src i_vtex;
83
 
   struct ureg_src sampler;
84
 
   struct ureg_dst tmp;
85
 
   struct ureg_dst t_sum;
86
 
   struct ureg_dst o_fragment;
87
 
   unsigned i;
88
 
 
89
 
   shader = ureg_create(PIPE_SHADER_FRAGMENT);
90
 
   if (!shader) {
91
 
      return NULL;
92
 
   }
93
 
 
94
 
   i_vtex = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX, TGSI_INTERPOLATE_LINEAR);
95
 
   sampler = ureg_DECL_sampler(shader, 0);
96
 
   ureg_DECL_sampler_view(shader, 0, TGSI_TEXTURE_2D,
97
 
                          TGSI_RETURN_TYPE_FLOAT,
98
 
                          TGSI_RETURN_TYPE_FLOAT,
99
 
                          TGSI_RETURN_TYPE_FLOAT,
100
 
                          TGSI_RETURN_TYPE_FLOAT);
101
 
 
102
 
   tmp = ureg_DECL_temporary(shader);
103
 
   t_sum = ureg_DECL_temporary(shader);
104
 
   o_fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
105
 
 
106
 
   ureg_MOV(shader, t_sum, ureg_imm1f(shader, 0.0f));
107
 
   for (i = 0; i < num_offsets; ++i) {
108
 
      if (matrix_values[i] == 0.0f)
109
 
         continue;
110
 
 
111
 
      if (!is_vec_zero(offsets[i])) {
112
 
         ureg_ADD(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XY),
113
 
                  i_vtex, ureg_imm2f(shader, offsets[i].x, offsets[i].y));
114
 
         ureg_MOV(shader, ureg_writemask(tmp, TGSI_WRITEMASK_ZW),
115
 
                  ureg_imm1f(shader, 0.0f));
116
 
         ureg_TEX(shader, tmp, TGSI_TEXTURE_2D, ureg_src(tmp), sampler);
117
 
      } else {
118
 
         ureg_TEX(shader, tmp, TGSI_TEXTURE_2D, i_vtex, sampler);
119
 
      }
120
 
      ureg_MAD(shader, t_sum, ureg_src(tmp), ureg_imm1f(shader, matrix_values[i]),
121
 
               ureg_src(t_sum));
122
 
   }
123
 
 
124
 
   ureg_MOV(shader, o_fragment, ureg_src(t_sum));
125
 
 
126
 
   ureg_END(shader);
127
 
 
128
 
   return ureg_create_shader_and_destroy(shader, filter->pipe);
129
 
}
130
 
 
131
 
bool
132
 
vl_matrix_filter_init(struct vl_matrix_filter *filter, struct pipe_context *pipe,
133
 
                      unsigned video_width, unsigned video_height,
134
 
                      unsigned matrix_width, unsigned matrix_height,
135
 
                      const float *matrix_values)
136
 
{
137
 
   struct pipe_rasterizer_state rs_state;
138
 
   struct pipe_blend_state blend;
139
 
   struct pipe_sampler_state sampler;
140
 
   struct pipe_vertex_element ve;
141
 
   struct vertex2f *offsets, v, sizes;
142
 
   unsigned i, num_offsets = matrix_width * matrix_height;
143
 
 
144
 
   assert(filter && pipe);
145
 
   assert(video_width && video_height);
146
 
   assert(matrix_width && matrix_height);
147
 
 
148
 
   memset(filter, 0, sizeof(*filter));
149
 
   filter->pipe = pipe;
150
 
 
151
 
   memset(&rs_state, 0, sizeof(rs_state));
152
 
   rs_state.half_pixel_center = true;
153
 
   rs_state.bottom_edge_rule = true;
154
 
   rs_state.depth_clip_near = 1;
155
 
   rs_state.depth_clip_far = 1;
156
 
 
157
 
   filter->rs_state = pipe->create_rasterizer_state(pipe, &rs_state);
158
 
   if (!filter->rs_state)
159
 
      goto error_rs_state;
160
 
 
161
 
   memset(&blend, 0, sizeof blend);
162
 
   blend.rt[0].rgb_func = PIPE_BLEND_ADD;
163
 
   blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
164
 
   blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
165
 
   blend.rt[0].alpha_func = PIPE_BLEND_ADD;
166
 
   blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
167
 
   blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
168
 
   blend.logicop_func = PIPE_LOGICOP_CLEAR;
169
 
   blend.rt[0].colormask = PIPE_MASK_RGBA;
170
 
   filter->blend = pipe->create_blend_state(pipe, &blend);
171
 
   if (!filter->blend)
172
 
      goto error_blend;
173
 
 
174
 
   memset(&sampler, 0, sizeof(sampler));
175
 
   sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
176
 
   sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
177
 
   sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
178
 
   sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
179
 
   sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
180
 
   sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
181
 
   sampler.compare_mode = PIPE_TEX_COMPARE_NONE;
182
 
   sampler.compare_func = PIPE_FUNC_ALWAYS;
183
 
   sampler.normalized_coords = 1;
184
 
   filter->sampler = pipe->create_sampler_state(pipe, &sampler);
185
 
   if (!filter->sampler)
186
 
      goto error_sampler;
187
 
 
188
 
   filter->quad = vl_vb_upload_quads(pipe);
189
 
   if(!filter->quad.buffer.resource)
190
 
      goto error_quad;
191
 
 
192
 
   memset(&ve, 0, sizeof(ve));
193
 
   ve.src_offset = 0;
194
 
   ve.instance_divisor = 0;
195
 
   ve.vertex_buffer_index = 0;
196
 
   ve.src_format = PIPE_FORMAT_R32G32_FLOAT;
197
 
   filter->ves = pipe->create_vertex_elements_state(pipe, 1, &ve);
198
 
   if (!filter->ves)
199
 
      goto error_ves;
200
 
 
201
 
   offsets = MALLOC(sizeof(struct vertex2f) * num_offsets);
202
 
   if (!offsets)
203
 
      goto error_offsets;
204
 
 
205
 
   sizes.x = (float)(matrix_width - 1) / 2.0f;
206
 
   sizes.y = (float)(matrix_height - 1) / 2.0f;
207
 
 
208
 
   for (v.x = -sizes.x, i = 0; v.x <= sizes.x; v.x += 1.0f)
209
 
      for (v.y = -sizes.y; v.y <= sizes.y; v.y += 1.0f)
210
 
         offsets[i++] = v;
211
 
 
212
 
   for (i = 0; i < num_offsets; ++i) {
213
 
      offsets[i].x /= video_width;
214
 
      offsets[i].y /= video_height;
215
 
   }
216
 
 
217
 
   filter->vs = create_vert_shader(filter);
218
 
   if (!filter->vs)
219
 
      goto error_vs;
220
 
 
221
 
   filter->fs = create_frag_shader(filter, num_offsets, offsets, matrix_values);
222
 
   if (!filter->fs)
223
 
      goto error_fs;
224
 
 
225
 
   FREE(offsets);
226
 
   return true;
227
 
 
228
 
error_fs:
229
 
   pipe->delete_vs_state(pipe, filter->vs);
230
 
 
231
 
error_vs:
232
 
   FREE(offsets);
233
 
 
234
 
error_offsets:
235
 
   pipe->delete_vertex_elements_state(pipe, filter->ves);
236
 
 
237
 
error_ves:
238
 
   pipe_resource_reference(&filter->quad.buffer.resource, NULL);
239
 
 
240
 
error_quad:
241
 
   pipe->delete_sampler_state(pipe, filter->sampler);
242
 
 
243
 
error_sampler:
244
 
   pipe->delete_blend_state(pipe, filter->blend);
245
 
 
246
 
error_blend:
247
 
   pipe->delete_rasterizer_state(pipe, filter->rs_state);
248
 
 
249
 
error_rs_state:
250
 
   return false;
251
 
}
252
 
 
253
 
void
254
 
vl_matrix_filter_cleanup(struct vl_matrix_filter *filter)
255
 
{
256
 
   assert(filter);
257
 
 
258
 
   filter->pipe->delete_sampler_state(filter->pipe, filter->sampler);
259
 
   filter->pipe->delete_blend_state(filter->pipe, filter->blend);
260
 
   filter->pipe->delete_rasterizer_state(filter->pipe, filter->rs_state);
261
 
   filter->pipe->delete_vertex_elements_state(filter->pipe, filter->ves);
262
 
   pipe_resource_reference(&filter->quad.buffer.resource, NULL);
263
 
 
264
 
   filter->pipe->delete_vs_state(filter->pipe, filter->vs);
265
 
   filter->pipe->delete_fs_state(filter->pipe, filter->fs);
266
 
}
267
 
 
268
 
void
269
 
vl_matrix_filter_render(struct vl_matrix_filter *filter,
270
 
                        struct pipe_sampler_view *src,
271
 
                        struct pipe_surface *dst)
272
 
{
273
 
   struct pipe_viewport_state viewport;
274
 
   struct pipe_framebuffer_state fb_state;
275
 
 
276
 
   assert(filter && src && dst);
277
 
 
278
 
   memset(&viewport, 0, sizeof(viewport));
279
 
   viewport.scale[0] = dst->width;
280
 
   viewport.scale[1] = dst->height;
281
 
   viewport.scale[2] = 1;
282
 
   viewport.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X;
283
 
   viewport.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y;
284
 
   viewport.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z;
285
 
   viewport.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W;
286
 
 
287
 
   memset(&fb_state, 0, sizeof(fb_state));
288
 
   fb_state.width = dst->width;
289
 
   fb_state.height = dst->height;
290
 
   fb_state.nr_cbufs = 1;
291
 
   fb_state.cbufs[0] = dst;
292
 
 
293
 
   filter->pipe->bind_rasterizer_state(filter->pipe, filter->rs_state);
294
 
   filter->pipe->bind_blend_state(filter->pipe, filter->blend);
295
 
   filter->pipe->bind_sampler_states(filter->pipe, PIPE_SHADER_FRAGMENT,
296
 
                                     0, 1, &filter->sampler);
297
 
   filter->pipe->set_sampler_views(filter->pipe, PIPE_SHADER_FRAGMENT,
298
 
                                   0, 1, 0, false, &src);
299
 
   filter->pipe->bind_vs_state(filter->pipe, filter->vs);
300
 
   filter->pipe->bind_fs_state(filter->pipe, filter->fs);
301
 
   filter->pipe->set_framebuffer_state(filter->pipe, &fb_state);
302
 
   filter->pipe->set_viewport_states(filter->pipe, 0, 1, &viewport);
303
 
   filter->pipe->set_vertex_buffers(filter->pipe, 0, 1, 0, false, &filter->quad);
304
 
   filter->pipe->bind_vertex_elements_state(filter->pipe, filter->ves);
305
 
 
306
 
   util_draw_arrays(filter->pipe, PIPE_PRIM_QUADS, 0, 4);
307
 
}