struct gl_buffer_object *ArrayBufferObj;
/** MESA_META_VIEWPORT */
- GLint ViewportX, ViewportY, ViewportW, ViewportH;
+ GLfloat ViewportX, ViewportY, ViewportW, ViewportH;
GLclampd DepthNear, DepthFar;
/** MESA_META_CLAMP_FRAGMENT_COLOR */
GLuint VBO;
GLuint ShaderProg;
GLint ColorLocation;
+ GLint LayerLocation;
GLuint IntegerShaderProg;
GLint IntegerColorLocation;
+ GLint IntegerLayerLocation;
};
_mesa_set_enable(ctx, GL_FRAGMENT_SHADER_ATI, GL_FALSE);
}
- if (ctx->Extensions.ARB_shader_objects) {
- _mesa_reference_shader_program(ctx, &save->VertexShader,
- ctx->Shader.CurrentVertexProgram);
- _mesa_reference_shader_program(ctx, &save->GeometryShader,
- ctx->Shader.CurrentGeometryProgram);
- _mesa_reference_shader_program(ctx, &save->FragmentShader,
- ctx->Shader.CurrentFragmentProgram);
- _mesa_reference_shader_program(ctx, &save->ActiveShader,
- ctx->Shader.ActiveProgram);
-
- _mesa_UseProgram(0);
- }
+ _mesa_reference_shader_program(ctx, &save->VertexShader,
+ ctx->Shader.CurrentVertexProgram);
+ _mesa_reference_shader_program(ctx, &save->GeometryShader,
+ ctx->Shader.CurrentGeometryProgram);
+ _mesa_reference_shader_program(ctx, &save->FragmentShader,
+ ctx->Shader.CurrentFragmentProgram);
+ _mesa_reference_shader_program(ctx, &save->ActiveShader,
+ ctx->Shader.ActiveProgram);
+
+ _mesa_UseProgram(0);
}
if (state & MESA_META_STENCIL_TEST) {
_mesa_LoadIdentity();
_mesa_MatrixMode(GL_PROJECTION);
_mesa_LoadIdentity();
- _mesa_Ortho(0.0, ctx->DrawBuffer->Width,
- 0.0, ctx->DrawBuffer->Height,
- -1.0, 1.0);
+
+ /* glOrtho with width = 0 or height = 0 generates GL_INVALID_VALUE.
+ * This can occur when there is no draw buffer.
+ */
+ if (ctx->DrawBuffer->Width != 0 && ctx->DrawBuffer->Height != 0)
+ _mesa_Ortho(0.0, ctx->DrawBuffer->Width,
+ 0.0, ctx->DrawBuffer->Height,
+ -1.0, 1.0);
}
if (state & MESA_META_CLIP) {
if (state & MESA_META_VIEWPORT) {
/* save viewport state */
- save->ViewportX = ctx->Viewport.X;
- save->ViewportY = ctx->Viewport.Y;
- save->ViewportW = ctx->Viewport.Width;
- save->ViewportH = ctx->Viewport.Height;
+ save->ViewportX = ctx->ViewportArray[0].X;
+ save->ViewportY = ctx->ViewportArray[0].Y;
+ save->ViewportW = ctx->ViewportArray[0].Width;
+ save->ViewportH = ctx->ViewportArray[0].Height;
/* set viewport to match window size */
- if (ctx->Viewport.X != 0 ||
- ctx->Viewport.Y != 0 ||
- ctx->Viewport.Width != ctx->DrawBuffer->Width ||
- ctx->Viewport.Height != ctx->DrawBuffer->Height) {
- _mesa_set_viewport(ctx, 0, 0,
+ if (ctx->ViewportArray[0].X != 0 ||
+ ctx->ViewportArray[0].Y != 0 ||
+ ctx->ViewportArray[0].Width != (float) ctx->DrawBuffer->Width ||
+ ctx->ViewportArray[0].Height != (float) ctx->DrawBuffer->Height) {
+ _mesa_set_viewport(ctx, 0, 0, 0,
ctx->DrawBuffer->Width, ctx->DrawBuffer->Height);
}
/* save depth range state */
- save->DepthNear = ctx->Viewport.Near;
- save->DepthFar = ctx->Viewport.Far;
+ save->DepthNear = ctx->ViewportArray[0].Near;
+ save->DepthFar = ctx->ViewportArray[0].Far;
/* set depth range to default */
_mesa_DepthRange(0.0, 1.0);
}
}
if (state & MESA_META_SCISSOR) {
- _mesa_set_enable(ctx, GL_SCISSOR_TEST, save->Scissor.Enabled);
- _mesa_Scissor(save->Scissor.X, save->Scissor.Y,
- save->Scissor.Width, save->Scissor.Height);
+ _mesa_set_enable(ctx, GL_SCISSOR_TEST, save->Scissor.EnableFlags);
+ _mesa_Scissor(save->Scissor.ScissorArray[0].X, save->Scissor.ScissorArray[0].Y,
+ save->Scissor.ScissorArray[0].Width, save->Scissor.ScissorArray[0].Height);
}
if (state & MESA_META_SHADER) {
if (ctx->Extensions.ARB_vertex_shader)
_mesa_use_shader_program(ctx, GL_VERTEX_SHADER, save->VertexShader);
- if (ctx->Extensions.ARB_geometry_shader4)
+ if (_mesa_has_geometry_shaders(ctx))
_mesa_use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB,
save->GeometryShader);
}
if (state & MESA_META_VIEWPORT) {
- if (save->ViewportX != ctx->Viewport.X ||
- save->ViewportY != ctx->Viewport.Y ||
- save->ViewportW != ctx->Viewport.Width ||
- save->ViewportH != ctx->Viewport.Height) {
- _mesa_set_viewport(ctx, save->ViewportX, save->ViewportY,
+ if (save->ViewportX != ctx->ViewportArray[0].X ||
+ save->ViewportY != ctx->ViewportArray[0].Y ||
+ save->ViewportW != ctx->ViewportArray[0].Width ||
+ save->ViewportH != ctx->ViewportArray[0].Height) {
+ _mesa_set_viewport(ctx, 0, save->ViewportX, save->ViewportY,
save->ViewportW, save->ViewportH);
}
_mesa_DepthRange(save->DepthNear, save->DepthFar);
sizeof(struct vertex), OFFSET(x));
_mesa_VertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,
sizeof(struct vertex), OFFSET(s));
+
+ _mesa_EnableVertexAttribArray(0);
+ _mesa_EnableVertexAttribArray(1);
}
/* Generate a relevant fragment shader program for the texture target */
"}\n";
fs_source = ralloc_asprintf(mem_ctx,
+ "#ifdef GL_ES\n"
+ "precision highp float;\n"
+ "#endif\n"
"uniform %s texSampler;\n"
"varying vec2 texCoords;\n"
"void main()\n"
_mesa_is_desktop_gl(ctx) ? "130" : "300 es");
fs_source = ralloc_asprintf(mem_ctx,
"#version %s\n"
+ "#ifdef GL_ES\n"
+ "precision highp float;\n"
+ "#endif\n"
"uniform %s texSampler;\n"
"in vec2 texCoords;\n"
"out vec4 out_color;\n"
_mesa_DeleteObjectARB(vs);
_mesa_BindAttribLocation(ShaderProg, 0, "position");
_mesa_BindAttribLocation(ShaderProg, 1, "texcoords");
- _mesa_EnableVertexAttribArray(0);
- _mesa_EnableVertexAttribArray(1);
link_program_with_debug(ctx, ShaderProg);
ralloc_free(mem_ctx);
if (texture_2d)
}
else {
assert(target == GL_TEXTURE_RECTANGLE_ARB);
- s0 = srcX0;
- s1 = srcX1;
- t0 = srcY0;
- t1 = srcY1;
+ s0 = (float) srcX0;
+ s1 = (float) srcX1;
+ t0 = (float) srcY0;
+ t1 = (float) srcY1;
}
/* setup vertex positions */
}
/* setup viewport */
- _mesa_set_viewport(ctx, dstX, dstY, dstW, dstH);
+ _mesa_set_viewport(ctx, 0, dstX, dstY, dstW, dstH);
_mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
_mesa_DepthMask(GL_FALSE);
_mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
const GLenum rb_base_format =
_mesa_base_tex_format(ctx, colorReadRb->InternalFormat);
- newTex = alloc_texture(tex, srcW, srcH, rb_base_format);
- setup_copypix_texture(ctx, tex, newTex, srcX, srcY, srcW, srcH,
+ /* Using the exact source rectangle to create the texture does incorrect
+ * linear filtering along the edges. So, allocate the texture extended along
+ * edges by one pixel in x, y directions.
+ */
+ newTex = alloc_texture(tex, srcW + 2, srcH + 2, rb_base_format);
+ setup_copypix_texture(ctx, tex, newTex,
+ srcX - 1, srcY - 1, srcW + 2, srcH + 2,
rb_base_format, filter);
/* texcoords (after texture allocation!) */
{
- verts[0].s = 0.0F;
- verts[0].t = 0.0F;
- verts[1].s = tex->Sright;
- verts[1].t = 0.0F;
- verts[2].s = tex->Sright;
- verts[2].t = tex->Ttop;
- verts[3].s = 0.0F;
- verts[3].t = tex->Ttop;
+ verts[0].s = 1.0F;
+ verts[0].t = 1.0F;
+ verts[1].s = tex->Sright - 1.0F;
+ verts[1].t = 1.0F;
+ verts[2].s = tex->Sright - 1.0F;
+ verts[2].t = tex->Ttop - 1.0F;
+ verts[3].s = 1.0F;
+ verts[3].t = tex->Ttop - 1.0F;
/* upload new vertex data */
_mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
}
- _mesa_set_viewport(ctx, dstX, dstY, dstW, dstH);
+ _mesa_set_viewport(ctx, 0, dstX, dstY, dstW, dstH);
_mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
_mesa_set_enable(ctx, GL_DEPTH_TEST, GL_FALSE);
_mesa_DepthMask(GL_FALSE);
_mesa_DepthFunc(GL_ALWAYS);
_mesa_DepthMask(GL_TRUE);
- _mesa_set_viewport(ctx, dstX, dstY, dstW, dstH);
+ _mesa_set_viewport(ctx, 0, dstX, dstY, dstW, dstH);
_mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
_mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
mask &= ~GL_DEPTH_BUFFER_BIT;
"{\n"
" gl_Position = position;\n"
"}\n";
+ const char *gs_source =
+ "#version 150\n"
+ "layout(triangles) in;\n"
+ "layout(triangle_strip, max_vertices = 4) out;\n"
+ "uniform int layer;\n"
+ "void main()\n"
+ "{\n"
+ " for (int i = 0; i < 3; i++) {\n"
+ " gl_Layer = layer;\n"
+ " gl_Position = gl_in[i].gl_Position;\n"
+ " EmitVertex();\n"
+ " }\n"
+ "}\n";
const char *fs_source =
+ "#ifdef GL_ES\n"
+ "precision highp float;\n"
+ "#endif\n"
"uniform vec4 color;\n"
"void main()\n"
"{\n"
" gl_FragColor = color;\n"
"}\n";
- GLuint vs, fs;
+ GLuint vs, gs = 0, fs;
bool has_integer_textures;
if (clear->ArrayObj != 0)
_mesa_ShaderSource(vs, 1, &vs_source, NULL);
_mesa_CompileShader(vs);
+ if (_mesa_has_geometry_shaders(ctx)) {
+ gs = _mesa_CreateShaderObjectARB(GL_GEOMETRY_SHADER);
+ _mesa_ShaderSource(gs, 1, &gs_source, NULL);
+ _mesa_CompileShader(gs);
+ }
+
fs = _mesa_CreateShaderObjectARB(GL_FRAGMENT_SHADER);
_mesa_ShaderSource(fs, 1, &fs_source, NULL);
_mesa_CompileShader(fs);
clear->ShaderProg = _mesa_CreateProgramObjectARB();
_mesa_AttachShader(clear->ShaderProg, fs);
_mesa_DeleteObjectARB(fs);
+ if (gs != 0)
+ _mesa_AttachShader(clear->ShaderProg, gs);
_mesa_AttachShader(clear->ShaderProg, vs);
_mesa_DeleteObjectARB(vs);
_mesa_BindAttribLocation(clear->ShaderProg, 0, "position");
clear->ColorLocation = _mesa_GetUniformLocation(clear->ShaderProg,
"color");
+ if (gs != 0) {
+ clear->LayerLocation = _mesa_GetUniformLocation(clear->ShaderProg,
+ "layer");
+ }
has_integer_textures = _mesa_is_gles3(ctx) ||
(_mesa_is_desktop_gl(ctx) && ctx->Const.GLSLVersion >= 130);
const char *fs_int_source =
ralloc_asprintf(shader_source_mem_ctx,
"#version %s\n"
+ "#ifdef GL_ES\n"
+ "precision highp float;\n"
+ "#endif\n"
"uniform ivec4 color;\n"
"out ivec4 out_color;\n"
"\n"
clear->IntegerShaderProg = _mesa_CreateProgramObjectARB();
_mesa_AttachShader(clear->IntegerShaderProg, fs);
_mesa_DeleteObjectARB(fs);
+ if (gs != 0)
+ _mesa_AttachShader(clear->IntegerShaderProg, gs);
_mesa_AttachShader(clear->IntegerShaderProg, vs);
_mesa_DeleteObjectARB(vs);
_mesa_BindAttribLocation(clear->IntegerShaderProg, 0, "position");
clear->IntegerColorLocation =
_mesa_GetUniformLocation(clear->IntegerShaderProg, "color");
+ if (gs != 0) {
+ clear->IntegerLayerLocation =
+ _mesa_GetUniformLocation(clear->IntegerShaderProg, "layer");
+ }
}
+ if (gs != 0)
+ _mesa_DeleteObjectARB(gs);
}
static void
_mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts,
GL_DYNAMIC_DRAW_ARB);
- /* draw quad */
- _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ /* draw quad(s) */
+ if (fb->MaxNumLayers > 0) {
+ unsigned layer;
+ for (layer = 0; layer < fb->MaxNumLayers; layer++) {
+ if (fb->_IntegerColor)
+ _mesa_Uniform1i(clear->IntegerLayerLocation, layer);
+ else
+ _mesa_Uniform1i(clear->LayerLocation, layer);
+ _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ }
+ } else {
+ _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ }
_mesa_meta_end(ctx);
}
_mesa_StencilMask(mask);
_mesa_ProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0,
- 255.0 / mask, 0.5, 0.0, 0.0);
+ 255.0f / mask, 0.5f, 0.0f, 0.0f);
_mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
r = (slice + 0.5f) / depth;
}
else if (faceTarget == GL_TEXTURE_2D_ARRAY)
- r = slice;
+ r = (float) slice;
else
r = 0.0F;
coords0[0] = 0.0F; /* s */
coords0[0] = 0.0F; /* s */
coords0[1] = 0.0F; /* t */
coords0[2] = 0.0F; /* r */
- coords1[0] = width;
+ coords1[0] = (float) width;
coords1[1] = 0.0F;
coords1[2] = 0.0F;
- coords2[0] = width;
- coords2[1] = height;
+ coords2[0] = (float) width;
+ coords2[1] = (float) height;
coords2[2] = 0.0F;
coords3[0] = 0.0F;
- coords3[1] = height;
+ coords3[1] = (float) height;
coords3[2] = 0.0F;
break;
case GL_TEXTURE_1D_ARRAY:
coords0[0] = 0.0F; /* s */
- coords0[1] = slice; /* t */
+ coords0[1] = (float) slice; /* t */
coords0[2] = 0.0F; /* r */
coords1[0] = 1.0f;
- coords1[1] = slice;
+ coords1[1] = (float) slice;
coords1[2] = 0.0F;
coords2[0] = 1.0F;
- coords2[1] = slice;
+ coords2[1] = (float) slice;
coords2[2] = 0.0F;
coords3[0] = 0.0F;
- coords3[1] = slice;
+ coords3[1] = (float) slice;
coords3[2] = 0.0F;
break;
fs_source = ralloc_asprintf(mem_ctx,
"#extension GL_EXT_texture_array : enable\n"
+ "#ifdef GL_ES\n"
+ "precision highp float;\n"
+ "#endif\n"
"uniform %s texSampler;\n"
"varying vec3 texCoords;\n"
"void main()\n"
_mesa_is_desktop_gl(ctx) ? "130" : "300 es");
fs_source = ralloc_asprintf(mem_ctx,
"#version %s\n"
+ "#ifdef GL_ES\n"
+ "precision highp float;\n"
+ "#endif\n"
"uniform %s texSampler;\n"
"in vec3 texCoords;\n"
"out vec4 out_color;\n"
assert(dstHeight == ctx->DrawBuffer->Height);
/* setup viewport */
- _mesa_set_viewport(ctx, 0, 0, dstWidth, dstHeight);
+ _mesa_set_viewport(ctx, 0, 0, 0, dstWidth, dstHeight);
_mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
verts[3].x = 0.0F;
verts[3].y = height;
+ _mesa_MatrixMode(GL_PROJECTION);
+ _mesa_LoadIdentity();
+ _mesa_Ortho(0.0, width, 0.0, height, -1.0, 1.0);
+ _mesa_set_viewport(ctx, 0, 0, 0, width, height);
+
/* upload new vertex data */
_mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
_mesa_get_format_datatype(texImage->TexFormat)
== GL_UNSIGNED_NORMALIZED) {
struct gl_texture_object *texObj = texImage->TexObject;
- const GLuint slice = 0; /* only 2D compressed textures for now */
+ GLuint slice;
/* Need to unlock the texture here to prevent deadlock... */
_mesa_unlock_texture(ctx, texObj);
- decompress_texture_image(ctx, texImage, slice, format, type, pixels);
+ for (slice = 0; slice < texImage->Depth; slice++) {
+ void *dst;
+ if (texImage->TexObject->Target == GL_TEXTURE_2D_ARRAY) {
+ /* Setup pixel packing. SkipPixels and SkipRows will be applied
+ * in the decompress_texture_image() function's call to
+ * glReadPixels but we need to compute the dest slice's address
+ * here (according to SkipImages and ImageHeight).
+ */
+ struct gl_pixelstore_attrib packing = ctx->Pack;
+ packing.SkipPixels = 0;
+ packing.SkipRows = 0;
+ dst = _mesa_image_address3d(&packing, pixels, texImage->Width,
+ texImage->Height, format, type,
+ slice, 0, 0);
+ }
+ else {
+ dst = pixels;
+ }
+ decompress_texture_image(ctx, texImage, slice, format, type, dst);
+ }
/* ... and relock it */
_mesa_lock_texture(ctx, texObj);
}