[D3D8][D3D9][DDRAW][D3DCOMPILER_43][WINED3D] Revert to Wine Staging 3.3
[reactos.git] / dll / directx / wine / wined3d / glsl_shader.c
index 41bd1fd..4c879f9 100644 (file)
@@ -91,6 +91,7 @@ struct glsl_sample_function
     enum wined3d_data_type data_type;
     BOOL output_single_component;
     unsigned int offset_size;
+    enum wined3d_shader_resource_type emulate_lod;
 };
 
 enum heap_node_op
@@ -804,12 +805,11 @@ static void append_transform_feedback_skip_components(const char **varyings,
     }
 }
 
-static BOOL shader_glsl_generate_transform_feedback_varyings(const struct wined3d_stream_output_desc *so_desc,
+static void shader_glsl_generate_transform_feedback_varyings(const struct wined3d_stream_output_desc *so_desc,
         struct wined3d_string_buffer *buffer, const char **varyings, unsigned int *varying_count,
         char *strings, unsigned int *strings_length, GLenum buffer_mode)
 {
     unsigned int i, buffer_idx, count, length, highest_output_slot, stride;
-    BOOL have_varyings_to_record = FALSE;
 
     count = length = 0;
     highest_output_slot = 0;
@@ -859,8 +859,6 @@ static BOOL shader_glsl_generate_transform_feedback_varyings(const struct wined3
                 string_buffer_sprintf(buffer, "shader_in_out.reg%u", e->register_idx);
                 append_transform_feedback_varying(varyings, &count, &strings, &length, buffer);
             }
-
-            have_varyings_to_record = TRUE;
         }
 
         if (buffer_idx < so_desc->buffer_stride_count
@@ -885,12 +883,10 @@ static BOOL shader_glsl_generate_transform_feedback_varyings(const struct wined3
         *varying_count = count;
     if (strings_length)
         *strings_length = length;
-
-    return have_varyings_to_record;
 }
 
 static void shader_glsl_init_transform_feedback(const struct wined3d_context *context,
-        struct shader_glsl_priv *priv, GLuint program_id, struct wined3d_shader *shader)
+        struct shader_glsl_priv *priv, GLuint program_id, const struct wined3d_shader *shader)
 {
     const struct wined3d_stream_output_desc *so_desc = &shader->u.gs.so_desc;
     const struct wined3d_gl_info *gl_info = context->gl_info;
@@ -946,13 +942,7 @@ static void shader_glsl_init_transform_feedback(const struct wined3d_context *co
 
     buffer = string_buffer_get(&priv->string_buffers);
 
-    if (!shader_glsl_generate_transform_feedback_varyings(so_desc, buffer, NULL, &count, NULL, &length, mode))
-    {
-        FIXME("No varyings to record, disabling transform feedback.\n");
-        shader->u.gs.so_desc.element_count = 0;
-        string_buffer_release(&priv->string_buffers, buffer);
-        return;
-    }
+    shader_glsl_generate_transform_feedback_varyings(so_desc, buffer, NULL, &count, NULL, &length, mode);
 
     if (!(varyings = heap_calloc(count, sizeof(*varyings))))
     {
@@ -1470,7 +1460,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
     const struct wined3d_shader *pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL];
     const struct wined3d_gl_info *gl_info = context->gl_info;
     struct shader_glsl_priv *priv = shader_priv;
-    float position_fixup[4 * WINED3D_MAX_VIEWPORTS];
+    float position_fixup[4];
     float normal[3 * 3];
     DWORD update_mask;
 
@@ -1508,11 +1498,9 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
 
     if (update_mask & WINED3D_SHADER_CONST_POS_FIXUP)
     {
-        unsigned int fixup_count = state->shader[WINED3D_SHADER_TYPE_GEOMETRY] ?
-                max(state->viewport_count, 1) : 1;
-        shader_get_position_fixup(context, state, fixup_count, position_fixup);
+        shader_get_position_fixup(context, state, position_fixup);
         if (state->shader[WINED3D_SHADER_TYPE_GEOMETRY])
-            GL_EXTCALL(glUniform4fv(prog->gs.pos_fixup_location, fixup_count, position_fixup));
+            GL_EXTCALL(glUniform4fv(prog->gs.pos_fixup_location, 1, position_fixup));
         else if (state->shader[WINED3D_SHADER_TYPE_DOMAIN])
             GL_EXTCALL(glUniform4fv(prog->ds.pos_fixup_location, 1, position_fixup));
         else
@@ -1969,11 +1957,6 @@ static void shader_glsl_declare_shader_outputs(const struct wined3d_gl_info *gl_
     }
 }
 
-static const char *get_fragment_output(const struct wined3d_gl_info *gl_info)
-{
-    return needs_legacy_glsl_syntax(gl_info) ? "gl_FragData" : "ps_out";
-}
-
 static const char *glsl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type)
 {
     switch (primitive_type)
@@ -2956,10 +2939,6 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
                 sprintf(register_name, "vpc[%u]", reg->idx[0].offset);
             break;
 
-        case WINED3DSPR_SAMPLEMASK:
-            sprintf(register_name, "sample_mask");
-            break;
-
         default:
             FIXME("Unhandled register type %#x.\n", reg->type);
             sprintf(register_name, "unrecognized_register");
@@ -3264,6 +3243,7 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context
     enum wined3d_shader_resource_type resource_type = ctx->reg_maps->resource_info[resource_idx].type;
     struct shader_glsl_ctx_priv *priv = ctx->backend_data;
     const struct wined3d_gl_info *gl_info = ctx->gl_info;
+    BOOL legacy_syntax = needs_legacy_glsl_syntax(gl_info);
     BOOL shadow = glsl_is_shadow_sampler(ctx->shader, priv->cur_ps_args, resource_idx, sampler_idx);
     BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED;
     BOOL texrect = ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL
@@ -3276,6 +3256,7 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context
     unsigned int coord_size, deriv_size;
 
     sample_function->data_type = ctx->reg_maps->resource_info[resource_idx].data_type;
+    sample_function->emulate_lod = WINED3D_SHADER_RESOURCE_NONE;
 
     if (resource_type >= ARRAY_SIZE(resource_type_info))
     {
@@ -3287,7 +3268,30 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context
     if (resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_CUBE)
         projected = FALSE;
 
-    if (needs_legacy_glsl_syntax(gl_info))
+    if (shadow && lod)
+    {
+        switch (resource_type)
+        {
+            /* emulate textureLod(sampler2DArrayShadow, ...) using textureGradOffset */
+            case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY:
+                sample_function->emulate_lod = resource_type;
+                grad = offset = TRUE;
+                lod = FALSE;
+                break;
+
+            /* emulate textureLod(samplerCubeShadow, ...) using shadowCubeGrad */
+            case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE:
+                sample_function->emulate_lod = resource_type;
+                grad = legacy_syntax = TRUE;
+                lod = FALSE;
+                break;
+
+            default:
+                break;
+        }
+    }
+
+    if (legacy_syntax)
     {
         if (shadow)
             base = "shadow";
@@ -3327,7 +3331,7 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context
     sample_function->offset_size = offset ? deriv_size : 0;
     sample_function->coord_mask = (1u << coord_size) - 1;
     sample_function->deriv_mask = (1u << deriv_size) - 1;
-    sample_function->output_single_component = shadow && !needs_legacy_glsl_syntax(gl_info);
+    sample_function->output_single_component = shadow && !legacy_syntax;
 }
 
 static void shader_glsl_release_sample_function(const struct wined3d_shader_context *ctx,
@@ -3448,6 +3452,7 @@ static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_
         const char *dx, const char *dy, const char *bias, const struct wined3d_shader_texel_offset *offset,
         const char *coord_reg_fmt, ...)
 {
+    static const struct wined3d_shader_texel_offset dummy_offset = {0, 0, 0};
     const struct wined3d_shader_version *version = &ins->ctx->reg_maps->shader_version;
     char dst_swizzle[6];
     struct color_fixup_desc fixup;
@@ -3516,6 +3521,26 @@ static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_
                 break;
         }
     }
+    if (sample_function->emulate_lod)
+    {
+        if (strcmp(bias, "0")) FIXME("Don't know how to emulate lod level %s\n", bias);
+        switch (sample_function->emulate_lod)
+        {
+            case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY:
+                if (!dx) dx = "vec2(0.0, 0.0)";
+                if (!dy) dy = "vec2(0.0, 0.0)";
+                break;
+
+            case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE:
+                if (!dx) dx = "vec3(0.0, 0.0, 0.0)";
+                if (!dy) dy = "vec3(0.0, 0.0, 0.0)";
+                break;
+
+            default:
+                break;
+        }
+        if (!offset) offset = &dummy_offset;
+    }
     if (dx && dy)
         shader_addline(ins->ctx->buffer, ", %s, %s", dx, dy);
     else if (bias)
@@ -3537,7 +3562,7 @@ static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_
         shader_glsl_color_correction(ins, fixup);
 }
 
-static void shader_glsl_fixup_position(struct wined3d_string_buffer *buffer, BOOL use_viewport_index)
+static void shader_glsl_fixup_position(struct wined3d_string_buffer *buffer)
 {
     /* Write the final position.
      *
@@ -3546,16 +3571,8 @@ static void shader_glsl_fixup_position(struct wined3d_string_buffer *buffer, BOO
      * pos_fixup. pos_fixup.y contains 1.0 or -1.0 to turn the rendering
      * upside down for offscreen rendering. pos_fixup.x contains 1.0 to allow
      * a MAD. */
-    if (use_viewport_index)
-    {
-        shader_addline(buffer, "gl_Position.y = gl_Position.y * pos_fixup[gl_ViewportIndex].y;\n");
-        shader_addline(buffer, "gl_Position.xy += pos_fixup[gl_ViewportIndex].zw * gl_Position.ww;\n");
-    }
-    else
-    {
-        shader_addline(buffer, "gl_Position.y = gl_Position.y * pos_fixup.y;\n");
-        shader_addline(buffer, "gl_Position.xy += pos_fixup.zw * gl_Position.ww;\n");
-    }
+    shader_addline(buffer, "gl_Position.y = gl_Position.y * pos_fixup.y;\n");
+    shader_addline(buffer, "gl_Position.xy += pos_fixup.zw * gl_Position.ww;\n");
 
     /* Z coord [0;1]->[-1;1] mapping, see comment in get_projection_matrix()
      * in utils.c
@@ -4881,11 +4898,10 @@ static void shader_glsl_else(const struct wined3d_shader_instruction *ins)
 static void shader_glsl_emit(const struct wined3d_shader_instruction *ins)
 {
     unsigned int stream = ins->handler_idx == WINED3DSIH_EMIT ? 0 : ins->src[0].reg.idx[0].offset;
-    const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
 
     shader_addline(ins->ctx->buffer, "setup_gs_output(gs_out);\n");
     if (!ins->ctx->gl_info->supported[ARB_CLIP_CONTROL])
-        shader_glsl_fixup_position(ins->ctx->buffer, reg_maps->viewport_array);
+        shader_glsl_fixup_position(ins->ctx->buffer);
 
     if (!stream)
         shader_addline(ins->ctx->buffer, "EmitVertex();\n");
@@ -5740,71 +5756,6 @@ static void shader_glsl_resinfo(const struct wined3d_shader_instruction *ins)
     shader_addline(buffer, ")%s);\n", dst_swizzle);
 }
 
-static void shader_glsl_sample_info(const struct wined3d_shader_instruction *ins)
-{
-    const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
-    const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
-    struct wined3d_string_buffer *buffer = ins->ctx->buffer;
-    const struct wined3d_shader_dst_param *dst = ins->dst;
-    const struct wined3d_shader_src_param *src = ins->src;
-    enum wined3d_shader_resource_type resource_type;
-    enum wined3d_data_type dst_data_type;
-    unsigned int resource_idx, bind_idx;
-    char dst_swizzle[6];
-    DWORD write_mask;
-
-    dst_data_type = dst->reg.data_type;
-    if (ins->flags == WINED3DSI_SAMPLE_INFO_UINT)
-        dst_data_type = WINED3D_DATA_UINT;
-    else if (ins->flags)
-        FIXME("Unhandled flags %#x.\n", ins->flags);
-
-    write_mask = shader_glsl_append_dst_ext(buffer, ins, dst, dst_data_type);
-    shader_glsl_get_swizzle(src, FALSE, write_mask, dst_swizzle);
-
-    if (dst_data_type == WINED3D_DATA_UINT)
-        shader_addline(buffer, "uvec4(");
-    else
-        shader_addline(buffer, "vec4(");
-
-    if (src->reg.type == WINED3DSPR_RASTERIZER)
-    {
-        if (gl_info->supported[ARB_SAMPLE_SHADING])
-        {
-            shader_addline(buffer, "gl_NumSamples");
-        }
-        else
-        {
-            FIXME("OpenGL implementation does not support ARB_sample_shading.\n");
-            shader_addline(buffer, "1");
-        }
-    }
-    else
-    {
-        resource_idx = src->reg.idx[0].offset;
-        resource_type = reg_maps->resource_info[resource_idx].type;
-        if (resource_type >= ARRAY_SIZE(resource_type_info))
-        {
-            ERR("Unexpected resource type %#x.\n", resource_type);
-            return;
-        }
-        bind_idx = shader_glsl_find_sampler(&reg_maps->sampler_map, resource_idx, WINED3D_SAMPLER_DEFAULT);
-
-        if (gl_info->supported[ARB_SHADER_TEXTURE_IMAGE_SAMPLES])
-        {
-            shader_addline(buffer, "textureSamples(%s_sampler%u)",
-                    shader_glsl_get_prefix(reg_maps->shader_version.type), bind_idx);
-        }
-        else
-        {
-            FIXME("textureSamples() is not supported.\n");
-            shader_addline(buffer, "1");
-        }
-    }
-
-    shader_addline(buffer, ", 0, 0, 0)%s);\n", dst_swizzle);
-}
-
 static void shader_glsl_ld(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
@@ -6547,7 +6498,7 @@ static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct w
         semantic_idx = input->semantic_idx;
         shader_glsl_write_mask_to_str(input->mask, reg_mask);
 
-        if (args->vp_mode == WINED3D_VP_MODE_SHADER)
+        if (args->vp_mode == vertexshader)
         {
             if (input->sysval_semantic == WINED3D_SV_POSITION && !semantic_idx)
             {
@@ -6563,14 +6514,6 @@ static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct w
                 shader_addline(buffer, "ps_in[%u]%s = uintBitsToFloat(gl_FrontFacing ? 0xffffffffu : 0u);\n",
                         input->register_idx, reg_mask);
             }
-            else if (input->sysval_semantic == WINED3D_SV_SAMPLE_INDEX)
-            {
-                if (gl_info->supported[ARB_SAMPLE_SHADING])
-                    shader_addline(buffer, "ps_in[%u]%s = intBitsToFloat(gl_SampleID);\n",
-                            input->register_idx, reg_mask);
-                else
-                    FIXME("ARB_sample_shading is not supported.\n");
-            }
             else if (input->sysval_semantic == WINED3D_SV_RENDER_TARGET_ARRAY_INDEX && !semantic_idx)
             {
                 if (gl_info->supported[ARB_FRAGMENT_LAYER_VIEWPORT])
@@ -6579,14 +6522,6 @@ static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct w
                 else
                     FIXME("ARB_fragment_layer_viewport is not supported.\n");
             }
-            else if (input->sysval_semantic == WINED3D_SV_VIEWPORT_ARRAY_INDEX && !semantic_idx)
-            {
-                if (gl_info->supported[ARB_VIEWPORT_ARRAY])
-                    shader_addline(buffer, "ps_in[%u]%s = intBitsToFloat(gl_ViewportIndex);\n",
-                            input->register_idx, reg_mask);
-                else
-                    FIXME("ARB_viewport_array is not supported.\n");
-            }
             else
             {
                 if (input->sysval_semantic)
@@ -6602,7 +6537,7 @@ static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct w
             if (args->pointsprite)
                 shader_addline(buffer, "ps_in[%u] = vec4(gl_PointCoord.xy, 0.0, 0.0);\n",
                         shader->u.ps.input_reg_map[input->register_idx]);
-            else if (args->vp_mode == WINED3D_VP_MODE_NONE && args->texcoords_initialized & (1u << semantic_idx))
+            else if (args->vp_mode == pretransformed && args->texcoords_initialized & (1u << semantic_idx))
                 shader_addline(buffer, "ps_in[%u]%s = %s[%u]%s;\n",
                         shader->u.ps.input_reg_map[input->register_idx], reg_mask,
                         needs_legacy_glsl_syntax(gl_info)
@@ -6878,11 +6813,6 @@ static void shader_glsl_setup_sm3_rasterizer_input(struct shader_glsl_priv *priv
             shader_addline(buffer, "gl_Layer = floatBitsToInt(outputs[%u])%s;\n",
                     output->register_idx, reg_mask);
         }
-        else if (output->sysval_semantic == WINED3D_SV_VIEWPORT_ARRAY_INDEX && !semantic_idx)
-        {
-            shader_addline(buffer, "gl_ViewportIndex = floatBitsToInt(outputs[%u])%s;\n",
-                    output->register_idx, reg_mask);
-        }
         else if (output->sysval_semantic == WINED3D_SV_CLIP_DISTANCE)
         {
             shader_glsl_generate_clip_or_cull_distances(buffer, output, reg_maps_out->clip_distance_mask);
@@ -7307,8 +7237,6 @@ static void shader_glsl_enable_extensions(struct wined3d_string_buffer *buffer,
         shader_addline(buffer, "#extension GL_ARB_shader_image_size : enable\n");
     if (gl_info->supported[ARB_SHADER_STORAGE_BUFFER_OBJECT])
         shader_addline(buffer, "#extension GL_ARB_shader_storage_buffer_object : enable\n");
-    if (gl_info->supported[ARB_SHADER_TEXTURE_IMAGE_SAMPLES])
-        shader_addline(buffer, "#extension GL_ARB_shader_texture_image_samples : enable\n");
     if (gl_info->supported[ARB_SHADING_LANGUAGE_420PACK])
         shader_addline(buffer, "#extension GL_ARB_shading_language_420pack : enable\n");
     if (gl_info->supported[ARB_SHADING_LANGUAGE_PACKING])
@@ -7321,8 +7249,6 @@ static void shader_glsl_enable_extensions(struct wined3d_string_buffer *buffer,
         shader_addline(buffer, "#extension GL_ARB_texture_query_levels : enable\n");
     if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT])
         shader_addline(buffer, "#extension GL_ARB_uniform_buffer_object : enable\n");
-    if (gl_info->supported[ARB_VIEWPORT_ARRAY])
-        shader_addline(buffer, "#extension GL_ARB_viewport_array : enable\n");
     if (gl_info->supported[EXT_GPU_SHADER4])
         shader_addline(buffer, "#extension GL_EXT_gpu_shader4 : enable\n");
     if (gl_info->supported[EXT_TEXTURE_ARRAY])
@@ -7348,9 +7274,6 @@ static void shader_glsl_generate_ps_epilogue(const struct wined3d_gl_info *gl_in
         shader_glsl_generate_fog_code(buffer, gl_info, args->fog);
 
     shader_glsl_generate_alpha_test(buffer, gl_info, args->alpha_test_func + 1);
-
-    if (reg_maps->sample_mask)
-        shader_addline(buffer, "gl_SampleMask[0] = floatBitsToInt(sample_mask);\n");
 }
 
 /* Context activation is done by the caller. */
@@ -7387,8 +7310,6 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
         shader_addline(buffer, "#extension GL_ARB_fragment_coord_conventions : enable\n");
     if (gl_info->supported[ARB_FRAGMENT_LAYER_VIEWPORT])
         shader_addline(buffer, "#extension GL_ARB_fragment_layer_viewport : enable\n");
-    if (gl_info->supported[ARB_SAMPLE_SHADING])
-        shader_addline(buffer, "#extension GL_ARB_sample_shading : enable\n");
     if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
         shader_addline(buffer, "#extension GL_ARB_shader_texture_lod : enable\n");
     /* The spec says that it doesn't have to be explicitly enabled, but the
@@ -7441,7 +7362,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
         shader_addline(buffer, "uniform vec4 %s_samplerNP2Fixup[%u];\n", prefix, fixup->num_consts);
     }
 
-    if (version->major < 3 || args->vp_mode != WINED3D_VP_MODE_SHADER)
+    if (version->major < 3 || args->vp_mode != vertexshader)
     {
         shader_addline(buffer, "uniform struct\n{\n");
         shader_addline(buffer, "    vec4 color;\n");
@@ -7475,7 +7396,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
     {
         unsigned int in_count = min(vec4_varyings(version->major, gl_info), shader->limits->packed_input);
 
-        if (args->vp_mode == WINED3D_VP_MODE_SHADER && reg_maps->input_registers)
+        if (args->vp_mode == vertexshader && reg_maps->input_registers)
             shader_glsl_declare_shader_inputs(gl_info, buffer, in_count,
                     shader->u.ps.interpolation_mode, version->major >= 4);
         shader_addline(buffer, "vec4 %s_in[%u];\n", prefix, in_count);
@@ -7561,9 +7482,6 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
 
     shader_addline(buffer, "void main()\n{\n");
 
-    if (reg_maps->sample_mask)
-        shader_addline(buffer, "float sample_mask = uintBitsToFloat(0xffffffffu);\n");
-
     /* Direct3D applications expect integer vPos values, while OpenGL drivers
      * add approximately 0.5. This causes off-by-one problems as spotted by
      * the vPos d3d9 visual test. Unfortunately ATI cards do not add exactly
@@ -7592,7 +7510,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
                     "vpos = vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1);\n");
     }
 
-    if (reg_maps->shader_version.major < 3 || args->vp_mode != WINED3D_VP_MODE_SHADER)
+    if (reg_maps->shader_version.major < 3 || args->vp_mode != vertexshader)
     {
         unsigned int i;
         WORD map = reg_maps->texcoord;
@@ -7686,7 +7604,7 @@ static void shader_glsl_generate_vs_epilogue(const struct wined3d_gl_info *gl_in
         shader_addline(buffer, "gl_PointSize = clamp(ffp_point.size, ffp_point.size_min, ffp_point.size_max);\n");
 
     if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL])
-        shader_glsl_fixup_position(buffer, FALSE);
+        shader_glsl_fixup_position(buffer);
 }
 
 /* Context activation is done by the caller. */
@@ -7924,7 +7842,7 @@ static void shader_glsl_generate_ds_epilogue(const struct wined3d_gl_info *gl_in
     shader_addline(buffer, "setup_ds_output(ds_out);\n");
 
     if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL])
-        shader_glsl_fixup_position(buffer, FALSE);
+        shader_glsl_fixup_position(buffer);
 }
 
 static GLuint shader_glsl_generate_domain_shader(const struct wined3d_context *context,
@@ -8028,11 +7946,7 @@ static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context
     const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
     struct wined3d_string_buffer *buffer = &priv->shader_buffer;
     const struct wined3d_gl_info *gl_info = context->gl_info;
-    const struct wined3d_shader_signature_element *output;
-    enum wined3d_primitive_type primitive_type;
     struct shader_glsl_ctx_priv priv_ctx;
-    unsigned int max_vertices;
-    unsigned int i, j;
     GLuint shader_id;
 
     memset(&priv_ctx, 0, sizeof(priv_ctx));
@@ -8044,42 +7958,16 @@ static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context
 
     shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx);
 
-    primitive_type = shader->u.gs.input_type ? shader->u.gs.input_type : args->primitive_type;
-    shader_addline(buffer, "layout(%s", glsl_primitive_type_from_d3d(primitive_type));
+    shader_addline(buffer, "layout(%s", glsl_primitive_type_from_d3d(shader->u.gs.input_type));
     if (shader->u.gs.instance_count > 1)
         shader_addline(buffer, ", invocations = %u", shader->u.gs.instance_count);
     shader_addline(buffer, ") in;\n");
-
-    primitive_type = shader->u.gs.output_type ? shader->u.gs.output_type : args->primitive_type;
-    if (!(max_vertices = shader->u.gs.vertices_out))
-    {
-        switch (args->primitive_type)
-        {
-            case WINED3D_PT_POINTLIST:
-                max_vertices = 1;
-                break;
-            case WINED3D_PT_LINELIST:
-                max_vertices = 2;
-                break;
-            case WINED3D_PT_TRIANGLELIST:
-                max_vertices = 3;
-                break;
-            default:
-                FIXME("Unhandled primitive type %s.\n", debug_d3dprimitivetype(args->primitive_type));
-                break;
-        }
-    }
     shader_addline(buffer, "layout(%s, max_vertices = %u) out;\n",
-            glsl_primitive_type_from_d3d(primitive_type), max_vertices);
+            glsl_primitive_type_from_d3d(shader->u.gs.output_type), shader->u.gs.vertices_out);
     shader_addline(buffer, "in shader_in_out { vec4 reg[%u]; } shader_in[];\n", shader->limits->packed_input);
 
     if (!gl_info->supported[ARB_CLIP_CONTROL])
