/** * Setup uniforms telling the coordinates of the destination rectangle in the * native w-tiled space. These are needed to ignore pixels that lie outside. * The destination is drawn as Y-tiled and in some cases the Y-tiled drawing * rectangle is larger than the original (for example 1x4 w-tiled requires * 16x2 y-tiled). */ static void setup_bounding_rect(GLuint prog, const struct blit_dims *dims) { _mesa_Uniform1i(_mesa_GetUniformLocation(prog, "dst_x0"), dims->dst_x0); _mesa_Uniform1i(_mesa_GetUniformLocation(prog, "dst_x1"), dims->dst_x1); _mesa_Uniform1i(_mesa_GetUniformLocation(prog, "dst_y0"), dims->dst_y0); _mesa_Uniform1i(_mesa_GetUniformLocation(prog, "dst_y1"), dims->dst_y1); }
/** * Setup uniforms telling the destination width, height and the offset. These * are needed to unnoormalize the input coordinates and to correctly translate * between destination and source that may have differing offsets. */ static void setup_drawing_rect(GLuint prog, const struct blit_dims *dims) { _mesa_Uniform1f(_mesa_GetUniformLocation(prog, "draw_rect_w"), dims->dst_x1 - dims->dst_x0); _mesa_Uniform1f(_mesa_GetUniformLocation(prog, "draw_rect_h"), dims->dst_y1 - dims->dst_y0); _mesa_Uniform1f(_mesa_GetUniformLocation(prog, "dst_x_off"), dims->dst_x0); _mesa_Uniform1f(_mesa_GetUniformLocation(prog, "dst_y_off"), dims->dst_y0); }
/** * Setup uniforms providing relation between source and destination surfaces. * Destination coordinates are in Y-tiling layout while texelFetch() expects * W-tiled coordinates. Once the destination coordinates are re-interpreted by * the program into the original W-tiled layout, the program needs to know the * offset and scaling factors between the destination and source. * Note that these are calculated in the original W-tiled space before the * destination rectangle is adjusted for possible msaa and Y-tiling. */ static void setup_coord_transform(GLuint prog, const struct blit_dims *dims) { setup_coord_coeff(prog, _mesa_GetUniformLocation(prog, "src_x_scale"), _mesa_GetUniformLocation(prog, "src_x_off"), dims->src_x0, dims->src_x1, dims->dst_x0, dims->dst_x1, dims->mirror_x); setup_coord_coeff(prog, _mesa_GetUniformLocation(prog, "src_y_scale"), _mesa_GetUniformLocation(prog, "src_y_off"), dims->src_y0, dims->src_y1, dims->dst_y0, dims->dst_y1, dims->mirror_y); }
static void brw_bind_rep_write_shader(struct brw_context *brw, float *color) { const char *vs_source = "#extension GL_AMD_vertex_shader_layer : enable\n" "#extension GL_ARB_draw_instanced : enable\n" "attribute vec4 position;\n" "uniform int layer;\n" "void main()\n" "{\n" "#ifdef GL_AMD_vertex_shader_layer\n" " gl_Layer = gl_InstanceID;\n" "#endif\n" " gl_Position = position;\n" "}\n"; const char *fs_source = "uniform vec4 color;\n" "void main()\n" "{\n" " gl_FragColor = color;\n" "}\n"; GLuint vs, fs; struct brw_fast_clear_state *clear = brw->fast_clear_state; struct gl_context *ctx = &brw->ctx; if (clear->shader_prog) { _mesa_UseProgram(clear->shader_prog); _mesa_Uniform4fv(clear->color_location, 1, color); return; } vs = _mesa_meta_compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_source); fs = _mesa_meta_compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_source); clear->shader_prog = _mesa_CreateProgram(); _mesa_AttachShader(clear->shader_prog, fs); _mesa_DeleteShader(fs); _mesa_AttachShader(clear->shader_prog, vs); _mesa_DeleteShader(vs); _mesa_BindAttribLocation(clear->shader_prog, 0, "position"); _mesa_ObjectLabel(GL_PROGRAM, clear->shader_prog, -1, "meta clear"); _mesa_LinkProgram(clear->shader_prog); clear->color_location = _mesa_GetUniformLocation(clear->shader_prog, "color"); _mesa_UseProgram(clear->shader_prog); _mesa_Uniform4fv(clear->color_location, 1, color); }
static void setup_glsl_msaa_blit_scaled_shader(struct gl_context *ctx, struct blit_state *blit, struct gl_renderbuffer *src_rb, GLenum target, GLenum filter) { GLint loc_src_width, loc_src_height; int i, samples; int shader_offset = 0; void *mem_ctx = ralloc_context(NULL); char *fs_source; char *name, *sample_number; const uint8_t *sample_map; char *sample_map_str = rzalloc_size(mem_ctx, 1); char *sample_map_expr = rzalloc_size(mem_ctx, 1); char *texel_fetch_macro = rzalloc_size(mem_ctx, 1); const char *sampler_array_suffix = ""; float y_scale; enum blit_msaa_shader shader_index; assert(src_rb); samples = MAX2(src_rb->NumSamples, 1); y_scale = samples * 0.5; /* We expect only power of 2 samples in source multisample buffer. */ assert(samples > 0 && _mesa_is_pow_two(samples)); while (samples >> (shader_offset + 1)) { shader_offset++; } /* Update the assert if we plan to support more than 8X MSAA. */ assert(shader_offset > 0 && shader_offset < 4); assert(target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY); shader_index = BLIT_2X_MSAA_SHADER_2D_MULTISAMPLE_SCALED_RESOLVE + shader_offset - 1; if (target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) { shader_index += BLIT_2X_MSAA_SHADER_2D_MULTISAMPLE_ARRAY_SCALED_RESOLVE - BLIT_2X_MSAA_SHADER_2D_MULTISAMPLE_SCALED_RESOLVE; sampler_array_suffix = "Array"; } if (blit->msaa_shaders[shader_index]) { _mesa_UseProgram(blit->msaa_shaders[shader_index]); /* Update the uniform values. */ loc_src_width = _mesa_GetUniformLocation(blit->msaa_shaders[shader_index], "src_width"); loc_src_height = _mesa_GetUniformLocation(blit->msaa_shaders[shader_index], "src_height"); _mesa_Uniform1f(loc_src_width, src_rb->Width); _mesa_Uniform1f(loc_src_height, src_rb->Height); return; } name = ralloc_asprintf(mem_ctx, "vec4 MSAA scaled resolve"); /* Below switch is used to setup the shader expression, which computes * sample index and map it to to a sample number on hardware. */ switch(samples) { case 2: sample_number = "sample_map[int(2 * fract(coord.x))]"; sample_map = ctx->Const.SampleMap2x; break; case 4: sample_number = "sample_map[int(2 * fract(coord.x) + 4 * fract(coord.y))]"; sample_map = ctx->Const.SampleMap4x; break; case 8: sample_number = "sample_map[int(2 * fract(coord.x) + 8 * fract(coord.y))]"; sample_map = ctx->Const.SampleMap8x; break; default: sample_number = NULL; sample_map = NULL; _mesa_problem(ctx, "Unsupported sample count %d\n", samples); unreachable("Unsupported sample count"); } /* Create sample map string. */ for (i = 0 ; i < samples - 1; i++) { ralloc_asprintf_append(&sample_map_str, "%d, ", sample_map[i]); } ralloc_asprintf_append(&sample_map_str, "%d", sample_map[samples - 1]); /* Create sample map expression using above string. */ ralloc_asprintf_append(&sample_map_expr, " const int sample_map[%d] = int[%d](%s);\n", samples, samples, sample_map_str); if (target == GL_TEXTURE_2D_MULTISAMPLE) { ralloc_asprintf_append(&texel_fetch_macro, "#define TEXEL_FETCH(coord) texelFetch(texSampler, ivec2(coord), %s);\n", sample_number); } else { ralloc_asprintf_append(&texel_fetch_macro, "#define TEXEL_FETCH(coord) texelFetch(texSampler, ivec3(coord, layer), %s);\n", sample_number); } static const char vs_source[] = "#version 130\n" "in vec2 position;\n" "in vec3 textureCoords;\n" "out vec2 texCoords;\n" "flat out int layer;\n" "void main()\n" "{\n" " texCoords = textureCoords.xy;\n" " layer = int(textureCoords.z);\n" " gl_Position = vec4(position, 0.0, 1.0);\n" "}\n" ; fs_source = ralloc_asprintf(mem_ctx, "#version 130\n" "#extension GL_ARB_texture_multisample : enable\n" "uniform sampler2DMS%s texSampler;\n" "uniform float src_width, src_height;\n" "in vec2 texCoords;\n" "flat in int layer;\n" "out vec4 out_color;\n" "\n" "void main()\n" "{\n" "%s" " vec2 interp;\n" " const vec2 scale = vec2(2.0f, %ff);\n" " const vec2 scale_inv = vec2(0.5f, %ff);\n" " const vec2 s_0_offset = vec2(0.25f, %ff);\n" " vec2 s_0_coord, s_1_coord, s_2_coord, s_3_coord;\n" " vec4 s_0_color, s_1_color, s_2_color, s_3_color;\n" " vec4 x_0_color, x_1_color;\n" " vec2 tex_coord = texCoords - s_0_offset;\n" "\n" " tex_coord *= scale;\n" " clamp(tex_coord.x, 0.0f, scale.x * src_width - 1.0f);\n" " clamp(tex_coord.y, 0.0f, scale.y * src_height - 1.0f);\n" " interp = fract(tex_coord);\n" " tex_coord = ivec2(tex_coord) * scale_inv;\n" "\n" " /* Compute the sample coordinates used for filtering. */\n" " s_0_coord = tex_coord;\n" " s_1_coord = tex_coord + vec2(scale_inv.x, 0.0f);\n" " s_2_coord = tex_coord + vec2(0.0f, scale_inv.y);\n" " s_3_coord = tex_coord + vec2(scale_inv.x, scale_inv.y);\n" "\n" " /* Fetch sample color values. */\n" "%s" " s_0_color = TEXEL_FETCH(s_0_coord)\n" " s_1_color = TEXEL_FETCH(s_1_coord)\n" " s_2_color = TEXEL_FETCH(s_2_coord)\n" " s_3_color = TEXEL_FETCH(s_3_coord)\n" "#undef TEXEL_FETCH\n" "\n" " /* Do bilinear filtering on sample colors. */\n" " x_0_color = mix(s_0_color, s_1_color, interp.x);\n" " x_1_color = mix(s_2_color, s_3_color, interp.x);\n" " out_color = mix(x_0_color, x_1_color, interp.y);\n" "}\n", sampler_array_suffix, sample_map_expr, y_scale, 1.0f / y_scale, 1.0f / samples, texel_fetch_macro); _mesa_meta_compile_and_link_program(ctx, vs_source, fs_source, name, &blit->msaa_shaders[shader_index]); loc_src_width = _mesa_GetUniformLocation(blit->msaa_shaders[shader_index], "src_width"); loc_src_height = _mesa_GetUniformLocation(blit->msaa_shaders[shader_index], "src_height"); _mesa_Uniform1f(loc_src_width, src_rb->Width); _mesa_Uniform1f(loc_src_height, src_rb->Height); ralloc_free(mem_ctx); }