Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/auxiliary/vl/vl_zscan.c
4565 views
1
/**************************************************************************
2
*
3
* Copyright 2011 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 <assert.h>
29
30
#include "pipe/p_screen.h"
31
#include "pipe/p_context.h"
32
33
#include "util/u_draw.h"
34
#include "util/u_sampler.h"
35
#include "util/u_inlines.h"
36
#include "util/u_memory.h"
37
38
#include "tgsi/tgsi_ureg.h"
39
40
#include "vl_defines.h"
41
#include "vl_types.h"
42
43
#include "vl_zscan.h"
44
#include "vl_vertex_buffers.h"
45
46
enum VS_OUTPUT
47
{
48
VS_O_VPOS = 0,
49
VS_O_VTEX = 0
50
};
51
52
const int vl_zscan_normal_16[] =
53
{
54
/* Zig-Zag scan pattern */
55
0, 1, 4, 8, 5, 2, 3, 6,
56
9,12,13,10, 7,11,14,15
57
};
58
59
const int vl_zscan_linear[] =
60
{
61
/* Linear scan pattern */
62
0, 1, 2, 3, 4, 5, 6, 7,
63
8, 9,10,11,12,13,14,15,
64
16,17,18,19,20,21,22,23,
65
24,25,26,27,28,29,30,31,
66
32,33,34,35,36,37,38,39,
67
40,41,42,43,44,45,46,47,
68
48,49,50,51,52,53,54,55,
69
56,57,58,59,60,61,62,63
70
};
71
72
const int vl_zscan_normal[] =
73
{
74
/* Zig-Zag scan pattern */
75
0, 1, 8,16, 9, 2, 3,10,
76
17,24,32,25,18,11, 4, 5,
77
12,19,26,33,40,48,41,34,
78
27,20,13, 6, 7,14,21,28,
79
35,42,49,56,57,50,43,36,
80
29,22,15,23,30,37,44,51,
81
58,59,52,45,38,31,39,46,
82
53,60,61,54,47,55,62,63
83
};
84
85
const int vl_zscan_alternate[] =
86
{
87
/* Alternate scan pattern */
88
0, 8,16,24, 1, 9, 2,10,
89
17,25,32,40,48,56,57,49,
90
41,33,26,18, 3,11, 4,12,
91
19,27,34,42,50,58,35,43,
92
51,59,20,28, 5,13, 6,14,
93
21,29,36,44,52,60,37,45,
94
53,61,22,30, 7,15,23,31,
95
38,46,54,62,39,47,55,63
96
};
97
98
const int vl_zscan_h265_up_right_diagonal_16[] =
99
{
100
/* Up-right diagonal scan order for 4x4 blocks - see H.265 section 6.5.3. */
101
0, 4, 1, 8, 5, 2, 12, 9,
102
6, 3, 13, 10, 7, 14, 11, 15,
103
};
104
105
const int vl_zscan_h265_up_right_diagonal[] =
106
{
107
/* Up-right diagonal scan order for 8x8 blocks - see H.265 section 6.5.3. */
108
0, 8, 1, 16, 9, 2, 24, 17,
109
10, 3, 32, 25, 18, 11, 4, 40,
110
33, 26, 19, 12, 5, 48, 41, 34,
111
27, 20, 13, 6, 56, 49, 42, 35,
112
28, 21, 14, 7, 57, 50, 43, 36,
113
29, 22, 15, 58, 51, 44, 37, 30,
114
23, 59, 52, 45, 38, 31, 60, 53,
115
46, 39, 61, 54, 47, 62, 55, 63,
116
};
117
118
119
static void *
120
create_vert_shader(struct vl_zscan *zscan)
121
{
122
struct ureg_program *shader;
123
struct ureg_src scale;
124
struct ureg_src vrect, vpos, block_num;
125
struct ureg_dst tmp;
126
struct ureg_dst o_vpos;
127
struct ureg_dst *o_vtex;
128
unsigned i;
129
130
shader = ureg_create(PIPE_SHADER_VERTEX);
131
if (!shader)
132
return NULL;
133
134
o_vtex = MALLOC(zscan->num_channels * sizeof(struct ureg_dst));
135
136
scale = ureg_imm2f(shader,
137
(float)VL_BLOCK_WIDTH / zscan->buffer_width,
138
(float)VL_BLOCK_HEIGHT / zscan->buffer_height);
139
140
vrect = ureg_DECL_vs_input(shader, VS_I_RECT);
141
vpos = ureg_DECL_vs_input(shader, VS_I_VPOS);
142
block_num = ureg_DECL_vs_input(shader, VS_I_BLOCK_NUM);
143
144
tmp = ureg_DECL_temporary(shader);
145
146
o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS);
147
148
for (i = 0; i < zscan->num_channels; ++i)
149
o_vtex[i] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX + i);
150
151
/*
152
* o_vpos.xy = (vpos + vrect) * scale
153
* o_vpos.zw = 1.0f
154
*
155
* tmp.xy = InstanceID / blocks_per_line
156
* tmp.x = frac(tmp.x)
157
* tmp.y = floor(tmp.y)
158
*
159
* o_vtex.x = vrect.x / blocks_per_line + tmp.x
160
* o_vtex.y = vrect.y
161
* o_vtex.z = tmp.z * blocks_per_line / blocks_total
162
*/
163
ureg_ADD(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XY), vpos, vrect);
164
ureg_MUL(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), ureg_src(tmp), scale);
165
ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), ureg_imm1f(shader, 1.0f));
166
167
ureg_MUL(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XW), ureg_scalar(block_num, TGSI_SWIZZLE_X),
168
ureg_imm1f(shader, 1.0f / zscan->blocks_per_line));
169
170
ureg_FRC(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X));
171
ureg_FLR(shader, ureg_writemask(tmp, TGSI_WRITEMASK_W), ureg_src(tmp));
172
173
for (i = 0; i < zscan->num_channels; ++i) {
174
ureg_ADD(shader, ureg_writemask(tmp, TGSI_WRITEMASK_X), ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y),
175
ureg_imm1f(shader, 1.0f / (zscan->blocks_per_line * VL_BLOCK_WIDTH)
176
* ((signed)i - (signed)zscan->num_channels / 2)));
177
178
ureg_MAD(shader, ureg_writemask(o_vtex[i], TGSI_WRITEMASK_X), vrect,
179
ureg_imm1f(shader, 1.0f / zscan->blocks_per_line), ureg_src(tmp));
180
ureg_MOV(shader, ureg_writemask(o_vtex[i], TGSI_WRITEMASK_Y), vrect);
181
ureg_MOV(shader, ureg_writemask(o_vtex[i], TGSI_WRITEMASK_Z), vpos);
182
ureg_MUL(shader, ureg_writemask(o_vtex[i], TGSI_WRITEMASK_W), ureg_src(tmp),
183
ureg_imm1f(shader, (float)zscan->blocks_per_line / zscan->blocks_total));
184
}
185
186
ureg_release_temporary(shader, tmp);
187
ureg_END(shader);
188
189
FREE(o_vtex);
190
191
return ureg_create_shader_and_destroy(shader, zscan->pipe);
192
}
193
194
static void *
195
create_frag_shader(struct vl_zscan *zscan)
196
{
197
struct ureg_program *shader;
198
struct ureg_src *vtex;
199
200
struct ureg_src samp_src, samp_scan, samp_quant;
201
202
struct ureg_dst *tmp;
203
struct ureg_dst quant, fragment;
204
205
unsigned i;
206
207
shader = ureg_create(PIPE_SHADER_FRAGMENT);
208
if (!shader)
209
return NULL;
210
211
vtex = MALLOC(zscan->num_channels * sizeof(struct ureg_src));
212
tmp = MALLOC(zscan->num_channels * sizeof(struct ureg_dst));
213
214
for (i = 0; i < zscan->num_channels; ++i)
215
vtex[i] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX + i, TGSI_INTERPOLATE_LINEAR);
216
217
samp_src = ureg_DECL_sampler(shader, 0);
218
samp_scan = ureg_DECL_sampler(shader, 1);
219
samp_quant = ureg_DECL_sampler(shader, 2);
220
221
for (i = 0; i < zscan->num_channels; ++i)
222
tmp[i] = ureg_DECL_temporary(shader);
223
quant = ureg_DECL_temporary(shader);
224
225
fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
226
227
/*
228
* tmp.x = tex(vtex, 1)
229
* tmp.y = vtex.z
230
* fragment = tex(tmp, 0) * quant
231
*/
232
for (i = 0; i < zscan->num_channels; ++i)
233
ureg_TEX(shader, ureg_writemask(tmp[i], TGSI_WRITEMASK_X), TGSI_TEXTURE_2D, vtex[i], samp_scan);
234
235
for (i = 0; i < zscan->num_channels; ++i)
236
ureg_MOV(shader, ureg_writemask(tmp[i], TGSI_WRITEMASK_Y), ureg_scalar(vtex[i], TGSI_SWIZZLE_W));
237
238
for (i = 0; i < zscan->num_channels; ++i) {
239
ureg_TEX(shader, ureg_writemask(tmp[0], TGSI_WRITEMASK_X << i), TGSI_TEXTURE_2D, ureg_src(tmp[i]), samp_src);
240
ureg_TEX(shader, ureg_writemask(quant, TGSI_WRITEMASK_X << i), TGSI_TEXTURE_3D, vtex[i], samp_quant);
241
}
242
243
ureg_MUL(shader, quant, ureg_src(quant), ureg_imm1f(shader, 16.0f));
244
ureg_MUL(shader, fragment, ureg_src(tmp[0]), ureg_src(quant));
245
246
for (i = 0; i < zscan->num_channels; ++i)
247
ureg_release_temporary(shader, tmp[i]);
248
ureg_END(shader);
249
250
FREE(vtex);
251
FREE(tmp);
252
253
return ureg_create_shader_and_destroy(shader, zscan->pipe);
254
}
255
256
static bool
257
init_shaders(struct vl_zscan *zscan)
258
{
259
assert(zscan);
260
261
zscan->vs = create_vert_shader(zscan);
262
if (!zscan->vs)
263
goto error_vs;
264
265
zscan->fs = create_frag_shader(zscan);
266
if (!zscan->fs)
267
goto error_fs;
268
269
return true;
270
271
error_fs:
272
zscan->pipe->delete_vs_state(zscan->pipe, zscan->vs);
273
274
error_vs:
275
return false;
276
}
277
278
static void
279
cleanup_shaders(struct vl_zscan *zscan)
280
{
281
assert(zscan);
282
283
zscan->pipe->delete_vs_state(zscan->pipe, zscan->vs);
284
zscan->pipe->delete_fs_state(zscan->pipe, zscan->fs);
285
}
286
287
static bool
288
init_state(struct vl_zscan *zscan)
289
{
290
struct pipe_blend_state blend;
291
struct pipe_rasterizer_state rs_state;
292
struct pipe_sampler_state sampler;
293
unsigned i;
294
295
assert(zscan);
296
297
memset(&rs_state, 0, sizeof(rs_state));
298
rs_state.half_pixel_center = true;
299
rs_state.bottom_edge_rule = true;
300
rs_state.depth_clip_near = 1;
301
rs_state.depth_clip_far = 1;
302
303
zscan->rs_state = zscan->pipe->create_rasterizer_state(zscan->pipe, &rs_state);
304
if (!zscan->rs_state)
305
goto error_rs_state;
306
307
memset(&blend, 0, sizeof blend);
308
309
blend.independent_blend_enable = 0;
310
blend.rt[0].blend_enable = 0;
311
blend.rt[0].rgb_func = PIPE_BLEND_ADD;
312
blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
313
blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
314
blend.rt[0].alpha_func = PIPE_BLEND_ADD;
315
blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
316
blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
317
blend.logicop_enable = 0;
318
blend.logicop_func = PIPE_LOGICOP_CLEAR;
319
/* Needed to allow color writes to FB, even if blending disabled */
320
blend.rt[0].colormask = PIPE_MASK_RGBA;
321
blend.dither = 0;
322
zscan->blend = zscan->pipe->create_blend_state(zscan->pipe, &blend);
323
if (!zscan->blend)
324
goto error_blend;
325
326
for (i = 0; i < 3; ++i) {
327
memset(&sampler, 0, sizeof(sampler));
328
sampler.wrap_s = PIPE_TEX_WRAP_REPEAT;
329
sampler.wrap_t = PIPE_TEX_WRAP_REPEAT;
330
sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
331
sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
332
sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
333
sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
334
sampler.compare_mode = PIPE_TEX_COMPARE_NONE;
335
sampler.compare_func = PIPE_FUNC_ALWAYS;
336
sampler.normalized_coords = 1;
337
zscan->samplers[i] = zscan->pipe->create_sampler_state(zscan->pipe, &sampler);
338
if (!zscan->samplers[i])
339
goto error_samplers;
340
}
341
342
return true;
343
344
error_samplers:
345
for (i = 0; i < 2; ++i)
346
if (zscan->samplers[i])
347
zscan->pipe->delete_sampler_state(zscan->pipe, zscan->samplers[i]);
348
349
zscan->pipe->delete_rasterizer_state(zscan->pipe, zscan->rs_state);
350
351
error_blend:
352
zscan->pipe->delete_blend_state(zscan->pipe, zscan->blend);
353
354
error_rs_state:
355
return false;
356
}
357
358
static void
359
cleanup_state(struct vl_zscan *zscan)
360
{
361
unsigned i;
362
363
assert(zscan);
364
365
for (i = 0; i < 3; ++i)
366
zscan->pipe->delete_sampler_state(zscan->pipe, zscan->samplers[i]);
367
368
zscan->pipe->delete_rasterizer_state(zscan->pipe, zscan->rs_state);
369
zscan->pipe->delete_blend_state(zscan->pipe, zscan->blend);
370
}
371
372
struct pipe_sampler_view *
373
vl_zscan_layout(struct pipe_context *pipe, const int layout[64], unsigned blocks_per_line)
374
{
375
const unsigned total_size = blocks_per_line * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT;
376
377
int patched_layout[64];
378
379
struct pipe_resource res_tmpl, *res;
380
struct pipe_sampler_view sv_tmpl, *sv;
381
struct pipe_transfer *buf_transfer;
382
unsigned x, y, i, pitch;
383
float *f;
384
385
struct pipe_box rect =
386
{
387
0, 0, 0,
388
VL_BLOCK_WIDTH * blocks_per_line,
389
VL_BLOCK_HEIGHT,
390
1
391
};
392
393
assert(pipe && layout && blocks_per_line);
394
395
for (i = 0; i < 64; ++i)
396
patched_layout[layout[i]] = i;
397
398
memset(&res_tmpl, 0, sizeof(res_tmpl));
399
res_tmpl.target = PIPE_TEXTURE_2D;
400
res_tmpl.format = PIPE_FORMAT_R32_FLOAT;
401
res_tmpl.width0 = VL_BLOCK_WIDTH * blocks_per_line;
402
res_tmpl.height0 = VL_BLOCK_HEIGHT;
403
res_tmpl.depth0 = 1;
404
res_tmpl.array_size = 1;
405
res_tmpl.usage = PIPE_USAGE_IMMUTABLE;
406
res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW;
407
408
res = pipe->screen->resource_create(pipe->screen, &res_tmpl);
409
if (!res)
410
goto error_resource;
411
412
f = pipe->texture_map(pipe, res,
413
0, PIPE_MAP_WRITE | PIPE_MAP_DISCARD_RANGE,
414
&rect, &buf_transfer);
415
if (!f)
416
goto error_map;
417
418
pitch = buf_transfer->stride / sizeof(float);
419
420
for (i = 0; i < blocks_per_line; ++i)
421
for (y = 0; y < VL_BLOCK_HEIGHT; ++y)
422
for (x = 0; x < VL_BLOCK_WIDTH; ++x) {
423
float addr = patched_layout[x + y * VL_BLOCK_WIDTH] +
424
i * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT;
425
426
addr /= total_size;
427
428
f[i * VL_BLOCK_WIDTH + y * pitch + x] = addr;
429
}
430
431
pipe->texture_unmap(pipe, buf_transfer);
432
433
memset(&sv_tmpl, 0, sizeof(sv_tmpl));
434
u_sampler_view_default_template(&sv_tmpl, res, res->format);
435
sv = pipe->create_sampler_view(pipe, res, &sv_tmpl);
436
pipe_resource_reference(&res, NULL);
437
if (!sv)
438
goto error_map;
439
440
return sv;
441
442
error_map:
443
pipe_resource_reference(&res, NULL);
444
445
error_resource:
446
return NULL;
447
}
448
449
bool
450
vl_zscan_init(struct vl_zscan *zscan, struct pipe_context *pipe,
451
unsigned buffer_width, unsigned buffer_height,
452
unsigned blocks_per_line, unsigned blocks_total,
453
unsigned num_channels)
454
{
455
assert(zscan && pipe);
456
457
zscan->pipe = pipe;
458
zscan->buffer_width = buffer_width;
459
zscan->buffer_height = buffer_height;
460
zscan->num_channels = num_channels;
461
zscan->blocks_per_line = blocks_per_line;
462
zscan->blocks_total = blocks_total;
463
464
if(!init_shaders(zscan))
465
return false;
466
467
if(!init_state(zscan)) {
468
cleanup_shaders(zscan);
469
return false;
470
}
471
472
return true;
473
}
474
475
void
476
vl_zscan_cleanup(struct vl_zscan *zscan)
477
{
478
assert(zscan);
479
480
cleanup_shaders(zscan);
481
cleanup_state(zscan);
482
}
483
484
bool
485
vl_zscan_init_buffer(struct vl_zscan *zscan, struct vl_zscan_buffer *buffer,
486
struct pipe_sampler_view *src, struct pipe_surface *dst)
487
{
488
struct pipe_resource res_tmpl, *res;
489
struct pipe_sampler_view sv_tmpl;
490
491
assert(zscan && buffer);
492
493
memset(buffer, 0, sizeof(struct vl_zscan_buffer));
494
495
pipe_sampler_view_reference(&buffer->src, src);
496
497
buffer->viewport.scale[0] = dst->width;
498
buffer->viewport.scale[1] = dst->height;
499
buffer->viewport.scale[2] = 1;
500
buffer->viewport.translate[0] = 0;
501
buffer->viewport.translate[1] = 0;
502
buffer->viewport.translate[2] = 0;
503
buffer->viewport.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X;
504
buffer->viewport.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y;
505
buffer->viewport.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z;
506
buffer->viewport.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W;
507
508
buffer->fb_state.width = dst->width;
509
buffer->fb_state.height = dst->height;
510
buffer->fb_state.nr_cbufs = 1;
511
pipe_surface_reference(&buffer->fb_state.cbufs[0], dst);
512
513
memset(&res_tmpl, 0, sizeof(res_tmpl));
514
res_tmpl.target = PIPE_TEXTURE_3D;
515
res_tmpl.format = PIPE_FORMAT_R8_UNORM;
516
res_tmpl.width0 = VL_BLOCK_WIDTH * zscan->blocks_per_line;
517
res_tmpl.height0 = VL_BLOCK_HEIGHT;
518
res_tmpl.depth0 = 2;
519
res_tmpl.array_size = 1;
520
res_tmpl.usage = PIPE_USAGE_IMMUTABLE;
521
res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW;
522
523
res = zscan->pipe->screen->resource_create(zscan->pipe->screen, &res_tmpl);
524
if (!res)
525
return false;
526
527
memset(&sv_tmpl, 0, sizeof(sv_tmpl));
528
u_sampler_view_default_template(&sv_tmpl, res, res->format);
529
sv_tmpl.swizzle_r = sv_tmpl.swizzle_g = sv_tmpl.swizzle_b = sv_tmpl.swizzle_a = TGSI_SWIZZLE_X;
530
buffer->quant = zscan->pipe->create_sampler_view(zscan->pipe, res, &sv_tmpl);
531
pipe_resource_reference(&res, NULL);
532
if (!buffer->quant)
533
return false;
534
535
return true;
536
}
537
538
void
539
vl_zscan_cleanup_buffer(struct vl_zscan_buffer *buffer)
540
{
541
assert(buffer);
542
543
pipe_sampler_view_reference(&buffer->src, NULL);
544
pipe_sampler_view_reference(&buffer->layout, NULL);
545
pipe_sampler_view_reference(&buffer->quant, NULL);
546
pipe_surface_reference(&buffer->fb_state.cbufs[0], NULL);
547
}
548
549
void
550
vl_zscan_set_layout(struct vl_zscan_buffer *buffer, struct pipe_sampler_view *layout)
551
{
552
assert(buffer);
553
assert(layout);
554
555
pipe_sampler_view_reference(&buffer->layout, layout);
556
}
557
558
void
559
vl_zscan_upload_quant(struct vl_zscan *zscan, struct vl_zscan_buffer *buffer,
560
const uint8_t matrix[64], bool intra)
561
{
562
struct pipe_context *pipe;
563
struct pipe_transfer *buf_transfer;
564
unsigned x, y, i, pitch;
565
uint8_t *data;
566
567
struct pipe_box rect =
568
{
569
0, 0, intra ? 1 : 0,
570
VL_BLOCK_WIDTH,
571
VL_BLOCK_HEIGHT,
572
1
573
};
574
575
assert(buffer);
576
assert(matrix);
577
578
pipe = zscan->pipe;
579
580
rect.width *= zscan->blocks_per_line;
581
582
data = pipe->texture_map(pipe, buffer->quant->texture,
583
0, PIPE_MAP_WRITE |
584
PIPE_MAP_DISCARD_RANGE,
585
&rect, &buf_transfer);
586
if (!data)
587
return;
588
589
pitch = buf_transfer->stride;
590
591
for (i = 0; i < zscan->blocks_per_line; ++i)
592
for (y = 0; y < VL_BLOCK_HEIGHT; ++y)
593
for (x = 0; x < VL_BLOCK_WIDTH; ++x)
594
data[i * VL_BLOCK_WIDTH + y * pitch + x] = matrix[x + y * VL_BLOCK_WIDTH];
595
596
pipe->texture_unmap(pipe, buf_transfer);
597
}
598
599
void
600
vl_zscan_render(struct vl_zscan *zscan, struct vl_zscan_buffer *buffer, unsigned num_instances)
601
{
602
assert(buffer);
603
604
zscan->pipe->bind_rasterizer_state(zscan->pipe, zscan->rs_state);
605
zscan->pipe->bind_blend_state(zscan->pipe, zscan->blend);
606
zscan->pipe->bind_sampler_states(zscan->pipe, PIPE_SHADER_FRAGMENT,
607
0, 3, zscan->samplers);
608
zscan->pipe->set_framebuffer_state(zscan->pipe, &buffer->fb_state);
609
zscan->pipe->set_viewport_states(zscan->pipe, 0, 1, &buffer->viewport);
610
zscan->pipe->set_sampler_views(zscan->pipe, PIPE_SHADER_FRAGMENT,
611
0, 3, 0, &buffer->src);
612
zscan->pipe->bind_vs_state(zscan->pipe, zscan->vs);
613
zscan->pipe->bind_fs_state(zscan->pipe, zscan->fs);
614
util_draw_arrays_instanced(zscan->pipe, PIPE_PRIM_QUADS, 0, 4, 0, num_instances);
615
}
616
617