-    {
-        shader_addline(buffer, "uniform vec4 pos_fixup");
-        if (reg_maps->viewport_array)
-            shader_addline(buffer, "[%u]", WINED3D_MAX_VIEWPORTS);
-        shader_addline(buffer, ";\n");
-    }
+        shader_addline(buffer, "uniform vec4 pos_fixup;\n");
 
     if (is_rasterization_disabled(shader))
     {
@@ -8090,29 +7978,9 @@ static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context
         shader_glsl_generate_sm4_output_setup(priv, shader, args->output_count,
                 gl_info, TRUE, args->interpolation_mode);
     }
-
     shader_addline(buffer, "void main()\n{\n");
-    if (shader->function)
-    {
-        if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL)))
-            return 0;
-    }
-    else
-    {
-        for (i = 0; i < max_vertices; ++i)
-        {
-            for (j = 0; j < shader->output_signature.element_count; ++j)
-            {
-                output = &shader->output_signature.elements[j];
-                shader_addline(buffer, "gs_out[%u] = shader_in[%u].reg[%u];\n",
-                        output->register_idx, i, output->register_idx);
-            }
-            shader_addline(buffer, "setup_gs_output(gs_out);\n");
-            if (!gl_info->supported[ARB_CLIP_CONTROL])
-                shader_glsl_fixup_position(buffer, FALSE);
-            shader_addline(buffer, "EmitVertex();\n");
-        }
-    }
+    if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL)))
+        return 0;
     shader_addline(buffer, "}\n");
 
     shader_id = GL_EXTCALL(glCreateShader(GL_GEOMETRY_SHADER));
