13e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt/*
23e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt * Mesa 3-D graphics library
33e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt *
43e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
53e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt *
63e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt * Permission is hereby granted, free of charge, to any person obtaining a
73e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt * copy of this software and associated documentation files (the "Software"),
83e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt * to deal in the Software without restriction, including without limitation
93e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense,
103e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt * and/or sell copies of the Software, and to permit persons to whom the
113e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt * Software is furnished to do so, subject to the following conditions:
123e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt *
133e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt * The above copyright notice and this permission notice shall be included
143e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt * in all copies or substantial portions of the Software.
153e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt *
163e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
173e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
183e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
193e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
203e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
213e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
223e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt * OTHER DEALINGS IN THE SOFTWARE.
233e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt */
243e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt
253e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt#include "main/glheader.h"
263e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt#include "main/mtypes.h"
273e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt#include "main/imports.h"
283e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt#include "main/arbprogram.h"
293e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt#include "main/arrayobj.h"
303e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt#include "main/blend.h"
313e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt#include "main/condrender.h"
323e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt#include "main/depth.h"
333e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt#include "main/enable.h"
347d2f73e73759d6508833d76181295cdd3e0588feEric Anholt#include "main/enums.h"
353e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt#include "main/fbobject.h"
36d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes#include "main/image.h"
373e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt#include "main/macros.h"
383e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt#include "main/matrix.h"
39b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt#include "main/multisample.h"
400e2c7e2f6ecfc2f5bf74e99955a175caa2f4515fEric Anholt#include "main/objectlabel.h"
413e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt#include "main/readpix.h"
42d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes#include "main/scissor.h"
433e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt#include "main/shaderapi.h"
443e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt#include "main/texobj.h"
453e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt#include "main/texenv.h"
463e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt#include "main/teximage.h"
473e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt#include "main/texparam.h"
4825266b2c1185874494309ed4962ffd51350f7ba2Anuj Phogat#include "main/uniforms.h"
493e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt#include "main/varray.h"
503e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt#include "main/viewport.h"
513e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt#include "swrast/swrast.h"
523e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt#include "drivers/common/meta.h"
531e0da6233be6e5fb0143615d5e3d3642ddb7964fKenneth Graunke#include "util/ralloc.h"
543e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt
553e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt/** Return offset in bytes of the field within a vertex struct */
563e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt#define OFFSET(FIELD) ((void *) offsetof(struct vertex, FIELD))
573e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt
583e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholtstatic void
5968ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogatsetup_glsl_msaa_blit_scaled_shader(struct gl_context *ctx,
6068ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                                   struct blit_state *blit,
6168ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                                   struct gl_renderbuffer *src_rb,
6268ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                                   GLenum target, GLenum filter)
6368ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat{
6468ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   GLint loc_src_width, loc_src_height;
6568ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   int i, samples;
6668ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   int shader_offset = 0;
6768ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   void *mem_ctx = ralloc_context(NULL);
6868ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   char *fs_source;
6968ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   char *name, *sample_number;
7068ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   const uint8_t *sample_map;
7168ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   char *sample_map_str = rzalloc_size(mem_ctx, 1);
7268ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   char *sample_map_expr = rzalloc_size(mem_ctx, 1);
73dea0fcf4e60093f6dcd1c5da8de3b6df5de0fc70Roland Scheidegger   char *texel_fetch_macro = rzalloc_size(mem_ctx, 1);
7468ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   const char *sampler_array_suffix = "";
752dd76ec16e599bd919962f439b59fdd73e85ff94Neil Roberts   float x_scale, y_scale;
7668ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   enum blit_msaa_shader shader_index;
7768ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat
7868ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   assert(src_rb);
7968ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   samples = MAX2(src_rb->NumSamples, 1);
802dd76ec16e599bd919962f439b59fdd73e85ff94Neil Roberts
812dd76ec16e599bd919962f439b59fdd73e85ff94Neil Roberts   if (samples == 16)
822dd76ec16e599bd919962f439b59fdd73e85ff94Neil Roberts      x_scale = 4.0;
832dd76ec16e599bd919962f439b59fdd73e85ff94Neil Roberts   else
842dd76ec16e599bd919962f439b59fdd73e85ff94Neil Roberts      x_scale = 2.0;
852dd76ec16e599bd919962f439b59fdd73e85ff94Neil Roberts   y_scale = samples / x_scale;
8668ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat
8768ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   /* We expect only power of 2 samples in source multisample buffer. */
882484263fe97cebc9fa7a5c9de04c757dc6cc7713Anuj Phogat   assert(samples > 0 && _mesa_is_pow_two(samples));
8968ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   while (samples >> (shader_offset + 1)) {
9068ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat      shader_offset++;
9168ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   }
922dd76ec16e599bd919962f439b59fdd73e85ff94Neil Roberts   /* Update the assert if we plan to support more than 16X MSAA. */
932dd76ec16e599bd919962f439b59fdd73e85ff94Neil Roberts   assert(shader_offset > 0 && shader_offset <= 4);
9468ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat
9568ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   assert(target == GL_TEXTURE_2D_MULTISAMPLE ||
9668ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat          target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
9768ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat
9868ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   shader_index = BLIT_2X_MSAA_SHADER_2D_MULTISAMPLE_SCALED_RESOLVE +
9968ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                  shader_offset - 1;
10068ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat
10168ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   if (target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {
10268ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat      shader_index += BLIT_2X_MSAA_SHADER_2D_MULTISAMPLE_ARRAY_SCALED_RESOLVE -
10368ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                      BLIT_2X_MSAA_SHADER_2D_MULTISAMPLE_SCALED_RESOLVE;
10468ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat      sampler_array_suffix = "Array";
10568ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   }
10668ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat
10768ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   if (blit->msaa_shaders[shader_index]) {
1089c1e01c4a883ac4a738f6f8c17c0236621101e28Kenneth Graunke      _mesa_meta_use_program(ctx, blit->msaa_shaders[shader_index]);
10968ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat      /* Update the uniform values. */
11068ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat      loc_src_width =
1119c1e01c4a883ac4a738f6f8c17c0236621101e28Kenneth Graunke         _mesa_program_resource_location(blit->msaa_shaders[shader_index], GL_UNIFORM, "src_width");
11268ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat      loc_src_height =
1139c1e01c4a883ac4a738f6f8c17c0236621101e28Kenneth Graunke         _mesa_program_resource_location(blit->msaa_shaders[shader_index], GL_UNIFORM, "src_height");
11425266b2c1185874494309ed4962ffd51350f7ba2Anuj Phogat      _mesa_Uniform1f(loc_src_width, src_rb->Width);
11525266b2c1185874494309ed4962ffd51350f7ba2Anuj Phogat      _mesa_Uniform1f(loc_src_height, src_rb->Height);
11668ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat      return;
11768ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   }
11868ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat
11968ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   name = ralloc_asprintf(mem_ctx, "vec4 MSAA scaled resolve");
12068ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat
12168ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   /* Below switch is used to setup the shader expression, which computes
12268ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat    * sample index and map it to to a sample number on hardware.
12368ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat    */
12468ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   switch(samples) {
12568ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   case 2:
12668ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat      sample_number =  "sample_map[int(2 * fract(coord.x))]";
12768ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat      sample_map = ctx->Const.SampleMap2x;
12868ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat      break;
12968ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   case 4:
13068ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat      sample_number =  "sample_map[int(2 * fract(coord.x) + 4 * fract(coord.y))]";
13168ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat      sample_map = ctx->Const.SampleMap4x;
13268ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat      break;
13368ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   case 8:
13468ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat      sample_number =  "sample_map[int(2 * fract(coord.x) + 8 * fract(coord.y))]";
13568ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat      sample_map = ctx->Const.SampleMap8x;
13668ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat      break;
1372dd76ec16e599bd919962f439b59fdd73e85ff94Neil Roberts   case 16:
1382dd76ec16e599bd919962f439b59fdd73e85ff94Neil Roberts      sample_number =  "sample_map[int(4 * fract(coord.x) + 16 * fract(coord.y))]";
1392dd76ec16e599bd919962f439b59fdd73e85ff94Neil Roberts      sample_map = ctx->Const.SampleMap16x;
1402dd76ec16e599bd919962f439b59fdd73e85ff94Neil Roberts      break;
14168ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   default:
142544f56b75a58baf4cfadb646b0a21939a67c0113Brian Paul      sample_number = NULL;
143544f56b75a58baf4cfadb646b0a21939a67c0113Brian Paul      sample_map = NULL;
14468ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat      _mesa_problem(ctx, "Unsupported sample count %d\n", samples);
14581041c4a4a170e6bb332013085117d3fc67d517bChris Forbes      unreachable("Unsupported sample count");
14668ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   }
14768ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat
14868ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   /* Create sample map string. */
14968ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   for (i = 0 ; i < samples - 1; i++) {
15068ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat      ralloc_asprintf_append(&sample_map_str, "%d, ", sample_map[i]);
15168ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   }
15268ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   ralloc_asprintf_append(&sample_map_str, "%d", sample_map[samples - 1]);
15368ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat
15468ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   /* Create sample map expression using above string. */
15568ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   ralloc_asprintf_append(&sample_map_expr,
15668ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                          "   const int sample_map[%d] = int[%d](%s);\n",
15768ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                          samples, samples, sample_map_str);
15868ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat
1599bd9cf1fa402bf948020ee5d560259a5cfd2a739Ian Romanick   if (target == GL_TEXTURE_2D_MULTISAMPLE) {
1609bd9cf1fa402bf948020ee5d560259a5cfd2a739Ian Romanick      ralloc_asprintf_append(&texel_fetch_macro,
1619bd9cf1fa402bf948020ee5d560259a5cfd2a739Ian Romanick                             "#define TEXEL_FETCH(coord) texelFetch(texSampler, ivec2(coord), %s);\n",
1629bd9cf1fa402bf948020ee5d560259a5cfd2a739Ian Romanick                             sample_number);
1639bd9cf1fa402bf948020ee5d560259a5cfd2a739Ian Romanick   } else {
1649bd9cf1fa402bf948020ee5d560259a5cfd2a739Ian Romanick      ralloc_asprintf_append(&texel_fetch_macro,
1659bd9cf1fa402bf948020ee5d560259a5cfd2a739Ian Romanick                             "#define TEXEL_FETCH(coord) texelFetch(texSampler, ivec3(coord, layer), %s);\n",
1669bd9cf1fa402bf948020ee5d560259a5cfd2a739Ian Romanick                             sample_number);
1679bd9cf1fa402bf948020ee5d560259a5cfd2a739Ian Romanick   }
16868ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat
1699bd9cf1fa402bf948020ee5d560259a5cfd2a739Ian Romanick   static const char vs_source[] =
17068ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "#version 130\n"
171b566317e7e6eb78a22cac759a4af2e9d78f74a32Kenneth Graunke                               "#extension GL_ARB_explicit_attrib_location: enable\n"
172b566317e7e6eb78a22cac759a4af2e9d78f74a32Kenneth Graunke                               "layout(location = 0) in vec2 position;\n"
173b566317e7e6eb78a22cac759a4af2e9d78f74a32Kenneth Graunke                               "layout(location = 1) in vec3 textureCoords;\n"
1749bd9cf1fa402bf948020ee5d560259a5cfd2a739Ian Romanick                               "out vec2 texCoords;\n"
1759bd9cf1fa402bf948020ee5d560259a5cfd2a739Ian Romanick                               "flat out int layer;\n"
17668ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "void main()\n"
17768ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "{\n"
1789bd9cf1fa402bf948020ee5d560259a5cfd2a739Ian Romanick                               "   texCoords = textureCoords.xy;\n"
1799bd9cf1fa402bf948020ee5d560259a5cfd2a739Ian Romanick                               "   layer = int(textureCoords.z);\n"
18068ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "   gl_Position = vec4(position, 0.0, 1.0);\n"
1819bd9cf1fa402bf948020ee5d560259a5cfd2a739Ian Romanick                               "}\n"
1829bd9cf1fa402bf948020ee5d560259a5cfd2a739Ian Romanick      ;
1839bd9cf1fa402bf948020ee5d560259a5cfd2a739Ian Romanick
18468ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   fs_source = ralloc_asprintf(mem_ctx,
18568ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "#version 130\n"
18668ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "#extension GL_ARB_texture_multisample : enable\n"
18768ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "uniform sampler2DMS%s texSampler;\n"
18868ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "uniform float src_width, src_height;\n"
1899bd9cf1fa402bf948020ee5d560259a5cfd2a739Ian Romanick                               "in vec2 texCoords;\n"
1909bd9cf1fa402bf948020ee5d560259a5cfd2a739Ian Romanick                               "flat in int layer;\n"
19168ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "out vec4 out_color;\n"
19268ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "\n"
19368ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "void main()\n"
19468ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "{\n"
19568ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "%s"
19668ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "   vec2 interp;\n"
1972dd76ec16e599bd919962f439b59fdd73e85ff94Neil Roberts                               "   const vec2 scale = vec2(%ff, %ff);\n"
1982dd76ec16e599bd919962f439b59fdd73e85ff94Neil Roberts                               "   const vec2 scale_inv = vec2(%ff, %ff);\n"
1992dd76ec16e599bd919962f439b59fdd73e85ff94Neil Roberts                               "   const vec2 s_0_offset = vec2(%ff, %ff);\n"
20068ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "   vec2 s_0_coord, s_1_coord, s_2_coord, s_3_coord;\n"
20168ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "   vec4 s_0_color, s_1_color, s_2_color, s_3_color;\n"
20268ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "   vec4 x_0_color, x_1_color;\n"
20368ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "   vec2 tex_coord = texCoords - s_0_offset;\n"
20468ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "\n"
20568ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "   tex_coord *= scale;\n"
2064603723722127e707a5c1fa28736ee932f326846Ian Romanick                               "   tex_coord.x = clamp(tex_coord.x, 0.0f, scale.x * src_width - 1.0f);\n"
2074603723722127e707a5c1fa28736ee932f326846Ian Romanick                               "   tex_coord.y = clamp(tex_coord.y, 0.0f, scale.y * src_height - 1.0f);\n"
20868ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "   interp = fract(tex_coord);\n"
20968ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "   tex_coord = ivec2(tex_coord) * scale_inv;\n"
21068ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "\n"
21168ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "   /* Compute the sample coordinates used for filtering. */\n"
21268ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "   s_0_coord = tex_coord;\n"
21368ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "   s_1_coord = tex_coord + vec2(scale_inv.x, 0.0f);\n"
21468ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "   s_2_coord = tex_coord + vec2(0.0f, scale_inv.y);\n"
21568ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "   s_3_coord = tex_coord + vec2(scale_inv.x, scale_inv.y);\n"
21668ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "\n"
21768ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "   /* Fetch sample color values. */\n"
21868ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "%s"
21968ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "   s_0_color = TEXEL_FETCH(s_0_coord)\n"
22068ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "   s_1_color = TEXEL_FETCH(s_1_coord)\n"
22168ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "   s_2_color = TEXEL_FETCH(s_2_coord)\n"
22268ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "   s_3_color = TEXEL_FETCH(s_3_coord)\n"
22368ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "#undef TEXEL_FETCH\n"
22468ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "\n"
22568ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "   /* Do bilinear filtering on sample colors. */\n"
22659c19b76873d66eaf9fa422e04a0a403c26e929cAnuj Phogat                               "   x_0_color = mix(s_0_color, s_1_color, interp.x);\n"
22759c19b76873d66eaf9fa422e04a0a403c26e929cAnuj Phogat                               "   x_1_color = mix(s_2_color, s_3_color, interp.x);\n"
22868ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "   out_color = mix(x_0_color, x_1_color, interp.y);\n"
22968ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               "}\n",
23068ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               sampler_array_suffix,
23168ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               sample_map_expr,
2322dd76ec16e599bd919962f439b59fdd73e85ff94Neil Roberts                               x_scale, y_scale,
2332dd76ec16e599bd919962f439b59fdd73e85ff94Neil Roberts                               1.0f / x_scale, 1.0f / y_scale,
2342dd76ec16e599bd919962f439b59fdd73e85ff94Neil Roberts                               0.5f / x_scale, 0.5f / y_scale,
23568ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                               texel_fetch_macro);
23668ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat
23768ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   _mesa_meta_compile_and_link_program(ctx, vs_source, fs_source, name,
23868ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                                       &blit->msaa_shaders[shader_index]);
23968ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   loc_src_width =
2409c1e01c4a883ac4a738f6f8c17c0236621101e28Kenneth Graunke      _mesa_program_resource_location(blit->msaa_shaders[shader_index], GL_UNIFORM, "src_width");
24168ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   loc_src_height =
2429c1e01c4a883ac4a738f6f8c17c0236621101e28Kenneth Graunke      _mesa_program_resource_location(blit->msaa_shaders[shader_index], GL_UNIFORM, "src_height");
24325266b2c1185874494309ed4962ffd51350f7ba2Anuj Phogat   _mesa_Uniform1f(loc_src_width, src_rb->Width);
24425266b2c1185874494309ed4962ffd51350f7ba2Anuj Phogat   _mesa_Uniform1f(loc_src_height, src_rb->Height);
24568ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat
24668ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   ralloc_free(mem_ctx);
24768ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat}
24868ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat
24968ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogatstatic void
2507d2f73e73759d6508833d76181295cdd3e0588feEric Anholtsetup_glsl_msaa_blit_shader(struct gl_context *ctx,
2517d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                            struct blit_state *blit,
252e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand                            const struct gl_framebuffer *drawFb,
2537d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                            struct gl_renderbuffer *src_rb,
2547d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                            GLenum target)
2557d2f73e73759d6508833d76181295cdd3e0588feEric Anholt{
2567d2f73e73759d6508833d76181295cdd3e0588feEric Anholt   const char *vs_source;
2577d2f73e73759d6508833d76181295cdd3e0588feEric Anholt   char *fs_source;
2587d2f73e73759d6508833d76181295cdd3e0588feEric Anholt   void *mem_ctx;
2597d2f73e73759d6508833d76181295cdd3e0588feEric Anholt   enum blit_msaa_shader shader_index;
260b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt   bool dst_is_msaa = false;
261f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt   GLenum src_datatype;
262f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt   const char *vec4_prefix;
263e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt   const char *sampler_array_suffix = "";
2640e2c7e2f6ecfc2f5bf74e99955a175caa2f4515fEric Anholt   char *name;
265e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt   const char *texcoord_type = "vec2";
266e13a8dc37dde097710ea13bef24c022b263ea1ebJuha-Pekka Heikkila   int samples;
267d09167a39ff6ca50cd607547b001d28ee7b63fefAnuj Phogat   int shader_offset = 0;
268d09167a39ff6ca50cd607547b001d28ee7b63fefAnuj Phogat
269f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt   if (src_rb) {
270e13a8dc37dde097710ea13bef24c022b263ea1ebJuha-Pekka Heikkila      samples = MAX2(src_rb->NumSamples, 1);
271f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt      src_datatype = _mesa_get_format_datatype(src_rb->Format);
272f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt   } else {
273f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt      /* depth-or-color glCopyTexImage fallback path that passes a NULL rb and
274f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt       * doesn't handle integer.
275f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt       */
276e13a8dc37dde097710ea13bef24c022b263ea1ebJuha-Pekka Heikkila      samples = 1;
277f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt      src_datatype = GL_UNSIGNED_NORMALIZED;
278f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt   }
279b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt
280e13a8dc37dde097710ea13bef24c022b263ea1ebJuha-Pekka Heikkila   /* We expect only power of 2 samples in source multisample buffer. */
2812484263fe97cebc9fa7a5c9de04c757dc6cc7713Anuj Phogat   assert(samples > 0 && _mesa_is_pow_two(samples));
282e13a8dc37dde097710ea13bef24c022b263ea1ebJuha-Pekka Heikkila   while (samples >> (shader_offset + 1)) {
283e13a8dc37dde097710ea13bef24c022b263ea1ebJuha-Pekka Heikkila      shader_offset++;
284e13a8dc37dde097710ea13bef24c022b263ea1ebJuha-Pekka Heikkila   }
285e13a8dc37dde097710ea13bef24c022b263ea1ebJuha-Pekka Heikkila   /* Update the assert if we plan to support more than 16X MSAA. */
286e13a8dc37dde097710ea13bef24c022b263ea1ebJuha-Pekka Heikkila   assert(shader_offset >= 0 && shader_offset <= 4);
287e13a8dc37dde097710ea13bef24c022b263ea1ebJuha-Pekka Heikkila
288e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand   if (drawFb->Visual.samples > 1) {
289b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt      /* If you're calling meta_BlitFramebuffer with the destination
290b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt       * multisampled, this is the only path that will work -- swrast and
291b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt       * CopyTexImage won't work on it either.
292b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt       */
293b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt      assert(ctx->Extensions.ARB_sample_shading);
294b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt
295b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt      dst_is_msaa = true;
296b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt
297b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt      /* We need shader invocation per sample, not per pixel */
298b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt      _mesa_set_enable(ctx, GL_MULTISAMPLE, GL_TRUE);
299b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt      _mesa_set_enable(ctx, GL_SAMPLE_SHADING, GL_TRUE);
300b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt      _mesa_MinSampleShading(1.0);
301b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt   }
3027d2f73e73759d6508833d76181295cdd3e0588feEric Anholt
3037d2f73e73759d6508833d76181295cdd3e0588feEric Anholt   switch (target) {
3047d2f73e73759d6508833d76181295cdd3e0588feEric Anholt   case GL_TEXTURE_2D_MULTISAMPLE:
305e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
306e13a8dc37dde097710ea13bef24c022b263ea1ebJuha-Pekka Heikkila      if (src_rb && (src_rb->_BaseFormat == GL_DEPTH_COMPONENT ||
307e13a8dc37dde097710ea13bef24c022b263ea1ebJuha-Pekka Heikkila          src_rb->_BaseFormat == GL_DEPTH_STENCIL)) {
308b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt         if (dst_is_msaa)
309b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt            shader_index = BLIT_MSAA_SHADER_2D_MULTISAMPLE_DEPTH_COPY;
310b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt         else
311b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt            shader_index = BLIT_MSAA_SHADER_2D_MULTISAMPLE_DEPTH_RESOLVE;
3127d2f73e73759d6508833d76181295cdd3e0588feEric Anholt      } else {
313b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt         if (dst_is_msaa)
314b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt            shader_index = BLIT_MSAA_SHADER_2D_MULTISAMPLE_COPY;
315d09167a39ff6ca50cd607547b001d28ee7b63fefAnuj Phogat         else {
316d09167a39ff6ca50cd607547b001d28ee7b63fefAnuj Phogat            shader_index = BLIT_1X_MSAA_SHADER_2D_MULTISAMPLE_RESOLVE +
317d09167a39ff6ca50cd607547b001d28ee7b63fefAnuj Phogat                           shader_offset;
318d09167a39ff6ca50cd607547b001d28ee7b63fefAnuj Phogat         }
3197d2f73e73759d6508833d76181295cdd3e0588feEric Anholt      }
320e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt
321e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt      if (target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {
322d09167a39ff6ca50cd607547b001d28ee7b63fefAnuj Phogat         shader_index += (BLIT_1X_MSAA_SHADER_2D_MULTISAMPLE_ARRAY_RESOLVE -
323d09167a39ff6ca50cd607547b001d28ee7b63fefAnuj Phogat                          BLIT_1X_MSAA_SHADER_2D_MULTISAMPLE_RESOLVE);
324e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt         sampler_array_suffix = "Array";
325e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt         texcoord_type = "vec3";
326e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt      }
3277d2f73e73759d6508833d76181295cdd3e0588feEric Anholt      break;
3287d2f73e73759d6508833d76181295cdd3e0588feEric Anholt   default:
3297af9930ab4c8af766e7e851cd65704671ee9dca0Andreas Boll      _mesa_problem(ctx, "Unknown texture target %s\n",
3302f11e92cef51c88a09bc778e2ceca4ab50cf0017Kenneth Graunke                    _mesa_enum_to_string(target));
331d09167a39ff6ca50cd607547b001d28ee7b63fefAnuj Phogat      shader_index = BLIT_2X_MSAA_SHADER_2D_MULTISAMPLE_RESOLVE;
3327d2f73e73759d6508833d76181295cdd3e0588feEric Anholt   }
3337d2f73e73759d6508833d76181295cdd3e0588feEric Anholt
334f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt   /* We rely on the enum being sorted this way. */
335d09167a39ff6ca50cd607547b001d28ee7b63fefAnuj Phogat   STATIC_ASSERT(BLIT_1X_MSAA_SHADER_2D_MULTISAMPLE_RESOLVE_INT ==
336d09167a39ff6ca50cd607547b001d28ee7b63fefAnuj Phogat                 BLIT_1X_MSAA_SHADER_2D_MULTISAMPLE_RESOLVE + 5);
337d09167a39ff6ca50cd607547b001d28ee7b63fefAnuj Phogat   STATIC_ASSERT(BLIT_1X_MSAA_SHADER_2D_MULTISAMPLE_RESOLVE_UINT ==
338d09167a39ff6ca50cd607547b001d28ee7b63fefAnuj Phogat                 BLIT_1X_MSAA_SHADER_2D_MULTISAMPLE_RESOLVE + 10);
339f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt   if (src_datatype == GL_INT) {
340d09167a39ff6ca50cd607547b001d28ee7b63fefAnuj Phogat      shader_index += 5;
341f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt      vec4_prefix = "i";
342f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt   } else if (src_datatype == GL_UNSIGNED_INT) {
343d09167a39ff6ca50cd607547b001d28ee7b63fefAnuj Phogat      shader_index += 10;
344f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt      vec4_prefix = "u";
345f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt   } else {
346f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt      vec4_prefix = "";
347f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt   }
348f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt
3497d2f73e73759d6508833d76181295cdd3e0588feEric Anholt   if (blit->msaa_shaders[shader_index]) {
3509c1e01c4a883ac4a738f6f8c17c0236621101e28Kenneth Graunke      _mesa_meta_use_program(ctx, blit->msaa_shaders[shader_index]);
3517d2f73e73759d6508833d76181295cdd3e0588feEric Anholt      return;
3527d2f73e73759d6508833d76181295cdd3e0588feEric Anholt   }
3537d2f73e73759d6508833d76181295cdd3e0588feEric Anholt
3547d2f73e73759d6508833d76181295cdd3e0588feEric Anholt   mem_ctx = ralloc_context(NULL);
3557d2f73e73759d6508833d76181295cdd3e0588feEric Anholt
356b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt   if (shader_index == BLIT_MSAA_SHADER_2D_MULTISAMPLE_DEPTH_RESOLVE ||
357e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt       shader_index == BLIT_MSAA_SHADER_2D_MULTISAMPLE_ARRAY_DEPTH_RESOLVE ||
358e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt       shader_index == BLIT_MSAA_SHADER_2D_MULTISAMPLE_ARRAY_DEPTH_COPY ||
359b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt       shader_index == BLIT_MSAA_SHADER_2D_MULTISAMPLE_DEPTH_COPY) {
360b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt      char *sample_index;
361aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts      const char *tex_coords = "texCoords";
362b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt
363b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt      if (dst_is_msaa) {
364b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt         sample_index = "gl_SampleID";
3650e2c7e2f6ecfc2f5bf74e99955a175caa2f4515fEric Anholt         name = "depth MSAA copy";
366aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts
367aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts         if (ctx->Extensions.ARB_gpu_shader5 && samples >= 16) {
368aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts            /* See comment below for the color copy */
369aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts            tex_coords = "interpolateAtOffset(texCoords, vec2(0.0))";
370aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts         }
371b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt      } else {
372b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt         /* From the GL 4.3 spec:
373b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt          *
374b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt          *     "If there is a multisample buffer (the value of SAMPLE_BUFFERS
375b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt          *      is one), then values are obtained from the depth samples in
376b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt          *      this buffer. It is recommended that the depth value of the
377b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt          *      centermost sample be used, though implementations may choose
378b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt          *      any function of the depth sample values at each pixel.
379b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt          *
380b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt          * We're slacking and instead of choosing centermost, we've got 0.
381b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt          */
382b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt         sample_index = "0";
3830e2c7e2f6ecfc2f5bf74e99955a175caa2f4515fEric Anholt         name = "depth MSAA resolve";
384b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt      }
385b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt
3867d2f73e73759d6508833d76181295cdd3e0588feEric Anholt      vs_source = ralloc_asprintf(mem_ctx,
3877d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  "#version 130\n"
388b566317e7e6eb78a22cac759a4af2e9d78f74a32Kenneth Graunke                                  "#extension GL_ARB_explicit_attrib_location: enable\n"
389b566317e7e6eb78a22cac759a4af2e9d78f74a32Kenneth Graunke                                  "layout(location = 0) in vec2 position;\n"
390b566317e7e6eb78a22cac759a4af2e9d78f74a32Kenneth Graunke                                  "layout(location = 1) in %s textureCoords;\n"
391e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt                                  "out %s texCoords;\n"
3927d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  "void main()\n"
3937d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  "{\n"
3947d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  "   texCoords = textureCoords;\n"
3957d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  "   gl_Position = vec4(position, 0.0, 1.0);\n"
396e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt                                  "}\n",
397e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt                                  texcoord_type,
398e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt                                  texcoord_type);
3997d2f73e73759d6508833d76181295cdd3e0588feEric Anholt      fs_source = ralloc_asprintf(mem_ctx,
4007d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  "#version 130\n"
4017d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  "#extension GL_ARB_texture_multisample : enable\n"
402b080b3d54d99dfb46b5e8a6eb94fdbdeb937f255Neil Roberts                                  "#extension GL_ARB_sample_shading : enable\n"
403aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts                                  "#extension GL_ARB_gpu_shader5 : enable\n"
404e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt                                  "uniform sampler2DMS%s texSampler;\n"
405e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt                                  "in %s texCoords;\n"
4067d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  "out vec4 out_color;\n"
4077d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  "\n"
4087d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  "void main()\n"
4097d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  "{\n"
410aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts                                  "   gl_FragDepth = texelFetch(texSampler, i%s(%s), %s).r;\n"
411b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt                                  "}\n",
412e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt                                  sampler_array_suffix,
413e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt                                  texcoord_type,
414e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt                                  texcoord_type,
415aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts                                  tex_coords,
416b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt                                  sample_index);
417b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt   } else {
4187d2f73e73759d6508833d76181295cdd3e0588feEric Anholt      /* You can create 2D_MULTISAMPLE textures with 0 sample count (meaning 1
4197d2f73e73759d6508833d76181295cdd3e0588feEric Anholt       * sample).  Yes, this is ridiculous.
4207d2f73e73759d6508833d76181295cdd3e0588feEric Anholt       */
421b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt      char *sample_resolve;
422f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt      const char *merge_function;
4230e2c7e2f6ecfc2f5bf74e99955a175caa2f4515fEric Anholt      name = ralloc_asprintf(mem_ctx, "%svec4 MSAA %s",
4240e2c7e2f6ecfc2f5bf74e99955a175caa2f4515fEric Anholt                             vec4_prefix,
4250e2c7e2f6ecfc2f5bf74e99955a175caa2f4515fEric Anholt                             dst_is_msaa ? "copy" : "resolve");
4267d2f73e73759d6508833d76181295cdd3e0588feEric Anholt
427b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt      if (dst_is_msaa) {
428aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts         const char *tex_coords;
429aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts
430aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts         if (ctx->Extensions.ARB_gpu_shader5 && samples >= 16) {
431aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts            /* If interpolateAtOffset is available then it will be used to
432aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts             * force the interpolation to the center. This is required at
433aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts             * least on Intel hardware because it is possible to have a sample
434aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts             * position on the 0 x or y axis which means it will lie exactly
435aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts             * on the pixel boundary. If we let the hardware interpolate the
436aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts             * coordinates at one of these positions then it is possible for
437aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts             * it to jump to a neighboring texel when converting to ints due
438aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts             * to rounding errors. This is only done for >= 16x MSAA because
439aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts             * it probably has some overhead. It is more likely that some
440aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts             * hardware will use one of these problematic positions at 16x
441aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts             * MSAA because in that case in D3D they are defined to be at
442aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts             * these positions.
443aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts             */
444aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts            tex_coords = "interpolateAtOffset(texCoords, vec2(0.0))";
445aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts         } else {
446aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts            tex_coords = "texCoords";
447aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts         }
448aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts
449aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts         sample_resolve =
450aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts            ralloc_asprintf(mem_ctx,
451aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts                            "   out_color = texelFetch(texSampler, "
452aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts                            "i%s(%s), gl_SampleID);",
453aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts                            texcoord_type, tex_coords);
454aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts
455f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt         merge_function = "";
456b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt      } else {
45724ce678f83ce232f795548c5d27ae36b22e27dc4Vinson Lee         int i;
45824ce678f83ce232f795548c5d27ae36b22e27dc4Vinson Lee         int step;
45924ce678f83ce232f795548c5d27ae36b22e27dc4Vinson Lee
460fe8f3bef31b91fe9296711e0f9dbf511ac9737bfKenneth Graunke         if (src_datatype == GL_INT || src_datatype == GL_UNSIGNED_INT) {
4614f4f393bf303887e1dbedf495780f41f6a313a92Jason Ekstrand            /* From the OpenGL ES 3.2 spec section 16.2.1:
4624f4f393bf303887e1dbedf495780f41f6a313a92Jason Ekstrand             *
4634f4f393bf303887e1dbedf495780f41f6a313a92Jason Ekstrand             *    "If the source formats are integer types or stencil values,
4644f4f393bf303887e1dbedf495780f41f6a313a92Jason Ekstrand             *    a single sample's value is selected for each pixel."
4654f4f393bf303887e1dbedf495780f41f6a313a92Jason Ekstrand             *
4664f4f393bf303887e1dbedf495780f41f6a313a92Jason Ekstrand             * The OpenGL 4.4 spec contains exactly the same language.
4674f4f393bf303887e1dbedf495780f41f6a313a92Jason Ekstrand             *
4684f4f393bf303887e1dbedf495780f41f6a313a92Jason Ekstrand             * We can accomplish this by making the merge function return just
4694f4f393bf303887e1dbedf495780f41f6a313a92Jason Ekstrand             * one of the two samples.  The compiler should do the rest.
4704f4f393bf303887e1dbedf495780f41f6a313a92Jason Ekstrand             */
4714f4f393bf303887e1dbedf495780f41f6a313a92Jason Ekstrand            merge_function = "gvec4 merge(gvec4 a, gvec4 b) { return a; }\n";
472f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt         } else {
473f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt            /* The divide will happen at the end for floats. */
474f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt            merge_function =
475f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt               "vec4 merge(vec4 a, vec4 b) { return (a + b); }\n";
476f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt         }
477f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt
478b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt         /* We're assuming power of two samples for this resolution procedure.
479b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt          *
480b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt          * To avoid losing any floating point precision if the samples all
481b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt          * happen to have the same value, we merge pairs of values at a time
482b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt          * (so the floating point exponent just gets increased), rather than
483b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt          * doing a naive sum and dividing.
484b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt          */
4852484263fe97cebc9fa7a5c9de04c757dc6cc7713Anuj Phogat         assert(_mesa_is_pow_two(samples));
486b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt         /* Fetch each individual sample. */
487b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt         sample_resolve = rzalloc_size(mem_ctx, 1);
48824ce678f83ce232f795548c5d27ae36b22e27dc4Vinson Lee         for (i = 0; i < samples; i++) {
4897d2f73e73759d6508833d76181295cdd3e0588feEric Anholt            ralloc_asprintf_append(&sample_resolve,
490e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt                                   "   gvec4 sample_1_%d = texelFetch(texSampler, i%s(texCoords), %d);\n",
491e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt                                   i, texcoord_type, i);
492b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt         }
493b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt         /* Now, merge each pair of samples, then merge each pair of those,
494b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt          * etc.
495b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt          */
49624ce678f83ce232f795548c5d27ae36b22e27dc4Vinson Lee         for (step = 2; step <= samples; step *= 2) {
49724ce678f83ce232f795548c5d27ae36b22e27dc4Vinson Lee            for (i = 0; i < samples; i += step) {
498b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt               ralloc_asprintf_append(&sample_resolve,
499fe8f3bef31b91fe9296711e0f9dbf511ac9737bfKenneth Graunke                                      "   gvec4 sample_%d_%d = merge(sample_%d_%d, sample_%d_%d);\n",
500b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt                                      step, i,
501b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt                                      step / 2, i,
502b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt                                      step / 2, i + step / 2);
503b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt            }
5047d2f73e73759d6508833d76181295cdd3e0588feEric Anholt         }
5057d2f73e73759d6508833d76181295cdd3e0588feEric Anholt
506b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt         /* Scale the final result. */
507f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt         if (src_datatype == GL_UNSIGNED_INT || src_datatype == GL_INT) {
508f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt            ralloc_asprintf_append(&sample_resolve,
509f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt                                   "   out_color = sample_%d_0;\n",
510f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt                                   samples);
511f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt         } else {
512f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt            ralloc_asprintf_append(&sample_resolve,
513a6022e5405a11ef24e3870ca86ffbbb52929ad4fTopi Pohjolainen                                   "   gl_FragColor = sample_%d_0 / %f;\n",
514f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt                                   samples, (float)samples);
515f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt         }
516b0a8d0ee40b7a9e43c5073a4da8f2ab9df63d2ebEric Anholt      }
5177d2f73e73759d6508833d76181295cdd3e0588feEric Anholt
5187d2f73e73759d6508833d76181295cdd3e0588feEric Anholt      vs_source = ralloc_asprintf(mem_ctx,
5197d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  "#version 130\n"
520b566317e7e6eb78a22cac759a4af2e9d78f74a32Kenneth Graunke                                  "#extension GL_ARB_explicit_attrib_location: enable\n"
521b566317e7e6eb78a22cac759a4af2e9d78f74a32Kenneth Graunke                                  "layout(location = 0) in vec2 position;\n"
522b566317e7e6eb78a22cac759a4af2e9d78f74a32Kenneth Graunke                                  "layout(location = 1) in %s textureCoords;\n"
523e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt                                  "out %s texCoords;\n"
5247d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  "void main()\n"
5257d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  "{\n"
5267d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  "   texCoords = textureCoords;\n"
5277d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  "   gl_Position = vec4(position, 0.0, 1.0);\n"
528e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt                                  "}\n",
529e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt                                  texcoord_type,
530e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt                                  texcoord_type);
5317d2f73e73759d6508833d76181295cdd3e0588feEric Anholt      fs_source = ralloc_asprintf(mem_ctx,
5327d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  "#version 130\n"
5337d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  "#extension GL_ARB_texture_multisample : enable\n"
534b080b3d54d99dfb46b5e8a6eb94fdbdeb937f255Neil Roberts                                  "#extension GL_ARB_sample_shading : enable\n"
535aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54Neil Roberts                                  "#extension GL_ARB_gpu_shader5 : enable\n"
536fe8f3bef31b91fe9296711e0f9dbf511ac9737bfKenneth Graunke                                  "#define gvec4 %svec4\n"
537e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt                                  "uniform %ssampler2DMS%s texSampler;\n"
538e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt                                  "in %s texCoords;\n"
539fe8f3bef31b91fe9296711e0f9dbf511ac9737bfKenneth Graunke                                  "out gvec4 out_color;\n"
5407d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  "\n"
541f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt                                  "%s" /* merge_function */
5427d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  "void main()\n"
5437d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  "{\n"
5447d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  "%s\n" /* sample_resolve */
5457d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  "}\n",
5466984a6be5cdb42fe668239abbc20995f5ee289a6Kenneth Graunke                                  vec4_prefix,
547f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt                                  vec4_prefix,
548e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt                                  sampler_array_suffix,
549e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt                                  texcoord_type,
550f2f337c6d57b16901c0b21beb14793cb9fef8568Eric Anholt                                  merge_function,
5517d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                                  sample_resolve);
5527d2f73e73759d6508833d76181295cdd3e0588feEric Anholt   }
5537d2f73e73759d6508833d76181295cdd3e0588feEric Anholt
554ac4db0aa559ac07262d977f35915953f97875333Topi Pohjolainen   _mesa_meta_compile_and_link_program(ctx, vs_source, fs_source, name,
555ac4db0aa559ac07262d977f35915953f97875333Topi Pohjolainen                                       &blit->msaa_shaders[shader_index]);
5567d2f73e73759d6508833d76181295cdd3e0588feEric Anholt
5577d2f73e73759d6508833d76181295cdd3e0588feEric Anholt   ralloc_free(mem_ctx);
5587d2f73e73759d6508833d76181295cdd3e0588feEric Anholt}
5597d2f73e73759d6508833d76181295cdd3e0588feEric Anholt
5607d2f73e73759d6508833d76181295cdd3e0588feEric Anholtstatic void
5613e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholtsetup_glsl_blit_framebuffer(struct gl_context *ctx,
5623e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt                            struct blit_state *blit,
563e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand                            const struct gl_framebuffer *drawFb,
5647d2f73e73759d6508833d76181295cdd3e0588feEric Anholt                            struct gl_renderbuffer *src_rb,
56568ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                            GLenum target, GLenum filter,
566941aced635aab743bf1ec40ae7f3d21989c8a28eTopi Pohjolainen                            bool is_scaled_blit,
567941aced635aab743bf1ec40ae7f3d21989c8a28eTopi Pohjolainen                            bool do_depth)
5683e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt{
569c98b704128ed450b46c61e139d9f17c652a74c09José Fonseca   unsigned texcoord_size;
57068ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   bool is_target_multisample = target == GL_TEXTURE_2D_MULTISAMPLE ||
57168ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                                target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
57268ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   bool is_filter_scaled_resolve = filter == GL_SCALED_RESOLVE_FASTEST_EXT ||
57368ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                                   filter == GL_SCALED_RESOLVE_NICEST_EXT;
574c98b704128ed450b46c61e139d9f17c652a74c09José Fonseca
5753e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt   /* target = GL_TEXTURE_RECTANGLE is not supported in GLES 3.0 */
5763e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt   assert(_mesa_is_desktop_gl(ctx) || target == GL_TEXTURE_2D);
5773e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt
578c98b704128ed450b46c61e139d9f17c652a74c09José Fonseca   texcoord_size = 2 + (src_rb->Depth > 1 ? 1 : 0);
57957876fee3872f4f224feeeb56eea6d2e10858fe9Jordan Justen
5801035e00a815f0babddac0c6c43d01fd34f7e8a94Ian Romanick   _mesa_meta_setup_vertex_objects(ctx, &blit->VAO, &blit->buf_obj, true,
58157876fee3872f4f224feeeb56eea6d2e10858fe9Jordan Justen                                   2, texcoord_size, 0);
5823e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt
58368ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   if (is_target_multisample && is_filter_scaled_resolve && is_scaled_blit) {
58468ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat      setup_glsl_msaa_blit_scaled_shader(ctx, blit, src_rb, target, filter);
58568ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   } else if (is_target_multisample) {
586e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand      setup_glsl_msaa_blit_shader(ctx, blit, drawFb, src_rb, target);
5877d2f73e73759d6508833d76181295cdd3e0588feEric Anholt   } else {
588941aced635aab743bf1ec40ae7f3d21989c8a28eTopi Pohjolainen      _mesa_meta_setup_blit_shader(ctx, target, do_depth,
589941aced635aab743bf1ec40ae7f3d21989c8a28eTopi Pohjolainen                                   do_depth ? &blit->shaders_with_depth
590941aced635aab743bf1ec40ae7f3d21989c8a28eTopi Pohjolainen                                            : &blit->shaders_without_depth);
5917d2f73e73759d6508833d76181295cdd3e0588feEric Anholt   }
5923e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt}
5933e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt
5943e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt/**
595255bd9c0b83e3cb3914ee5a1386c8d5acdbc046aEric Anholt * Try to do a color or depth glBlitFramebuffer using texturing.
596067c7b67e8080bb2ad9ed857f1e62ddae8da6e6dEric Anholt *
597067c7b67e8080bb2ad9ed857f1e62ddae8da6e6dEric Anholt * We can do this when the src renderbuffer is actually a texture, or when the
598067c7b67e8080bb2ad9ed857f1e62ddae8da6e6dEric Anholt * driver exposes BindRenderbufferTexImage().
5993e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt */
600431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholtstatic bool
6013e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholtblitframebuffer_texture(struct gl_context *ctx,
602e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand                        const struct gl_framebuffer *readFb,
603e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand                        const struct gl_framebuffer *drawFb,
6043e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt                        GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
6053e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt                        GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
606431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt                        GLenum filter, GLint flipX, GLint flipY,
607255bd9c0b83e3cb3914ee5a1386c8d5acdbc046aEric Anholt                        GLboolean glsl_version, GLboolean do_depth)
6083e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt{
609255bd9c0b83e3cb3914ee5a1386c8d5acdbc046aEric Anholt   int att_index = do_depth ? BUFFER_DEPTH : readFb->_ColorReadBufferIndex;
610431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   const struct gl_renderbuffer_attachment *readAtt =
611255bd9c0b83e3cb3914ee5a1386c8d5acdbc046aEric Anholt      &readFb->Attachment[att_index];
612431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   struct blit_state *blit = &ctx->Meta->Blit;
6132a549c43a8c585b312fda920fcd7048e52fdcb05Topi Pohjolainen   struct fb_tex_blit_state fb_tex_blit;
614431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   const GLint dstX = MIN2(dstX0, dstX1);
615431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   const GLint dstY = MIN2(dstY0, dstY1);
616431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   const GLint dstW = abs(dstX1 - dstX0);
617431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   const GLint dstH = abs(dstY1 - dstY0);
61868ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   const int srcW = abs(srcX1 - srcX0);
61968ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   const int srcH = abs(srcY1 - srcY0);
62068ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   bool scaled_blit = false;
621067c7b67e8080bb2ad9ed857f1e62ddae8da6e6dEric Anholt   struct gl_texture_object *texObj;
622431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   GLuint srcLevel;
623431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   GLenum target;
6247d2f73e73759d6508833d76181295cdd3e0588feEric Anholt   struct gl_renderbuffer *rb = readAtt->Renderbuffer;
625b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt   struct temp_texture *meta_temp_texture;
6267d2f73e73759d6508833d76181295cdd3e0588feEric Anholt
6277d2f73e73759d6508833d76181295cdd3e0588feEric Anholt   if (rb->NumSamples && !ctx->Extensions.ARB_texture_multisample)
6287d2f73e73759d6508833d76181295cdd3e0588feEric Anholt      return false;
6297d2f73e73759d6508833d76181295cdd3e0588feEric Anholt
6302a549c43a8c585b312fda920fcd7048e52fdcb05Topi Pohjolainen   _mesa_meta_fb_tex_blit_begin(ctx, &fb_tex_blit);
6312a549c43a8c585b312fda920fcd7048e52fdcb05Topi Pohjolainen
632b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt   if (readAtt->Texture &&
633b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt       (readAtt->Texture->Target == GL_TEXTURE_2D ||
634b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt        readAtt->Texture->Target == GL_TEXTURE_RECTANGLE ||
635e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt        readAtt->Texture->Target == GL_TEXTURE_2D_MULTISAMPLE ||
636e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt        readAtt->Texture->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)) {
637067c7b67e8080bb2ad9ed857f1e62ddae8da6e6dEric Anholt      /* If there's a texture attached of a type we can handle, then just use
638067c7b67e8080bb2ad9ed857f1e62ddae8da6e6dEric Anholt       * it directly.
639067c7b67e8080bb2ad9ed857f1e62ddae8da6e6dEric Anholt       */
640431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      srcLevel = readAtt->TextureLevel;
641431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      texObj = readAtt->Texture;
642067c7b67e8080bb2ad9ed857f1e62ddae8da6e6dEric Anholt      target = texObj->Target;
643b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt   } else if (!readAtt->Texture && ctx->Driver.BindRenderbufferTexImage) {
6442a549c43a8c585b312fda920fcd7048e52fdcb05Topi Pohjolainen      if (!_mesa_meta_bind_rb_as_tex_image(ctx, rb, &fb_tex_blit.tempTex,
6452a549c43a8c585b312fda920fcd7048e52fdcb05Topi Pohjolainen                                           &texObj, &target))
646067c7b67e8080bb2ad9ed857f1e62ddae8da6e6dEric Anholt         return false;
647067c7b67e8080bb2ad9ed857f1e62ddae8da6e6dEric Anholt
648a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen      srcLevel = 0;
649a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen      if (_mesa_is_winsys_fbo(readFb)) {
650a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen         GLint temp = srcY0;
651a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen         srcY0 = rb->Height - srcY1;
652a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen         srcY1 = rb->Height - temp;
653a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen         flipY = -flipY;
654067c7b67e8080bb2ad9ed857f1e62ddae8da6e6dEric Anholt      }
655431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   } else {
656b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt      GLenum tex_base_format;
657b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt      /* Fall back to doing a CopyTexSubImage to get the destination
658b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt       * renderbuffer into a texture.
659b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt       */
660234db609544ee521458ce8b648e70cffe2fda6f9Eric Anholt      if (ctx->Meta->Blit.no_ctsi_fallback)
661234db609544ee521458ce8b648e70cffe2fda6f9Eric Anholt         return false;
662234db609544ee521458ce8b648e70cffe2fda6f9Eric Anholt
663b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt      if (rb->NumSamples > 1)
664b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt         return false;
665b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt
666b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt      if (do_depth) {
6674cc42805e72d7edba0599f4d45099b4ed97ec185Eric Anholt         meta_temp_texture = _mesa_meta_get_temp_depth_texture(ctx);
6684cc42805e72d7edba0599f4d45099b4ed97ec185Eric Anholt         tex_base_format = GL_DEPTH_COMPONENT;
669b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt      } else {
670b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt         meta_temp_texture = _mesa_meta_get_temp_texture(ctx);
671b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt         tex_base_format =
672b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt            _mesa_base_tex_format(ctx, rb->InternalFormat);
673b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt      }
674b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt
675b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt      srcLevel = 0;
676b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt      target = meta_temp_texture->Target;
677b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt      texObj = _mesa_lookup_texture(ctx, meta_temp_texture->TexObj);
6785c9056d37f0143eb4c2fe01365b0e6531378ffacJuha-Pekka Heikkila      if (texObj == NULL) {
6795c9056d37f0143eb4c2fe01365b0e6531378ffacJuha-Pekka Heikkila         return false;
6805c9056d37f0143eb4c2fe01365b0e6531378ffacJuha-Pekka Heikkila      }
681b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt
682b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt      _mesa_meta_setup_copypix_texture(ctx, meta_temp_texture,
683b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt                                       srcX0, srcY0,
684b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt                                       srcW, srcH,
685b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt                                       tex_base_format,
686b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt                                       filter);
687b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt
688b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt
689b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt      srcX0 = 0;
690b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt      srcY0 = 0;
691b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt      srcX1 = srcW;
692b702233f53d6de50943fa0b81e1def8f879ab644Eric Anholt      srcY1 = srcH;
693431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   }
6943e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt
6952a549c43a8c585b312fda920fcd7048e52fdcb05Topi Pohjolainen   fb_tex_blit.baseLevelSave = texObj->BaseLevel;
6962a549c43a8c585b312fda920fcd7048e52fdcb05Topi Pohjolainen   fb_tex_blit.maxLevelSave = texObj->MaxLevel;
697c246828c4d59025bf4e1d5d9de5d9bc5517b3a7bTopi Pohjolainen   fb_tex_blit.stencilSamplingSave = texObj->StencilSampling;
6983e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt
69968ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   scaled_blit = dstW != srcW || dstH != srcH;
70068ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat
701431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   if (glsl_version) {
702e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand      setup_glsl_blit_framebuffer(ctx, blit, drawFb, rb, target, filter, scaled_blit,
703941aced635aab743bf1ec40ae7f3d21989c8a28eTopi Pohjolainen                                  do_depth);
704431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   }
705431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   else {
7063b5a7d450dea9bfadf1d72338f4418c87340805bIan Romanick      _mesa_meta_setup_ff_tnl_for_blit(ctx,
7073b5a7d450dea9bfadf1d72338f4418c87340805bIan Romanick                                       &ctx->Meta->Blit.VAO,
7081035e00a815f0babddac0c6c43d01fd34f7e8a94Ian Romanick                                       &ctx->Meta->Blit.buf_obj,
709431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt                                       2);
710431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   }
711431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt
712431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   /*
713431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt     printf("Blit from texture!\n");
714431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt     printf("  srcAtt %p  dstAtt %p\n", readAtt, drawAtt);
715431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt     printf("  srcTex %p  dstText %p\n", texObj, drawAtt->Texture);
716431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   */
717431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt
718d796b491cc0fb42c503b982a043e0e490d691353Ian Romanick   fb_tex_blit.samp_obj = _mesa_meta_setup_sampler(ctx, texObj, target, filter,
719d796b491cc0fb42c503b982a043e0e490d691353Ian Romanick                                                   srcLevel);
7203e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt
721431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   if (ctx->Extensions.EXT_texture_sRGB_decode) {
722f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke      /* The GL 4.4 spec, section 18.3.1 ("Blitting Pixel Rectangles") says:
723f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke       *
724f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke       *    "When values are taken from the read buffer, if FRAMEBUFFER_SRGB
725f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke       *     is enabled and the value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING
726f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke       *     for the framebuffer attachment corresponding to the read buffer
727f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke       *     is SRGB (see section 9.2.3), the red, green, and blue components
728f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke       *     are converted from the non-linear sRGB color space according to
729f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke       *     equation 3.24.
730f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke       *
731f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke       *     When values are written to the draw buffers, blit operations
732f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke       *     bypass most of the fragment pipeline.  The only fragment
733f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke       *     operations which affect a blit are the pixel ownership test,
734f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke       *     the scissor test, and sRGB conversion (see section 17.3.9)."
735f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke       *
736f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke       * ES 3.0 contains nearly the exact same text, but omits the part
737f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke       * about GL_FRAMEBUFFER_SRGB as that doesn't exist in ES.  Mesa
738f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke       * defaults it to on for ES contexts, so we can safely check it.
739f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke       */
740f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke      const bool decode =
741f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke         ctx->Color.sRGBEnabled &&
742f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke         _mesa_get_format_color_encoding(rb->Format) == GL_SRGB;
743f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke
744f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke      _mesa_set_sampler_srgb_decode(ctx, fb_tex_blit.samp_obj,
745f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke                                    decode ? GL_DECODE_EXT
746f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke                                           : GL_SKIP_DECODE_EXT);
747431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   }
7483e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt
7491020d8937ef52725cc5adafc12465f6332815e82Eric Anholt   if (!glsl_version) {
750431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
751431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      _mesa_set_enable(ctx, target, GL_TRUE);
752431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   }
753431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt
754431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   /* Prepare vertex data (the VBO was previously created and bound) */
755431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   {
756431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      struct vertex verts[4];
757431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      GLfloat s0, t0, s1, t1;
758431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt
759431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      if (target == GL_TEXTURE_2D) {
760431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt         const struct gl_texture_image *texImage
761f262ed6e3dd9d447355ea2490e84c0a6b0fd1ddbBrian Paul            = _mesa_select_tex_image(texObj, target, srcLevel);
762431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt         s0 = srcX0 / (float) texImage->Width;
763431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt         s1 = srcX1 / (float) texImage->Width;
764431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt         t0 = srcY0 / (float) texImage->Height;
765431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt         t1 = srcY1 / (float) texImage->Height;
766431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      }
767431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      else {
7687d2f73e73759d6508833d76181295cdd3e0588feEric Anholt         assert(target == GL_TEXTURE_RECTANGLE_ARB ||
769e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt                target == GL_TEXTURE_2D_MULTISAMPLE ||
770e5b86cb64b2eec6b2d798d80f9abe574825dcb71Eric Anholt                target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
771431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt         s0 = (float) srcX0;
772431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt         s1 = (float) srcX1;
773431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt         t0 = (float) srcY0;
774431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt         t1 = (float) srcY1;
7753e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt      }
776431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt
777431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      /* Silence valgrind warnings about reading uninitialized stack. */
778431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      memset(verts, 0, sizeof(verts));
779431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt
780431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      /* setup vertex positions */
781431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      verts[0].x = -1.0F * flipX;
782431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      verts[0].y = -1.0F * flipY;
783431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      verts[1].x =  1.0F * flipX;
784431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      verts[1].y = -1.0F * flipY;
785431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      verts[2].x =  1.0F * flipX;
786431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      verts[2].y =  1.0F * flipY;
787431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      verts[3].x = -1.0F * flipX;
788431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      verts[3].y =  1.0F * flipY;
789431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt
790431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      verts[0].tex[0] = s0;
791431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      verts[0].tex[1] = t0;
79257876fee3872f4f224feeeb56eea6d2e10858fe9Jordan Justen      verts[0].tex[2] = readAtt->Zoffset;
793431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      verts[1].tex[0] = s1;
794431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      verts[1].tex[1] = t0;
79557876fee3872f4f224feeeb56eea6d2e10858fe9Jordan Justen      verts[1].tex[2] = readAtt->Zoffset;
796431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      verts[2].tex[0] = s1;
797431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      verts[2].tex[1] = t1;
79857876fee3872f4f224feeeb56eea6d2e10858fe9Jordan Justen      verts[2].tex[2] = readAtt->Zoffset;
799431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      verts[3].tex[0] = s0;
800431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      verts[3].tex[1] = t1;
80157876fee3872f4f224feeeb56eea6d2e10858fe9Jordan Justen      verts[3].tex[2] = readAtt->Zoffset;
802431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt
8031035e00a815f0babddac0c6c43d01fd34f7e8a94Ian Romanick      _mesa_buffer_sub_data(ctx, blit->buf_obj, 0, sizeof(verts), verts,
8041035e00a815f0babddac0c6c43d01fd34f7e8a94Ian Romanick                            __func__);
805431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   }
806431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt
807431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   /* setup viewport */
808431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   _mesa_set_viewport(ctx, 0, dstX, dstY, dstW, dstH);
809255bd9c0b83e3cb3914ee5a1386c8d5acdbc046aEric Anholt   _mesa_ColorMask(!do_depth, !do_depth, !do_depth, !do_depth);
810255bd9c0b83e3cb3914ee5a1386c8d5acdbc046aEric Anholt   _mesa_set_enable(ctx, GL_DEPTH_TEST, do_depth);
811255bd9c0b83e3cb3914ee5a1386c8d5acdbc046aEric Anholt   _mesa_DepthMask(do_depth);
812255bd9c0b83e3cb3914ee5a1386c8d5acdbc046aEric Anholt   _mesa_DepthFunc(GL_ALWAYS);
813255bd9c0b83e3cb3914ee5a1386c8d5acdbc046aEric Anholt
814431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
8152a549c43a8c585b312fda920fcd7048e52fdcb05Topi Pohjolainen   _mesa_meta_fb_tex_blit_end(ctx, target, &fb_tex_blit);
8162a549c43a8c585b312fda920fcd7048e52fdcb05Topi Pohjolainen
8172a549c43a8c585b312fda920fcd7048e52fdcb05Topi Pohjolainen   return true;
8182a549c43a8c585b312fda920fcd7048e52fdcb05Topi Pohjolainen}
8192a549c43a8c585b312fda920fcd7048e52fdcb05Topi Pohjolainen
8202a549c43a8c585b312fda920fcd7048e52fdcb05Topi Pohjolainenvoid
8219638c03a4ead3f3f2dd4f349e91ef207cc7c74fdBrian Paul_mesa_meta_fb_tex_blit_begin(struct gl_context *ctx,
8222a549c43a8c585b312fda920fcd7048e52fdcb05Topi Pohjolainen                             struct fb_tex_blit_state *blit)
8232a549c43a8c585b312fda920fcd7048e52fdcb05Topi Pohjolainen{
824533320e4d1367f8acb81dab6e1a15bbc3ebb2385Ian Romanick   /* None of the existing callers preinitialize fb_tex_blit_state to zeros,
825533320e4d1367f8acb81dab6e1a15bbc3ebb2385Ian Romanick    * and both use stack variables.  If samp_obj_save is not NULL,
826533320e4d1367f8acb81dab6e1a15bbc3ebb2385Ian Romanick    * _mesa_reference_sampler_object will try to dereference it.  Leaving
827533320e4d1367f8acb81dab6e1a15bbc3ebb2385Ian Romanick    * random garbage in samp_obj_save can only lead to crashes.
828533320e4d1367f8acb81dab6e1a15bbc3ebb2385Ian Romanick    *
829533320e4d1367f8acb81dab6e1a15bbc3ebb2385Ian Romanick    * Since the state isn't persistent across calls, we won't catch ref
830533320e4d1367f8acb81dab6e1a15bbc3ebb2385Ian Romanick    * counting problems.
831533320e4d1367f8acb81dab6e1a15bbc3ebb2385Ian Romanick    */
832533320e4d1367f8acb81dab6e1a15bbc3ebb2385Ian Romanick   blit->samp_obj_save = NULL;
833533320e4d1367f8acb81dab6e1a15bbc3ebb2385Ian Romanick   _mesa_reference_sampler_object(ctx, &blit->samp_obj_save,
834533320e4d1367f8acb81dab6e1a15bbc3ebb2385Ian Romanick                                  ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler);
8352a549c43a8c585b312fda920fcd7048e52fdcb05Topi Pohjolainen   blit->tempTex = 0;
8362a549c43a8c585b312fda920fcd7048e52fdcb05Topi Pohjolainen}
837431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt
8382a549c43a8c585b312fda920fcd7048e52fdcb05Topi Pohjolainenvoid
839c246828c4d59025bf4e1d5d9de5d9bc5517b3a7bTopi Pohjolainen_mesa_meta_fb_tex_blit_end(struct gl_context *ctx, GLenum target,
8402a549c43a8c585b312fda920fcd7048e52fdcb05Topi Pohjolainen                           struct fb_tex_blit_state *blit)
8412a549c43a8c585b312fda920fcd7048e52fdcb05Topi Pohjolainen{
8422542871387393e855f6afe6c94d44611eefaf6ebIan Romanick   struct gl_texture_object *const texObj =
8432542871387393e855f6afe6c94d44611eefaf6ebIan Romanick      _mesa_get_current_tex_object(ctx, target);
8442542871387393e855f6afe6c94d44611eefaf6ebIan Romanick
845431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   /* Restore texture object state, the texture binding will
846431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt    * be restored by _mesa_meta_end().
847431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt    */
848431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   if (target != GL_TEXTURE_RECTANGLE_ARB) {
8492542871387393e855f6afe6c94d44611eefaf6ebIan Romanick      _mesa_texture_parameteriv(ctx, texObj, GL_TEXTURE_BASE_LEVEL,
8502542871387393e855f6afe6c94d44611eefaf6ebIan Romanick                                &blit->baseLevelSave, false);
8512542871387393e855f6afe6c94d44611eefaf6ebIan Romanick      _mesa_texture_parameteriv(ctx, texObj, GL_TEXTURE_MAX_LEVEL,
8522542871387393e855f6afe6c94d44611eefaf6ebIan Romanick                                &blit->maxLevelSave, false);
85318b0ba340b9229e7afd5e38b5d825fde3a435b63Ian Romanick   }
854c246828c4d59025bf4e1d5d9de5d9bc5517b3a7bTopi Pohjolainen
8552542871387393e855f6afe6c94d44611eefaf6ebIan Romanick   /* If ARB_stencil_texturing is not supported, the mode won't have changed. */
8562542871387393e855f6afe6c94d44611eefaf6ebIan Romanick   if (texObj->StencilSampling != blit->stencilSamplingSave) {
8572542871387393e855f6afe6c94d44611eefaf6ebIan Romanick      /* GLint so the compiler won't complain about type signedness mismatch
8582542871387393e855f6afe6c94d44611eefaf6ebIan Romanick       * in the call to _mesa_texture_parameteriv below.
8592542871387393e855f6afe6c94d44611eefaf6ebIan Romanick       */
8602542871387393e855f6afe6c94d44611eefaf6ebIan Romanick      const GLint param = blit->stencilSamplingSave ?
8612542871387393e855f6afe6c94d44611eefaf6ebIan Romanick         GL_STENCIL_INDEX : GL_DEPTH_COMPONENT;
862c246828c4d59025bf4e1d5d9de5d9bc5517b3a7bTopi Pohjolainen
8632542871387393e855f6afe6c94d44611eefaf6ebIan Romanick      _mesa_texture_parameteriv(ctx, texObj, GL_DEPTH_STENCIL_TEXTURE_MODE,
8642542871387393e855f6afe6c94d44611eefaf6ebIan Romanick                                &param, false);
8653e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt   }
8663e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt
867533320e4d1367f8acb81dab6e1a15bbc3ebb2385Ian Romanick   _mesa_bind_sampler(ctx, ctx->Texture.CurrentUnit, blit->samp_obj_save);
868533320e4d1367f8acb81dab6e1a15bbc3ebb2385Ian Romanick   _mesa_reference_sampler_object(ctx, &blit->samp_obj_save, NULL);
869963065b76cbc254f2fbc6be4e0491264aeaec4ceIan Romanick   _mesa_reference_sampler_object(ctx, &blit->samp_obj, NULL);
870d796b491cc0fb42c503b982a043e0e490d691353Ian Romanick
8712a549c43a8c585b312fda920fcd7048e52fdcb05Topi Pohjolainen   if (blit->tempTex)
8722a549c43a8c585b312fda920fcd7048e52fdcb05Topi Pohjolainen      _mesa_DeleteTextures(1, &blit->tempTex);
8733e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt}
8743e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt
875a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi PohjolainenGLboolean
876a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen_mesa_meta_bind_rb_as_tex_image(struct gl_context *ctx,
877a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen                                struct gl_renderbuffer *rb,
878a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen                                GLuint *tex,
879a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen                                struct gl_texture_object **texObj,
880a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen                                GLenum *target)
881a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen{
882a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen   struct gl_texture_image *texImage;
883a82b29d52627c0b0a35efa437c4d81aaaafbbe0cJuha-Pekka Heikkila   GLuint tempTex;
884a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen
885a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen   if (rb->NumSamples > 1)
886a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen      *target = GL_TEXTURE_2D_MULTISAMPLE;
887a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen   else
888a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen      *target = GL_TEXTURE_2D;
889a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen
890a82b29d52627c0b0a35efa437c4d81aaaafbbe0cJuha-Pekka Heikkila   tempTex = 0;
891a82b29d52627c0b0a35efa437c4d81aaaafbbe0cJuha-Pekka Heikkila   _mesa_GenTextures(1, &tempTex);
892a82b29d52627c0b0a35efa437c4d81aaaafbbe0cJuha-Pekka Heikkila   if (tempTex == 0)
893a82b29d52627c0b0a35efa437c4d81aaaafbbe0cJuha-Pekka Heikkila      return false;
894a82b29d52627c0b0a35efa437c4d81aaaafbbe0cJuha-Pekka Heikkila
895a82b29d52627c0b0a35efa437c4d81aaaafbbe0cJuha-Pekka Heikkila   *tex = tempTex;
896a82b29d52627c0b0a35efa437c4d81aaaafbbe0cJuha-Pekka Heikkila
897a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen   _mesa_BindTexture(*target, *tex);
898a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen   *texObj = _mesa_lookup_texture(ctx, *tex);
899a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen   texImage = _mesa_get_tex_image(ctx, *texObj, *target, 0);
900a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen
901a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen   if (!ctx->Driver.BindRenderbufferTexImage(ctx, rb, texImage)) {
902a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen      _mesa_DeleteTextures(1, tex);
903a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen      return false;
904a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen   }
905a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen
906a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen   if (ctx->Driver.FinishRenderTexture && !rb->NeedsFinishRenderTexture) {
907a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen      rb->NeedsFinishRenderTexture = true;
908a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen      ctx->Driver.FinishRenderTexture(ctx, rb);
909a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen   }
910a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen
911a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen   return true;
912a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen}
913a2952315ac2c97311c0a967bf1c337a6c0b82a2fTopi Pohjolainen
914d796b491cc0fb42c503b982a043e0e490d691353Ian Romanickstruct gl_sampler_object *
9154dc9c314c89c011aee3c33997cbc9cd6bc78674fTopi Pohjolainen_mesa_meta_setup_sampler(struct gl_context *ctx,
9162542871387393e855f6afe6c94d44611eefaf6ebIan Romanick                         struct gl_texture_object *texObj,
9174dc9c314c89c011aee3c33997cbc9cd6bc78674fTopi Pohjolainen                         GLenum target, GLenum filter, GLuint srcLevel)
9184dc9c314c89c011aee3c33997cbc9cd6bc78674fTopi Pohjolainen{
919d796b491cc0fb42c503b982a043e0e490d691353Ian Romanick   struct gl_sampler_object *samp_obj;
92068ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat   GLenum tex_filter = (filter == GL_SCALED_RESOLVE_FASTEST_EXT ||
92168ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                        filter == GL_SCALED_RESOLVE_NICEST_EXT) ?
92268ee950c78a809db8df821d1c9f0a083b02fd905Anuj Phogat                       GL_NEAREST : filter;
9234dc9c314c89c011aee3c33997cbc9cd6bc78674fTopi Pohjolainen
924963065b76cbc254f2fbc6be4e0491264aeaec4ceIan Romanick   samp_obj =  ctx->Driver.NewSamplerObject(ctx, 0xDEADBEEF);
925963065b76cbc254f2fbc6be4e0491264aeaec4ceIan Romanick   if (samp_obj == NULL)
926963065b76cbc254f2fbc6be4e0491264aeaec4ceIan Romanick      return NULL;
927d796b491cc0fb42c503b982a043e0e490d691353Ian Romanick
928d796b491cc0fb42c503b982a043e0e490d691353Ian Romanick   _mesa_bind_sampler(ctx, ctx->Texture.CurrentUnit, samp_obj);
929d796b491cc0fb42c503b982a043e0e490d691353Ian Romanick   _mesa_set_sampler_filters(ctx, samp_obj, tex_filter, tex_filter);
930d796b491cc0fb42c503b982a043e0e490d691353Ian Romanick   _mesa_set_sampler_wrap(ctx, samp_obj, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE,
931d796b491cc0fb42c503b982a043e0e490d691353Ian Romanick                          samp_obj->WrapR);
9324dc9c314c89c011aee3c33997cbc9cd6bc78674fTopi Pohjolainen
9334dc9c314c89c011aee3c33997cbc9cd6bc78674fTopi Pohjolainen   /* Prepare src texture state */
9344dc9c314c89c011aee3c33997cbc9cd6bc78674fTopi Pohjolainen   _mesa_BindTexture(target, texObj->Name);
9354dc9c314c89c011aee3c33997cbc9cd6bc78674fTopi Pohjolainen   if (target != GL_TEXTURE_RECTANGLE_ARB) {
9362542871387393e855f6afe6c94d44611eefaf6ebIan Romanick      _mesa_texture_parameteriv(ctx, texObj, GL_TEXTURE_BASE_LEVEL,
9372542871387393e855f6afe6c94d44611eefaf6ebIan Romanick                                (GLint *) &srcLevel, false);
9382542871387393e855f6afe6c94d44611eefaf6ebIan Romanick      _mesa_texture_parameteriv(ctx, texObj, GL_TEXTURE_MAX_LEVEL,
9392542871387393e855f6afe6c94d44611eefaf6ebIan Romanick                                (GLint *) &srcLevel, false);
9404dc9c314c89c011aee3c33997cbc9cd6bc78674fTopi Pohjolainen   }
9414dc9c314c89c011aee3c33997cbc9cd6bc78674fTopi Pohjolainen
942d796b491cc0fb42c503b982a043e0e490d691353Ian Romanick   return samp_obj;
9434dc9c314c89c011aee3c33997cbc9cd6bc78674fTopi Pohjolainen}
9444dc9c314c89c011aee3c33997cbc9cd6bc78674fTopi Pohjolainen
9453e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt/**
9463e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt * Meta implementation of ctx->Driver.BlitFramebuffer() in terms
9473e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt * of texture mapping and polygon rendering.
9483e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt */
94954540ea691e926b36a81a9b1e27b8f035995d07dKenneth GraunkeGLbitfield
9503e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt_mesa_meta_BlitFramebuffer(struct gl_context *ctx,
951e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand                           const struct gl_framebuffer *readFb,
952e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand                           const struct gl_framebuffer *drawFb,
9533e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt                           GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
9543e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt                           GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
9553e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt                           GLbitfield mask, GLenum filter)
9563e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt{
9573e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt   const GLint dstW = abs(dstX1 - dstX0);
9583e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt   const GLint dstH = abs(dstY1 - dstY0);
9593e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt   const GLint dstFlipX = (dstX1 - dstX0) / dstW;
9603e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt   const GLint dstFlipY = (dstY1 - dstY0) / dstH;
961d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes
962d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes   struct {
963d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes      GLint srcX0, srcY0, srcX1, srcY1;
964d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes      GLint dstX0, dstY0, dstX1, dstY1;
965d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes   } clip = {
966d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes      srcX0, srcY0, srcX1, srcY1,
967d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes      dstX0, dstY0, dstX1, dstY1
968d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes   };
969d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes
9703e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt   const GLboolean use_glsl_version = ctx->Extensions.ARB_vertex_shader &&
971085f61bd4eb4e75c705cc82ce8c2ecacff6b8383Kenneth Graunke                                      ctx->Extensions.ARB_fragment_shader;
9723e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt
9737d2f73e73759d6508833d76181295cdd3e0588feEric Anholt   /* Multisample texture blit support requires texture multisample. */
974e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand   if (readFb->Visual.samples > 0 &&
9757d2f73e73759d6508833d76181295cdd3e0588feEric Anholt       !ctx->Extensions.ARB_texture_multisample) {
97654540ea691e926b36a81a9b1e27b8f035995d07dKenneth Graunke      return mask;
9773e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt   }
9783e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt
979d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes   /* Clip a copy of the blit coordinates. If these differ from the input
980d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes    * coordinates, then we'll set the scissor.
981d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes    */
982e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand   if (!_mesa_clip_blit(ctx, readFb, drawFb,
983e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand                        &clip.srcX0, &clip.srcY0, &clip.srcX1, &clip.srcY1,
984d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes                        &clip.dstX0, &clip.dstY0, &clip.dstX1, &clip.dstY1)) {
985d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes      /* clipped/scissored everything away */
98654540ea691e926b36a81a9b1e27b8f035995d07dKenneth Graunke      return 0;
987d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes   }
988d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes
989f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke   /* Only scissor and FRAMEBUFFER_SRGB affect blit.  Leave sRGB alone, but
990f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke    * save restore scissor as we'll set a custom scissor if necessary.
991d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes    */
992f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke   _mesa_meta_begin(ctx, MESA_META_ALL &
993f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke                         ~(MESA_META_DRAW_BUFFERS |
994f6dc71483abb876386824ba97097089cc0b8f454Kenneth Graunke                           MESA_META_FRAMEBUFFER_SRGB));
995d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes
996816dbdb106dd1955d7db90084790af21fc496d83Neil Roberts   /* Dithering shouldn't be performed for glBlitFramebuffer */
997816dbdb106dd1955d7db90084790af21fc496d83Neil Roberts   _mesa_set_enable(ctx, GL_DITHER, GL_FALSE);
998816dbdb106dd1955d7db90084790af21fc496d83Neil Roberts
999d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes   /* If the clipping earlier changed the destination rect at all, then
1000d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes    * enable the scissor to clip to it.
1001d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes    */
1002d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes   if (clip.dstX0 != dstX0 || clip.dstY0 != dstY0 ||
1003d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes       clip.dstX1 != dstX1 || clip.dstY1 != dstY1) {
1004d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes      _mesa_set_enable(ctx, GL_SCISSOR_TEST, GL_TRUE);
1005d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes      _mesa_Scissor(MIN2(clip.dstX0, clip.dstX1),
1006d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes                    MIN2(clip.dstY0, clip.dstY1),
1007d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes                    abs(clip.dstX0 - clip.dstX1),
1008d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes                    abs(clip.dstY0 - clip.dstY1));
1009d1b6f6711095cd94e80372e7488aa0189e328d88Chris Forbes   }
10103e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt
10113e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt   /* Try faster, direct texture approach first */
1012431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt   if (mask & GL_COLOR_BUFFER_BIT) {
1013e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand      if (blitframebuffer_texture(ctx, readFb, drawFb,
1014e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand                                  srcX0, srcY0, srcX1, srcY1,
1015431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt                                  dstX0, dstY0, dstX1, dstY1,
1016431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt                                  filter, dstFlipX, dstFlipY,
1017255bd9c0b83e3cb3914ee5a1386c8d5acdbc046aEric Anholt                                  use_glsl_version, false)) {
1018431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt         mask &= ~GL_COLOR_BUFFER_BIT;
1019431decf16f0971534e32ec4c6c24cbce281a06f6Eric Anholt      }
10203e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt   }
10213e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt
1022255bd9c0b83e3cb3914ee5a1386c8d5acdbc046aEric Anholt   if (mask & GL_DEPTH_BUFFER_BIT && use_glsl_version) {
1023e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand      if (blitframebuffer_texture(ctx, readFb, drawFb,
1024e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand                                  srcX0, srcY0, srcX1, srcY1,
1025255bd9c0b83e3cb3914ee5a1386c8d5acdbc046aEric Anholt                                  dstX0, dstY0, dstX1, dstY1,
1026255bd9c0b83e3cb3914ee5a1386c8d5acdbc046aEric Anholt                                  filter, dstFlipX, dstFlipY,
1027255bd9c0b83e3cb3914ee5a1386c8d5acdbc046aEric Anholt                                  use_glsl_version, true)) {
1028255bd9c0b83e3cb3914ee5a1386c8d5acdbc046aEric Anholt         mask &= ~GL_DEPTH_BUFFER_BIT;
1029255bd9c0b83e3cb3914ee5a1386c8d5acdbc046aEric Anholt      }
1030255bd9c0b83e3cb3914ee5a1386c8d5acdbc046aEric Anholt   }
1031255bd9c0b83e3cb3914ee5a1386c8d5acdbc046aEric Anholt
10323e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt   if (mask & GL_STENCIL_BUFFER_BIT) {
10333e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt      /* XXX can't easily do stencil */
10343e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt   }
10353e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt
10363e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt   _mesa_meta_end(ctx);
10373e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt
103854540ea691e926b36a81a9b1e27b8f035995d07dKenneth Graunke   return mask;
10393e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt}
10403e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt
10413e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholtvoid
104276cfe2bc4436186fd585be96c4f402c1b1c79bdfIan Romanick_mesa_meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit)
10433e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt{
10443e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt   if (blit->VAO) {
10453e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt      _mesa_DeleteVertexArrays(1, &blit->VAO);
10463e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt      blit->VAO = 0;
104776cfe2bc4436186fd585be96c4f402c1b1c79bdfIan Romanick      _mesa_reference_buffer_object(ctx, &blit->buf_obj, NULL);
10483e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt   }
10493e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt
10509c1e01c4a883ac4a738f6f8c17c0236621101e28Kenneth Graunke   _mesa_meta_blit_shader_table_cleanup(ctx, &blit->shaders_with_depth);
10519c1e01c4a883ac4a738f6f8c17c0236621101e28Kenneth Graunke   _mesa_meta_blit_shader_table_cleanup(ctx, &blit->shaders_without_depth);
10523e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt
10533e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt   _mesa_DeleteTextures(1, &blit->depthTex.TexObj);
10543e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt   blit->depthTex.TexObj = 0;
10553e4ccf499e1d0dd8bf6864f3aba96d58f0a96048Eric Anholt}
105654540ea691e926b36a81a9b1e27b8f035995d07dKenneth Graunke
105754540ea691e926b36a81a9b1e27b8f035995d07dKenneth Graunkevoid
105854540ea691e926b36a81a9b1e27b8f035995d07dKenneth Graunke_mesa_meta_and_swrast_BlitFramebuffer(struct gl_context *ctx,
1059e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand                                      struct gl_framebuffer *readFb,
1060e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand                                      struct gl_framebuffer *drawFb,
106154540ea691e926b36a81a9b1e27b8f035995d07dKenneth Graunke                                      GLint srcX0, GLint srcY0,
106254540ea691e926b36a81a9b1e27b8f035995d07dKenneth Graunke                                      GLint srcX1, GLint srcY1,
106354540ea691e926b36a81a9b1e27b8f035995d07dKenneth Graunke                                      GLint dstX0, GLint dstY0,
106454540ea691e926b36a81a9b1e27b8f035995d07dKenneth Graunke                                      GLint dstX1, GLint dstY1,
106554540ea691e926b36a81a9b1e27b8f035995d07dKenneth Graunke                                      GLbitfield mask, GLenum filter)
106654540ea691e926b36a81a9b1e27b8f035995d07dKenneth Graunke{
1067e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand   mask = _mesa_meta_BlitFramebuffer(ctx, readFb, drawFb,
106854540ea691e926b36a81a9b1e27b8f035995d07dKenneth Graunke                                     srcX0, srcY0, srcX1, srcY1,
106954540ea691e926b36a81a9b1e27b8f035995d07dKenneth Graunke                                     dstX0, dstY0, dstX1, dstY1,
107054540ea691e926b36a81a9b1e27b8f035995d07dKenneth Graunke                                     mask, filter);
107154540ea691e926b36a81a9b1e27b8f035995d07dKenneth Graunke   if (mask == 0x0)
107254540ea691e926b36a81a9b1e27b8f035995d07dKenneth Graunke      return;
107354540ea691e926b36a81a9b1e27b8f035995d07dKenneth Graunke
1074e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand   _swrast_BlitFramebuffer(ctx, readFb, drawFb,
107554540ea691e926b36a81a9b1e27b8f035995d07dKenneth Graunke                           srcX0, srcY0, srcX1, srcY1,
107654540ea691e926b36a81a9b1e27b8f035995d07dKenneth Graunke                           dstX0, dstY0, dstX1, dstY1,
107754540ea691e926b36a81a9b1e27b8f035995d07dKenneth Graunke                           mask, filter);
107854540ea691e926b36a81a9b1e27b8f035995d07dKenneth Graunke}
1079