OSDN Git Service

gallium/swr: add OpenSWR driver
[android-x86/external-mesa.git] / src / gallium / drivers / swr / swr_state.cpp
1 /****************************************************************************
2  * Copyright (C) 2015 Intel Corporation.   All Rights Reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  ***************************************************************************/
23
24 #include "common/os.h"
25 #include "jit_api.h"
26 #include "JitManager.h"
27 #include "state_llvm.h"
28
29 #include "gallivm/lp_bld_tgsi.h"
30 #include "util/u_format.h"
31
32 #include "util/u_memory.h"
33 #include "util/u_inlines.h"
34 #include "util/u_helpers.h"
35 #include "util/u_framebuffer.h"
36
37 #include "swr_state.h"
38 #include "swr_context.h"
39 #include "swr_context_llvm.h"
40 #include "swr_screen.h"
41 #include "swr_resource.h"
42 #include "swr_tex_sample.h"
43 #include "swr_scratch.h"
44 #include "swr_shader.h"
45
46 /* These should be pulled out into separate files as necessary
47  * Just initializing everything here to get going. */
48
49 static void *
50 swr_create_blend_state(struct pipe_context *pipe,
51                        const struct pipe_blend_state *blend)
52 {
53    struct swr_blend_state *state = CALLOC_STRUCT(swr_blend_state);
54
55    memcpy(&state->pipe, blend, sizeof(*blend));
56
57    struct pipe_blend_state *pipe_blend = &state->pipe;
58
59    for (int target = 0;
60         target < std::min(SWR_NUM_RENDERTARGETS, PIPE_MAX_COLOR_BUFS);
61         target++) {
62
63       struct pipe_rt_blend_state *rt_blend = &pipe_blend->rt[target];
64       SWR_RENDER_TARGET_BLEND_STATE &blendState =
65          state->blendState.renderTarget[target];
66       RENDER_TARGET_BLEND_COMPILE_STATE &compileState =
67          state->compileState[target];
68
69       if (target != 0 && !pipe_blend->independent_blend_enable) {
70          memcpy(&compileState,
71                 &state->compileState[0],
72                 sizeof(RENDER_TARGET_BLEND_COMPILE_STATE));
73          continue;
74       }
75
76       compileState.blendEnable = rt_blend->blend_enable;
77       if (compileState.blendEnable) {
78          compileState.sourceAlphaBlendFactor =
79             swr_convert_blend_factor(rt_blend->alpha_src_factor);
80          compileState.destAlphaBlendFactor =
81             swr_convert_blend_factor(rt_blend->alpha_dst_factor);
82          compileState.sourceBlendFactor =
83             swr_convert_blend_factor(rt_blend->rgb_src_factor);
84          compileState.destBlendFactor =
85             swr_convert_blend_factor(rt_blend->rgb_dst_factor);
86
87          compileState.colorBlendFunc =
88             swr_convert_blend_func(rt_blend->rgb_func);
89          compileState.alphaBlendFunc =
90             swr_convert_blend_func(rt_blend->alpha_func);
91       }
92       compileState.logicOpEnable = state->pipe.logicop_enable;
93       if (compileState.logicOpEnable) {
94          compileState.logicOpFunc =
95             swr_convert_logic_op(state->pipe.logicop_func);
96       }
97
98       blendState.writeDisableRed =
99          (rt_blend->colormask & PIPE_MASK_R) ? 0 : 1;
100       blendState.writeDisableGreen =
101          (rt_blend->colormask & PIPE_MASK_G) ? 0 : 1;
102       blendState.writeDisableBlue =
103          (rt_blend->colormask & PIPE_MASK_B) ? 0 : 1;
104       blendState.writeDisableAlpha =
105          (rt_blend->colormask & PIPE_MASK_A) ? 0 : 1;
106
107       if (rt_blend->colormask == 0)
108          compileState.blendEnable = false;
109    }
110
111    return state;
112 }
113
114 static void
115 swr_bind_blend_state(struct pipe_context *pipe, void *blend)
116 {
117    struct swr_context *ctx = swr_context(pipe);
118
119    if (ctx->blend == blend)
120       return;
121
122    ctx->blend = (swr_blend_state *)blend;
123
124    ctx->dirty |= SWR_NEW_BLEND;
125 }
126
127 static void
128 swr_delete_blend_state(struct pipe_context *pipe, void *blend)
129 {
130    FREE(blend);
131 }
132
133 static void
134 swr_set_blend_color(struct pipe_context *pipe,
135                     const struct pipe_blend_color *color)
136 {
137    struct swr_context *ctx = swr_context(pipe);
138
139    ctx->blend_color = *color;
140
141    ctx->dirty |= SWR_NEW_BLEND;
142 }
143
144 static void
145 swr_set_stencil_ref(struct pipe_context *pipe,
146                     const struct pipe_stencil_ref *ref)
147 {
148    struct swr_context *ctx = swr_context(pipe);
149
150    ctx->stencil_ref = *ref;
151
152    ctx->dirty |= SWR_NEW_DEPTH_STENCIL_ALPHA;
153 }
154
155 static void *
156 swr_create_depth_stencil_state(
157    struct pipe_context *pipe,
158    const struct pipe_depth_stencil_alpha_state *depth_stencil)
159 {
160    struct pipe_depth_stencil_alpha_state *state;
161
162    state = (pipe_depth_stencil_alpha_state *)mem_dup(depth_stencil,
163                                                      sizeof *depth_stencil);
164
165    return state;
166 }
167
168 static void
169 swr_bind_depth_stencil_state(struct pipe_context *pipe, void *depth_stencil)
170 {
171    struct swr_context *ctx = swr_context(pipe);
172
173    if (ctx->depth_stencil == (pipe_depth_stencil_alpha_state *)depth_stencil)
174       return;
175
176    ctx->depth_stencil = (pipe_depth_stencil_alpha_state *)depth_stencil;
177
178    ctx->dirty |= SWR_NEW_DEPTH_STENCIL_ALPHA;
179 }
180
181 static void
182 swr_delete_depth_stencil_state(struct pipe_context *pipe, void *depth)
183 {
184    FREE(depth);
185 }
186
187
188 static void *
189 swr_create_rasterizer_state(struct pipe_context *pipe,
190                             const struct pipe_rasterizer_state *rast)
191 {
192    struct pipe_rasterizer_state *state;
193    state = (pipe_rasterizer_state *)mem_dup(rast, sizeof *rast);
194
195    return state;
196 }
197
198 static void
199 swr_bind_rasterizer_state(struct pipe_context *pipe, void *handle)
200 {
201    struct swr_context *ctx = swr_context(pipe);
202    const struct pipe_rasterizer_state *rasterizer =
203       (const struct pipe_rasterizer_state *)handle;
204
205    if (ctx->rasterizer == (pipe_rasterizer_state *)rasterizer)
206       return;
207
208    ctx->rasterizer = (pipe_rasterizer_state *)rasterizer;
209
210    ctx->dirty |= SWR_NEW_RASTERIZER;
211 }
212
213 static void
214 swr_delete_rasterizer_state(struct pipe_context *pipe, void *rasterizer)
215 {
216    FREE(rasterizer);
217 }
218
219
220 static void *
221 swr_create_sampler_state(struct pipe_context *pipe,
222                          const struct pipe_sampler_state *sampler)
223 {
224    struct pipe_sampler_state *state =
225       (pipe_sampler_state *)mem_dup(sampler, sizeof *sampler);
226
227    return state;
228 }
229
230 static void
231 swr_bind_sampler_states(struct pipe_context *pipe,
232                         unsigned shader,
233                         unsigned start,
234                         unsigned num,
235                         void **samplers)
236 {
237    struct swr_context *ctx = swr_context(pipe);
238    unsigned i;
239
240    assert(shader < PIPE_SHADER_TYPES);
241    assert(start + num <= Elements(ctx->samplers[shader]));
242
243    /* set the new samplers */
244    ctx->num_samplers[shader] = num;
245    for (i = 0; i < num; i++) {
246       ctx->samplers[shader][start + i] = (pipe_sampler_state *)samplers[i];
247    }
248
249    ctx->dirty |= SWR_NEW_SAMPLER;
250 }
251
252 static void
253 swr_delete_sampler_state(struct pipe_context *pipe, void *sampler)
254 {
255    FREE(sampler);
256 }
257
258
259 static struct pipe_sampler_view *
260 swr_create_sampler_view(struct pipe_context *pipe,
261                         struct pipe_resource *texture,
262                         const struct pipe_sampler_view *templ)
263 {
264    struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
265
266    if (view) {
267       *view = *templ;
268       view->reference.count = 1;
269       view->texture = NULL;
270       pipe_resource_reference(&view->texture, texture);
271       view->context = pipe;
272    }
273
274    return view;
275 }
276
277 static void
278 swr_set_sampler_views(struct pipe_context *pipe,
279                       unsigned shader,
280                       unsigned start,
281                       unsigned num,
282                       struct pipe_sampler_view **views)
283 {
284    struct swr_context *ctx = swr_context(pipe);
285    uint i;
286
287    assert(num <= PIPE_MAX_SHADER_SAMPLER_VIEWS);
288
289    assert(shader < PIPE_SHADER_TYPES);
290    assert(start + num <= Elements(ctx->sampler_views[shader]));
291
292    /* set the new sampler views */
293    ctx->num_sampler_views[shader] = num;
294    for (i = 0; i < num; i++) {
295       /* Note: we're using pipe_sampler_view_release() here to work around
296        * a possible crash when the old view belongs to another context that
297        * was already destroyed.
298        */
299       pipe_sampler_view_release(pipe, &ctx->sampler_views[shader][start + i]);
300       pipe_sampler_view_reference(&ctx->sampler_views[shader][start + i],
301                                   views[i]);
302    }
303
304    ctx->dirty |= SWR_NEW_SAMPLER_VIEW;
305 }
306
307 static void
308 swr_sampler_view_destroy(struct pipe_context *pipe,
309                          struct pipe_sampler_view *view)
310 {
311    pipe_resource_reference(&view->texture, NULL);
312    FREE(view);
313 }
314
315 static void *
316 swr_create_vs_state(struct pipe_context *pipe,
317                     const struct pipe_shader_state *vs)
318 {
319    struct swr_vertex_shader *swr_vs =
320       (swr_vertex_shader *)CALLOC_STRUCT(swr_vertex_shader);
321    if (!swr_vs)
322       return NULL;
323
324    swr_vs->pipe.tokens = tgsi_dup_tokens(vs->tokens);
325    swr_vs->pipe.stream_output = vs->stream_output;
326
327    lp_build_tgsi_info(vs->tokens, &swr_vs->info);
328
329    swr_vs->func = swr_compile_vs(pipe, swr_vs);
330
331    swr_vs->soState = {0};
332
333    if (swr_vs->pipe.stream_output.num_outputs) {
334       pipe_stream_output_info *stream_output = &swr_vs->pipe.stream_output;
335
336       swr_vs->soState.soEnable = true;
337       // soState.rasterizerDisable set on state dirty
338       // soState.streamToRasterizer not used
339
340       for (uint32_t i = 0; i < stream_output->num_outputs; i++) {
341          swr_vs->soState.streamMasks[stream_output->output[i].stream] |=
342             1 << (stream_output->output[i].register_index - 1);
343       }
344       for (uint32_t i = 0; i < MAX_SO_STREAMS; i++) {
345         swr_vs->soState.streamNumEntries[i] =
346              _mm_popcnt_u32(swr_vs->soState.streamMasks[i]);
347        }
348    }
349
350    return swr_vs;
351 }
352
353 static void
354 swr_bind_vs_state(struct pipe_context *pipe, void *vs)
355 {
356    struct swr_context *ctx = swr_context(pipe);
357
358    if (ctx->vs == vs)
359       return;
360
361    ctx->vs = (swr_vertex_shader *)vs;
362    ctx->dirty |= SWR_NEW_VS;
363 }
364
365 static void
366 swr_delete_vs_state(struct pipe_context *pipe, void *vs)
367 {
368    struct swr_vertex_shader *swr_vs = (swr_vertex_shader *)vs;
369    FREE((void *)swr_vs->pipe.tokens);
370    FREE(vs);
371 }
372
373 static void *
374 swr_create_fs_state(struct pipe_context *pipe,
375                     const struct pipe_shader_state *fs)
376 {
377    struct swr_fragment_shader *swr_fs = new swr_fragment_shader;
378    if (!swr_fs)
379       return NULL;
380
381    swr_fs->pipe.tokens = tgsi_dup_tokens(fs->tokens);
382
383    lp_build_tgsi_info(fs->tokens, &swr_fs->info);
384
385    return swr_fs;
386 }
387
388
389 static void
390 swr_bind_fs_state(struct pipe_context *pipe, void *fs)
391 {
392    struct swr_context *ctx = swr_context(pipe);
393
394    if (ctx->fs == fs)
395       return;
396
397    ctx->fs = (swr_fragment_shader *)fs;
398    ctx->dirty |= SWR_NEW_FS;
399 }
400
401 static void
402 swr_delete_fs_state(struct pipe_context *pipe, void *fs)
403 {
404    struct swr_fragment_shader *swr_fs = (swr_fragment_shader *)fs;
405    FREE((void *)swr_fs->pipe.tokens);
406    delete swr_fs;
407 }
408
409
410 static void
411 swr_set_constant_buffer(struct pipe_context *pipe,
412                         uint shader,
413                         uint index,
414                         struct pipe_constant_buffer *cb)
415 {
416    struct swr_context *ctx = swr_context(pipe);
417    struct pipe_resource *constants = cb ? cb->buffer : NULL;
418
419    assert(shader < PIPE_SHADER_TYPES);
420    assert(index < Elements(ctx->constants[shader]));
421
422    /* note: reference counting */
423    util_copy_constant_buffer(&ctx->constants[shader][index], cb);
424
425    if (shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) {
426       ctx->dirty |= SWR_NEW_VSCONSTANTS;
427    } else if (shader == PIPE_SHADER_FRAGMENT) {
428       ctx->dirty |= SWR_NEW_FSCONSTANTS;
429    }
430
431    if (cb && cb->user_buffer) {
432       pipe_resource_reference(&constants, NULL);
433    }
434 }
435
436
437 static void *
438 swr_create_vertex_elements_state(struct pipe_context *pipe,
439                                  unsigned num_elements,
440                                  const struct pipe_vertex_element *attribs)
441 {
442    struct swr_vertex_element_state *velems;
443    assert(num_elements <= PIPE_MAX_ATTRIBS);
444    velems = CALLOC_STRUCT(swr_vertex_element_state);
445    if (velems) {
446       velems->fsState.numAttribs = num_elements;
447       for (unsigned i = 0; i < num_elements; i++) {
448          // XXX: we should do this keyed on the VS usage info
449
450          const struct util_format_description *desc =
451             util_format_description(attribs[i].src_format);
452
453          velems->fsState.layout[i].AlignedByteOffset = attribs[i].src_offset;
454          velems->fsState.layout[i].Format =
455             mesa_to_swr_format(attribs[i].src_format);
456          velems->fsState.layout[i].StreamIndex =
457             attribs[i].vertex_buffer_index;
458          velems->fsState.layout[i].InstanceEnable =
459             attribs[i].instance_divisor != 0;
460          velems->fsState.layout[i].ComponentControl0 =
461             desc->channel[0].type != UTIL_FORMAT_TYPE_VOID
462             ? ComponentControl::StoreSrc
463             : ComponentControl::Store0;
464          velems->fsState.layout[i].ComponentControl1 =
465             desc->channel[1].type != UTIL_FORMAT_TYPE_VOID
466             ? ComponentControl::StoreSrc
467             : ComponentControl::Store0;
468          velems->fsState.layout[i].ComponentControl2 =
469             desc->channel[2].type != UTIL_FORMAT_TYPE_VOID
470             ? ComponentControl::StoreSrc
471             : ComponentControl::Store0;
472          velems->fsState.layout[i].ComponentControl3 =
473             desc->channel[3].type != UTIL_FORMAT_TYPE_VOID
474             ? ComponentControl::StoreSrc
475             : ComponentControl::Store1Fp;
476          velems->fsState.layout[i].ComponentPacking = ComponentEnable::XYZW;
477          velems->fsState.layout[i].InstanceDataStepRate =
478             attribs[i].instance_divisor;
479
480          /* Calculate the pitch of each stream */
481          const SWR_FORMAT_INFO &swr_desc = GetFormatInfo(
482             mesa_to_swr_format(attribs[i].src_format));
483          velems->stream_pitch[attribs[i].vertex_buffer_index] += swr_desc.Bpp;
484       }
485    }
486
487    return velems;
488 }
489
490 static void
491 swr_bind_vertex_elements_state(struct pipe_context *pipe, void *velems)
492 {
493    struct swr_context *ctx = swr_context(pipe);
494    struct swr_vertex_element_state *swr_velems =
495       (struct swr_vertex_element_state *)velems;
496
497    ctx->velems = swr_velems;
498    ctx->dirty |= SWR_NEW_VERTEX;
499 }
500
501 static void
502 swr_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
503 {
504    /* XXX Need to destroy fetch shader? */
505    FREE(velems);
506 }
507
508
509 static void
510 swr_set_vertex_buffers(struct pipe_context *pipe,
511                        unsigned start_slot,
512                        unsigned num_elements,
513                        const struct pipe_vertex_buffer *buffers)
514 {
515    struct swr_context *ctx = swr_context(pipe);
516
517    assert(num_elements <= PIPE_MAX_ATTRIBS);
518
519    util_set_vertex_buffers_count(ctx->vertex_buffer,
520                                  &ctx->num_vertex_buffers,
521                                  buffers,
522                                  start_slot,
523                                  num_elements);
524
525    ctx->dirty |= SWR_NEW_VERTEX;
526 }
527
528
529 static void
530 swr_set_index_buffer(struct pipe_context *pipe,
531                      const struct pipe_index_buffer *ib)
532 {
533    struct swr_context *ctx = swr_context(pipe);
534
535    if (ib)
536       memcpy(&ctx->index_buffer, ib, sizeof(ctx->index_buffer));
537    else
538       memset(&ctx->index_buffer, 0, sizeof(ctx->index_buffer));
539
540    ctx->dirty |= SWR_NEW_VERTEX;
541 }
542
543 static void
544 swr_set_polygon_stipple(struct pipe_context *pipe,
545                         const struct pipe_poly_stipple *stipple)
546 {
547    struct swr_context *ctx = swr_context(pipe);
548
549    ctx->poly_stipple = *stipple; /* struct copy */
550    ctx->dirty |= SWR_NEW_STIPPLE;
551 }
552
553 static void
554 swr_set_clip_state(struct pipe_context *pipe,
555                    const struct pipe_clip_state *clip)
556 {
557    struct swr_context *ctx = swr_context(pipe);
558
559    ctx->clip = *clip;
560    /* XXX Unimplemented, but prevents crash */
561
562    ctx->dirty |= SWR_NEW_CLIP;
563 }
564
565
566 static void
567 swr_set_scissor_states(struct pipe_context *pipe,
568                        unsigned start_slot,
569                        unsigned num_viewports,
570                        const struct pipe_scissor_state *scissor)
571 {
572    struct swr_context *ctx = swr_context(pipe);
573
574    ctx->scissor = *scissor;
575    ctx->dirty |= SWR_NEW_SCISSOR;
576 }
577
578 static void
579 swr_set_viewport_states(struct pipe_context *pipe,
580                         unsigned start_slot,
581                         unsigned num_viewports,
582                         const struct pipe_viewport_state *vpt)
583 {
584    struct swr_context *ctx = swr_context(pipe);
585
586    ctx->viewport = *vpt;
587    ctx->dirty |= SWR_NEW_VIEWPORT;
588 }
589
590
591 static void
592 swr_set_framebuffer_state(struct pipe_context *pipe,
593                           const struct pipe_framebuffer_state *fb)
594 {
595    struct swr_context *ctx = swr_context(pipe);
596
597    boolean changed = !util_framebuffer_state_equal(&ctx->framebuffer, fb);
598
599    assert(fb->width <= KNOB_GUARDBAND_WIDTH);
600    assert(fb->height <= KNOB_GUARDBAND_HEIGHT);
601
602    if (changed) {
603       unsigned i;
604       for (i = 0; i < fb->nr_cbufs; ++i)
605          pipe_surface_reference(&ctx->framebuffer.cbufs[i], fb->cbufs[i]);
606       for (; i < ctx->framebuffer.nr_cbufs; ++i)
607          pipe_surface_reference(&ctx->framebuffer.cbufs[i], NULL);
608
609       ctx->framebuffer.nr_cbufs = fb->nr_cbufs;
610
611       ctx->framebuffer.width = fb->width;
612       ctx->framebuffer.height = fb->height;
613
614       pipe_surface_reference(&ctx->framebuffer.zsbuf, fb->zsbuf);
615
616       ctx->dirty |= SWR_NEW_FRAMEBUFFER;
617    }
618 }
619
620
621 static void
622 swr_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)
623 {
624    struct swr_context *ctx = swr_context(pipe);
625
626    if (sample_mask != ctx->sample_mask) {
627       ctx->sample_mask = sample_mask;
628       ctx->dirty |= SWR_NEW_RASTERIZER;
629    }
630 }
631
632
633 void
634 swr_update_derived(struct swr_context *ctx,
635                    const struct pipe_draw_info *p_draw_info)
636 {
637    /* Any state that requires dirty flags to be re-triggered sets this mask */
638    /* For example, user_buffer vertex and index buffers. */
639    unsigned post_update_dirty_flags = 0;
640
641    /* Render Targets */
642    if (ctx->dirty & SWR_NEW_FRAMEBUFFER) {
643       struct pipe_framebuffer_state *fb = &ctx->framebuffer;
644       SWR_SURFACE_STATE *new_attachment[SWR_NUM_ATTACHMENTS] = {0};
645       UINT i;
646
647       /* colorbuffer targets */
648       if (fb->nr_cbufs)
649          for (i = 0; i < fb->nr_cbufs; ++i)
650             if (fb->cbufs[i]) {
651                struct swr_resource *colorBuffer =
652                   swr_resource(fb->cbufs[i]->texture);
653                new_attachment[SWR_ATTACHMENT_COLOR0 + i] = &colorBuffer->swr;
654             }
655
656       /* depth/stencil target */
657       if (fb->zsbuf) {
658          struct swr_resource *depthStencilBuffer =
659             swr_resource(fb->zsbuf->texture);
660          if (depthStencilBuffer->has_depth) {
661             new_attachment[SWR_ATTACHMENT_DEPTH] = &depthStencilBuffer->swr;
662
663             if (depthStencilBuffer->has_stencil)
664                new_attachment[SWR_ATTACHMENT_STENCIL] =
665                   &depthStencilBuffer->secondary;
666
667          } else if (depthStencilBuffer->has_stencil)
668             new_attachment[SWR_ATTACHMENT_STENCIL] = &depthStencilBuffer->swr;
669       }
670
671       /* Make the attachment updates */
672       swr_draw_context *pDC = &ctx->swrDC;
673       SWR_SURFACE_STATE *renderTargets = pDC->renderTargets;
674       for (i = 0; i < SWR_NUM_ATTACHMENTS; i++) {
675          void *new_base = nullptr;
676          if (new_attachment[i])
677             new_base = new_attachment[i]->pBaseAddress;
678          
679          /* StoreTile for changed target */
680          if (renderTargets[i].pBaseAddress != new_base) {
681             if (renderTargets[i].pBaseAddress) {
682                enum SWR_TILE_STATE post_state = (new_attachment[i]
683                   ? SWR_TILE_INVALID : SWR_TILE_RESOLVED);
684                swr_store_render_target(ctx, i, post_state);
685             }
686
687             /* Make new attachment */
688             if (new_attachment[i])
689                renderTargets[i] = *new_attachment[i];
690             else
691                if (renderTargets[i].pBaseAddress)
692                   renderTargets[i] = {0};
693          }
694       }
695    }
696
697    /* Raster state */
698    if (ctx->dirty & (SWR_NEW_RASTERIZER | SWR_NEW_FRAMEBUFFER)) {
699       pipe_rasterizer_state *rasterizer = ctx->rasterizer;
700       pipe_framebuffer_state *fb = &ctx->framebuffer;
701
702       SWR_RASTSTATE *rastState = &ctx->derived.rastState;
703       rastState->cullMode = swr_convert_cull_mode(rasterizer->cull_face);
704       rastState->frontWinding = rasterizer->front_ccw
705          ? SWR_FRONTWINDING_CCW
706          : SWR_FRONTWINDING_CW;
707       rastState->scissorEnable = rasterizer->scissor;
708       rastState->pointSize = rasterizer->point_size > 0.0f
709          ? rasterizer->point_size
710          : 1.0f;
711       rastState->lineWidth = rasterizer->line_width > 0.0f
712          ? rasterizer->line_width
713          : 1.0f;
714
715       rastState->pointParam = rasterizer->point_size_per_vertex;
716
717       rastState->pointSpriteEnable = rasterizer->sprite_coord_enable;
718       rastState->pointSpriteTopOrigin =
719          rasterizer->sprite_coord_mode == PIPE_SPRITE_COORD_UPPER_LEFT;
720
721       /* XXX TODO: Add multisample */
722       rastState->msaaRastEnable = false;
723       rastState->rastMode = SWR_MSAA_RASTMODE_OFF_PIXEL;
724       rastState->sampleCount = SWR_MULTISAMPLE_1X;
725       rastState->bForcedSampleCount = false;
726
727       bool do_offset = false;
728       switch (rasterizer->fill_front) {
729       case PIPE_POLYGON_MODE_FILL:
730          do_offset = rasterizer->offset_tri;
731          break;
732       case PIPE_POLYGON_MODE_LINE:
733          do_offset = rasterizer->offset_line;
734          break;
735       case PIPE_POLYGON_MODE_POINT:
736          do_offset = rasterizer->offset_point;
737          break;
738       }
739
740       if (do_offset) {
741          rastState->depthBias = rasterizer->offset_units;
742          rastState->slopeScaledDepthBias = rasterizer->offset_scale;
743          rastState->depthBiasClamp = rasterizer->offset_clamp;
744       } else {
745          rastState->depthBias = 0;
746          rastState->slopeScaledDepthBias = 0;
747          rastState->depthBiasClamp = 0;
748       }
749       struct pipe_surface *zb = fb->zsbuf;
750       if (zb && swr_resource(zb->texture)->has_depth)
751          rastState->depthFormat = swr_resource(zb->texture)->swr.format;
752
753       rastState->depthClipEnable = rasterizer->depth_clip;
754
755       SwrSetRastState(ctx->swrContext, rastState);
756    }
757
758    /* Scissor */
759    if (ctx->dirty & SWR_NEW_SCISSOR) {
760       pipe_scissor_state *scissor = &ctx->scissor;
761       BBOX bbox(scissor->miny, scissor->maxy,
762                 scissor->minx, scissor->maxx);
763       SwrSetScissorRects(ctx->swrContext, 1, &bbox);
764    }
765
766    /* Viewport */
767    if (ctx->dirty & (SWR_NEW_VIEWPORT | SWR_NEW_FRAMEBUFFER
768                      | SWR_NEW_RASTERIZER)) {
769       pipe_viewport_state *state = &ctx->viewport;
770       pipe_framebuffer_state *fb = &ctx->framebuffer;
771       pipe_rasterizer_state *rasterizer = ctx->rasterizer;
772
773       SWR_VIEWPORT *vp = &ctx->derived.vp;
774       SWR_VIEWPORT_MATRIX *vpm = &ctx->derived.vpm;
775
776       vp->x = state->translate[0] - state->scale[0];
777       vp->width = state->translate[0] + state->scale[0];
778       vp->y = state->translate[1] - fabs(state->scale[1]);
779       vp->height = state->translate[1] + fabs(state->scale[1]);
780       if (rasterizer->clip_halfz == 0) {
781          vp->minZ = state->translate[2] - state->scale[2];
782          vp->maxZ = state->translate[2] + state->scale[2];
783       } else {
784          vp->minZ = state->translate[2];
785          vp->maxZ = state->translate[2] + state->scale[2];
786       }
787
788       vpm->m00 = state->scale[0];
789       vpm->m11 = state->scale[1];
790       vpm->m22 = state->scale[2];
791       vpm->m30 = state->translate[0];
792       vpm->m31 = state->translate[1];
793       vpm->m32 = state->translate[2];
794
795       /* Now that the matrix is calculated, clip the view coords to screen
796        * size.  OpenGL allows for -ve x,y in the viewport.
797        */
798       vp->x = std::max(vp->x, 0.0f);
799       vp->y = std::max(vp->y, 0.0f);
800       vp->width = std::min(vp->width, (float)fb->width);
801       vp->height = std::min(vp->height, (float)fb->height);
802
803       SwrSetViewports(ctx->swrContext, 1, vp, vpm);
804    }
805
806    /* Set vertex & index buffers */
807    /* (using draw info if called by swr_draw_vbo) */
808    if (ctx->dirty & SWR_NEW_VERTEX) {
809       uint32_t size, pitch, max_vertex, partial_inbounds;
810       const uint8_t *p_data;
811
812       /* If being called by swr_draw_vbo, copy draw details */
813       struct pipe_draw_info info = {0};
814       if (p_draw_info)
815          info = *p_draw_info;
816
817       /* vertex buffers */
818       SWR_VERTEX_BUFFER_STATE swrVertexBuffers[PIPE_MAX_ATTRIBS];
819       for (UINT i = 0; i < ctx->num_vertex_buffers; i++) {
820          pipe_vertex_buffer *vb = &ctx->vertex_buffer[i];
821
822          pitch = vb->stride;
823          if (!vb->user_buffer) {
824             /* VBO
825              * size is based on buffer->width0 rather than info.max_index
826              * to prevent having to validate VBO on each draw */
827             size = vb->buffer->width0;
828             max_vertex = size / pitch;
829             partial_inbounds = size % pitch;
830
831             p_data = (const uint8_t *)swr_resource_data(vb->buffer)
832                + vb->buffer_offset;
833          } else {
834             /* Client buffer
835              * client memory is one-time use, re-trigger SWR_NEW_VERTEX to
836              * revalidate on each draw */
837             post_update_dirty_flags |= SWR_NEW_VERTEX;
838
839             if (pitch) {
840                size = (info.max_index - info.min_index + 1) * pitch;
841             } else {
842                /* pitch = 0, means constant value
843                 * set size to 1 vertex */
844                size = ctx->velems->stream_pitch[i];
845             }
846
847             max_vertex = info.max_index + 1;
848             partial_inbounds = 0;
849
850             /* Copy only needed vertices to scratch space */
851             size = AlignUp(size, 4);
852             const void *ptr = (const uint8_t *) vb->user_buffer
853                + info.min_index * pitch;
854             ptr = swr_copy_to_scratch_space(
855                ctx, &ctx->scratch->vertex_buffer, ptr, size);
856             p_data = (const uint8_t *)ptr - info.min_index * pitch;
857          }
858
859          swrVertexBuffers[i] = {0};
860          swrVertexBuffers[i].index = i;
861          swrVertexBuffers[i].pitch = pitch;
862          swrVertexBuffers[i].pData = p_data;
863          swrVertexBuffers[i].size = size;
864          swrVertexBuffers[i].maxVertex = max_vertex;
865          swrVertexBuffers[i].partialInboundsSize = partial_inbounds;
866       }
867
868       SwrSetVertexBuffers(
869          ctx->swrContext, ctx->num_vertex_buffers, swrVertexBuffers);
870
871       /* index buffer, if required (info passed in by swr_draw_vbo) */
872       SWR_FORMAT index_type = R32_UINT; /* Default for non-indexed draws */
873       if (info.indexed) {
874          pipe_index_buffer *ib = &ctx->index_buffer;
875
876          pitch = ib->index_size ? ib->index_size : sizeof(uint32_t);
877          index_type = swr_convert_index_type(pitch);
878
879          if (!ib->user_buffer) {
880             /* VBO
881              * size is based on buffer->width0 rather than info.count
882              * to prevent having to validate VBO on each draw */
883             size = ib->buffer->width0;
884             p_data =
885                (const uint8_t *)swr_resource_data(ib->buffer) + ib->offset;
886          } else {
887             /* Client buffer
888              * client memory is one-time use, re-trigger SWR_NEW_VERTEX to
889              * revalidate on each draw */
890             post_update_dirty_flags |= SWR_NEW_VERTEX;
891
892             size = info.count * pitch;
893             size = AlignUp(size, 4);
894
895             /* Copy indices to scratch space */
896             const void *ptr = ib->user_buffer;
897             ptr = swr_copy_to_scratch_space(
898                ctx, &ctx->scratch->index_buffer, ptr, size);
899             p_data = (const uint8_t *)ptr;
900          }
901
902          SWR_INDEX_BUFFER_STATE swrIndexBuffer;
903          swrIndexBuffer.format = swr_convert_index_type(ib->index_size);
904          swrIndexBuffer.pIndices = p_data;
905          swrIndexBuffer.size = size;
906
907          SwrSetIndexBuffer(ctx->swrContext, &swrIndexBuffer);
908       }
909
910       struct swr_vertex_element_state *velems = ctx->velems;
911       if (velems && velems->fsState.indexType != index_type) {
912          velems->fsFunc = NULL;
913          velems->fsState.indexType = index_type;
914       }
915    }
916
917    /* VertexShader */
918    if (ctx->dirty & (SWR_NEW_VS | SWR_NEW_FRAMEBUFFER)) {
919       SwrSetVertexFunc(ctx->swrContext, ctx->vs->func);
920    }
921
922    swr_jit_key key;
923    if (ctx->dirty & (SWR_NEW_FS | SWR_NEW_SAMPLER | SWR_NEW_SAMPLER_VIEW
924                      | SWR_NEW_RASTERIZER | SWR_NEW_FRAMEBUFFER)) {
925       memset(&key, 0, sizeof(key));
926       swr_generate_fs_key(key, ctx, ctx->fs);
927       auto search = ctx->fs->map.find(key);
928       PFN_PIXEL_KERNEL func;
929       if (search != ctx->fs->map.end()) {
930          func = search->second;
931       } else {
932          func = swr_compile_fs(ctx, key);
933          ctx->fs->map.insert(std::make_pair(key, func));
934       }
935       SWR_PS_STATE psState = {0};
936       psState.pfnPixelShader = func;
937       psState.killsPixel = ctx->fs->info.base.uses_kill;
938       psState.inputCoverage = SWR_INPUT_COVERAGE_NORMAL;
939       psState.writesODepth = ctx->fs->info.base.writes_z;
940       psState.usesSourceDepth = ctx->fs->info.base.reads_z;
941       psState.shadingRate = SWR_SHADING_RATE_PIXEL; // XXX
942       psState.numRenderTargets = ctx->framebuffer.nr_cbufs;
943       psState.posOffset = SWR_PS_POSITION_SAMPLE_NONE; // XXX msaa
944       uint32_t barycentricsMask = 0;
945 #if 0
946       // when we switch to mesa-master
947       if (ctx->fs->info.base.uses_persp_center ||
948           ctx->fs->info.base.uses_linear_center)
949          barycentricsMask |= SWR_BARYCENTRIC_PER_PIXEL_MASK;
950       if (ctx->fs->info.base.uses_persp_centroid ||
951           ctx->fs->info.base.uses_linear_centroid)
952          barycentricsMask |= SWR_BARYCENTRIC_CENTROID_MASK;
953       if (ctx->fs->info.base.uses_persp_sample ||
954           ctx->fs->info.base.uses_linear_sample)
955          barycentricsMask |= SWR_BARYCENTRIC_PER_SAMPLE_MASK;
956 #else
957       for (unsigned i = 0; i < ctx->fs->info.base.num_inputs; i++) {
958          switch (ctx->fs->info.base.input_interpolate_loc[i]) {
959          case TGSI_INTERPOLATE_LOC_CENTER:
960             barycentricsMask |= SWR_BARYCENTRIC_PER_PIXEL_MASK;
961             break;
962          case TGSI_INTERPOLATE_LOC_CENTROID:
963             barycentricsMask |= SWR_BARYCENTRIC_CENTROID_MASK;
964             break;
965          case TGSI_INTERPOLATE_LOC_SAMPLE:
966             barycentricsMask |= SWR_BARYCENTRIC_PER_SAMPLE_MASK;
967             break;
968          }
969       }
970 #endif
971       psState.barycentricsMask = barycentricsMask;
972       psState.usesUAV = false; // XXX
973       psState.forceEarlyZ = false;
974       SwrSetPixelShaderState(ctx->swrContext, &psState);
975    }
976
977    /* JIT sampler state */
978    if (ctx->dirty & SWR_NEW_SAMPLER) {
979       swr_draw_context *pDC = &ctx->swrDC;
980
981       for (unsigned i = 0; i < key.nr_samplers; i++) {
982          const struct pipe_sampler_state *sampler =
983             ctx->samplers[PIPE_SHADER_FRAGMENT][i];
984
985          if (sampler) {
986             pDC->samplersFS[i].min_lod = sampler->min_lod;
987             pDC->samplersFS[i].max_lod = sampler->max_lod;
988             pDC->samplersFS[i].lod_bias = sampler->lod_bias;
989             COPY_4V(pDC->samplersFS[i].border_color, sampler->border_color.f);
990          }
991       }
992    }
993
994    /* JIT sampler view state */
995    if (ctx->dirty & (SWR_NEW_SAMPLER_VIEW | SWR_NEW_FRAMEBUFFER)) {
996       swr_draw_context *pDC = &ctx->swrDC;
997
998       for (unsigned i = 0; i < key.nr_sampler_views; i++) {
999          struct pipe_sampler_view *view =
1000             ctx->sampler_views[PIPE_SHADER_FRAGMENT][i];
1001
1002          if (view) {
1003             struct pipe_resource *res = view->texture;
1004             struct swr_resource *swr_res = swr_resource(res);
1005             struct swr_jit_texture *jit_tex = &pDC->texturesFS[i];
1006             memset(jit_tex, 0, sizeof(*jit_tex));
1007             jit_tex->width = res->width0;
1008             jit_tex->height = res->height0;
1009             jit_tex->depth = res->depth0;
1010             jit_tex->first_level = view->u.tex.first_level;
1011             jit_tex->last_level = view->u.tex.last_level;
1012             jit_tex->base_ptr = swr_res->swr.pBaseAddress;
1013
1014             for (unsigned level = jit_tex->first_level;
1015                  level <= jit_tex->last_level;
1016                  level++) {
1017                jit_tex->row_stride[level] = swr_res->row_stride[level];
1018                jit_tex->img_stride[level] = swr_res->img_stride[level];
1019                jit_tex->mip_offsets[level] = swr_res->mip_offsets[level];
1020             }
1021          }
1022       }
1023    }
1024
1025    /* VertexShader Constants */
1026    if (ctx->dirty & SWR_NEW_VSCONSTANTS) {
1027       swr_draw_context *pDC = &ctx->swrDC;
1028
1029       for (UINT i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
1030          const pipe_constant_buffer *cb =
1031             &ctx->constants[PIPE_SHADER_VERTEX][i];
1032          pDC->num_constantsVS[i] = cb->buffer_size;
1033          if (cb->buffer)
1034             pDC->constantVS[i] =
1035                (const float *)((const BYTE *)cb->buffer + cb->buffer_offset);
1036          else {
1037             /* Need to copy these constants to scratch space */
1038             if (cb->user_buffer && cb->buffer_size) {
1039                const void *ptr =
1040                   ((const BYTE *)cb->user_buffer + cb->buffer_offset);
1041                uint32_t size = AlignUp(cb->buffer_size, 4);
1042                ptr = swr_copy_to_scratch_space(
1043                   ctx, &ctx->scratch->vs_constants, ptr, size);
1044                pDC->constantVS[i] = (const float *)ptr;
1045             }
1046          }
1047       }
1048    }
1049
1050    /* FragmentShader Constants */
1051    if (ctx->dirty & SWR_NEW_FSCONSTANTS) {
1052       swr_draw_context *pDC = &ctx->swrDC;
1053
1054       for (UINT i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
1055          const pipe_constant_buffer *cb =
1056             &ctx->constants[PIPE_SHADER_FRAGMENT][i];
1057          pDC->num_constantsFS[i] = cb->buffer_size;
1058          if (cb->buffer)
1059             pDC->constantFS[i] =
1060                (const float *)((const BYTE *)cb->buffer + cb->buffer_offset);
1061          else {
1062             /* Need to copy these constants to scratch space */
1063             if (cb->user_buffer && cb->buffer_size) {
1064                const void *ptr =
1065                   ((const BYTE *)cb->user_buffer + cb->buffer_offset);
1066                uint32_t size = AlignUp(cb->buffer_size, 4);
1067                ptr = swr_copy_to_scratch_space(
1068                   ctx, &ctx->scratch->fs_constants, ptr, size);
1069                pDC->constantFS[i] = (const float *)ptr;
1070             }
1071          }
1072       }
1073    }
1074
1075    /* Depth/stencil state */
1076    if (ctx->dirty & (SWR_NEW_DEPTH_STENCIL_ALPHA | SWR_NEW_FRAMEBUFFER)) {
1077       struct pipe_depth_state *depth = &(ctx->depth_stencil->depth);
1078       struct pipe_stencil_state *stencil = ctx->depth_stencil->stencil;
1079       SWR_DEPTH_STENCIL_STATE depthStencilState = {{0}};
1080
1081       /* XXX, incomplete.  Need to flesh out stencil & alpha test state
1082       struct pipe_stencil_state *front_stencil =
1083       ctx->depth_stencil.stencil[0];
1084       struct pipe_stencil_state *back_stencil = ctx->depth_stencil.stencil[1];
1085       struct pipe_alpha_state alpha;
1086       */
1087       if (stencil[0].enabled) {
1088          depthStencilState.stencilWriteEnable = 1;
1089          depthStencilState.stencilTestEnable = 1;
1090          depthStencilState.stencilTestFunc =
1091             swr_convert_depth_func(stencil[0].func);
1092
1093          depthStencilState.stencilPassDepthPassOp =
1094             swr_convert_stencil_op(stencil[0].zpass_op);
1095          depthStencilState.stencilPassDepthFailOp =
1096             swr_convert_stencil_op(stencil[0].zfail_op);
1097          depthStencilState.stencilFailOp =
1098             swr_convert_stencil_op(stencil[0].fail_op);
1099          depthStencilState.stencilWriteMask = stencil[0].writemask;
1100          depthStencilState.stencilTestMask = stencil[0].valuemask;
1101          depthStencilState.stencilRefValue = ctx->stencil_ref.ref_value[0];
1102       }
1103       if (stencil[1].enabled) {
1104          depthStencilState.doubleSidedStencilTestEnable = 1;
1105
1106          depthStencilState.backfaceStencilTestFunc =
1107             swr_convert_depth_func(stencil[1].func);
1108
1109          depthStencilState.backfaceStencilPassDepthPassOp =
1110             swr_convert_stencil_op(stencil[1].zpass_op);
1111          depthStencilState.backfaceStencilPassDepthFailOp =
1112             swr_convert_stencil_op(stencil[1].zfail_op);
1113          depthStencilState.backfaceStencilFailOp =
1114             swr_convert_stencil_op(stencil[1].fail_op);
1115          depthStencilState.backfaceStencilWriteMask = stencil[1].writemask;
1116          depthStencilState.backfaceStencilTestMask = stencil[1].valuemask;
1117
1118          depthStencilState.backfaceStencilRefValue =
1119             ctx->stencil_ref.ref_value[1];
1120       }
1121
1122       depthStencilState.depthTestEnable = depth->enabled;
1123       depthStencilState.depthTestFunc = swr_convert_depth_func(depth->func);
1124       depthStencilState.depthWriteEnable = depth->writemask;
1125       SwrSetDepthStencilState(ctx->swrContext, &depthStencilState);
1126    }
1127
1128    /* Blend State */
1129    if (ctx->dirty & (SWR_NEW_BLEND |
1130                      SWR_NEW_FRAMEBUFFER |
1131                      SWR_NEW_DEPTH_STENCIL_ALPHA)) {
1132       struct pipe_framebuffer_state *fb = &ctx->framebuffer;
1133
1134       SWR_BLEND_STATE blendState;
1135       memcpy(&blendState, &ctx->blend->blendState, sizeof(blendState));
1136       blendState.constantColor[0] = ctx->blend_color.color[0];
1137       blendState.constantColor[1] = ctx->blend_color.color[1];
1138       blendState.constantColor[2] = ctx->blend_color.color[2];
1139       blendState.constantColor[3] = ctx->blend_color.color[3];
1140       blendState.alphaTestReference =
1141          *((uint32_t*)&ctx->depth_stencil->alpha.ref_value);
1142
1143       // XXX MSAA
1144       blendState.sampleMask = 0;
1145       blendState.sampleCount = SWR_MULTISAMPLE_1X;
1146
1147       /* If there are no color buffers bound, disable writes on RT0
1148        * and skip loop */
1149       if (fb->nr_cbufs == 0) {
1150          blendState.renderTarget[0].writeDisableRed = 1;
1151          blendState.renderTarget[0].writeDisableGreen = 1;
1152          blendState.renderTarget[0].writeDisableBlue = 1;
1153          blendState.renderTarget[0].writeDisableAlpha = 1;
1154          SwrSetBlendFunc(ctx->swrContext, 0, NULL);
1155       }
1156       else
1157          for (int target = 0;
1158                target < std::min(SWR_NUM_RENDERTARGETS,
1159                                  PIPE_MAX_COLOR_BUFS);
1160                target++) {
1161             if (!fb->cbufs[target])
1162                continue;
1163
1164             struct swr_resource *colorBuffer =
1165                swr_resource(fb->cbufs[target]->texture);
1166
1167             BLEND_COMPILE_STATE compileState;
1168             memset(&compileState, 0, sizeof(compileState));
1169             compileState.format = colorBuffer->swr.format;
1170             memcpy(&compileState.blendState,
1171                    &ctx->blend->compileState[target],
1172                    sizeof(compileState.blendState));
1173
1174             if (compileState.blendState.blendEnable == false &&
1175                 compileState.blendState.logicOpEnable == false) {
1176                SwrSetBlendFunc(ctx->swrContext, target, NULL);
1177                continue;
1178             }
1179
1180             compileState.desc.alphaTestEnable =
1181                ctx->depth_stencil->alpha.enabled;
1182             compileState.desc.independentAlphaBlendEnable =
1183                ctx->blend->pipe.independent_blend_enable;
1184             compileState.desc.alphaToCoverageEnable =
1185                ctx->blend->pipe.alpha_to_coverage;
1186             compileState.desc.sampleMaskEnable = 0; // XXX
1187             compileState.desc.numSamples = 1; // XXX
1188
1189             compileState.alphaTestFunction =
1190                swr_convert_depth_func(ctx->depth_stencil->alpha.func);
1191             compileState.alphaTestFormat = ALPHA_TEST_FLOAT32; // xxx
1192
1193             PFN_BLEND_JIT_FUNC func = NULL;
1194             auto search = ctx->blendJIT->find(compileState);
1195             if (search != ctx->blendJIT->end()) {
1196                func = search->second;
1197             } else {
1198                HANDLE hJitMgr = swr_screen(ctx->pipe.screen)->hJitMgr;
1199                func = JitCompileBlend(hJitMgr, compileState);
1200                debug_printf("BLEND shader %p\n", func);
1201                assert(func && "Error: BlendShader = NULL");
1202
1203                ctx->blendJIT->insert(std::make_pair(compileState, func));
1204             }
1205             SwrSetBlendFunc(ctx->swrContext, target, func);
1206          }
1207
1208       SwrSetBlendState(ctx->swrContext, &blendState);
1209    }
1210
1211    if (ctx->dirty & SWR_NEW_STIPPLE) {
1212       /* XXX What to do with this one??? SWR doesn't stipple */
1213    }
1214
1215    if (ctx->dirty & (SWR_NEW_VS | SWR_NEW_SO | SWR_NEW_RASTERIZER)) {
1216       ctx->vs->soState.rasterizerDisable =
1217          ctx->rasterizer->rasterizer_discard;
1218       SwrSetSoState(ctx->swrContext, &ctx->vs->soState);
1219
1220       pipe_stream_output_info *stream_output = &ctx->vs->pipe.stream_output;
1221
1222       for (uint32_t i = 0; i < ctx->num_so_targets; i++) {
1223          SWR_STREAMOUT_BUFFER buffer = {0};
1224          if (!ctx->so_targets[i])
1225             continue;
1226          buffer.enable = true;
1227          buffer.pBuffer =
1228             (uint32_t *)swr_resource_data(ctx->so_targets[i]->buffer);
1229          buffer.bufferSize = ctx->so_targets[i]->buffer_size >> 2;
1230          buffer.pitch = stream_output->stride[i];
1231          buffer.streamOffset = ctx->so_targets[i]->buffer_offset >> 2;
1232
1233          SwrSetSoBuffers(ctx->swrContext, &buffer, i);
1234       }
1235    }
1236
1237    uint32_t linkage = ctx->vs->linkageMask;
1238    if (ctx->rasterizer->sprite_coord_enable)
1239       linkage |= (1 << ctx->vs->info.base.num_outputs);
1240
1241    SwrSetLinkage(ctx->swrContext, linkage, NULL);
1242
1243    // set up frontend state
1244    SWR_FRONTEND_STATE feState = {0};
1245    SwrSetFrontendState(ctx->swrContext, &feState);
1246
1247    // set up backend state
1248    SWR_BACKEND_STATE backendState = {0};
1249    backendState.numAttributes = 1;
1250    backendState.numComponents[0] = 4;
1251    backendState.constantInterpolationMask = ctx->fs->constantMask;
1252    backendState.pointSpriteTexCoordMask = ctx->fs->pointSpriteMask;
1253
1254    SwrSetBackendState(ctx->swrContext, &backendState);
1255
1256    ctx->dirty = post_update_dirty_flags;
1257 }
1258
1259 static struct pipe_stream_output_target *
1260 swr_create_so_target(struct pipe_context *pipe,
1261                      struct pipe_resource *buffer,
1262                      unsigned buffer_offset,
1263                      unsigned buffer_size)
1264 {
1265    struct pipe_stream_output_target *target;
1266
1267    target = CALLOC_STRUCT(pipe_stream_output_target);
1268    if (!target)
1269       return NULL;
1270
1271    target->context = pipe;
1272    target->reference.count = 1;
1273    pipe_resource_reference(&target->buffer, buffer);
1274    target->buffer_offset = buffer_offset;
1275    target->buffer_size = buffer_size;
1276    return target;
1277 }
1278
1279 static void
1280 swr_destroy_so_target(struct pipe_context *pipe,
1281                       struct pipe_stream_output_target *target)
1282 {
1283    pipe_resource_reference(&target->buffer, NULL);
1284    FREE(target);
1285 }
1286
1287 static void
1288 swr_set_so_targets(struct pipe_context *pipe,
1289                    unsigned num_targets,
1290                    struct pipe_stream_output_target **targets,
1291                    const unsigned *offsets)
1292 {
1293    struct swr_context *swr = swr_context(pipe);
1294    uint32_t i;
1295
1296    assert(num_targets < MAX_SO_STREAMS);
1297
1298    for (i = 0; i < num_targets; i++) {
1299       pipe_so_target_reference(
1300          (struct pipe_stream_output_target **)&swr->so_targets[i],
1301          targets[i]);
1302    }
1303
1304    for (/* fall-through */; i < swr->num_so_targets; i++) {
1305       pipe_so_target_reference(
1306          (struct pipe_stream_output_target **)&swr->so_targets[i], NULL);
1307    }
1308
1309    swr->num_so_targets = num_targets;
1310
1311    swr->dirty = SWR_NEW_SO;
1312 }
1313
1314
1315 void
1316 swr_state_init(struct pipe_context *pipe)
1317 {
1318    pipe->create_blend_state = swr_create_blend_state;
1319    pipe->bind_blend_state = swr_bind_blend_state;
1320    pipe->delete_blend_state = swr_delete_blend_state;
1321
1322    pipe->create_depth_stencil_alpha_state = swr_create_depth_stencil_state;
1323    pipe->bind_depth_stencil_alpha_state = swr_bind_depth_stencil_state;
1324    pipe->delete_depth_stencil_alpha_state = swr_delete_depth_stencil_state;
1325
1326    pipe->create_rasterizer_state = swr_create_rasterizer_state;
1327    pipe->bind_rasterizer_state = swr_bind_rasterizer_state;
1328    pipe->delete_rasterizer_state = swr_delete_rasterizer_state;
1329
1330    pipe->create_sampler_state = swr_create_sampler_state;
1331    pipe->bind_sampler_states = swr_bind_sampler_states;
1332    pipe->delete_sampler_state = swr_delete_sampler_state;
1333
1334    pipe->create_sampler_view = swr_create_sampler_view;
1335    pipe->set_sampler_views = swr_set_sampler_views;
1336    pipe->sampler_view_destroy = swr_sampler_view_destroy;
1337
1338    pipe->create_vs_state = swr_create_vs_state;
1339    pipe->bind_vs_state = swr_bind_vs_state;
1340    pipe->delete_vs_state = swr_delete_vs_state;
1341
1342    pipe->create_fs_state = swr_create_fs_state;
1343    pipe->bind_fs_state = swr_bind_fs_state;
1344    pipe->delete_fs_state = swr_delete_fs_state;
1345
1346    pipe->set_constant_buffer = swr_set_constant_buffer;
1347
1348    pipe->create_vertex_elements_state = swr_create_vertex_elements_state;
1349    pipe->bind_vertex_elements_state = swr_bind_vertex_elements_state;
1350    pipe->delete_vertex_elements_state = swr_delete_vertex_elements_state;
1351
1352    pipe->set_vertex_buffers = swr_set_vertex_buffers;
1353    pipe->set_index_buffer = swr_set_index_buffer;
1354
1355    pipe->set_polygon_stipple = swr_set_polygon_stipple;
1356    pipe->set_clip_state = swr_set_clip_state;
1357    pipe->set_scissor_states = swr_set_scissor_states;
1358    pipe->set_viewport_states = swr_set_viewport_states;
1359
1360    pipe->set_framebuffer_state = swr_set_framebuffer_state;
1361
1362    pipe->set_blend_color = swr_set_blend_color;
1363    pipe->set_stencil_ref = swr_set_stencil_ref;
1364
1365    pipe->set_sample_mask = swr_set_sample_mask;
1366
1367    pipe->create_stream_output_target = swr_create_so_target;
1368    pipe->stream_output_target_destroy = swr_destroy_so_target;
1369    pipe->set_stream_output_targets = swr_set_so_targets;
1370 }