@@ -9042,7 +8910,7 @@ static const char *shader_glsl_get_ffp_fragment_op_arg(struct wined3d_string_buf
 }
 
 static void shader_glsl_ffp_fragment_op(struct wined3d_string_buffer *buffer, unsigned int stage, BOOL color,
-        BOOL alpha, BOOL tmp_dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2)
+        BOOL alpha, DWORD dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2)
 {
     const char *dstmask, *dstreg, *arg0, *arg1, *arg2;
 
@@ -9053,7 +8921,10 @@ static void shader_glsl_ffp_fragment_op(struct wined3d_string_buffer *buffer, un
     else
         dstmask = ".w";
 
-    dstreg = tmp_dst ? "temp_reg" : "ret";
+    if (dst == tempreg)
+        dstreg = "temp_reg";
+    else
+        dstreg = "ret";
 
     arg0 = shader_glsl_get_ffp_fragment_op_arg(buffer, 0, stage, dw_arg0);
     arg1 = shader_glsl_get_ffp_fragment_op_arg(buffer, 1, stage, dw_arg1);
@@ -9223,7 +9094,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
             tfactor_used = TRUE;
         if (arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP)
             tempreg_used = TRUE;
-        if (settings->op[stage].tmp_dst)
+        if (settings->op[stage].dst == tempreg)
             tempreg_used = TRUE;
         if (arg0 == WINED3DTA_CONSTANT || arg1 == WINED3DTA_CONSTANT || arg2 == WINED3DTA_CONSTANT)
             tss_const_map |= 1u << stage;
@@ -9419,12 +9290,12 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
         if (!(tex_map & (1u << stage)))
             continue;
 
-        if (settings->op[stage].projected == WINED3D_PROJECTION_NONE)
+        if (settings->op[stage].projected == proj_none)
         {
             proj = FALSE;
         }
-        else if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT4
-                || settings->op[stage].projected == WINED3D_PROJECTION_COUNT3)
+        else if (settings->op[stage].projected == proj_count4
+                || settings->op[stage].projected == proj_count3)
         {
             proj = TRUE;
         }
@@ -9507,12 +9378,12 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
             shader_addline(buffer, "ret.xy = bumpenv_mat%u * tex%u.xy;\n", stage - 1, stage - 1);
 
             /* With projective textures, texbem only divides the static
-             * texture coordinate, not the displacement, so multiply the
+             * texture coord, not the displacement, so multiply the
              * displacement with the dividing parameter before passing it to
              * TXP. */
-            if (settings->op[stage].projected != WINED3D_PROJECTION_NONE)
+            if (settings->op[stage].projected != proj_none)
             {
-                if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT4)
+                if (settings->op[stage].projected == proj_count4)
                 {
                     shader_addline(buffer, "ret.xy = (ret.xy * ffp_texcoord[%u].w) + ffp_texcoord[%u].xy;\n",
                             stage, stage);
@@ -9537,7 +9408,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
                 shader_addline(buffer, "tex%u *= clamp(tex%u.z * bumpenv_lum_scale%u + bumpenv_lum_offset%u, 0.0, 1.0);\n",
                         stage, stage - 1, stage - 1, stage - 1);
         }
-        else if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT3)
+        else if (settings->op[stage].projected == proj_count3)
         {
             shader_addline(buffer, "tex%u = %s(ps_sampler%u, ffp_texcoord[%u].xyz);\n",
                     stage, texture_function, stage, stage);
@@ -9589,23 +9460,23 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
 
         if (settings->op[stage].aop == WINED3D_TOP_DISABLE)
         {
-            shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].tmp_dst,
+            shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].dst,
                     settings->op[stage].cop, settings->op[stage].carg0,
                     settings->op[stage].carg1, settings->op[stage].carg2);
         }
         else if (op_equal)
         {
-            shader_glsl_ffp_fragment_op(buffer, stage, TRUE, TRUE, settings->op[stage].tmp_dst,
+            shader_glsl_ffp_fragment_op(buffer, stage, TRUE, TRUE, settings->op[stage].dst,
                     settings->op[stage].cop, settings->op[stage].carg0,
                     settings->op[stage].carg1, settings->op[stage].carg2);
         }
         else if (settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP
                 && settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP_LUMINANCE)
         {
-            shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].tmp_dst,
+            shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].dst,
                     settings->op[stage].cop, settings->op[stage].carg0,
                     settings->op[stage].carg1, settings->op[stage].carg2);
