static enum pipe_error emit_hw_fs(struct svga_context *svga, unsigned dirty) { struct svga_shader_variant *variant = NULL; enum pipe_error ret = PIPE_OK; struct svga_fragment_shader *fs = svga->curr.fs; struct svga_compile_key key; /* SVGA_NEW_BLEND * SVGA_NEW_TEXTURE_BINDING * SVGA_NEW_RAST * SVGA_NEW_NEED_SWTNL * SVGA_NEW_SAMPLER * SVGA_NEW_FRAME_BUFFER * SVGA_NEW_DEPTH_STENCIL_ALPHA * SVGA_NEW_VS */ ret = make_fs_key(svga, fs, &key); if (ret != PIPE_OK) return ret; variant = svga_search_shader_key(&fs->base, &key); if (!variant) { ret = compile_fs(svga, fs, &key, &variant); if (ret != PIPE_OK) return ret; } assert(variant); if (variant != svga->state.hw_draw.fs) { ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_PS, variant); if (ret != PIPE_OK) return ret; svga->rebind.flags.fs = FALSE; svga->dirty |= SVGA_NEW_FS_VARIANT; svga->state.hw_draw.fs = variant; } return PIPE_OK; }
static enum pipe_error emit_hw_gs(struct svga_context *svga, unsigned dirty) { struct svga_shader_variant *variant; struct svga_geometry_shader *gs = svga->curr.gs; enum pipe_error ret = PIPE_OK; struct svga_compile_key key; /* If there's a user-defined GS, we should have a pointer to a derived * GS. This should have been resolved in update_tgsi_transform(). */ if (svga->curr.user_gs) assert(svga->curr.gs); if (!gs) { if (svga->state.hw_draw.gs != NULL) { /** The previous geometry shader is made inactive. * Needs to unbind the geometry shader. */ ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_GS, NULL); svga->state.hw_draw.gs = NULL; } return ret; } /* If there is stream output info for this geometry shader, then use * it instead of the one from the vertex shader. */ if (svga_have_gs_streamout(svga)) { svga_set_stream_output(svga, gs->base.stream_output); } else if (!svga_have_vs_streamout(svga)) { /* turn off stream out */ svga_set_stream_output(svga, NULL); } /* SVGA_NEW_NEED_SWTNL */ if (svga->state.sw.need_swtnl && !svga_have_vgpu10(svga)) { /* No geometry shader is needed */ variant = NULL; } else { make_gs_key(svga, &key); /* See if we already have a GS variant that matches the key */ variant = svga_search_shader_key(&gs->base, &key); if (!variant) { ret = compile_gs(svga, gs, &key, &variant); if (ret != PIPE_OK) return ret; /* insert the new variant at head of linked list */ assert(variant); variant->next = gs->base.variants; gs->base.variants = variant; } } if (variant != svga->state.hw_draw.gs) { /* Bind the new variant */ ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_GS, variant); if (ret != PIPE_OK) return ret; svga->rebind.flags.gs = FALSE; svga->dirty |= SVGA_NEW_GS_VARIANT; svga->state.hw_draw.gs = variant; } return PIPE_OK; }
static enum pipe_error emit_hw_vs(struct svga_context *svga, unsigned dirty) { struct svga_shader_variant *variant; struct svga_vertex_shader *vs = svga->curr.vs; struct svga_fragment_shader *fs = svga->curr.fs; enum pipe_error ret = PIPE_OK; struct svga_compile_key key; /* If there is an active geometry shader, and it has stream output * defined, then we will skip the stream output from the vertex shader */ if (!svga_have_gs_streamout(svga)) { /* No GS stream out */ if (svga_have_vs_streamout(svga)) { /* Set VS stream out */ svga_set_stream_output(svga, vs->base.stream_output); } else { /* turn off stream out */ svga_set_stream_output(svga, NULL); } } /* SVGA_NEW_NEED_SWTNL */ if (svga->state.sw.need_swtnl && !svga_have_vgpu10(svga)) { /* No vertex shader is needed */ variant = NULL; } else { make_vs_key(svga, &key); /* See if we already have a VS variant that matches the key */ variant = svga_search_shader_key(&vs->base, &key); if (!variant) { /* Create VS variant now */ if (key.vs.passthrough) { ret = compile_passthrough_vs(svga, vs, fs, &variant); } else { ret = compile_vs(svga, vs, &key, &variant); } if (ret != PIPE_OK) return ret; /* insert the new variant at head of linked list */ assert(variant); variant->next = vs->base.variants; vs->base.variants = variant; } } if (variant != svga->state.hw_draw.vs) { /* Bind the new variant */ if (variant) { ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_VS, variant); if (ret != PIPE_OK) return ret; svga->rebind.flags.vs = FALSE; } svga->dirty |= SVGA_NEW_VS_VARIANT; svga->state.hw_draw.vs = variant; } return PIPE_OK; }