1 /****************************************************************************
2 * Copyright (C) 2015 Intel Corporation. All Rights Reserved.
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:
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
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
22 ***************************************************************************/
24 #include "common/os.h"
26 #include "JitManager.h"
27 #include "state_llvm.h"
29 #include "gallivm/lp_bld_tgsi.h"
30 #include "util/u_format.h"
32 #include "util/u_memory.h"
33 #include "util/u_inlines.h"
34 #include "util/u_helpers.h"
35 #include "util/u_framebuffer.h"
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"
46 /* These should be pulled out into separate files as necessary
47 * Just initializing everything here to get going. */
50 swr_create_blend_state(struct pipe_context *pipe,
51 const struct pipe_blend_state *blend)
53 struct swr_blend_state *state = CALLOC_STRUCT(swr_blend_state);
55 memcpy(&state->pipe, blend, sizeof(*blend));
57 struct pipe_blend_state *pipe_blend = &state->pipe;
60 target < std::min(SWR_NUM_RENDERTARGETS, PIPE_MAX_COLOR_BUFS);
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];
69 if (target != 0 && !pipe_blend->independent_blend_enable) {
71 &state->compileState[0],
72 sizeof(RENDER_TARGET_BLEND_COMPILE_STATE));
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);
87 compileState.colorBlendFunc =
88 swr_convert_blend_func(rt_blend->rgb_func);
89 compileState.alphaBlendFunc =
90 swr_convert_blend_func(rt_blend->alpha_func);
92 compileState.logicOpEnable = state->pipe.logicop_enable;
93 if (compileState.logicOpEnable) {
94 compileState.logicOpFunc =
95 swr_convert_logic_op(state->pipe.logicop_func);
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;
107 if (rt_blend->colormask == 0)
108 compileState.blendEnable = false;
115 swr_bind_blend_state(struct pipe_context *pipe, void *blend)
117 struct swr_context *ctx = swr_context(pipe);
119 if (ctx->blend == blend)
122 ctx->blend = (swr_blend_state *)blend;
124 ctx->dirty |= SWR_NEW_BLEND;
128 swr_delete_blend_state(struct pipe_context *pipe, void *blend)
134 swr_set_blend_color(struct pipe_context *pipe,
135 const struct pipe_blend_color *color)
137 struct swr_context *ctx = swr_context(pipe);
139 ctx->blend_color = *color;
141 ctx->dirty |= SWR_NEW_BLEND;
145 swr_set_stencil_ref(struct pipe_context *pipe,
146 const struct pipe_stencil_ref *ref)
148 struct swr_context *ctx = swr_context(pipe);
150 ctx->stencil_ref = *ref;
152 ctx->dirty |= SWR_NEW_DEPTH_STENCIL_ALPHA;
156 swr_create_depth_stencil_state(
157 struct pipe_context *pipe,
158 const struct pipe_depth_stencil_alpha_state *depth_stencil)
160 struct pipe_depth_stencil_alpha_state *state;
162 state = (pipe_depth_stencil_alpha_state *)mem_dup(depth_stencil,
163 sizeof *depth_stencil);
169 swr_bind_depth_stencil_state(struct pipe_context *pipe, void *depth_stencil)
171 struct swr_context *ctx = swr_context(pipe);
173 if (ctx->depth_stencil == (pipe_depth_stencil_alpha_state *)depth_stencil)
176 ctx->depth_stencil = (pipe_depth_stencil_alpha_state *)depth_stencil;
178 ctx->dirty |= SWR_NEW_DEPTH_STENCIL_ALPHA;
182 swr_delete_depth_stencil_state(struct pipe_context *pipe, void *depth)
189 swr_create_rasterizer_state(struct pipe_context *pipe,
190 const struct pipe_rasterizer_state *rast)
192 struct pipe_rasterizer_state *state;
193 state = (pipe_rasterizer_state *)mem_dup(rast, sizeof *rast);
199 swr_bind_rasterizer_state(struct pipe_context *pipe, void *handle)
201 struct swr_context *ctx = swr_context(pipe);
202 const struct pipe_rasterizer_state *rasterizer =
203 (const struct pipe_rasterizer_state *)handle;
205 if (ctx->rasterizer == (pipe_rasterizer_state *)rasterizer)
208 ctx->rasterizer = (pipe_rasterizer_state *)rasterizer;
210 ctx->dirty |= SWR_NEW_RASTERIZER;
214 swr_delete_rasterizer_state(struct pipe_context *pipe, void *rasterizer)
221 swr_create_sampler_state(struct pipe_context *pipe,
222 const struct pipe_sampler_state *sampler)
224 struct pipe_sampler_state *state =
225 (pipe_sampler_state *)mem_dup(sampler, sizeof *sampler);
231 swr_bind_sampler_states(struct pipe_context *pipe,
237 struct swr_context *ctx = swr_context(pipe);
240 assert(shader < PIPE_SHADER_TYPES);
241 assert(start + num <= Elements(ctx->samplers[shader]));
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];
249 ctx->dirty |= SWR_NEW_SAMPLER;
253 swr_delete_sampler_state(struct pipe_context *pipe, void *sampler)
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)
264 struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
268 view->reference.count = 1;
269 view->texture = NULL;
270 pipe_resource_reference(&view->texture, texture);
271 view->context = pipe;
278 swr_set_sampler_views(struct pipe_context *pipe,
282 struct pipe_sampler_view **views)
284 struct swr_context *ctx = swr_context(pipe);
287 assert(num <= PIPE_MAX_SHADER_SAMPLER_VIEWS);
289 assert(shader < PIPE_SHADER_TYPES);
290 assert(start + num <= Elements(ctx->sampler_views[shader]));
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.
299 pipe_sampler_view_release(pipe, &ctx->sampler_views[shader][start + i]);
300 pipe_sampler_view_reference(&ctx->sampler_views[shader][start + i],
304 ctx->dirty |= SWR_NEW_SAMPLER_VIEW;
308 swr_sampler_view_destroy(struct pipe_context *pipe,
309 struct pipe_sampler_view *view)
311 pipe_resource_reference(&view->texture, NULL);
316 swr_create_vs_state(struct pipe_context *pipe,
317 const struct pipe_shader_state *vs)
319 struct swr_vertex_shader *swr_vs =
320 (swr_vertex_shader *)CALLOC_STRUCT(swr_vertex_shader);
324 swr_vs->pipe.tokens = tgsi_dup_tokens(vs->tokens);
325 swr_vs->pipe.stream_output = vs->stream_output;
327 lp_build_tgsi_info(vs->tokens, &swr_vs->info);
329 swr_vs->func = swr_compile_vs(pipe, swr_vs);
331 swr_vs->soState = {0};
333 if (swr_vs->pipe.stream_output.num_outputs) {
334 pipe_stream_output_info *stream_output = &swr_vs->pipe.stream_output;
336 swr_vs->soState.soEnable = true;
337 // soState.rasterizerDisable set on state dirty
338 // soState.streamToRasterizer not used
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);
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]);
354 swr_bind_vs_state(struct pipe_context *pipe, void *vs)
356 struct swr_context *ctx = swr_context(pipe);
361 ctx->vs = (swr_vertex_shader *)vs;
362 ctx->dirty |= SWR_NEW_VS;
366 swr_delete_vs_state(struct pipe_context *pipe, void *vs)
368 struct swr_vertex_shader *swr_vs = (swr_vertex_shader *)vs;
369 FREE((void *)swr_vs->pipe.tokens);
374 swr_create_fs_state(struct pipe_context *pipe,
375 const struct pipe_shader_state *fs)
377 struct swr_fragment_shader *swr_fs = new swr_fragment_shader;
381 swr_fs->pipe.tokens = tgsi_dup_tokens(fs->tokens);
383 lp_build_tgsi_info(fs->tokens, &swr_fs->info);
390 swr_bind_fs_state(struct pipe_context *pipe, void *fs)
392 struct swr_context *ctx = swr_context(pipe);
397 ctx->fs = (swr_fragment_shader *)fs;
398 ctx->dirty |= SWR_NEW_FS;
402 swr_delete_fs_state(struct pipe_context *pipe, void *fs)
404 struct swr_fragment_shader *swr_fs = (swr_fragment_shader *)fs;
405 FREE((void *)swr_fs->pipe.tokens);
411 swr_set_constant_buffer(struct pipe_context *pipe,
414 struct pipe_constant_buffer *cb)
416 struct swr_context *ctx = swr_context(pipe);
417 struct pipe_resource *constants = cb ? cb->buffer : NULL;
419 assert(shader < PIPE_SHADER_TYPES);
420 assert(index < Elements(ctx->constants[shader]));
422 /* note: reference counting */
423 util_copy_constant_buffer(&ctx->constants[shader][index], cb);
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;
431 if (cb && cb->user_buffer) {
432 pipe_resource_reference(&constants, NULL);
438 swr_create_vertex_elements_state(struct pipe_context *pipe,
439 unsigned num_elements,
440 const struct pipe_vertex_element *attribs)
442 struct swr_vertex_element_state *velems;
443 assert(num_elements <= PIPE_MAX_ATTRIBS);
444 velems = CALLOC_STRUCT(swr_vertex_element_state);
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
450 const struct util_format_description *desc =
451 util_format_description(attribs[i].src_format);
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;
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;
491 swr_bind_vertex_elements_state(struct pipe_context *pipe, void *velems)
493 struct swr_context *ctx = swr_context(pipe);
494 struct swr_vertex_element_state *swr_velems =
495 (struct swr_vertex_element_state *)velems;
497 ctx->velems = swr_velems;
498 ctx->dirty |= SWR_NEW_VERTEX;
502 swr_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
504 /* XXX Need to destroy fetch shader? */
510 swr_set_vertex_buffers(struct pipe_context *pipe,
512 unsigned num_elements,
513 const struct pipe_vertex_buffer *buffers)
515 struct swr_context *ctx = swr_context(pipe);
517 assert(num_elements <= PIPE_MAX_ATTRIBS);
519 util_set_vertex_buffers_count(ctx->vertex_buffer,
520 &ctx->num_vertex_buffers,
525 ctx->dirty |= SWR_NEW_VERTEX;
530 swr_set_index_buffer(struct pipe_context *pipe,
531 const struct pipe_index_buffer *ib)
533 struct swr_context *ctx = swr_context(pipe);
536 memcpy(&ctx->index_buffer, ib, sizeof(ctx->index_buffer));
538 memset(&ctx->index_buffer, 0, sizeof(ctx->index_buffer));
540 ctx->dirty |= SWR_NEW_VERTEX;
544 swr_set_polygon_stipple(struct pipe_context *pipe,
545 const struct pipe_poly_stipple *stipple)
547 struct swr_context *ctx = swr_context(pipe);
549 ctx->poly_stipple = *stipple; /* struct copy */
550 ctx->dirty |= SWR_NEW_STIPPLE;
554 swr_set_clip_state(struct pipe_context *pipe,
555 const struct pipe_clip_state *clip)
557 struct swr_context *ctx = swr_context(pipe);
560 /* XXX Unimplemented, but prevents crash */
562 ctx->dirty |= SWR_NEW_CLIP;
567 swr_set_scissor_states(struct pipe_context *pipe,
569 unsigned num_viewports,
570 const struct pipe_scissor_state *scissor)
572 struct swr_context *ctx = swr_context(pipe);
574 ctx->scissor = *scissor;
575 ctx->dirty |= SWR_NEW_SCISSOR;
579 swr_set_viewport_states(struct pipe_context *pipe,
581 unsigned num_viewports,
582 const struct pipe_viewport_state *vpt)
584 struct swr_context *ctx = swr_context(pipe);
586 ctx->viewport = *vpt;
587 ctx->dirty |= SWR_NEW_VIEWPORT;
592 swr_set_framebuffer_state(struct pipe_context *pipe,
593 const struct pipe_framebuffer_state *fb)
595 struct swr_context *ctx = swr_context(pipe);
597 boolean changed = !util_framebuffer_state_equal(&ctx->framebuffer, fb);
599 assert(fb->width <= KNOB_GUARDBAND_WIDTH);
600 assert(fb->height <= KNOB_GUARDBAND_HEIGHT);
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);
609 ctx->framebuffer.nr_cbufs = fb->nr_cbufs;
611 ctx->framebuffer.width = fb->width;
612 ctx->framebuffer.height = fb->height;
614 pipe_surface_reference(&ctx->framebuffer.zsbuf, fb->zsbuf);
616 ctx->dirty |= SWR_NEW_FRAMEBUFFER;
622 swr_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)
624 struct swr_context *ctx = swr_context(pipe);
626 if (sample_mask != ctx->sample_mask) {
627 ctx->sample_mask = sample_mask;
628 ctx->dirty |= SWR_NEW_RASTERIZER;
634 swr_update_derived(struct swr_context *ctx,
635 const struct pipe_draw_info *p_draw_info)
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;
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};
647 /* colorbuffer targets */
649 for (i = 0; i < fb->nr_cbufs; ++i)
651 struct swr_resource *colorBuffer =
652 swr_resource(fb->cbufs[i]->texture);
653 new_attachment[SWR_ATTACHMENT_COLOR0 + i] = &colorBuffer->swr;
656 /* depth/stencil target */
658 struct swr_resource *depthStencilBuffer =
659 swr_resource(fb->zsbuf->texture);
660 if (depthStencilBuffer->has_depth) {
661 new_attachment[SWR_ATTACHMENT_DEPTH] = &depthStencilBuffer->swr;
663 if (depthStencilBuffer->has_stencil)
664 new_attachment[SWR_ATTACHMENT_STENCIL] =
665 &depthStencilBuffer->secondary;
667 } else if (depthStencilBuffer->has_stencil)
668 new_attachment[SWR_ATTACHMENT_STENCIL] = &depthStencilBuffer->swr;
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;
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);
687 /* Make new attachment */
688 if (new_attachment[i])
689 renderTargets[i] = *new_attachment[i];
691 if (renderTargets[i].pBaseAddress)
692 renderTargets[i] = {0};
698 if (ctx->dirty & (SWR_NEW_RASTERIZER | SWR_NEW_FRAMEBUFFER)) {
699 pipe_rasterizer_state *rasterizer = ctx->rasterizer;
700 pipe_framebuffer_state *fb = &ctx->framebuffer;
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
711 rastState->lineWidth = rasterizer->line_width > 0.0f
712 ? rasterizer->line_width
715 rastState->pointParam = rasterizer->point_size_per_vertex;
717 rastState->pointSpriteEnable = rasterizer->sprite_coord_enable;
718 rastState->pointSpriteTopOrigin =
719 rasterizer->sprite_coord_mode == PIPE_SPRITE_COORD_UPPER_LEFT;
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;
727 bool do_offset = false;
728 switch (rasterizer->fill_front) {
729 case PIPE_POLYGON_MODE_FILL:
730 do_offset = rasterizer->offset_tri;
732 case PIPE_POLYGON_MODE_LINE:
733 do_offset = rasterizer->offset_line;
735 case PIPE_POLYGON_MODE_POINT:
736 do_offset = rasterizer->offset_point;
741 rastState->depthBias = rasterizer->offset_units;
742 rastState->slopeScaledDepthBias = rasterizer->offset_scale;
743 rastState->depthBiasClamp = rasterizer->offset_clamp;
745 rastState->depthBias = 0;
746 rastState->slopeScaledDepthBias = 0;
747 rastState->depthBiasClamp = 0;
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;
753 rastState->depthClipEnable = rasterizer->depth_clip;
755 SwrSetRastState(ctx->swrContext, rastState);
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);
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;
773 SWR_VIEWPORT *vp = &ctx->derived.vp;
774 SWR_VIEWPORT_MATRIX *vpm = &ctx->derived.vpm;
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];
784 vp->minZ = state->translate[2];
785 vp->maxZ = state->translate[2] + state->scale[2];
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];
795 /* Now that the matrix is calculated, clip the view coords to screen
796 * size. OpenGL allows for -ve x,y in the viewport.
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);
803 SwrSetViewports(ctx->swrContext, 1, vp, vpm);
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;
812 /* If being called by swr_draw_vbo, copy draw details */
813 struct pipe_draw_info info = {0};
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];
823 if (!vb->user_buffer) {
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;
831 p_data = (const uint8_t *)swr_resource_data(vb->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;
840 size = (info.max_index - info.min_index + 1) * pitch;
842 /* pitch = 0, means constant value
843 * set size to 1 vertex */
844 size = ctx->velems->stream_pitch[i];
847 max_vertex = info.max_index + 1;
848 partial_inbounds = 0;
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;
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;
869 ctx->swrContext, ctx->num_vertex_buffers, swrVertexBuffers);
871 /* index buffer, if required (info passed in by swr_draw_vbo) */
872 SWR_FORMAT index_type = R32_UINT; /* Default for non-indexed draws */
874 pipe_index_buffer *ib = &ctx->index_buffer;
876 pitch = ib->index_size ? ib->index_size : sizeof(uint32_t);
877 index_type = swr_convert_index_type(pitch);
879 if (!ib->user_buffer) {
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;
885 (const uint8_t *)swr_resource_data(ib->buffer) + ib->offset;
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;
892 size = info.count * pitch;
893 size = AlignUp(size, 4);
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;
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;
907 SwrSetIndexBuffer(ctx->swrContext, &swrIndexBuffer);
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;
918 if (ctx->dirty & (SWR_NEW_VS | SWR_NEW_FRAMEBUFFER)) {
919 SwrSetVertexFunc(ctx->swrContext, ctx->vs->func);
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;
932 func = swr_compile_fs(ctx, key);
933 ctx->fs->map.insert(std::make_pair(key, func));
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;
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;
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;
962 case TGSI_INTERPOLATE_LOC_CENTROID:
963 barycentricsMask |= SWR_BARYCENTRIC_CENTROID_MASK;
965 case TGSI_INTERPOLATE_LOC_SAMPLE:
966 barycentricsMask |= SWR_BARYCENTRIC_PER_SAMPLE_MASK;
971 psState.barycentricsMask = barycentricsMask;
972 psState.usesUAV = false; // XXX
973 psState.forceEarlyZ = false;
974 SwrSetPixelShaderState(ctx->swrContext, &psState);
977 /* JIT sampler state */
978 if (ctx->dirty & SWR_NEW_SAMPLER) {
979 swr_draw_context *pDC = &ctx->swrDC;
981 for (unsigned i = 0; i < key.nr_samplers; i++) {
982 const struct pipe_sampler_state *sampler =
983 ctx->samplers[PIPE_SHADER_FRAGMENT][i];
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);
994 /* JIT sampler view state */
995 if (ctx->dirty & (SWR_NEW_SAMPLER_VIEW | SWR_NEW_FRAMEBUFFER)) {
996 swr_draw_context *pDC = &ctx->swrDC;
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];
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;
1014 for (unsigned level = jit_tex->first_level;
1015 level <= jit_tex->last_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];
1025 /* VertexShader Constants */
1026 if (ctx->dirty & SWR_NEW_VSCONSTANTS) {
1027 swr_draw_context *pDC = &ctx->swrDC;
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;
1034 pDC->constantVS[i] =
1035 (const float *)((const BYTE *)cb->buffer + cb->buffer_offset);
1037 /* Need to copy these constants to scratch space */
1038 if (cb->user_buffer && cb->buffer_size) {
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;
1050 /* FragmentShader Constants */
1051 if (ctx->dirty & SWR_NEW_FSCONSTANTS) {
1052 swr_draw_context *pDC = &ctx->swrDC;
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;
1059 pDC->constantFS[i] =
1060 (const float *)((const BYTE *)cb->buffer + cb->buffer_offset);
1062 /* Need to copy these constants to scratch space */
1063 if (cb->user_buffer && cb->buffer_size) {
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;
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}};
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;
1087 if (stencil[0].enabled) {
1088 depthStencilState.stencilWriteEnable = 1;
1089 depthStencilState.stencilTestEnable = 1;
1090 depthStencilState.stencilTestFunc =
1091 swr_convert_depth_func(stencil[0].func);
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];
1103 if (stencil[1].enabled) {
1104 depthStencilState.doubleSidedStencilTestEnable = 1;
1106 depthStencilState.backfaceStencilTestFunc =
1107 swr_convert_depth_func(stencil[1].func);
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;
1118 depthStencilState.backfaceStencilRefValue =
1119 ctx->stencil_ref.ref_value[1];
1122 depthStencilState.depthTestEnable = depth->enabled;
1123 depthStencilState.depthTestFunc = swr_convert_depth_func(depth->func);
1124 depthStencilState.depthWriteEnable = depth->writemask;
1125 SwrSetDepthStencilState(ctx->swrContext, &depthStencilState);
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;
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);
1144 blendState.sampleMask = 0;
1145 blendState.sampleCount = SWR_MULTISAMPLE_1X;
1147 /* If there are no color buffers bound, disable writes on RT0
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);
1157 for (int target = 0;
1158 target < std::min(SWR_NUM_RENDERTARGETS,
1159 PIPE_MAX_COLOR_BUFS);
1161 if (!fb->cbufs[target])
1164 struct swr_resource *colorBuffer =
1165 swr_resource(fb->cbufs[target]->texture);
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));
1174 if (compileState.blendState.blendEnable == false &&
1175 compileState.blendState.logicOpEnable == false) {
1176 SwrSetBlendFunc(ctx->swrContext, target, NULL);
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
1189 compileState.alphaTestFunction =
1190 swr_convert_depth_func(ctx->depth_stencil->alpha.func);
1191 compileState.alphaTestFormat = ALPHA_TEST_FLOAT32; // xxx
1193 PFN_BLEND_JIT_FUNC func = NULL;
1194 auto search = ctx->blendJIT->find(compileState);
1195 if (search != ctx->blendJIT->end()) {
1196 func = search->second;
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");
1203 ctx->blendJIT->insert(std::make_pair(compileState, func));
1205 SwrSetBlendFunc(ctx->swrContext, target, func);
1208 SwrSetBlendState(ctx->swrContext, &blendState);
1211 if (ctx->dirty & SWR_NEW_STIPPLE) {
1212 /* XXX What to do with this one??? SWR doesn't stipple */
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);
1220 pipe_stream_output_info *stream_output = &ctx->vs->pipe.stream_output;
1222 for (uint32_t i = 0; i < ctx->num_so_targets; i++) {
1223 SWR_STREAMOUT_BUFFER buffer = {0};
1224 if (!ctx->so_targets[i])
1226 buffer.enable = true;
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;
1233 SwrSetSoBuffers(ctx->swrContext, &buffer, i);
1237 uint32_t linkage = ctx->vs->linkageMask;
1238 if (ctx->rasterizer->sprite_coord_enable)
1239 linkage |= (1 << ctx->vs->info.base.num_outputs);
1241 SwrSetLinkage(ctx->swrContext, linkage, NULL);
1243 // set up frontend state
1244 SWR_FRONTEND_STATE feState = {0};
1245 SwrSetFrontendState(ctx->swrContext, &feState);
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;
1254 SwrSetBackendState(ctx->swrContext, &backendState);
1256 ctx->dirty = post_update_dirty_flags;
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)
1265 struct pipe_stream_output_target *target;
1267 target = CALLOC_STRUCT(pipe_stream_output_target);
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;
1280 swr_destroy_so_target(struct pipe_context *pipe,
1281 struct pipe_stream_output_target *target)
1283 pipe_resource_reference(&target->buffer, NULL);
1288 swr_set_so_targets(struct pipe_context *pipe,
1289 unsigned num_targets,
1290 struct pipe_stream_output_target **targets,
1291 const unsigned *offsets)
1293 struct swr_context *swr = swr_context(pipe);
1296 assert(num_targets < MAX_SO_STREAMS);
1298 for (i = 0; i < num_targets; i++) {
1299 pipe_so_target_reference(
1300 (struct pipe_stream_output_target **)&swr->so_targets[i],
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);
1309 swr->num_so_targets = num_targets;
1311 swr->dirty = SWR_NEW_SO;
1316 swr_state_init(struct pipe_context *pipe)
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;
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;
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;
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;
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;
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;
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;
1346 pipe->set_constant_buffer = swr_set_constant_buffer;
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;
1352 pipe->set_vertex_buffers = swr_set_vertex_buffers;
1353 pipe->set_index_buffer = swr_set_index_buffer;
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;
1360 pipe->set_framebuffer_state = swr_set_framebuffer_state;
1362 pipe->set_blend_color = swr_set_blend_color;
1363 pipe->set_stencil_ref = swr_set_stencil_ref;
1365 pipe->set_sample_mask = swr_set_sample_mask;
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;