-            shader_glsl_ffp_fragment_op(buffer, stage, FALSE, TRUE, settings->op[stage].tmp_dst,
+            shader_glsl_ffp_fragment_op(buffer, stage, FALSE, TRUE, settings->op[stage].dst,
                     settings->op[stage].aop, settings->op[stage].aarg0,
                     settings->op[stage].aarg1, settings->op[stage].aarg2);
         }
@@ -10905,7 +10776,6 @@ static unsigned int shader_glsl_get_shader_model(const struct wined3d_gl_info *g
             && gl_info->supported[ARB_SHADER_IMAGE_SIZE]
             && gl_info->supported[ARB_SHADING_LANGUAGE_PACKING]
             && gl_info->supported[ARB_TESSELLATION_SHADER]
-            && gl_info->supported[ARB_TEXTURE_COMPRESSION_BPTC]
             && gl_info->supported[ARB_TEXTURE_GATHER]
             && gl_info->supported[ARB_TRANSFORM_FEEDBACK3])
         return 5;
@@ -11163,7 +11033,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
     /* WINED3DSIH_SAMPLE_C                         */ shader_glsl_sample_c,
     /* WINED3DSIH_SAMPLE_C_LZ                      */ shader_glsl_sample_c,
     /* WINED3DSIH_SAMPLE_GRAD                      */ shader_glsl_sample,
-    /* WINED3DSIH_SAMPLE_INFO                      */ shader_glsl_sample_info,
+    /* WINED3DSIH_SAMPLE_INFO                      */ NULL,
     /* WINED3DSIH_SAMPLE_LOD                       */ shader_glsl_sample,
     /* WINED3DSIH_SAMPLE_POS                       */ NULL,
     /* WINED3DSIH_SETP                             */ NULL,
@@ -12108,854 +11978,3 @@ const struct fragment_pipeline glsl_fragment_pipe =
     shader_glsl_color_fixup_supported,
     glsl_fragment_pipe_state_template,
 };
