1bf215546Sopenharmony_ci/**************************************************************************
2bf215546Sopenharmony_ci *
3bf215546Sopenharmony_ci * Copyright 2003 VMware, Inc.
4bf215546Sopenharmony_ci * All Rights Reserved.
5bf215546Sopenharmony_ci *
6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the
8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to
11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
12bf215546Sopenharmony_ci * the following conditions:
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the
15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions
16bf215546Sopenharmony_ci * of the Software.
17bf215546Sopenharmony_ci *
18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25bf215546Sopenharmony_ci *
26bf215546Sopenharmony_ci **************************************************************************/
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#include "util/u_inlines.h"
29bf215546Sopenharmony_ci#include "util/u_math.h"
30bf215546Sopenharmony_ci#include "util/u_memory.h"
31bf215546Sopenharmony_ci#include "pipe/p_shader_tokens.h"
32bf215546Sopenharmony_ci#include "draw/draw_context.h"
33bf215546Sopenharmony_ci#include "draw/draw_vertex.h"
34bf215546Sopenharmony_ci#include "sp_context.h"
35bf215546Sopenharmony_ci#include "sp_screen.h"
36bf215546Sopenharmony_ci#include "sp_state.h"
37bf215546Sopenharmony_ci#include "sp_texture.h"
38bf215546Sopenharmony_ci#include "sp_tex_sample.h"
39bf215546Sopenharmony_ci#include "sp_tex_tile_cache.h"
40bf215546Sopenharmony_ci
41bf215546Sopenharmony_ci
42bf215546Sopenharmony_ci/**
43bf215546Sopenharmony_ci * Mark the current vertex layout as "invalid".
44bf215546Sopenharmony_ci * We'll validate the vertex layout later, when we start to actually
45bf215546Sopenharmony_ci * render a point or line or tri.
46bf215546Sopenharmony_ci */
47bf215546Sopenharmony_cistatic void
48bf215546Sopenharmony_ciinvalidate_vertex_layout(struct softpipe_context *softpipe)
49bf215546Sopenharmony_ci{
50bf215546Sopenharmony_ci   softpipe->setup_info.valid =  0;
51bf215546Sopenharmony_ci}
52bf215546Sopenharmony_ci
53bf215546Sopenharmony_ci
54bf215546Sopenharmony_ci/**
55bf215546Sopenharmony_ci * The vertex info describes how to convert the post-transformed vertices
56bf215546Sopenharmony_ci * (simple float[][4]) used by the 'draw' module into vertices for
57bf215546Sopenharmony_ci * rasterization.
58bf215546Sopenharmony_ci *
59bf215546Sopenharmony_ci * This function validates the vertex layout.
60bf215546Sopenharmony_ci */
61bf215546Sopenharmony_cistatic void
62bf215546Sopenharmony_cisoftpipe_compute_vertex_info(struct softpipe_context *softpipe)
63bf215546Sopenharmony_ci{
64bf215546Sopenharmony_ci   struct sp_setup_info *sinfo = &softpipe->setup_info;
65bf215546Sopenharmony_ci
66bf215546Sopenharmony_ci   if (sinfo->valid == 0) {
67bf215546Sopenharmony_ci      const struct tgsi_shader_info *fsInfo = &softpipe->fs_variant->info;
68bf215546Sopenharmony_ci      struct vertex_info *vinfo = &softpipe->vertex_info;
69bf215546Sopenharmony_ci      uint i;
70bf215546Sopenharmony_ci      int vs_index;
71bf215546Sopenharmony_ci      /*
72bf215546Sopenharmony_ci       * This doesn't quite work right (wrt face injection, prim id,
73bf215546Sopenharmony_ci       * wide points) - hit a couple assertions, misrenderings plus
74bf215546Sopenharmony_ci       * memory corruption. Albeit could fix (the former two) by calling
75bf215546Sopenharmony_ci       * this "more often" (rasterizer changes etc.). (The latter would
76bf215546Sopenharmony_ci       * need to be included in draw_prepare_shader_outputs, but it looks
77bf215546Sopenharmony_ci       * like that would potentially allocate quite some unused additional
78bf215546Sopenharmony_ci       * vertex outputs.)
79bf215546Sopenharmony_ci       * draw_prepare_shader_outputs(softpipe->draw);
80bf215546Sopenharmony_ci       */
81bf215546Sopenharmony_ci
82bf215546Sopenharmony_ci      /*
83bf215546Sopenharmony_ci       * Those can't actually be 0 (because pos is always at 0).
84bf215546Sopenharmony_ci       * But use ints anyway to avoid confusion (in vs outputs, they
85bf215546Sopenharmony_ci       * can very well be at pos 0).
86bf215546Sopenharmony_ci       */
87bf215546Sopenharmony_ci      softpipe->viewport_index_slot = -1;
88bf215546Sopenharmony_ci      softpipe->layer_slot = -1;
89bf215546Sopenharmony_ci      softpipe->psize_slot = -1;
90bf215546Sopenharmony_ci
91bf215546Sopenharmony_ci      vinfo->num_attribs = 0;
92bf215546Sopenharmony_ci
93bf215546Sopenharmony_ci      /*
94bf215546Sopenharmony_ci       * Put position always first (setup needs it there).
95bf215546Sopenharmony_ci       */
96bf215546Sopenharmony_ci      vs_index = draw_find_shader_output(softpipe->draw,
97bf215546Sopenharmony_ci                                         TGSI_SEMANTIC_POSITION, 0);
98bf215546Sopenharmony_ci
99bf215546Sopenharmony_ci      draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
100bf215546Sopenharmony_ci
101bf215546Sopenharmony_ci      /*
102bf215546Sopenharmony_ci       * Match FS inputs against VS outputs, emitting the necessary
103bf215546Sopenharmony_ci       * attributes.
104bf215546Sopenharmony_ci       */
105bf215546Sopenharmony_ci      for (i = 0; i < fsInfo->num_inputs; i++) {
106bf215546Sopenharmony_ci         enum sp_interp_mode interp = SP_INTERP_LINEAR;
107bf215546Sopenharmony_ci
108bf215546Sopenharmony_ci         switch (fsInfo->input_interpolate[i]) {
109bf215546Sopenharmony_ci         case TGSI_INTERPOLATE_CONSTANT:
110bf215546Sopenharmony_ci            interp = SP_INTERP_CONSTANT;
111bf215546Sopenharmony_ci            break;
112bf215546Sopenharmony_ci         case TGSI_INTERPOLATE_LINEAR:
113bf215546Sopenharmony_ci            interp = SP_INTERP_LINEAR;
114bf215546Sopenharmony_ci            break;
115bf215546Sopenharmony_ci         case TGSI_INTERPOLATE_PERSPECTIVE:
116bf215546Sopenharmony_ci            interp = SP_INTERP_PERSPECTIVE;
117bf215546Sopenharmony_ci            break;
118bf215546Sopenharmony_ci         case TGSI_INTERPOLATE_COLOR:
119bf215546Sopenharmony_ci            assert(fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_COLOR);
120bf215546Sopenharmony_ci            break;
121bf215546Sopenharmony_ci         default:
122bf215546Sopenharmony_ci            assert(0);
123bf215546Sopenharmony_ci         }
124bf215546Sopenharmony_ci
125bf215546Sopenharmony_ci         switch (fsInfo->input_semantic_name[i]) {
126bf215546Sopenharmony_ci         case TGSI_SEMANTIC_POSITION:
127bf215546Sopenharmony_ci            interp = SP_INTERP_POS;
128bf215546Sopenharmony_ci            break;
129bf215546Sopenharmony_ci
130bf215546Sopenharmony_ci         case TGSI_SEMANTIC_COLOR:
131bf215546Sopenharmony_ci            if (fsInfo->input_interpolate[i] == TGSI_INTERPOLATE_COLOR) {
132bf215546Sopenharmony_ci               if (softpipe->rasterizer->flatshade)
133bf215546Sopenharmony_ci                  interp = SP_INTERP_CONSTANT;
134bf215546Sopenharmony_ci               else
135bf215546Sopenharmony_ci                  interp = SP_INTERP_PERSPECTIVE;
136bf215546Sopenharmony_ci            }
137bf215546Sopenharmony_ci            break;
138bf215546Sopenharmony_ci         }
139bf215546Sopenharmony_ci
140bf215546Sopenharmony_ci         /*
141bf215546Sopenharmony_ci          * Search for each input in current vs output:
142bf215546Sopenharmony_ci          */
143bf215546Sopenharmony_ci         vs_index = draw_find_shader_output(softpipe->draw,
144bf215546Sopenharmony_ci                                            fsInfo->input_semantic_name[i],
145bf215546Sopenharmony_ci                                            fsInfo->input_semantic_index[i]);
146bf215546Sopenharmony_ci
147bf215546Sopenharmony_ci         if (fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_COLOR &&
148bf215546Sopenharmony_ci             vs_index == -1) {
149bf215546Sopenharmony_ci            /*
150bf215546Sopenharmony_ci             * try and find a bcolor.
151bf215546Sopenharmony_ci             * Note that if there's both front and back color, draw will
152bf215546Sopenharmony_ci             * have copied back to front color already.
153bf215546Sopenharmony_ci             */
154bf215546Sopenharmony_ci            vs_index = draw_find_shader_output(softpipe->draw,
155bf215546Sopenharmony_ci                                               TGSI_SEMANTIC_BCOLOR,
156bf215546Sopenharmony_ci                                               fsInfo->input_semantic_index[i]);
157bf215546Sopenharmony_ci         }
158bf215546Sopenharmony_ci
159bf215546Sopenharmony_ci         sinfo->attrib[i].interp = interp;
160bf215546Sopenharmony_ci         /* extremely pointless index map */
161bf215546Sopenharmony_ci         sinfo->attrib[i].src_index = i + 1;
162bf215546Sopenharmony_ci         /*
163bf215546Sopenharmony_ci          * For vp index and layer, if the fs requires them but the vs doesn't
164bf215546Sopenharmony_ci          * provide them, draw (vbuf) will give us the required 0 (slot -1).
165bf215546Sopenharmony_ci          * (This means in this case we'll also use those slots in setup, which
166bf215546Sopenharmony_ci          * isn't necessary but they'll contain the correct (0) value.)
167bf215546Sopenharmony_ci          */
168bf215546Sopenharmony_ci         if (fsInfo->input_semantic_name[i] ==
169bf215546Sopenharmony_ci                    TGSI_SEMANTIC_VIEWPORT_INDEX) {
170bf215546Sopenharmony_ci            softpipe->viewport_index_slot = (int)vinfo->num_attribs;
171bf215546Sopenharmony_ci            draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
172bf215546Sopenharmony_ci         } else if (fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_LAYER) {
173bf215546Sopenharmony_ci            softpipe->layer_slot = (int)vinfo->num_attribs;
174bf215546Sopenharmony_ci            draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
175bf215546Sopenharmony_ci            /*
176bf215546Sopenharmony_ci             * Note that we'd actually want to skip position (as we won't use
177bf215546Sopenharmony_ci             * the attribute in the fs) but can't. The reason is that we don't
178bf215546Sopenharmony_ci             * actually have an input/output map for setup (even though it looks
179bf215546Sopenharmony_ci             * like we do...). Could adjust for this though even without a map.
180bf215546Sopenharmony_ci             */
181bf215546Sopenharmony_ci         } else {
182bf215546Sopenharmony_ci            /*
183bf215546Sopenharmony_ci             * Note that we'd actually want to skip position (as we won't use
184bf215546Sopenharmony_ci             * the attribute in the fs) but can't. The reason is that we don't
185bf215546Sopenharmony_ci             * actually have an input/output map for setup (even though it looks
186bf215546Sopenharmony_ci             * like we do...). Could adjust for this though even without a map.
187bf215546Sopenharmony_ci             */
188bf215546Sopenharmony_ci            draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
189bf215546Sopenharmony_ci         }
190bf215546Sopenharmony_ci      }
191bf215546Sopenharmony_ci
192bf215546Sopenharmony_ci      /* Figure out if we need pointsize as well.
193bf215546Sopenharmony_ci       */
194bf215546Sopenharmony_ci      vs_index = draw_find_shader_output(softpipe->draw,
195bf215546Sopenharmony_ci                                         TGSI_SEMANTIC_PSIZE, 0);
196bf215546Sopenharmony_ci
197bf215546Sopenharmony_ci      if (vs_index >= 0) {
198bf215546Sopenharmony_ci         softpipe->psize_slot = (int)vinfo->num_attribs;
199bf215546Sopenharmony_ci         draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
200bf215546Sopenharmony_ci      }
201bf215546Sopenharmony_ci
202bf215546Sopenharmony_ci      /* Figure out if we need viewport index (if it wasn't already in fs input) */
203bf215546Sopenharmony_ci      if (softpipe->viewport_index_slot < 0) {
204bf215546Sopenharmony_ci         vs_index = draw_find_shader_output(softpipe->draw,
205bf215546Sopenharmony_ci                                            TGSI_SEMANTIC_VIEWPORT_INDEX,
206bf215546Sopenharmony_ci                                            0);
207bf215546Sopenharmony_ci         if (vs_index >= 0) {
208bf215546Sopenharmony_ci            softpipe->viewport_index_slot =(int)vinfo->num_attribs;
209bf215546Sopenharmony_ci            draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
210bf215546Sopenharmony_ci         }
211bf215546Sopenharmony_ci      }
212bf215546Sopenharmony_ci
213bf215546Sopenharmony_ci      /* Figure out if we need layer (if it wasn't already in fs input) */
214bf215546Sopenharmony_ci      if (softpipe->layer_slot < 0) {
215bf215546Sopenharmony_ci         vs_index = draw_find_shader_output(softpipe->draw,
216bf215546Sopenharmony_ci                                            TGSI_SEMANTIC_LAYER,
217bf215546Sopenharmony_ci                                            0);
218bf215546Sopenharmony_ci         if (vs_index >= 0) {
219bf215546Sopenharmony_ci            softpipe->layer_slot = (int)vinfo->num_attribs;
220bf215546Sopenharmony_ci            draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
221bf215546Sopenharmony_ci         }
222bf215546Sopenharmony_ci      }
223bf215546Sopenharmony_ci
224bf215546Sopenharmony_ci      draw_compute_vertex_size(vinfo);
225bf215546Sopenharmony_ci      softpipe->setup_info.valid = 1;
226bf215546Sopenharmony_ci   }
227bf215546Sopenharmony_ci   return;
228bf215546Sopenharmony_ci}
229bf215546Sopenharmony_ci
230bf215546Sopenharmony_ci
231bf215546Sopenharmony_ci/**
232bf215546Sopenharmony_ci * Called from vbuf module.
233bf215546Sopenharmony_ci *
234bf215546Sopenharmony_ci * This will trigger validation of the vertex layout (and also compute
235bf215546Sopenharmony_ci * the required information for setup).
236bf215546Sopenharmony_ci */
237bf215546Sopenharmony_cistruct vertex_info *
238bf215546Sopenharmony_cisoftpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe)
239bf215546Sopenharmony_ci{
240bf215546Sopenharmony_ci   softpipe_compute_vertex_info(softpipe);
241bf215546Sopenharmony_ci   return &softpipe->vertex_info;
242bf215546Sopenharmony_ci}
243bf215546Sopenharmony_ci
244bf215546Sopenharmony_ci
245bf215546Sopenharmony_ci/**
246bf215546Sopenharmony_ci * Recompute cliprect from scissor bounds, scissor enable and surface size.
247bf215546Sopenharmony_ci */
248bf215546Sopenharmony_cistatic void
249bf215546Sopenharmony_cicompute_cliprect(struct softpipe_context *sp)
250bf215546Sopenharmony_ci{
251bf215546Sopenharmony_ci   unsigned i;
252bf215546Sopenharmony_ci   /* SP_NEW_FRAMEBUFFER
253bf215546Sopenharmony_ci    */
254bf215546Sopenharmony_ci   uint surfWidth = sp->framebuffer.width;
255bf215546Sopenharmony_ci   uint surfHeight = sp->framebuffer.height;
256bf215546Sopenharmony_ci
257bf215546Sopenharmony_ci   for (i = 0; i < PIPE_MAX_VIEWPORTS; i++) {
258bf215546Sopenharmony_ci      /* SP_NEW_RASTERIZER
259bf215546Sopenharmony_ci       */
260bf215546Sopenharmony_ci      if (sp->rasterizer->scissor) {
261bf215546Sopenharmony_ci
262bf215546Sopenharmony_ci         /* SP_NEW_SCISSOR
263bf215546Sopenharmony_ci          *
264bf215546Sopenharmony_ci          * clip to scissor rect:
265bf215546Sopenharmony_ci          */
266bf215546Sopenharmony_ci         sp->cliprect[i].minx = MAX2(sp->scissors[i].minx, 0);
267bf215546Sopenharmony_ci         sp->cliprect[i].miny = MAX2(sp->scissors[i].miny, 0);
268bf215546Sopenharmony_ci         sp->cliprect[i].maxx = MIN2(sp->scissors[i].maxx, surfWidth);
269bf215546Sopenharmony_ci         sp->cliprect[i].maxy = MIN2(sp->scissors[i].maxy, surfHeight);
270bf215546Sopenharmony_ci      }
271bf215546Sopenharmony_ci      else {
272bf215546Sopenharmony_ci         /* clip to surface bounds */
273bf215546Sopenharmony_ci         sp->cliprect[i].minx = 0;
274bf215546Sopenharmony_ci         sp->cliprect[i].miny = 0;
275bf215546Sopenharmony_ci         sp->cliprect[i].maxx = surfWidth;
276bf215546Sopenharmony_ci         sp->cliprect[i].maxy = surfHeight;
277bf215546Sopenharmony_ci      }
278bf215546Sopenharmony_ci   }
279bf215546Sopenharmony_ci}
280bf215546Sopenharmony_ci
281bf215546Sopenharmony_ci
282bf215546Sopenharmony_cistatic void
283bf215546Sopenharmony_ciset_shader_sampler(struct softpipe_context *softpipe,
284bf215546Sopenharmony_ci                   enum pipe_shader_type shader,
285bf215546Sopenharmony_ci                   int max_sampler)
286bf215546Sopenharmony_ci{
287bf215546Sopenharmony_ci   int i;
288bf215546Sopenharmony_ci   for (i = 0; i <= max_sampler; i++) {
289bf215546Sopenharmony_ci      softpipe->tgsi.sampler[shader]->sp_sampler[i] =
290bf215546Sopenharmony_ci         (struct sp_sampler *)(softpipe->samplers[shader][i]);
291bf215546Sopenharmony_ci   }
292bf215546Sopenharmony_ci}
293bf215546Sopenharmony_ci
294bf215546Sopenharmony_civoid
295bf215546Sopenharmony_cisoftpipe_update_compute_samplers(struct softpipe_context *softpipe)
296bf215546Sopenharmony_ci{
297bf215546Sopenharmony_ci   set_shader_sampler(softpipe, PIPE_SHADER_COMPUTE, softpipe->cs->max_sampler);
298bf215546Sopenharmony_ci}
299bf215546Sopenharmony_ci
300bf215546Sopenharmony_cistatic void
301bf215546Sopenharmony_ciupdate_tgsi_samplers( struct softpipe_context *softpipe )
302bf215546Sopenharmony_ci{
303bf215546Sopenharmony_ci   unsigned i, sh;
304bf215546Sopenharmony_ci
305bf215546Sopenharmony_ci   set_shader_sampler(softpipe, PIPE_SHADER_VERTEX,
306bf215546Sopenharmony_ci                      softpipe->vs->max_sampler);
307bf215546Sopenharmony_ci   set_shader_sampler(softpipe, PIPE_SHADER_FRAGMENT,
308bf215546Sopenharmony_ci                      softpipe->fs_variant->info.file_max[TGSI_FILE_SAMPLER]);
309bf215546Sopenharmony_ci   if (softpipe->gs) {
310bf215546Sopenharmony_ci      set_shader_sampler(softpipe, PIPE_SHADER_GEOMETRY,
311bf215546Sopenharmony_ci                         softpipe->gs->max_sampler);
312bf215546Sopenharmony_ci   }
313bf215546Sopenharmony_ci
314bf215546Sopenharmony_ci   /* XXX is this really necessary here??? */
315bf215546Sopenharmony_ci   for (sh = 0; sh < ARRAY_SIZE(softpipe->tex_cache); sh++) {
316bf215546Sopenharmony_ci      for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
317bf215546Sopenharmony_ci         struct softpipe_tex_tile_cache *tc = softpipe->tex_cache[sh][i];
318bf215546Sopenharmony_ci         if (tc && tc->texture) {
319bf215546Sopenharmony_ci            struct softpipe_resource *spt = softpipe_resource(tc->texture);
320bf215546Sopenharmony_ci            if (spt->timestamp != tc->timestamp) {
321bf215546Sopenharmony_ci               sp_tex_tile_cache_validate_texture( tc );
322bf215546Sopenharmony_ci               /*
323bf215546Sopenharmony_ci                 _debug_printf("INV %d %d\n", tc->timestamp, spt->timestamp);
324bf215546Sopenharmony_ci               */
325bf215546Sopenharmony_ci               tc->timestamp = spt->timestamp;
326bf215546Sopenharmony_ci            }
327bf215546Sopenharmony_ci         }
328bf215546Sopenharmony_ci      }
329bf215546Sopenharmony_ci   }
330bf215546Sopenharmony_ci}
331bf215546Sopenharmony_ci
332bf215546Sopenharmony_ci
333bf215546Sopenharmony_cistatic void
334bf215546Sopenharmony_ciupdate_fragment_shader(struct softpipe_context *softpipe, unsigned prim)
335bf215546Sopenharmony_ci{
336bf215546Sopenharmony_ci   struct sp_fragment_shader_variant_key key;
337bf215546Sopenharmony_ci
338bf215546Sopenharmony_ci   memset(&key, 0, sizeof(key));
339bf215546Sopenharmony_ci
340bf215546Sopenharmony_ci   if (softpipe->fs) {
341bf215546Sopenharmony_ci      softpipe->fs_variant = softpipe_find_fs_variant(softpipe,
342bf215546Sopenharmony_ci                                                      softpipe->fs, &key);
343bf215546Sopenharmony_ci
344bf215546Sopenharmony_ci      /* prepare the TGSI interpreter for FS execution */
345bf215546Sopenharmony_ci      softpipe->fs_variant->prepare(softpipe->fs_variant,
346bf215546Sopenharmony_ci                                    softpipe->fs_machine,
347bf215546Sopenharmony_ci                                    (struct tgsi_sampler *) softpipe->
348bf215546Sopenharmony_ci                                    tgsi.sampler[PIPE_SHADER_FRAGMENT],
349bf215546Sopenharmony_ci                                    (struct tgsi_image *)softpipe->tgsi.image[PIPE_SHADER_FRAGMENT],
350bf215546Sopenharmony_ci                                    (struct tgsi_buffer *)softpipe->tgsi.buffer[PIPE_SHADER_FRAGMENT]);
351bf215546Sopenharmony_ci   }
352bf215546Sopenharmony_ci   else {
353bf215546Sopenharmony_ci      softpipe->fs_variant = NULL;
354bf215546Sopenharmony_ci   }
355bf215546Sopenharmony_ci
356bf215546Sopenharmony_ci   /* This would be the logical place to pass the fragment shader
357bf215546Sopenharmony_ci    * to the draw module.  However, doing this here, during state
358bf215546Sopenharmony_ci    * validation, causes problems with the 'draw' module helpers for
359bf215546Sopenharmony_ci    * wide/AA/stippled lines.
360bf215546Sopenharmony_ci    * In principle, the draw's fragment shader should be per-variant
361bf215546Sopenharmony_ci    * but that doesn't work.  So we use a single draw fragment shader
362bf215546Sopenharmony_ci    * per fragment shader, not per variant.
363bf215546Sopenharmony_ci    */
364bf215546Sopenharmony_ci#if 0
365bf215546Sopenharmony_ci   if (softpipe->fs_variant) {
366bf215546Sopenharmony_ci      draw_bind_fragment_shader(softpipe->draw,
367bf215546Sopenharmony_ci                                softpipe->fs_variant->draw_shader);
368bf215546Sopenharmony_ci   }
369bf215546Sopenharmony_ci   else {
370bf215546Sopenharmony_ci      draw_bind_fragment_shader(softpipe->draw, NULL);
371bf215546Sopenharmony_ci   }
372bf215546Sopenharmony_ci#endif
373bf215546Sopenharmony_ci}
374bf215546Sopenharmony_ci
375bf215546Sopenharmony_ci
376bf215546Sopenharmony_ci/* Hopefully this will remain quite simple, otherwise need to pull in
377bf215546Sopenharmony_ci * something like the gallium frontend mechanism.
378bf215546Sopenharmony_ci */
379bf215546Sopenharmony_civoid
380bf215546Sopenharmony_cisoftpipe_update_derived(struct softpipe_context *softpipe, unsigned prim)
381bf215546Sopenharmony_ci{
382bf215546Sopenharmony_ci   struct softpipe_screen *sp_screen = softpipe_screen(softpipe->pipe.screen);
383bf215546Sopenharmony_ci
384bf215546Sopenharmony_ci   /* Check for updated textures.
385bf215546Sopenharmony_ci    */
386bf215546Sopenharmony_ci   if (softpipe->tex_timestamp != sp_screen->timestamp) {
387bf215546Sopenharmony_ci      softpipe->tex_timestamp = sp_screen->timestamp;
388bf215546Sopenharmony_ci      softpipe->dirty |= SP_NEW_TEXTURE;
389bf215546Sopenharmony_ci   }
390bf215546Sopenharmony_ci
391bf215546Sopenharmony_ci   if (softpipe->dirty & (SP_NEW_RASTERIZER |
392bf215546Sopenharmony_ci                          SP_NEW_FS))
393bf215546Sopenharmony_ci      update_fragment_shader(softpipe, prim);
394bf215546Sopenharmony_ci
395bf215546Sopenharmony_ci   /* TODO: this looks suboptimal */
396bf215546Sopenharmony_ci   if (softpipe->dirty & (SP_NEW_SAMPLER |
397bf215546Sopenharmony_ci                          SP_NEW_TEXTURE |
398bf215546Sopenharmony_ci                          SP_NEW_FS |
399bf215546Sopenharmony_ci                          SP_NEW_VS))
400bf215546Sopenharmony_ci      update_tgsi_samplers( softpipe );
401bf215546Sopenharmony_ci
402bf215546Sopenharmony_ci   if (softpipe->dirty & (SP_NEW_RASTERIZER |
403bf215546Sopenharmony_ci                          SP_NEW_FS |
404bf215546Sopenharmony_ci                          SP_NEW_VS))
405bf215546Sopenharmony_ci      invalidate_vertex_layout( softpipe );
406bf215546Sopenharmony_ci
407bf215546Sopenharmony_ci   if (softpipe->dirty & (SP_NEW_SCISSOR |
408bf215546Sopenharmony_ci                          SP_NEW_RASTERIZER |
409bf215546Sopenharmony_ci                          SP_NEW_FRAMEBUFFER))
410bf215546Sopenharmony_ci      compute_cliprect(softpipe);
411bf215546Sopenharmony_ci
412bf215546Sopenharmony_ci   if (softpipe->dirty & (SP_NEW_BLEND |
413bf215546Sopenharmony_ci                          SP_NEW_DEPTH_STENCIL_ALPHA |
414bf215546Sopenharmony_ci                          SP_NEW_FRAMEBUFFER |
415bf215546Sopenharmony_ci                          SP_NEW_FS))
416bf215546Sopenharmony_ci      sp_build_quad_pipeline(softpipe);
417bf215546Sopenharmony_ci
418bf215546Sopenharmony_ci   softpipe->dirty = 0;
419bf215546Sopenharmony_ci}
420