14686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul/**********************************************************
24686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul * Copyright 2008-2012 VMware, Inc.  All rights reserved.
34686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul *
44686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul * Permission is hereby granted, free of charge, to any person
54686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul * obtaining a copy of this software and associated documentation
64686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul * files (the "Software"), to deal in the Software without
74686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul * restriction, including without limitation the rights to use, copy,
84686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul * modify, merge, publish, distribute, sublicense, and/or sell copies
94686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul * of the Software, and to permit persons to whom the Software is
104686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul * furnished to do so, subject to the following conditions:
114686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul *
124686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul * The above copyright notice and this permission notice shall be
134686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul * included in all copies or substantial portions of the Software.
144686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul *
154686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
164686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
174686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
184686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
194686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
204686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
214686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
224686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul * SOFTWARE.
234686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul *
244686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul **********************************************************/
254686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul
264686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul#include "util/u_bitmask.h"
274686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul#include "util/u_memory.h"
284686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul#include "svga_context.h"
294686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul#include "svga_cmd.h"
30e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul#include "svga_format.h"
314686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul#include "svga_shader.h"
324686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul
334686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul
34e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul/**
35e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * This bit isn't really used anywhere.  It only serves to help
36e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * generate a unique "signature" for the vertex shader output bitmask.
37e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * Shader input/output signatures are used to resolve shader linking
38e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * issues.
39e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul */
40e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul#define FOG_GENERIC_BIT (((uint64_t) 1) << 63)
41e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
42e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
43e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul/**
44e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * Use the shader info to generate a bitmask indicating which generic
45e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * inputs are used by the shader.  A set bit indicates that GENERIC[i]
46e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * is used.
47e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul */
48e054251ed11e25a080f64b92db9334c9b07c8c76Brian Pauluint64_t
49e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paulsvga_get_generic_inputs_mask(const struct tgsi_shader_info *info)
50e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul{
51e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   unsigned i;
52e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   uint64_t mask = 0x0;
53e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
54e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   for (i = 0; i < info->num_inputs; i++) {
55e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      if (info->input_semantic_name[i] == TGSI_SEMANTIC_GENERIC) {
56e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         unsigned j = info->input_semantic_index[i];
57e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         assert(j < sizeof(mask) * 8);
58e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         mask |= ((uint64_t) 1) << j;
59e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      }
60e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   }
61e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
62e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   return mask;
63e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul}
64e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
65e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
66e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul/**
67e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * Scan shader info to return a bitmask of written outputs.
68e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul */
69e054251ed11e25a080f64b92db9334c9b07c8c76Brian Pauluint64_t
70e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paulsvga_get_generic_outputs_mask(const struct tgsi_shader_info *info)
71e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul{
72e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   unsigned i;
73e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   uint64_t mask = 0x0;
74e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
75e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   for (i = 0; i < info->num_outputs; i++) {
76e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      switch (info->output_semantic_name[i]) {
77e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      case TGSI_SEMANTIC_GENERIC:
78e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         {
79e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul            unsigned j = info->output_semantic_index[i];
80e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul            assert(j < sizeof(mask) * 8);
81e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul            mask |= ((uint64_t) 1) << j;
82e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         }
83e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         break;
84e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      case TGSI_SEMANTIC_FOG:
85e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         mask |= FOG_GENERIC_BIT;
86e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         break;
87e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      }
88e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   }
89e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
90e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   return mask;
91e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul}
92e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
93e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
94e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
95e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul/**
96e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * Given a mask of used generic variables (as returned by the above functions)
97e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * fill in a table which maps those indexes to small integers.
98e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * This table is used by the remap_generic_index() function in
99e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * svga_tgsi_decl_sm30.c
100e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * Example: if generics_mask = binary(1010) it means that GENERIC[1] and
101e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * GENERIC[3] are used.  The remap_table will contain:
102e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul *   table[1] = 0;
103e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul *   table[3] = 1;
104e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * The remaining table entries will be filled in with the next unused
105e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * generic index (in this example, 2).
106e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul */
107e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paulvoid
108e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paulsvga_remap_generics(uint64_t generics_mask,
109e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul                    int8_t remap_table[MAX_GENERIC_VARYING])
110e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul{
111e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   /* Note texcoord[0] is reserved so start at 1 */
112e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   unsigned count = 1, i;
113e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
114e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   for (i = 0; i < MAX_GENERIC_VARYING; i++) {
115e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      remap_table[i] = -1;
116e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   }
117e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
118e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   /* for each bit set in generic_mask */
119e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   while (generics_mask) {
120e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      unsigned index = ffsll(generics_mask) - 1;
121e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      remap_table[index] = count++;
122e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      generics_mask &= ~((uint64_t) 1 << index);
123e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   }
124e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul}
125e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
126e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
127e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul/**
128e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * Use the generic remap table to map a TGSI generic varying variable
129e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * index to a small integer.  If the remapping table doesn't have a
130e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * valid value for the given index (the table entry is -1) it means
131e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * the fragment shader doesn't use that VS output.  Just allocate
132e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * the next free value in that case.  Alternately, we could cull
133e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * VS instructions that write to register, or replace the register
134e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * with a dummy temp register.
135e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * XXX TODO: we should do one of the later as it would save precious
136e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * texcoord registers.
137e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul */
138e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paulint
139e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paulsvga_remap_generic_index(int8_t remap_table[MAX_GENERIC_VARYING],
140e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul                         int generic_index)
141e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul{
142e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   assert(generic_index < MAX_GENERIC_VARYING);
143e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
144e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   if (generic_index >= MAX_GENERIC_VARYING) {
145e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      /* just don't return a random/garbage value */
146e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      generic_index = MAX_GENERIC_VARYING - 1;
147e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   }
148e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
149e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   if (remap_table[generic_index] == -1) {
150e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      /* This is a VS output that has no matching PS input.  Find a
151e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul       * free index.
152e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul       */
153e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      int i, max = 0;
154e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      for (i = 0; i < MAX_GENERIC_VARYING; i++) {
155e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         max = MAX2(max, remap_table[i]);
156e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      }
157e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      remap_table[generic_index] = max + 1;
158e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   }
159e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
160e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   return remap_table[generic_index];
161e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul}
162e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
163e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
164e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul/**
165e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * Initialize the shader-neutral fields of svga_compile_key from context
166e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * state.  This is basically the texture-related state.
167e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul */
168e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paulvoid
169f5602c27ec681f1f66cdb8d79378991b79ce45e7Brian Paulsvga_init_shader_key_common(const struct svga_context *svga,
170f5602c27ec681f1f66cdb8d79378991b79ce45e7Brian Paul                            enum pipe_shader_type shader,
171e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul                            struct svga_compile_key *key)
172e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul{
173e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   unsigned i, idx = 0;
174e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
175e0184b3995fa308c125ae8e090d2bbdffd495b5fBrian Paul   assert(shader < ARRAY_SIZE(svga->curr.num_sampler_views));
176e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
17750a669de4e216d2e3bea3ec1148c7e79f77ecb27Brian Paul   /* In case the number of samplers and sampler_views doesn't match,
17850a669de4e216d2e3bea3ec1148c7e79f77ecb27Brian Paul    * loop over the lower of the two counts.
17950a669de4e216d2e3bea3ec1148c7e79f77ecb27Brian Paul    */
18050a669de4e216d2e3bea3ec1148c7e79f77ecb27Brian Paul   key->num_textures = MIN2(svga->curr.num_sampler_views[shader],
18150a669de4e216d2e3bea3ec1148c7e79f77ecb27Brian Paul                            svga->curr.num_samplers[shader]);
18250a669de4e216d2e3bea3ec1148c7e79f77ecb27Brian Paul
18350a669de4e216d2e3bea3ec1148c7e79f77ecb27Brian Paul   for (i = 0; i < key->num_textures; i++) {
184e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      struct pipe_sampler_view *view = svga->curr.sampler_views[shader][i];
18550a669de4e216d2e3bea3ec1148c7e79f77ecb27Brian Paul      const struct svga_sampler_state *sampler = svga->curr.sampler[shader][i];
18650a669de4e216d2e3bea3ec1148c7e79f77ecb27Brian Paul      if (view && sampler) {
187e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         assert(view->texture);
188e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         assert(view->texture->target < (1 << 4)); /* texture_target:4 */
189e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
190e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         /* 1D/2D array textures with one slice are treated as non-arrays
191e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul          * by the SVGA3D device.  Convert the texture type here so that
192e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul          * we emit the right TEX/SAMPLE instruction in the shader.
193e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul          */
194dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul         if (view->texture->target == PIPE_TEXTURE_1D_ARRAY ||
195dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul             view->texture->target == PIPE_TEXTURE_2D_ARRAY) {
196dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul            if (view->texture->array_size == 1) {
197dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul               key->tex[i].is_array = 0;
198e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul            }
199dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul            else {
200dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul               assert(view->texture->array_size > 1);
201dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul               key->tex[i].is_array = 1;
202e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul            }
203e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         }
204e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
20550a669de4e216d2e3bea3ec1148c7e79f77ecb27Brian Paul         if (!sampler->normalized_coords) {
206e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul            assert(idx < (1 << 5));  /* width_height_idx:5 bitfield */
207e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul            key->tex[i].width_height_idx = idx++;
208e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul            key->tex[i].unnormalized = TRUE;
209e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul            ++key->num_unnormalized_coords;
210e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         }
211e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
212e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         key->tex[i].swizzle_r = view->swizzle_r;
213e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         key->tex[i].swizzle_g = view->swizzle_g;
214e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         key->tex[i].swizzle_b = view->swizzle_b;
215e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         key->tex[i].swizzle_a = view->swizzle_a;
216e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      }
217e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   }
218e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul}
219e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
220e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
221e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul/** Search for a compiled shader variant with the same compile key */
222e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paulstruct svga_shader_variant *
223e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paulsvga_search_shader_key(const struct svga_shader *shader,
224e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul                       const struct svga_compile_key *key)
225e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul{
226e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   struct svga_shader_variant *variant = shader->variants;
227e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
228e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   assert(key);
229e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
230e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   for ( ; variant; variant = variant->next) {
231e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      if (svga_compile_keys_equal(key, &variant->key))
232e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         return variant;
233e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   }
234e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   return NULL;
235e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul}
236e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
237e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul/** Search for a shader with the same token key */
238e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paulstruct svga_shader *
239e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paulsvga_search_shader_token_key(struct svga_shader *pshader,
240e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul                             const struct svga_token_key *key)
241e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul{
242e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   struct svga_shader *shader = pshader;
243e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
244e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   assert(key);
245e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
246e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   for ( ; shader; shader = shader->next) {
247e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      if (memcmp(key, &shader->token_key, sizeof(struct svga_token_key)) == 0)
248e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         return shader;
249e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   }
250e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   return NULL;
251e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul}
252e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
253e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul/**
254e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * Helper function to define a gb shader for non-vgpu10 device
255e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul */
256e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paulstatic enum pipe_error
257e054251ed11e25a080f64b92db9334c9b07c8c76Brian Pauldefine_gb_shader_vgpu9(struct svga_context *svga,
258e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul                       SVGA3dShaderType type,
259e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul                       struct svga_shader_variant *variant,
260e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul                       unsigned codeLen)
261e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul{
262e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
263e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   enum pipe_error ret;
264e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
265e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   /**
266e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul    * Create gb memory for the shader and upload the shader code.
267e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul    * Kernel module will allocate an id for the shader and issue
268e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul    * the DefineGBShader command.
269e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul    */
270e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   variant->gb_shader = sws->shader_create(sws, type,
271e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul                                           variant->tokens, codeLen);
272e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
273e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   if (!variant->gb_shader)
274e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      return PIPE_ERROR_OUT_OF_MEMORY;
275e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
276e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   ret = SVGA3D_BindGBShader(svga->swc, variant->gb_shader);
277e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
278e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   return ret;
279e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul}
280e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
281e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul/**
282e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * Helper function to define a gb shader for vgpu10 device
283e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul */
284e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paulstatic enum pipe_error
285e054251ed11e25a080f64b92db9334c9b07c8c76Brian Pauldefine_gb_shader_vgpu10(struct svga_context *svga,
286e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul                        SVGA3dShaderType type,
287e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul                        struct svga_shader_variant *variant,
288e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul                        unsigned codeLen)
289e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul{
290e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   struct svga_winsys_context *swc = svga->swc;
291e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   enum pipe_error ret;
292e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
293e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   /**
294e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul    * Shaders in VGPU10 enabled device reside in the device COTable.
295e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul    * SVGA driver will allocate an integer ID for the shader and
296e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul    * issue DXDefineShader and DXBindShader commands.
297e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul    */
298e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   variant->id = util_bitmask_add(svga->shader_id_bm);
299e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   if (variant->id == UTIL_BITMASK_INVALID_INDEX) {
300e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      return PIPE_ERROR_OUT_OF_MEMORY;
301e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   }
302e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
303e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   /* Create gb memory for the shader and upload the shader code */
304e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   variant->gb_shader = swc->shader_create(swc,
305e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul                                           variant->id, type,
306e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul                                           variant->tokens, codeLen);
307e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
308e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   if (!variant->gb_shader) {
309e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      /* Free the shader ID */
310e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      assert(variant->id != UTIL_BITMASK_INVALID_INDEX);
311e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      goto fail_no_allocation;
312e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   }
313e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
314e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   /**
315e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul    * Since we don't want to do any flush within state emission to avoid
316e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul    * partial state in a command buffer, it's important to make sure that
317e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul    * there is enough room to send both the DXDefineShader & DXBindShader
318e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul    * commands in the same command buffer. So let's send both
319e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul    * commands in one command reservation. If it fails, we'll undo
320e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul    * the shader creation and return an error.
321e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul    */
322e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   ret = SVGA3D_vgpu10_DefineAndBindShader(swc, variant->gb_shader,
323e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul                                           variant->id, type, codeLen);
324e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
325e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   if (ret != PIPE_OK)
326e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      goto fail;
327e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
328e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   return PIPE_OK;
329e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
330e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paulfail:
331e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   swc->shader_destroy(swc, variant->gb_shader);
332e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   variant->gb_shader = NULL;
333e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
334e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paulfail_no_allocation:
335e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   util_bitmask_clear(svga->shader_id_bm, variant->id);
336e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   variant->id = UTIL_BITMASK_INVALID_INDEX;
337e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
338e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   return PIPE_ERROR_OUT_OF_MEMORY;
339e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul}
3404686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul
3414686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul/**
3424686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul * Issue the SVGA3D commands to define a new shader.
343e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * \param variant  contains the shader tokens, etc.  The result->id field will
344e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul *                 be set here.
3454686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul */
3464686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paulenum pipe_error
3474686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paulsvga_define_shader(struct svga_context *svga,
3484686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul                   SVGA3dShaderType type,
3494686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul                   struct svga_shader_variant *variant)
3504686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul{
3514686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul   unsigned codeLen = variant->nr_tokens * sizeof(variant->tokens[0]);
352e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   enum pipe_error ret;
3534686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul
3542e1cfcc431471c68ba79c9323716bed7da79c909Charmaine Lee   SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_DEFINESHADER);
3552e1cfcc431471c68ba79c9323716bed7da79c909Charmaine Lee
356e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   variant->id = UTIL_BITMASK_INVALID_INDEX;
357556a415033223108eb5706364604b3400f497c58Thomas Hellstrom
358e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   if (svga_have_gb_objects(svga)) {
359e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      if (svga_have_vgpu10(svga))
3602e1cfcc431471c68ba79c9323716bed7da79c909Charmaine Lee         ret = define_gb_shader_vgpu10(svga, type, variant, codeLen);
361e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      else
3622e1cfcc431471c68ba79c9323716bed7da79c909Charmaine Lee         ret = define_gb_shader_vgpu9(svga, type, variant, codeLen);
363f84c830b144fd4d53f862fc6ad05541e5bf60a3bBrian Paul   }
364f84c830b144fd4d53f862fc6ad05541e5bf60a3bBrian Paul   else {
3654686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul      /* Allocate an integer ID for the shader */
3664686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul      variant->id = util_bitmask_add(svga->shader_id_bm);
3674686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul      if (variant->id == UTIL_BITMASK_INVALID_INDEX) {
3682e1cfcc431471c68ba79c9323716bed7da79c909Charmaine Lee         ret = PIPE_ERROR_OUT_OF_MEMORY;
3692e1cfcc431471c68ba79c9323716bed7da79c909Charmaine Lee         goto done;
3704686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul      }
3714686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul
3724686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul      /* Issue SVGA3D device command to define the shader */
3734686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul      ret = SVGA3D_DefineShader(svga->swc,
3744686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul                                variant->id,
3754686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul                                type,
3764686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul                                variant->tokens,
3774686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul                                codeLen);
3784686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul      if (ret != PIPE_OK) {
3794686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul         /* free the ID */
3804686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul         assert(variant->id != UTIL_BITMASK_INVALID_INDEX);
3814686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul         util_bitmask_clear(svga->shader_id_bm, variant->id);
3824686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul         variant->id = UTIL_BITMASK_INVALID_INDEX;
3834686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul      }
3844686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul   }
3854686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul
3862e1cfcc431471c68ba79c9323716bed7da79c909Charmaine Leedone:
3872e1cfcc431471c68ba79c9323716bed7da79c909Charmaine Lee   SVGA_STATS_TIME_POP(svga_sws(svga));
388e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   return ret;
3894686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul}
3904686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul
3914686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul
392e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul/**
393e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * Issue the SVGA3D commands to set/bind a shader.
394e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * \param result  the shader to bind.
395e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul */
396e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paulenum pipe_error
397e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paulsvga_set_shader(struct svga_context *svga,
398e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul                SVGA3dShaderType type,
399e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul                struct svga_shader_variant *variant)
400e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul{
401e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   enum pipe_error ret;
402e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   unsigned id = variant ? variant->id : SVGA3D_INVALID_ID;
403e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
404e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   assert(type == SVGA3D_SHADERTYPE_VS ||
405e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul          type == SVGA3D_SHADERTYPE_GS ||
406e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul          type == SVGA3D_SHADERTYPE_PS);
407e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
408e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   if (svga_have_gb_objects(svga)) {
409e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      struct svga_winsys_gb_shader *gbshader =
410e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         variant ? variant->gb_shader : NULL;
411e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
412e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      if (svga_have_vgpu10(svga))
413e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         ret = SVGA3D_vgpu10_SetShader(svga->swc, type, gbshader, id);
414e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      else
415e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         ret = SVGA3D_SetGBShader(svga->swc, type, gbshader);
416e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   }
417e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   else {
418e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      ret = SVGA3D_SetShader(svga->swc, type, id);
419e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   }
420e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
421e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   return ret;
422e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul}
423e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
4244686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul
425f413f1a17c506d5d4474a1baa0556a9e9f554c63Brian Paulstruct svga_shader_variant *
426f413f1a17c506d5d4474a1baa0556a9e9f554c63Brian Paulsvga_new_shader_variant(struct svga_context *svga)
427f413f1a17c506d5d4474a1baa0556a9e9f554c63Brian Paul{
4289bc7e3105aeadbe360ca9f060c50a181d3fa7a3dNeha Bhende   svga->hud.num_shaders++;
429f413f1a17c506d5d4474a1baa0556a9e9f554c63Brian Paul   return CALLOC_STRUCT(svga_shader_variant);
430f413f1a17c506d5d4474a1baa0556a9e9f554c63Brian Paul}
431f413f1a17c506d5d4474a1baa0556a9e9f554c63Brian Paul
432f413f1a17c506d5d4474a1baa0556a9e9f554c63Brian Paul
4334686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paulenum pipe_error
4344686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paulsvga_destroy_shader_variant(struct svga_context *svga,
4354686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul                            SVGA3dShaderType type,
4364686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul                            struct svga_shader_variant *variant)
4374686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul{
4384686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul   enum pipe_error ret = PIPE_OK;
4394686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul
440e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   if (svga_have_gb_objects(svga) && variant->gb_shader) {
441e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      if (svga_have_vgpu10(svga)) {
442e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         struct svga_winsys_context *swc = svga->swc;
443e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         swc->shader_destroy(swc, variant->gb_shader);
444e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         ret = SVGA3D_vgpu10_DestroyShader(svga->swc, variant->id);
445e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         if (ret != PIPE_OK) {
446e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul            /* flush and try again */
447e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul            svga_context_flush(svga, NULL);
448e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul            ret = SVGA3D_vgpu10_DestroyShader(svga->swc, variant->id);
449e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         }
450e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         util_bitmask_clear(svga->shader_id_bm, variant->id);
451e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      }
452e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      else {
453e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
454e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         sws->shader_destroy(sws, variant->gb_shader);
455e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      }
456f84c830b144fd4d53f862fc6ad05541e5bf60a3bBrian Paul      variant->gb_shader = NULL;
457f84c830b144fd4d53f862fc6ad05541e5bf60a3bBrian Paul   }
458e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   else {
459e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      if (variant->id != UTIL_BITMASK_INVALID_INDEX) {
4604686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul         ret = SVGA3D_DestroyShader(svga->swc, variant->id, type);
461e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         if (ret != PIPE_OK) {
462e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul            /* flush and try again */
463e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul            svga_context_flush(svga, NULL);
464e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul            ret = SVGA3D_DestroyShader(svga->swc, variant->id, type);
465e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul            assert(ret == PIPE_OK);
466e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         }
467e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         util_bitmask_clear(svga->shader_id_bm, variant->id);
4684686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul      }
4694686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul   }
4704686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul
4714686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul   FREE((unsigned *)variant->tokens);
4724686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul   FREE(variant);
4734686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul
4749bc7e3105aeadbe360ca9f060c50a181d3fa7a3dNeha Bhende   svga->hud.num_shaders--;
4759bc7e3105aeadbe360ca9f060c50a181d3fa7a3dNeha Bhende
4764686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul   return ret;
4774686f610b18a04bc6213ccadf7be1176bbda3e34Brian Paul}
478e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
479e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul/*
480e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * Rebind shaders.
481e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * Called at the beginning of every new command buffer to ensure that
482e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * shaders are properly paged-in. Instead of sending the SetShader
483e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * command, this function sends a private allocation command to
484e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * page in a shader. This avoids emitting redundant state to the device
485e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul * just to page in a resource.
486e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul */
487e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paulenum pipe_error
488e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paulsvga_rebind_shaders(struct svga_context *svga)
489e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul{
490e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   struct svga_winsys_context *swc = svga->swc;
491e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   struct svga_hw_draw_state *hw = &svga->state.hw_draw;
492e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   enum pipe_error ret;
493e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
494e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   assert(svga_have_vgpu10(svga));
495e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
496e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   /**
497e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul    * If the underlying winsys layer does not need resource rebinding,
498e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul    * just clear the rebind flags and return.
499e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul    */
500e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   if (swc->resource_rebind == NULL) {
501e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      svga->rebind.flags.vs = 0;
502e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      svga->rebind.flags.gs = 0;
503e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      svga->rebind.flags.fs = 0;
504e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
505e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      return PIPE_OK;
506e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   }
507e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
508e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   if (svga->rebind.flags.vs && hw->vs && hw->vs->gb_shader) {
509e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      ret = swc->resource_rebind(swc, NULL, hw->vs->gb_shader, SVGA_RELOC_READ);
510e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      if (ret != PIPE_OK)
511e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         return ret;
512e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   }
513e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   svga->rebind.flags.vs = 0;
514e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
515e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   if (svga->rebind.flags.gs && hw->gs && hw->gs->gb_shader) {
516e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      ret = swc->resource_rebind(swc, NULL, hw->gs->gb_shader, SVGA_RELOC_READ);
517e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      if (ret != PIPE_OK)
518e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         return ret;
519e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   }
520e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   svga->rebind.flags.gs = 0;
521e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
522e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   if (svga->rebind.flags.fs && hw->fs && hw->fs->gb_shader) {
523e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      ret = swc->resource_rebind(swc, NULL, hw->fs->gb_shader, SVGA_RELOC_READ);
524e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      if (ret != PIPE_OK)
525e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         return ret;
526e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   }
527e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   svga->rebind.flags.fs = 0;
528e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul
529e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul   return PIPE_OK;
530e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul}
531