-
-struct glsl_blitter_args
-{
-    GLenum texture_type;
-    struct color_fixup_desc fixup;
-    unsigned short padding;
-};
-
-struct glsl_blitter_program
-{
-    struct wine_rb_entry entry;
-    struct glsl_blitter_args args;
-    GLuint id;
-};
-
-struct wined3d_glsl_blitter
-{
-    struct wined3d_blitter blitter;
-    struct wined3d_string_buffer_list string_buffers;
-    struct wine_rb_tree programs;
-    GLuint palette_texture;
-};
-
-static int glsl_blitter_args_compare(const void *key, const struct wine_rb_entry *entry)
-{
-    const struct glsl_blitter_args *a = key;
-    const struct glsl_blitter_args *b = &WINE_RB_ENTRY_VALUE(entry, const struct glsl_blitter_program, entry)->args;
-
-    return memcmp(a, b, sizeof(*a));
-}
-
-/* Context activation is done by the caller. */
-static void glsl_free_blitter_program(struct wine_rb_entry *entry, void *ctx)
-{
-    struct glsl_blitter_program *program = WINE_RB_ENTRY_VALUE(entry, struct glsl_blitter_program, entry);
-    struct wined3d_context *context = ctx;
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-
-    GL_EXTCALL(glDeleteProgram(program->id));
-    checkGLcall("glDeleteProgram()");
-    heap_free(program);
-}
-
-/* Context activation is done by the caller. */
-static void glsl_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_context *context)
-{
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    struct wined3d_glsl_blitter *glsl_blitter;
-    struct wined3d_blitter *next;
-
-    if ((next = blitter->next))
-        next->ops->blitter_destroy(next, context);
-
-    glsl_blitter = CONTAINING_RECORD(blitter, struct wined3d_glsl_blitter, blitter);
-
-    if (glsl_blitter->palette_texture)
-        gl_info->gl_ops.gl.p_glDeleteTextures(1, &glsl_blitter->palette_texture);
-
-    wine_rb_destroy(&glsl_blitter->programs, glsl_free_blitter_program, context);
-    string_buffer_list_cleanup(&glsl_blitter->string_buffers);
-
-    heap_free(glsl_blitter);
-}
-
-static void glsl_blitter_generate_p8_shader(struct wined3d_string_buffer *buffer,
-        const struct wined3d_gl_info *gl_info, const struct glsl_blitter_args *args,
-        const char *output, const char *tex_type, const char *swizzle)
-{
-    shader_addline(buffer, "uniform sampler1D sampler_palette;\n");
-    shader_addline(buffer, "\nvoid main()\n{\n");
-    /* The alpha-component contains the palette index. */
-    shader_addline(buffer, "    float index = texture%s(sampler, out_texcoord.%s).%c;\n",
-            needs_legacy_glsl_syntax(gl_info) ? tex_type : "", swizzle,
-            gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'x');
-    /* Scale the index by 255/256 and add a bias of 0.5 in order to sample in
-     * the middle. */
-    shader_addline(buffer, "    index = (index * 255.0 + 0.5) / 256.0;\n");
-    shader_addline(buffer, "    %s = texture%s(sampler_palette, index);\n",
-            output, needs_legacy_glsl_syntax(gl_info) ? "1D" : "");
-    shader_addline(buffer, "}\n");
-}
-
-static void gen_packed_yuv_read(struct wined3d_string_buffer *buffer,
-        const struct wined3d_gl_info *gl_info, const struct glsl_blitter_args *args,
-        const char *tex_type)
-{
-    enum complex_fixup complex_fixup = get_complex_fixup(args->fixup);
-    char chroma, luminance;
-    const char *tex;
-
-    /* The YUY2 and UYVY formats contain two pixels packed into a 32 bit
-     * macropixel, giving effectively 16 bits per pixel. The color consists of
-     * a luminance(Y) and two chroma(U and V) values. Each macropixel has two
-     * luminance values, one for each single pixel it contains, and one U and
-     * one V value shared between both pixels.
-     *
-     * The data is loaded into an A8L8 texture. With YUY2, the luminance
-     * component contains the luminance and alpha the chroma. With UYVY it is
-     * vice versa. Thus take the format into account when generating the read
-     * swizzles
-     *
-     * Reading the Y value is straightforward - just sample the texture. The
-     * hardware takes care of filtering in the horizontal and vertical
-     * direction.
-     *
-     * Reading the U and V values is harder. We have to avoid filtering
-     * horizontally, because that would mix the U and V values of one pixel or
-     * two adjacent pixels.  Thus floor the texture coordinate and add 0.5 to
-     * get an unfiltered read, regardless of the filtering setting. Vertical
-     * filtering works automatically though - the U and V values of two rows
-     * are mixed nicely.
-     *
-     * Apart of avoiding filtering issues, the code has to know which value it
-     * just read, and where it can find the other one. To determine this, it
-     * checks if it sampled an even or odd pixel, and shifts the 2nd read
-     * accordingly.
-     *
-     * Handling horizontal filtering of U and V values requires reading a 2nd
-     * pair of pixels, extracting U and V and mixing them. This is not
-     * implemented yet.
-     *
-     * An alternative implementation idea is to load the texture as A8R8G8B8
-     * texture, with width / 2. This way one read gives all 3 values, finding
-     * U and V is easy in an unfiltered situation. Finding the luminance on
-     * the other hand requires finding out if it is an odd or even pixel. The
-     * real drawback of this approach is filtering. This would have to be
-     * emulated completely in the shader, reading up two 2 packed pixels in up
-     * to 2 rows and interpolating both horizontally and vertically. Beyond
-     * that it would require adjustments to the texture handling code to deal
-     * with the width scaling. */
-
-    if (complex_fixup == COMPLEX_FIXUP_UYVY)
-    {
-        chroma = 'x';
-        luminance = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'y';
-    }
-    else
-    {
-        chroma = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'y';
-        luminance = 'x';
-    }
-
-    tex = needs_legacy_glsl_syntax(gl_info) ? tex_type : "";
-
-    /* First we have to read the chroma values. This means we need at least
-     * two pixels (no filtering), or 4 pixels (with filtering). To get the
-     * unmodified chroma, we have to rid ourselves of the filtering when we
-     * sample the texture. */
-    shader_addline(buffer, "    texcoord.xy = out_texcoord.xy;\n");
-    /* We must not allow filtering between pixel x and x+1, this would mix U
-     * and V. Vertical filtering is ok. However, bear in mind that the pixel
-     * center is at 0.5, so add 0.5. */
-    shader_addline(buffer, "    texcoord.x = (floor(texcoord.x * size.x) + 0.5) / size.x;\n");
-    shader_addline(buffer, "    luminance = texture%s(sampler, texcoord.xy).%c;\n", tex, chroma);
-
-    /* Multiply the x coordinate by 0.5 and get the fraction. This gives 0.25
-     * and 0.75 for the even and odd pixels respectively. */
-    /* Put the value into either of the chroma values. */
-    shader_addline(buffer, "    bool even = fract(texcoord.x * size.x * 0.5) < 0.5;\n");
-    shader_addline(buffer, "    if (even)\n");
-    shader_addline(buffer, "        chroma.y = luminance;\n");
-    shader_addline(buffer, "    else\n");
-    shader_addline(buffer, "        chroma.x = luminance;\n");
-
-    /* Sample pixel 2. If we read an even pixel, sample the pixel right to the
-     * current one. Otherwise, sample the left pixel. */
-    shader_addline(buffer, "    texcoord.x += even ? 1.0 / size.x : -1.0 / size.x;\n");
-    shader_addline(buffer, "    luminance = texture%s(sampler, texcoord.xy).%c;\n", tex, chroma);
-
-    /* Put the value into the other chroma. */
-    shader_addline(buffer, "    if (even)\n");
-    shader_addline(buffer, "        chroma.x = luminance;\n");
-    shader_addline(buffer, "    else\n");
-    shader_addline(buffer, "        chroma.y = luminance;\n");
-
-    /* TODO: If filtering is enabled, sample a 2nd pair of pixels left or right of
-     * the current one and lerp the two U and V values. */
-
-    /* This gives the correctly filtered luminance value. */
-    shader_addline(buffer, "    luminance = texture%s(sampler, out_texcoord.xy).%c;\n", tex, luminance);
-}
-
-static void gen_yv12_read(struct wined3d_string_buffer *buffer,
-        const struct wined3d_gl_info *gl_info, const char *tex_type)
-{
-    char component = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'x';
-    const char *tex = needs_legacy_glsl_syntax(gl_info) ? tex_type : "";
-
-    /* YV12 surfaces contain a WxH sized luminance plane, followed by a
-     * (W/2)x(H/2) V and a (W/2)x(H/2) U plane, each with 8 bit per pixel. So
-     * the effective bitdepth is 12 bits per pixel. Since the U and V planes
-     * have only half the pitch of the luminance plane, the packing into the
-     * gl texture is a bit unfortunate. If the whole texture is interpreted as
-     * luminance data it looks approximately like this:
-     *
-     *        +----------------------------------+----
-     *        |                                  |
-     *        |                                  |
-     *        |                                  |
-     *        |                                  |
-     *        |                                  |   2
-     *        |            LUMINANCE             |   -
-     *        |                                  |   3
-     *        |                                  |
-     *        |                                  |
-     *        |                                  |
-     *        |                                  |
-     *        +----------------+-----------------+----
-     *        |                |                 |
-     *        |  V even rows   |  V odd rows     |
-     *        |                |                 |   1
-     *        +----------------+------------------   -
-     *        |                |                 |   3
-     *        |  U even rows   |  U odd rows     |
-     *        |                |                 |
-     *        +----------------+-----------------+----
-     *        |                |                 |
-     *        |     0.5        |       0.5       |
-     *
-     * So it appears as if there are 4 chroma images, but in fact the odd rows
-     * in the chroma images are in the same row as the even ones. So it is
-     * kinda tricky to read. */
-
-    /* First sample the chroma values. */
-    shader_addline(buffer, "    texcoord.xy = out_texcoord.xy;\n");
-    /* The chroma planes have only half the width. */
-    shader_addline(buffer, "    texcoord.x *= 0.5;\n");
-
-    /* The first value is between 2/3 and 5/6 of the texture's height, so
-     * scale+bias the coordinate. Also read the right side of the image when
-     * reading odd lines.
-     *
-     * Don't forget to clamp the y values in into the range, otherwise we'll
-     * get filtering bleeding. */
-
-    /* Read odd lines from the right side (add 0.5 to the x coordinate). */
-    shader_addline(buffer, "    if (fract(floor(texcoord.y * size.y) * 0.5 + 1.0 / 6.0) >= 0.5)\n");
-    shader_addline(buffer, "        texcoord.x += 0.5;\n");
-
-    /* Clamp, keep the half pixel origin in mind. */
-    shader_addline(buffer, "    texcoord.y = clamp(2.0 / 3.0 + texcoord.y / 6.0, "
-            "2.0 / 3.0 + 0.5 / size.y, 5.0 / 6.0 - 0.5 / size.y);\n");
-
-    shader_addline(buffer, "    chroma.x = texture%s(sampler, texcoord.xy).%c;\n", tex, component);
-
-    /* The other chroma value is 1/6th of the texture lower, from 5/6th to
-     * 6/6th No need to clamp because we're just reusing the already clamped
-     * value from above. */
-    shader_addline(buffer, "    texcoord.y += 1.0 / 6.0;\n");
-    shader_addline(buffer, "    chroma.y = texture%s(sampler, texcoord.xy).%c;\n", tex, component);
-
-    /* Sample the luminance value. It is in the top 2/3rd of the texture, so
-     * scale the y coordinate.  Clamp the y coordinate to prevent the chroma
-     * values from bleeding into the sampled luminance values due to
-     * filtering. */
-    shader_addline(buffer, "    texcoord.xy = out_texcoord.xy;\n");
-    /* Multiply the y coordinate by 2/3 and clamp it. */
-    shader_addline(buffer, "    texcoord.y = min(texcoord.y * 2.0 / 3.0, 2.0 / 3.0 - 0.5 / size.y);\n");
-    shader_addline(buffer, "    luminance = texture%s(sampler, texcoord.xy).%c;\n", tex, component);
-}
-
-static void gen_nv12_read(struct wined3d_string_buffer *buffer,
-        const struct wined3d_gl_info *gl_info, const char *tex_type)
-{
-    char component = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'x';
-    const char *tex = needs_legacy_glsl_syntax(gl_info) ? tex_type : "";
-
-    /* NV12 surfaces contain a WxH sized luminance plane, followed by a
-     * (W/2)x(H/2) sized plane where each component is an UV pair. So the
-     * effective bitdepth is 12 bits per pixel. If the whole texture is
-     * interpreted as luminance data it looks approximately like this:
-     *
-     *        +----------------------------------+----
-     *        |                                  |
-     *        |                                  |
-     *        |                                  |
-     *        |                                  |
-     *        |                                  |   2
-     *        |            LUMINANCE             |   -
-     *        |                                  |   3
-     *        |                                  |
-     *        |                                  |
-     *        |                                  |
-     *        |                                  |
-     *        +----------------------------------+----
-     *        |UVUVUVUVUVUVUVUVUVUVUVUVUVUVUVUVUV|
-     *        |UVUVUVUVUVUVUVUVUVUVUVUVUVUVUVUVUV|
-     *        |                                  |   1
-     *        |                                  |   -
-     *        |                                  |   3
-     *        |                                  |
-     *        |                                  |
-     *        +----------------------------------+---- */
-
-    /* First sample the chroma values. */
-    shader_addline(buffer, "    texcoord.xy = out_texcoord.xy;\n");
-    /* We only have half the number of chroma pixels. */
-    shader_addline(buffer, "    texcoord.x *= 0.5;\n");
-    shader_addline(buffer, "    texcoord.y = (texcoord.y + 2.0) / 3.0;\n");
-
-    /* We must not allow filtering horizontally, this would mix U and V.
-     * Vertical filtering is ok. However, bear in mind that the pixel center
-     * is at 0.5, so add 0.5. */
-
-    /* Convert to non-normalised coordinates so we can find the individual
-     * pixel. */
-    shader_addline(buffer, "    texcoord.x = floor(texcoord.x * size.x);\n");
-    /* Multiply by 2 since chroma components are stored in UV pixel pairs, add
-     * 0.5 to hit the center of the pixel. Then convert back to normalised
-     * coordinates. */
-    shader_addline(buffer, "    texcoord.x = (texcoord.x * 2.0 + 0.5) / size.x;\n");
-    /* Clamp, keep the half pixel origin in mind. */
-    shader_addline(buffer, "    texcoord.y = max(texcoord.y, 2.0 / 3.0 + 0.5 / size.y);\n");
-
-    shader_addline(buffer, "    chroma.y = texture%s(sampler, texcoord.xy).%c;\n", tex, component);
-    /* Add 1.0 / size.x to sample the adjacent texel. */
-    shader_addline(buffer, "    texcoord.x += 1.0 / size.x;\n");
-    shader_addline(buffer, "    chroma.x = texture%s(sampler, texcoord.xy).%c;\n", tex, component);
-
-    /* Sample the luminance value. It is in the top 2/3rd of the texture, so
-     * scale the y coordinate. Clamp the y coordinate to prevent the chroma
-     * values from bleeding into the sampled luminance values due to
-     * filtering. */
-    shader_addline(buffer, "    texcoord.xy = out_texcoord.xy;\n");
-    /* Multiply the y coordinate by 2/3 and clamp it. */
-    shader_addline(buffer, "    texcoord.y = min(texcoord.y * 2.0 / 3.0, 2.0 / 3.0 - 0.5 / size.y);\n");
-    shader_addline(buffer, "    luminance = texture%s(sampler, texcoord.xy).%c;\n", tex, component);
-}
-
-static void glsl_blitter_generate_yuv_shader(struct wined3d_string_buffer *buffer,
-        const struct wined3d_gl_info *gl_info, const struct glsl_blitter_args *args,
-        const char *output, const char *tex_type, const char *swizzle)
-{
-    enum complex_fixup complex_fixup = get_complex_fixup(args->fixup);
-
-    shader_addline(buffer, "const vec4 yuv_coef = vec4(1.403, -0.344, -0.714, 1.770);\n");
-    shader_addline(buffer, "float luminance;\n");
-    shader_addline(buffer, "vec2 texcoord;\n");
-    shader_addline(buffer, "vec2 chroma;\n");
-    shader_addline(buffer, "uniform vec2 size;\n");
-
-    shader_addline(buffer, "\nvoid main()\n{\n");
-
-    switch (complex_fixup)
-    {
-        case COMPLEX_FIXUP_UYVY:
-        case COMPLEX_FIXUP_YUY2:
-            gen_packed_yuv_read(buffer, gl_info, args, tex_type);
-            break;
-
-        case COMPLEX_FIXUP_YV12:
-            gen_yv12_read(buffer, gl_info, tex_type);
-            break;
-
-        case COMPLEX_FIXUP_NV12:
-            gen_nv12_read(buffer, gl_info, tex_type);
-            break;
-
-        default:
-            FIXME("Unsupported fixup %#x.\n", complex_fixup);
-            string_buffer_free(buffer);
-            return;
-    }
-
-    /* Calculate the final result. Formula is taken from
-     * http://www.fourcc.org/fccyvrgb.php. Note that the chroma
-     * ranges from -0.5 to 0.5. */
-    shader_addline(buffer, "\n    chroma.xy -= 0.5;\n");
-
-    shader_addline(buffer, "    %s.x = luminance + chroma.x * yuv_coef.x;\n", output);
-    shader_addline(buffer, "    %s.y = luminance + chroma.y * yuv_coef.y + chroma.x * yuv_coef.z;\n", output);
-    shader_addline(buffer, "    %s.z = luminance + chroma.y * yuv_coef.w;\n", output);
-
-    shader_addline(buffer, "}\n");
-}
-
-static void glsl_blitter_generate_plain_shader(struct wined3d_string_buffer *buffer,
-        const struct wined3d_gl_info *gl_info, const struct glsl_blitter_args *args,
-        const char *output, const char *tex_type, const char *swizzle)
-{
-    shader_addline(buffer, "\nvoid main()\n{\n");
-    shader_addline(buffer, "    %s = texture%s(sampler, out_texcoord.%s);\n",
-            output, needs_legacy_glsl_syntax(gl_info) ? tex_type : "", swizzle);
-    shader_glsl_color_correction_ext(buffer, output, WINED3DSP_WRITEMASK_ALL, args->fixup);
-    shader_addline(buffer, "}\n");
-}
-
-/* Context activation is done by the caller. */
-static GLuint glsl_blitter_generate_program(struct wined3d_glsl_blitter *blitter,
-        const struct wined3d_gl_info *gl_info, const struct glsl_blitter_args *args)
-{
-    static const struct
-    {
-        GLenum texture_target;
-        const char texture_type[7];
-        const char texcoord_swizzle[4];
-    }
-    texture_data[] =
-    {
-        {GL_TEXTURE_2D, "2D", "xy"},
-        {GL_TEXTURE_CUBE_MAP, "Cube", "xyz"},
-        {GL_TEXTURE_RECTANGLE_ARB, "2DRect", "xy"},
-    };
-    static const char vshader_main[] =
-        "\n"
-        "void main()\n"
-        "{\n"
-        "    gl_Position = vec4(pos, 0.0, 1.0);\n"
-        "    out_texcoord = texcoord;\n"
-        "}\n";
-    enum complex_fixup complex_fixup = get_complex_fixup(args->fixup);
-    struct wined3d_string_buffer *buffer, *output;
-    GLuint program, vshader_id, fshader_id;
-    const char *tex_type, *swizzle, *ptr;
-    unsigned int i;
-    GLint loc;
-
-    for (i = 0; i < ARRAY_SIZE(texture_data); ++i)
-    {
-        if (args->texture_type == texture_data[i].texture_target)
-        {
-            tex_type = texture_data[i].texture_type;
-            swizzle = texture_data[i].texcoord_swizzle;
-            break;
-        }
-    }
-    if (i == ARRAY_SIZE(texture_data))
-    {
-        FIXME("Unsupported texture type %#x.\n", args->texture_type);
-        return 0;
-    }
-
-    program = GL_EXTCALL(glCreateProgram());
-
-    vshader_id = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER));
-
-    buffer = string_buffer_get(&blitter->string_buffers);
-    shader_glsl_add_version_declaration(buffer, gl_info);
-    shader_addline(buffer, "%s vec2 pos;\n", get_attribute_keyword(gl_info));
-    shader_addline(buffer, "%s vec3 texcoord;\n", get_attribute_keyword(gl_info));
-    declare_out_varying(gl_info, buffer, FALSE, "vec3 out_texcoord;\n");
-    shader_addline(buffer, vshader_main);
-
-    ptr = buffer->buffer;
-    GL_EXTCALL(glShaderSource(vshader_id, 1, &ptr, NULL));
-    GL_EXTCALL(glAttachShader(program, vshader_id));
-    GL_EXTCALL(glDeleteShader(vshader_id));
-
-    fshader_id = GL_EXTCALL(glCreateShader(GL_FRAGMENT_SHADER));
-
-    string_buffer_clear(buffer);
-    shader_glsl_add_version_declaration(buffer, gl_info);
-    shader_addline(buffer, "uniform sampler%s sampler;\n", tex_type);
-    declare_in_varying(gl_info, buffer, FALSE, "vec3 out_texcoord;\n");
-    if (!needs_legacy_glsl_syntax(gl_info))
-        shader_addline(buffer, "out vec4 ps_out[1];\n");
-
-    output = string_buffer_get(&blitter->string_buffers);
-    string_buffer_sprintf(output, "%s[0]", get_fragment_output(gl_info));
-
-    switch (complex_fixup)
-    {
-        case COMPLEX_FIXUP_P8:
-            glsl_blitter_generate_p8_shader(buffer, gl_info, args, output->buffer, tex_type, swizzle);
-            break;
-        case COMPLEX_FIXUP_YUY2:
-        case COMPLEX_FIXUP_UYVY:
-        case COMPLEX_FIXUP_YV12:
-        case COMPLEX_FIXUP_NV12:
-            glsl_blitter_generate_yuv_shader(buffer, gl_info, args, output->buffer, tex_type, swizzle);
-            break;
-        case COMPLEX_FIXUP_NONE:
-            glsl_blitter_generate_plain_shader(buffer, gl_info, args, output->buffer, tex_type, swizzle);
-    }
-
-    string_buffer_release(&blitter->string_buffers, output);
-
-    ptr = buffer->buffer;
-    GL_EXTCALL(glShaderSource(fshader_id, 1, &ptr, NULL));
-    string_buffer_release(&blitter->string_buffers, buffer);
-    GL_EXTCALL(glAttachShader(program, fshader_id));
-    GL_EXTCALL(glDeleteShader(fshader_id));
-
-    GL_EXTCALL(glBindAttribLocation(program, 0, "pos"));
-    GL_EXTCALL(glBindAttribLocation(program, 1, "texcoord"));
-
-    if (!needs_legacy_glsl_syntax(gl_info))
-        GL_EXTCALL(glBindFragDataLocation(program, 0, "ps_out"));
-
-    GL_EXTCALL(glCompileShader(vshader_id));
-    print_glsl_info_log(gl_info, vshader_id, FALSE);
-    GL_EXTCALL(glCompileShader(fshader_id));
-    print_glsl_info_log(gl_info, fshader_id, FALSE);
-    GL_EXTCALL(glLinkProgram(program));
-    shader_glsl_validate_link(gl_info, program);
-
-    GL_EXTCALL(glUseProgram(program));
-    loc = GL_EXTCALL(glGetUniformLocation(program, "sampler"));
-    GL_EXTCALL(glUniform1i(loc, 0));
-    if (complex_fixup == COMPLEX_FIXUP_P8)
-    {
-        loc = GL_EXTCALL(glGetUniformLocation(program, "sampler_palette"));
-        GL_EXTCALL(glUniform1i(loc, 1));
-    }
-
-    return program;
-}
-
-/* Context activation is done by the caller. */
-static void glsl_blitter_upload_palette(struct wined3d_glsl_blitter *blitter,
-        struct wined3d_context *context, const struct wined3d_texture *texture)
-{
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    const struct wined3d_palette *palette;
-
-    palette = texture->swapchain ? texture->swapchain->palette : NULL;
-
-    if (!blitter->palette_texture)
-        gl_info->gl_ops.gl.p_glGenTextures(1, &blitter->palette_texture);
-
-    context_active_texture(context, gl_info, 1);
-    gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, blitter->palette_texture);
-    gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-
-    if (palette)
-    {
-        gl_info->gl_ops.gl.p_glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 256, 0, GL_BGRA,
-                GL_UNSIGNED_INT_8_8_8_8_REV, palette->colors);
-    }
-    else
-    {
-        static const DWORD black;
-
-        FIXME("P8 texture loaded without a palette.\n");
-        gl_info->gl_ops.gl.p_glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 1, 0, GL_BGRA,
-                GL_UNSIGNED_INT_8_8_8_8_REV, &black);
-    }
-
-    context_active_texture(context, gl_info, 0);
-}
-
-/* Context activation is done by the caller. */
-static struct glsl_blitter_program *glsl_blitter_get_program(struct wined3d_glsl_blitter *blitter,
-        struct wined3d_context *context, const struct wined3d_texture *texture)
-{
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    struct glsl_blitter_program *program;
-    struct glsl_blitter_args args;
-    struct wine_rb_entry *entry;
-
-    memset(&args, 0, sizeof(args));
-    args.texture_type = texture->target;
-    args.fixup = texture->resource.format->color_fixup;
-
-    if ((entry = wine_rb_get(&blitter->programs, &args)))
-        return WINE_RB_ENTRY_VALUE(entry, struct glsl_blitter_program, entry);
-
-    if (!(program = heap_alloc(sizeof(*program))))
-    {
-        ERR("Failed to allocate blitter program memory.\n");
-        return NULL;
-    }
-
-    program->args = args;
-    if (!(program->id = glsl_blitter_generate_program(blitter, gl_info, &args)))
-    {
-        WARN("Failed to generate blitter program.\n");
-        heap_free(program);
-        return NULL;
-    }
-
-    if (wine_rb_put(&blitter->programs, &program->args, &program->entry) == -1)
-    {
-        ERR("Failed to store blitter program.\n");
-        GL_EXTCALL(glDeleteProgram(program->id));
-        heap_free(program);
-        return NULL;
-    }
-
-    return program;
-}
-
-static BOOL glsl_blitter_supported(enum wined3d_blit_op blit_op, const struct wined3d_context *context,
-        const struct wined3d_texture *src_texture, DWORD src_location,
-        const struct wined3d_texture *dst_texture, DWORD dst_location)
-{
-    const struct wined3d_resource *src_resource = &src_texture->resource;
-    const struct wined3d_resource *dst_resource = &dst_texture->resource;
-    const struct wined3d_format *src_format = src_resource->format;
-    const struct wined3d_format *dst_format = dst_resource->format;
-    BOOL decompress;
-
-    if (blit_op == WINED3D_BLIT_OP_RAW_BLIT && dst_format->id == src_format->id)
-    {
-        if (dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
-            blit_op = WINED3D_BLIT_OP_DEPTH_BLIT;
-        else
-            blit_op = WINED3D_BLIT_OP_COLOR_BLIT;
-    }
-
-    if (blit_op != WINED3D_BLIT_OP_COLOR_BLIT)
-    {
-        TRACE("Unsupported blit_op %#x.\n", blit_op);
-        return FALSE;
-    }
-
-    if (src_resource->type != WINED3D_RTYPE_TEXTURE_2D)
-        return FALSE;
-
-    if (src_texture->target == GL_TEXTURE_2D_MULTISAMPLE
-            || dst_texture->target == GL_TEXTURE_2D_MULTISAMPLE
-            || src_texture->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY
-            || dst_texture->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
-    {
-        TRACE("Multi-sample textures not supported.\n");
-        return FALSE;
-    }
-
-    /* We don't necessarily want to blit from resources without
-     * WINED3D_RESOURCE_ACCESS_GPU, but that may be the only way to decompress
-     * compressed textures. */
-    decompress = src_format && (src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED)
-            && !(dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED);
-    if (!decompress && !(src_resource->access & dst_resource->access & WINED3D_RESOURCE_ACCESS_GPU))
-    {
-        TRACE("Source or destination resource does not have GPU access.\n");
-        return FALSE;
-    }
-
-    if (!is_identity_fixup(dst_format->color_fixup)
-            && (dst_format->id != src_format->id || dst_location != WINED3D_LOCATION_DRAWABLE))
-    {
-        TRACE("Destination fixups are not supported.\n");
-        return FALSE;
-    }
-
-    TRACE("Returning supported.\n");
-    return TRUE;
-}
-
-static DWORD glsl_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op,
-        struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx,
-        DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture,
-        unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect,
-        const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter)
-{
-    struct wined3d_device *device = dst_texture->resource.device;
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    struct wined3d_texture *staging_texture = NULL;
-    struct wined3d_glsl_blitter *glsl_blitter;
-    struct glsl_blitter_program *program;
-    struct wined3d_blitter *next;
-    unsigned int src_level;
-    GLint location;
-    RECT s, d;
-
-    TRACE("blitter %p, op %#x, context %p, src_texture %p, src_sub_resource_idx %u, src_location %s, src_rect %s, "
-            "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s.\n",
-            blitter, op, context, src_texture, src_sub_resource_idx, wined3d_debug_location(src_location),
-            wine_dbgstr_rect(src_rect), dst_texture, dst_sub_resource_idx, wined3d_debug_location(dst_location),
-            wine_dbgstr_rect(dst_rect), colour_key, debug_d3dtexturefiltertype(filter));
-
-    if (!glsl_blitter_supported(op, context, src_texture, src_location, dst_texture, dst_location))
-    {
-        if (!(next = blitter->next))
-        {
-            ERR("No blitter to handle blit op %#x.\n", op);
-            return dst_location;
-        }
-
-        TRACE("Forwarding to blitter %p.\n", next);
-        return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location,
-                src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, colour_key, filter);
-    }
-
-    glsl_blitter = CONTAINING_RECORD(blitter, struct wined3d_glsl_blitter, blitter);
-
-    if (!(src_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU))
-    {
-        struct wined3d_resource_desc desc;
-        struct wined3d_box upload_box;
-        HRESULT hr;
-
-        TRACE("Source texture is not GPU accessible, creating a staging texture.\n");
-
-        src_level = src_sub_resource_idx % src_texture->level_count;
-        desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
-        desc.format = src_texture->resource.format->id;
-        desc.multisample_type = src_texture->resource.multisample_type;
-        desc.multisample_quality = src_texture->resource.multisample_quality;
-        desc.usage = WINED3DUSAGE_PRIVATE;
-        desc.access = WINED3D_RESOURCE_ACCESS_GPU;
-        desc.width = wined3d_texture_get_level_width(src_texture, src_level);
-        desc.height = wined3d_texture_get_level_height(src_texture, src_level);
-        desc.depth = 1;
-        desc.size = 0;
-
-        if (FAILED(hr = wined3d_texture_create(device, &desc, 1, 1, 0,
-                NULL, NULL, &wined3d_null_parent_ops, &staging_texture)))
-        {
-            ERR("Failed to create staging texture, hr %#x.\n", hr);
-            return dst_location;
-        }
-
-        wined3d_box_set(&upload_box, 0, 0, desc.width, desc.height, 0, desc.depth);
-        wined3d_texture_upload_from_texture(staging_texture, 0, 0, 0, 0,
-                src_texture, src_sub_resource_idx, &upload_box);
-
-        src_texture = staging_texture;
-        src_sub_resource_idx = 0;
-    }
-    else if (wined3d_settings.offscreen_rendering_mode != ORM_FBO
-            && (src_texture->sub_resources[src_sub_resource_idx].locations
-            & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_DRAWABLE)) == WINED3D_LOCATION_DRAWABLE
-            && !wined3d_resource_is_offscreen(&src_texture->resource))
-    {
-
-        /* Without FBO blits transferring from the drawable to the texture is
-         * expensive, because we have to flip the data in sysmem. Since we can
-         * flip in the blitter, we don't actually need that flip anyway. So we
-         * use the surface's texture as scratch texture, and flip the source
-         * rectangle instead. */
-        texture2d_load_fb_texture(src_texture, src_sub_resource_idx, FALSE, context);
-
-        s = *src_rect;
-        src_level = src_sub_resource_idx % src_texture->level_count;
-        s.top = wined3d_texture_get_level_height(src_texture, src_level) - s.top;
-        s.bottom = wined3d_texture_get_level_height(src_texture, src_level) - s.bottom;
-        src_rect = &s;
-    }
-    else
-    {
-        wined3d_texture_load(src_texture, context, FALSE);
-    }
-
-    context_apply_blit_state(context, device);
-
-    if (dst_location == WINED3D_LOCATION_DRAWABLE)
-    {
-        d = *dst_rect;
-        wined3d_texture_translate_drawable_coords(dst_texture, context->win_handle, &d);
-        dst_rect = &d;
-    }
-
-    if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
-    {
-        GLenum buffer;
-
-        if (dst_location == WINED3D_LOCATION_DRAWABLE)
-        {
-            TRACE("Destination texture %p is onscreen.\n", dst_texture);
-            buffer = wined3d_texture_get_gl_buffer(dst_texture);
-        }
-        else
-        {
-            TRACE("Destination texture %p is offscreen.\n", dst_texture);
-            buffer = GL_COLOR_ATTACHMENT0;
-        }
-        context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER,
-                &dst_texture->resource, dst_sub_resource_idx, NULL, 0, dst_location);
-        context_set_draw_buffer(context, buffer);
-        context_check_fbo_status(context, GL_DRAW_FRAMEBUFFER);
-        context_invalidate_state(context, STATE_FRAMEBUFFER);
-    }
-
-    if (!(program = glsl_blitter_get_program(glsl_blitter, context, src_texture)))
-    {
-        ERR("Failed to get blitter program.\n");
-        return dst_location;
-    }
-    GL_EXTCALL(glUseProgram(program->id));
-    switch (get_complex_fixup(program->args.fixup))
-    {
-        case COMPLEX_FIXUP_P8:
-            glsl_blitter_upload_palette(glsl_blitter, context, src_texture);
-            break;
-
-        case COMPLEX_FIXUP_YUY2:
-        case COMPLEX_FIXUP_UYVY:
-        case COMPLEX_FIXUP_YV12:
-        case COMPLEX_FIXUP_NV12:
-            src_level = src_sub_resource_idx % src_texture->level_count;
-            location = GL_EXTCALL(glGetUniformLocation(program->id, "size"));
-            GL_EXTCALL(glUniform2f(location, wined3d_texture_get_level_pow2_width(src_texture, src_level),
-                    wined3d_texture_get_level_pow2_height(src_texture, src_level)));
-            break;
-
-        default:
-            break;
-    }
-    context_draw_shaded_quad(context, src_texture, src_sub_resource_idx, src_rect, dst_rect, filter);
-    GL_EXTCALL(glUseProgram(0));
-
-    if (dst_texture->swapchain && (dst_texture->swapchain->front_buffer == dst_texture))
-        gl_info->gl_ops.gl.p_glFlush();
-
-    if (staging_texture)
-        wined3d_texture_decref(staging_texture);
-
-    return dst_location;
-}
-
-static void glsl_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_device *device,
-        unsigned int rt_count, const struct wined3d_fb_state *fb, unsigned int rect_count, const RECT *clear_rects,
-        const RECT *draw_rect, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil)
-{
-    struct wined3d_blitter *next;
-
-    if ((next = blitter->next))
-        next->ops->blitter_clear(next, device, rt_count, fb, rect_count,
-                clear_rects, draw_rect, flags, color, depth, stencil);
-}
-
-static const struct wined3d_blitter_ops glsl_blitter_ops =
-{
-    glsl_blitter_destroy,
-    glsl_blitter_clear,
-    glsl_blitter_blit,
-};
-
-struct wined3d_blitter *wined3d_glsl_blitter_create(struct wined3d_blitter **next,
-        const struct wined3d_device *device)
-{
-    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
-    struct wined3d_glsl_blitter *blitter;
-
-    if (device->shader_backend != &glsl_shader_backend)
-        return NULL;
-
-    if (!gl_info->supported[ARB_VERTEX_SHADER] || !gl_info->supported[ARB_FRAGMENT_SHADER])
-        return NULL;
-
-    if (!(blitter = heap_alloc(sizeof(*blitter))))
-    {
-        ERR("Failed to allocate blitter.\n");
-        return NULL;
-    }
-
-    TRACE("Created blitter %p.\n", blitter);
-
-    blitter->blitter.ops = &glsl_blitter_ops;
-    blitter->blitter.next = *next;
-    string_buffer_list_init(&blitter->string_buffers);
-    wine_rb_init(&blitter->programs, glsl_blitter_args_compare);
-    blitter->palette_texture = 0;
-    *next = &blitter->blitter;
-
-    return *next;
-}