1f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König/**************************************************************************
2f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König *
3f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König * Copyright 2011 Christian König
4f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König * All Rights Reserved.
5f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König *
6f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König * Permission is hereby granted, free of charge, to any person obtaining a
7f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König * copy of this software and associated documentation files (the
8f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König * "Software"), to deal in the Software without restriction, including
9f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König * without limitation the rights to use, copy, modify, merge, publish,
10f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König * distribute, sub license, and/or sell copies of the Software, and to
11f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König * permit persons to whom the Software is furnished to do so, subject to
12f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König * the following conditions:
13f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König *
14f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König * The above copyright notice and this permission notice (including the
15f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König * next paragraph) shall be included in all copies or substantial portions
16f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König * of the Software.
17f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König *
18f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König *
26f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König **************************************************************************/
27f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
28f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König#include <assert.h>
29f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
3019bcd21ed151cf1716f2f87dff0f712231aa2ce7Kai Wasserbäch#include "pipe/p_screen.h"
3119bcd21ed151cf1716f2f87dff0f712231aa2ce7Kai Wasserbäch#include "pipe/p_context.h"
32f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
3319bcd21ed151cf1716f2f87dff0f712231aa2ce7Kai Wasserbäch#include "util/u_draw.h"
3419bcd21ed151cf1716f2f87dff0f712231aa2ce7Kai Wasserbäch#include "util/u_sampler.h"
3519bcd21ed151cf1716f2f87dff0f712231aa2ce7Kai Wasserbäch#include "util/u_inlines.h"
3619bcd21ed151cf1716f2f87dff0f712231aa2ce7Kai Wasserbäch#include "util/u_memory.h"
37f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
3819bcd21ed151cf1716f2f87dff0f712231aa2ce7Kai Wasserbäch#include "tgsi/tgsi_ureg.h"
39f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
4019bcd21ed151cf1716f2f87dff0f712231aa2ce7Kai Wasserbäch#include "vl_defines.h"
4119bcd21ed151cf1716f2f87dff0f712231aa2ce7Kai Wasserbäch#include "vl_types.h"
42f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
43f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König#include "vl_zscan.h"
44f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König#include "vl_vertex_buffers.h"
45f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
46f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königenum VS_OUTPUT
47f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König{
4895594bae47d8b3302be188e6f0be2d69c5507bb3Christian König   VS_O_VPOS = 0,
4995594bae47d8b3302be188e6f0be2d69c5507bb3Christian König   VS_O_VTEX = 0
50f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König};
51f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
526ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian Königconst int vl_zscan_linear[] =
536ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König{
546ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   /* Linear scan pattern */
556ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König    0, 1, 2, 3, 4, 5, 6, 7,
566ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König    8, 9,10,11,12,13,14,15,
576ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   16,17,18,19,20,21,22,23,
586ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   24,25,26,27,28,29,30,31,
596ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   32,33,34,35,36,37,38,39,
606ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   40,41,42,43,44,45,46,47,
616ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   48,49,50,51,52,53,54,55,
626ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   56,57,58,59,60,61,62,63
636ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König};
646ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König
656ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian Königconst int vl_zscan_normal[] =
666ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König{
676ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   /* Zig-Zag scan pattern */
686ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König    0, 1, 8,16, 9, 2, 3,10,
696ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   17,24,32,25,18,11, 4, 5,
706ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   12,19,26,33,40,48,41,34,
716ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   27,20,13, 6, 7,14,21,28,
726ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   35,42,49,56,57,50,43,36,
736ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   29,22,15,23,30,37,44,51,
746ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   58,59,52,45,38,31,39,46,
756ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   53,60,61,54,47,55,62,63
766ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König};
776ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König
786ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian Königconst int vl_zscan_alternate[] =
796ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König{
806ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   /* Alternate scan pattern */
816ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König    0, 8,16,24, 1, 9, 2,10,
826ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   17,25,32,40,48,56,57,49,
836ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   41,33,26,18, 3,11, 4,12,
846ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   19,27,34,42,50,58,35,43,
856ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   51,59,20,28, 5,13, 6,14,
866ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   21,29,36,44,52,60,37,45,
876ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   53,61,22,30, 7,15,23,31,
886ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   38,46,54,62,39,47,55,63
896ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König};
906ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König
91f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königstatic void *
92f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königcreate_vert_shader(struct vl_zscan *zscan)
93f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König{
94f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   struct ureg_program *shader;
95f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
96a6c76c8a90dc8995feed3c61b02dbd8408149036Christian König   struct ureg_src scale;
97a6c76c8a90dc8995feed3c61b02dbd8408149036Christian König   struct ureg_src vrect, vpos, block_num;
98f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
99f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   struct ureg_dst tmp;
1003cf22a0c6e215535266e7a7fac5ddd2404d4345dVinson Lee   struct ureg_dst o_vpos;
1013cf22a0c6e215535266e7a7fac5ddd2404d4345dVinson Lee   struct ureg_dst *o_vtex;
102f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
10320aabb9c2eff63fd97571b9f3db453fe3accc10aChristian König   signed i;
104f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
105f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   shader = ureg_create(TGSI_PROCESSOR_VERTEX);
106f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if (!shader)
107f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      return NULL;
108f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
1093cf22a0c6e215535266e7a7fac5ddd2404d4345dVinson Lee   o_vtex = MALLOC(zscan->num_channels * sizeof(struct ureg_dst));
1103cf22a0c6e215535266e7a7fac5ddd2404d4345dVinson Lee
111f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   scale = ureg_imm2f(shader,
11270a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König      (float)VL_BLOCK_WIDTH / zscan->buffer_width,
11370a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König      (float)VL_BLOCK_HEIGHT / zscan->buffer_height);
114f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
115f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   vrect = ureg_DECL_vs_input(shader, VS_I_RECT);
116f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   vpos = ureg_DECL_vs_input(shader, VS_I_VPOS);
117c6c2ef070957e5a0c0003e1d0a6d6e2fe197fb40Christian König   block_num = ureg_DECL_vs_input(shader, VS_I_BLOCK_NUM);
118a6c76c8a90dc8995feed3c61b02dbd8408149036Christian König
119f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   tmp = ureg_DECL_temporary(shader);
120f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
121f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS);
122f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
123f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   for (i = 0; i < zscan->num_channels; ++i)
124f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      o_vtex[i] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX + i);
125f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
126f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   /*
127f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König    * o_vpos.xy = (vpos + vrect) * scale
128f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König    * o_vpos.zw = 1.0f
129f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König    *
130f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König    * tmp.xy = InstanceID / blocks_per_line
131f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König    * tmp.x = frac(tmp.x)
132f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König    * tmp.y = floor(tmp.y)
133f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König    *
134f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König    * o_vtex.x = vrect.x / blocks_per_line + tmp.x
135f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König    * o_vtex.y = vrect.y
136f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König    * o_vtex.z = tmp.z * blocks_per_line / blocks_total
137f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König    */
138f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   ureg_ADD(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XY), vpos, vrect);
139f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   ureg_MUL(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), ureg_src(tmp), scale);
140f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), ureg_imm1f(shader, 1.0f));
141f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
142a6c76c8a90dc8995feed3c61b02dbd8408149036Christian König   ureg_MUL(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XW), ureg_scalar(block_num, TGSI_SWIZZLE_X),
143f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König            ureg_imm1f(shader, 1.0f / zscan->blocks_per_line));
144f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
14520aabb9c2eff63fd97571b9f3db453fe3accc10aChristian König   ureg_FRC(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X));
146912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   ureg_FLR(shader, ureg_writemask(tmp, TGSI_WRITEMASK_W), ureg_src(tmp));
147f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
148f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   for (i = 0; i < zscan->num_channels; ++i) {
14920aabb9c2eff63fd97571b9f3db453fe3accc10aChristian König      ureg_ADD(shader, ureg_writemask(tmp, TGSI_WRITEMASK_X), ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y),
15070a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König               ureg_imm1f(shader, 1.0f / (zscan->blocks_per_line * VL_BLOCK_WIDTH)
15170a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König                * (i - (signed)zscan->num_channels / 2)));
152f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
153f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      ureg_MAD(shader, ureg_writemask(o_vtex[i], TGSI_WRITEMASK_X), vrect,
154f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König               ureg_imm1f(shader, 1.0f / zscan->blocks_per_line), ureg_src(tmp));
155f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      ureg_MOV(shader, ureg_writemask(o_vtex[i], TGSI_WRITEMASK_Y), vrect);
156912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König      ureg_MOV(shader, ureg_writemask(o_vtex[i], TGSI_WRITEMASK_Z), vpos);
157912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König      ureg_MUL(shader, ureg_writemask(o_vtex[i], TGSI_WRITEMASK_W), ureg_src(tmp),
158f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König               ureg_imm1f(shader, (float)zscan->blocks_per_line / zscan->blocks_total));
159f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   }
160f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
161f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   ureg_release_temporary(shader, tmp);
162f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   ureg_END(shader);
163f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
1643cf22a0c6e215535266e7a7fac5ddd2404d4345dVinson Lee   FREE(o_vtex);
1653cf22a0c6e215535266e7a7fac5ddd2404d4345dVinson Lee
166f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   return ureg_create_shader_and_destroy(shader, zscan->pipe);
167f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König}
168f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
169f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königstatic void *
170f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königcreate_frag_shader(struct vl_zscan *zscan)
171f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König{
172f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   struct ureg_program *shader;
1733cf22a0c6e215535266e7a7fac5ddd2404d4345dVinson Lee   struct ureg_src *vtex;
174f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
175912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   struct ureg_src samp_src, samp_scan, samp_quant;
176f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
1773cf22a0c6e215535266e7a7fac5ddd2404d4345dVinson Lee   struct ureg_dst *tmp;
178912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   struct ureg_dst quant, fragment;
179f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
180f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   unsigned i;
181f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
182f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
183f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if (!shader)
184f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      return NULL;
185f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
1863cf22a0c6e215535266e7a7fac5ddd2404d4345dVinson Lee   vtex = MALLOC(zscan->num_channels * sizeof(struct ureg_src));
1873cf22a0c6e215535266e7a7fac5ddd2404d4345dVinson Lee   tmp = MALLOC(zscan->num_channels * sizeof(struct ureg_dst));
1883cf22a0c6e215535266e7a7fac5ddd2404d4345dVinson Lee
189f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   for (i = 0; i < zscan->num_channels; ++i)
190f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      vtex[i] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX + i, TGSI_INTERPOLATE_LINEAR);
191f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
192912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   samp_src = ureg_DECL_sampler(shader, 0);
193912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   samp_scan = ureg_DECL_sampler(shader, 1);
194912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   samp_quant = ureg_DECL_sampler(shader, 2);
195f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
196f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   for (i = 0; i < zscan->num_channels; ++i)
197f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      tmp[i] = ureg_DECL_temporary(shader);
198912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   quant = ureg_DECL_temporary(shader);
199f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
200f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
201f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
202f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   /*
203f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König    * tmp.x = tex(vtex, 1)
204f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König    * tmp.y = vtex.z
205f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König    * fragment = tex(tmp, 0) * quant
206f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König    */
207f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   for (i = 0; i < zscan->num_channels; ++i)
208912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König      ureg_TEX(shader, ureg_writemask(tmp[i], TGSI_WRITEMASK_X), TGSI_TEXTURE_2D, vtex[i], samp_scan);
209f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
210f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   for (i = 0; i < zscan->num_channels; ++i)
211912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König      ureg_MOV(shader, ureg_writemask(tmp[i], TGSI_WRITEMASK_Y), ureg_scalar(vtex[i], TGSI_SWIZZLE_W));
212f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
213912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   for (i = 0; i < zscan->num_channels; ++i) {
214912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König      ureg_TEX(shader, ureg_writemask(tmp[0], TGSI_WRITEMASK_X << i), TGSI_TEXTURE_2D, ureg_src(tmp[i]), samp_src);
215912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König      ureg_TEX(shader, ureg_writemask(quant, TGSI_WRITEMASK_X << i), TGSI_TEXTURE_3D, vtex[i], samp_quant);
216912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   }
217f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
218912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   ureg_MUL(shader, quant, ureg_src(quant), ureg_imm1f(shader, 16.0f));
219912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   ureg_MUL(shader, fragment, ureg_src(tmp[0]), ureg_src(quant));
220f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
221f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   for (i = 0; i < zscan->num_channels; ++i)
222f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      ureg_release_temporary(shader, tmp[i]);
223f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   ureg_END(shader);
224f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
2253cf22a0c6e215535266e7a7fac5ddd2404d4345dVinson Lee   FREE(vtex);
2263cf22a0c6e215535266e7a7fac5ddd2404d4345dVinson Lee   FREE(tmp);
2273cf22a0c6e215535266e7a7fac5ddd2404d4345dVinson Lee
228f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   return ureg_create_shader_and_destroy(shader, zscan->pipe);
229f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König}
230f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
231f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königstatic bool
232f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königinit_shaders(struct vl_zscan *zscan)
233f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König{
234f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   assert(zscan);
235f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
236f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   zscan->vs = create_vert_shader(zscan);
237f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if (!zscan->vs)
238f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      goto error_vs;
239f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
240f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   zscan->fs = create_frag_shader(zscan);
241f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if (!zscan->fs)
242f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      goto error_fs;
243f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
244f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   return true;
245f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
246f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königerror_fs:
247f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   zscan->pipe->delete_vs_state(zscan->pipe, zscan->vs);
248f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
249f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königerror_vs:
250f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   return false;
251f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König}
252f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
253f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königstatic void
254f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königcleanup_shaders(struct vl_zscan *zscan)
255f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König{
256f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   assert(zscan);
257f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
258f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   zscan->pipe->delete_vs_state(zscan->pipe, zscan->vs);
259f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   zscan->pipe->delete_fs_state(zscan->pipe, zscan->fs);
260f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König}
261f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
262f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königstatic bool
263f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königinit_state(struct vl_zscan *zscan)
264f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König{
265f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   struct pipe_blend_state blend;
266f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   struct pipe_rasterizer_state rs_state;
267f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   struct pipe_sampler_state sampler;
268f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   unsigned i;
269f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
270f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   assert(zscan);
271f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
272f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   memset(&rs_state, 0, sizeof(rs_state));
27320aabb9c2eff63fd97571b9f3db453fe3accc10aChristian König   rs_state.gl_rasterization_rules = true;
274dc4c821f0817a3db716f965692fb701079f66340Marek Olšák   rs_state.depth_clip = 1;
275f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   zscan->rs_state = zscan->pipe->create_rasterizer_state(zscan->pipe, &rs_state);
276f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if (!zscan->rs_state)
277f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      goto error_rs_state;
278f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
279f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   memset(&blend, 0, sizeof blend);
280f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
281f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   blend.independent_blend_enable = 0;
282f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   blend.rt[0].blend_enable = 0;
283f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   blend.rt[0].rgb_func = PIPE_BLEND_ADD;
284f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
285f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
286f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   blend.rt[0].alpha_func = PIPE_BLEND_ADD;
287f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
288f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
289f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   blend.logicop_enable = 0;
290f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   blend.logicop_func = PIPE_LOGICOP_CLEAR;
291f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   /* Needed to allow color writes to FB, even if blending disabled */
292f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   blend.rt[0].colormask = PIPE_MASK_RGBA;
293f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   blend.dither = 0;
294f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   zscan->blend = zscan->pipe->create_blend_state(zscan->pipe, &blend);
295f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if (!zscan->blend)
296f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      goto error_blend;
297f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
298f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   for (i = 0; i < 3; ++i) {
299f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      memset(&sampler, 0, sizeof(sampler));
300f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      sampler.wrap_s = PIPE_TEX_WRAP_REPEAT;
301f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      sampler.wrap_t = PIPE_TEX_WRAP_REPEAT;
302912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König      sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
303f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
304f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
305f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
306f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      sampler.compare_mode = PIPE_TEX_COMPARE_NONE;
307f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      sampler.compare_func = PIPE_FUNC_ALWAYS;
308f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      sampler.normalized_coords = 1;
309f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      zscan->samplers[i] = zscan->pipe->create_sampler_state(zscan->pipe, &sampler);
310f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      if (!zscan->samplers[i])
311f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König         goto error_samplers;
312f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   }
313f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
314f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   return true;
315f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
316f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königerror_samplers:
317f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   for (i = 0; i < 2; ++i)
318f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      if (zscan->samplers[i])
319f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König         zscan->pipe->delete_sampler_state(zscan->pipe, zscan->samplers[i]);
320f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
321f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   zscan->pipe->delete_rasterizer_state(zscan->pipe, zscan->rs_state);
322f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
323f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königerror_blend:
324f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   zscan->pipe->delete_blend_state(zscan->pipe, zscan->blend);
325f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
326f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königerror_rs_state:
327f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   return false;
328f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König}
329f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
330f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königstatic void
331f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königcleanup_state(struct vl_zscan *zscan)
332f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König{
333f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   unsigned i;
334f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
335f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   assert(zscan);
336f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
337f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   for (i = 0; i < 3; ++i)
338f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      zscan->pipe->delete_sampler_state(zscan->pipe, zscan->samplers[i]);
339f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
340f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   zscan->pipe->delete_rasterizer_state(zscan->pipe, zscan->rs_state);
341f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   zscan->pipe->delete_blend_state(zscan->pipe, zscan->blend);
342f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König}
343f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
344f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königstruct pipe_sampler_view *
3456ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian Königvl_zscan_layout(struct pipe_context *pipe, const int layout[64], unsigned blocks_per_line)
346f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König{
34770a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König   const unsigned total_size = blocks_per_line * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT;
348f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
3496ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   int patched_layout[64];
3506ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König
351f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   struct pipe_resource res_tmpl, *res;
352f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   struct pipe_sampler_view sv_tmpl, *sv;
353f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   struct pipe_transfer *buf_transfer;
354f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   unsigned x, y, i, pitch;
355f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   float *f;
356f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
357f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   struct pipe_box rect =
358f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   {
359f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      0, 0, 0,
36070a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König      VL_BLOCK_WIDTH * blocks_per_line,
36170a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König      VL_BLOCK_HEIGHT,
362f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      1
363f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   };
364f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
3656ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   assert(pipe && layout && blocks_per_line);
3666ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König
3676ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   for (i = 0; i < 64; ++i)
3686ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König      patched_layout[layout[i]] = i;
369f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
370f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   memset(&res_tmpl, 0, sizeof(res_tmpl));
371f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   res_tmpl.target = PIPE_TEXTURE_2D;
372f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   res_tmpl.format = PIPE_FORMAT_R32_FLOAT;
37370a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König   res_tmpl.width0 = VL_BLOCK_WIDTH * blocks_per_line;
37470a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König   res_tmpl.height0 = VL_BLOCK_HEIGHT;
375f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   res_tmpl.depth0 = 1;
376f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   res_tmpl.array_size = 1;
377f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   res_tmpl.usage = PIPE_USAGE_IMMUTABLE;
378f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW;
379f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
380f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   res = pipe->screen->resource_create(pipe->screen, &res_tmpl);
381f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if (!res)
382f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      goto error_resource;
383f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
384f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   buf_transfer = pipe->get_transfer
385f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   (
386f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      pipe, res,
3877cd1c62b6be88072e3d937b67c499592490927f1Marek Olšák      0, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE,
388f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      &rect
389f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   );
390f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if (!buf_transfer)
391f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      goto error_transfer;
392f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
393f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   pitch = buf_transfer->stride / sizeof(float);
394f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
395f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   f = pipe->transfer_map(pipe, buf_transfer);
396f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if (!f)
397f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      goto error_map;
398f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
399f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   for (i = 0; i < blocks_per_line; ++i)
40070a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König      for (y = 0; y < VL_BLOCK_HEIGHT; ++y)
40170a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König         for (x = 0; x < VL_BLOCK_WIDTH; ++x) {
40270a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König            float addr = patched_layout[x + y * VL_BLOCK_WIDTH] +
40370a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König               i * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT;
404f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
405f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König            addr /= total_size;
406f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
40770a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König            f[i * VL_BLOCK_WIDTH + y * pitch + x] = addr;
408f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König         }
409f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
410f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   pipe->transfer_unmap(pipe, buf_transfer);
411f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   pipe->transfer_destroy(pipe, buf_transfer);
412f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
413f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   memset(&sv_tmpl, 0, sizeof(sv_tmpl));
414f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   u_sampler_view_default_template(&sv_tmpl, res, res->format);
415f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   sv = pipe->create_sampler_view(pipe, res, &sv_tmpl);
416f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   pipe_resource_reference(&res, NULL);
417f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if (!sv)
418f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      goto error_map;
419f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
420f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   return sv;
421f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
422f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königerror_map:
423f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   pipe->transfer_destroy(pipe, buf_transfer);
424f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
425f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königerror_transfer:
426f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   pipe_resource_reference(&res, NULL);
427f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
428f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königerror_resource:
429f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   return NULL;
430f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König}
431f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
432f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königbool
433f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königvl_zscan_init(struct vl_zscan *zscan, struct pipe_context *pipe,
434f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König              unsigned buffer_width, unsigned buffer_height,
435f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König              unsigned blocks_per_line, unsigned blocks_total,
436f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König              unsigned num_channels)
437f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König{
438f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   assert(zscan && pipe);
439f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
440f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   zscan->pipe = pipe;
441f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   zscan->buffer_width = buffer_width;
442f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   zscan->buffer_height = buffer_height;
443f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   zscan->num_channels = num_channels;
444f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   zscan->blocks_per_line = blocks_per_line;
445f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   zscan->blocks_total = blocks_total;
446f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
447f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if(!init_shaders(zscan))
448f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      return false;
449f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
450f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   if(!init_state(zscan)) {
451f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      cleanup_shaders(zscan);
452f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König      return false;
453f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   }
454f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
455f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   return true;
456f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König}
457f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
458f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königvoid
459f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königvl_zscan_cleanup(struct vl_zscan *zscan)
460f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König{
461f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   assert(zscan);
462f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
463f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   cleanup_shaders(zscan);
464f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   cleanup_state(zscan);
465f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König}
466f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
467f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königbool
468f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königvl_zscan_init_buffer(struct vl_zscan *zscan, struct vl_zscan_buffer *buffer,
469f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König                     struct pipe_sampler_view *src, struct pipe_surface *dst)
470f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König{
471912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   struct pipe_resource res_tmpl, *res;
472912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   struct pipe_sampler_view sv_tmpl;
473912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König
474f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   assert(zscan && buffer);
475f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
476f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   memset(buffer, 0, sizeof(struct vl_zscan_buffer));
477f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
478f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   pipe_sampler_view_reference(&buffer->src, src);
479f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
480f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   buffer->viewport.scale[0] = dst->width;
481f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   buffer->viewport.scale[1] = dst->height;
482f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   buffer->viewport.scale[2] = 1;
483f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   buffer->viewport.scale[3] = 1;
484f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   buffer->viewport.translate[0] = 0;
485f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   buffer->viewport.translate[1] = 0;
486f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   buffer->viewport.translate[2] = 0;
487f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   buffer->viewport.translate[3] = 0;
488f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
489f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   buffer->fb_state.width = dst->width;
490f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   buffer->fb_state.height = dst->height;
491f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   buffer->fb_state.nr_cbufs = 1;
492f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   pipe_surface_reference(&buffer->fb_state.cbufs[0], dst);
493f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
494912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   memset(&res_tmpl, 0, sizeof(res_tmpl));
495912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   res_tmpl.target = PIPE_TEXTURE_3D;
496912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   res_tmpl.format = PIPE_FORMAT_R8_UNORM;
49770a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König   res_tmpl.width0 = VL_BLOCK_WIDTH * zscan->blocks_per_line;
49870a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König   res_tmpl.height0 = VL_BLOCK_HEIGHT;
499912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   res_tmpl.depth0 = 2;
500912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   res_tmpl.array_size = 1;
501912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   res_tmpl.usage = PIPE_USAGE_IMMUTABLE;
502912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW;
503912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König
504912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   res = zscan->pipe->screen->resource_create(zscan->pipe->screen, &res_tmpl);
505912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   if (!res)
506912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König      return false;
507912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König
508912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   memset(&sv_tmpl, 0, sizeof(sv_tmpl));
509912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   u_sampler_view_default_template(&sv_tmpl, res, res->format);
510912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   sv_tmpl.swizzle_r = sv_tmpl.swizzle_g = sv_tmpl.swizzle_b = sv_tmpl.swizzle_a = TGSI_SWIZZLE_X;
511912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   buffer->quant = zscan->pipe->create_sampler_view(zscan->pipe, res, &sv_tmpl);
512912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   pipe_resource_reference(&res, NULL);
513912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   if (!buffer->quant)
514912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König      return false;
515912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König
516f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   return true;
517f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König}
518f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
519f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königvoid
520f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königvl_zscan_cleanup_buffer(struct vl_zscan_buffer *buffer)
521f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König{
522f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   assert(buffer);
523f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
524f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   pipe_sampler_view_reference(&buffer->src, NULL);
5256ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   pipe_sampler_view_reference(&buffer->layout, NULL);
526f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   pipe_sampler_view_reference(&buffer->quant, NULL);
527f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   pipe_surface_reference(&buffer->fb_state.cbufs[0], NULL);
528f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König}
529f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
530f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königvoid
5316ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian Königvl_zscan_set_layout(struct vl_zscan_buffer *buffer, struct pipe_sampler_view *layout)
5326ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König{
5336ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   assert(buffer);
5346ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   assert(layout);
5356ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König
5366ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König   pipe_sampler_view_reference(&buffer->layout, layout);
5376ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König}
5386ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König
5396ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian Königvoid
540bce506ffc09c44552c3d1053c6a0450b8f010292Christian Königvl_zscan_upload_quant(struct vl_zscan *zscan, struct vl_zscan_buffer *buffer,
541bce506ffc09c44552c3d1053c6a0450b8f010292Christian König                      const uint8_t matrix[64], bool intra)
542912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König{
543912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   struct pipe_context *pipe;
544912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   struct pipe_transfer *buf_transfer;
545912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   unsigned x, y, i, pitch;
546d4cbd1272b723ba0da03a9664ee85452f8f2d457Christian König   uint8_t *data;
547912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König
548912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   struct pipe_box rect =
549912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   {
550d4cbd1272b723ba0da03a9664ee85452f8f2d457Christian König      0, 0, intra ? 1 : 0,
55170a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König      VL_BLOCK_WIDTH,
55270a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König      VL_BLOCK_HEIGHT,
553d4cbd1272b723ba0da03a9664ee85452f8f2d457Christian König      1
554912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   };
555912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König
556912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   assert(buffer);
557d4cbd1272b723ba0da03a9664ee85452f8f2d457Christian König   assert(matrix);
558912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König
559bce506ffc09c44552c3d1053c6a0450b8f010292Christian König   pipe = zscan->pipe;
560912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König
561bce506ffc09c44552c3d1053c6a0450b8f010292Christian König   rect.width *= zscan->blocks_per_line;
562912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König
563912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   buf_transfer = pipe->get_transfer
564912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   (
565912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König      pipe, buffer->quant->texture,
5667cd1c62b6be88072e3d937b67c499592490927f1Marek Olšák      0, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE,
567912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König      &rect
568912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   );
569912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   if (!buf_transfer)
570912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König      goto error_transfer;
571912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König
572912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   pitch = buf_transfer->stride;
573912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König
574d4cbd1272b723ba0da03a9664ee85452f8f2d457Christian König   data = pipe->transfer_map(pipe, buf_transfer);
575d4cbd1272b723ba0da03a9664ee85452f8f2d457Christian König   if (!data)
576912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König      goto error_map;
577912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König
578bce506ffc09c44552c3d1053c6a0450b8f010292Christian König   for (i = 0; i < zscan->blocks_per_line; ++i)
57970a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König      for (y = 0; y < VL_BLOCK_HEIGHT; ++y)
58070a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König         for (x = 0; x < VL_BLOCK_WIDTH; ++x)
58170a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König            data[i * VL_BLOCK_WIDTH + y * pitch + x] = matrix[x + y * VL_BLOCK_WIDTH];
582912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König
583912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   pipe->transfer_unmap(pipe, buf_transfer);
584912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König
585912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian Königerror_map:
586912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   pipe->transfer_destroy(pipe, buf_transfer);
587912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König
588912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian Königerror_transfer:
589912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   return;
590912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König}
591912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König
592912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian Königvoid
593bce506ffc09c44552c3d1053c6a0450b8f010292Christian Königvl_zscan_render(struct vl_zscan *zscan, struct vl_zscan_buffer *buffer, unsigned num_instances)
594f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König{
595f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   assert(buffer);
596f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König
597f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   zscan->pipe->bind_rasterizer_state(zscan->pipe, zscan->rs_state);
598f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   zscan->pipe->bind_blend_state(zscan->pipe, zscan->blend);
599912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   zscan->pipe->bind_fragment_sampler_states(zscan->pipe, 3, zscan->samplers);
600f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   zscan->pipe->set_framebuffer_state(zscan->pipe, &buffer->fb_state);
601f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   zscan->pipe->set_viewport_state(zscan->pipe, &buffer->viewport);
602912dc8ff09cd7c28926762c2e562de5a99d3e27aChristian König   zscan->pipe->set_fragment_sampler_views(zscan->pipe, 3, &buffer->src);
603f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   zscan->pipe->bind_vs_state(zscan->pipe, zscan->vs);
604f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   zscan->pipe->bind_fs_state(zscan->pipe, zscan->fs);
605f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König   util_draw_arrays_instanced(zscan->pipe, PIPE_PRIM_QUADS, 0, 4, 0, num_instances);
606f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König}
607