gallium/swr: remove use of BYTE from swr driver
[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 uint8_t *)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 uint8_t *)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 uint8_t *)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 uint8_t *)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 }