#include "main/bufferobj.h"
#include "main/buffers.h"
#include "main/clear.h"
-#include "main/colortab.h"
#include "main/condrender.h"
#include "main/depth.h"
#include "main/enable.h"
choose_blit_shader(GLenum target, struct blit_shader_table *table);
static void cleanup_temp_texture(struct temp_texture *tex);
-static void meta_glsl_clear_cleanup(struct clear_state *clear);
-static void meta_decompress_cleanup(struct decompress_state *decompress);
-static void meta_drawpix_cleanup(struct drawpix_state *drawpix);
+static void meta_glsl_clear_cleanup(struct gl_context *ctx,
+ struct clear_state *clear);
+static void meta_decompress_cleanup(struct gl_context *ctx,
+ struct decompress_state *decompress);
+static void meta_drawpix_cleanup(struct gl_context *ctx,
+ struct drawpix_state *drawpix);
void
_mesa_meta_bind_fbo_image(GLenum fboTarget, GLenum attachment,
void
_mesa_meta_setup_blit_shader(struct gl_context *ctx,
GLenum target,
+ bool do_depth,
struct blit_shader_table *table)
{
char *vs_source, *fs_source;
- void *const mem_ctx = ralloc_context(NULL);
struct blit_shader *shader = choose_blit_shader(target, table);
const char *vs_input, *vs_output, *fs_input, *vs_preprocess, *fs_preprocess;
+ void *mem_ctx;
if (ctx->Const.GLSLVersion < 130) {
vs_preprocess = "";
return;
}
+ mem_ctx = ralloc_context(NULL);
+
vs_source = ralloc_asprintf(mem_ctx,
"%s\n"
"%s vec2 position;\n"
"void main()\n"
"{\n"
" gl_FragColor = %s(texSampler, %s);\n"
- " gl_FragDepth = gl_FragColor.x;\n"
+ "%s"
"}\n",
fs_preprocess, shader->type, fs_input,
- shader->func, shader->texcoords);
+ shader->func, shader->texcoords,
+ do_depth ? " gl_FragDepth = gl_FragColor.x;\n" : "");
_mesa_meta_compile_and_link_program(ctx, vs_source, fs_source,
ralloc_asprintf(mem_ctx, "%s blit",
/**
* Configure vertex buffer and vertex array objects for tests
*
- * Regardless of whether a new VAO and new VBO are created, the objects
- * referenced by \c VAO and \c VBO will be bound into the GL state vector
- * when this function terminates.
+ * Regardless of whether a new VAO is created, the object referenced by \c VAO
+ * will be bound into the GL state vector when this function terminates. The
+ * object referenced by \c VBO will \b not be bound.
*
* \param VAO Storage for vertex array object handle. If 0, a new VAO
* will be created.
- * \param VBO Storage for vertex buffer object handle. If 0, a new VBO
+ * \param buf_obj Storage for vertex buffer object pointer. If \c NULL, a new VBO
* will be created. The new VBO will have storage for 4
* \c vertex structures.
* \param use_generic_attributes Should generic attributes 0 and 1 be used,
* Use \c texcoord_size instead.
*/
void
-_mesa_meta_setup_vertex_objects(GLuint *VAO, GLuint *VBO,
+_mesa_meta_setup_vertex_objects(struct gl_context *ctx,
+ GLuint *VAO, struct gl_buffer_object **buf_obj,
bool use_generic_attributes,
unsigned vertex_size, unsigned texcoord_size,
unsigned color_size)
{
if (*VAO == 0) {
- assert(*VBO == 0);
+ struct gl_vertex_array_object *array_obj;
+ assert(*buf_obj == NULL);
/* create vertex array object */
_mesa_GenVertexArrays(1, VAO);
_mesa_BindVertexArray(*VAO);
+ array_obj = _mesa_lookup_vao(ctx, *VAO);
+ assert(array_obj != NULL);
+
/* create vertex array buffer */
- _mesa_GenBuffers(1, VBO);
- _mesa_BindBuffer(GL_ARRAY_BUFFER, *VBO);
- _mesa_BufferData(GL_ARRAY_BUFFER, 4 * sizeof(struct vertex), NULL,
- GL_DYNAMIC_DRAW);
+ *buf_obj = ctx->Driver.NewBufferObject(ctx, 0xDEADBEEF);
+ if (*buf_obj == NULL)
+ return;
+
+ _mesa_buffer_data(ctx, *buf_obj, GL_NONE, 4 * sizeof(struct vertex), NULL,
+ GL_DYNAMIC_DRAW, __func__);
/* setup vertex arrays */
if (use_generic_attributes) {
assert(color_size == 0);
- _mesa_VertexAttribPointer(0, vertex_size, GL_FLOAT, GL_FALSE,
- sizeof(struct vertex), OFFSET(x));
- _mesa_EnableVertexAttribArray(0);
-
+ _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_GENERIC(0),
+ vertex_size, GL_FLOAT, GL_RGBA, GL_FALSE,
+ GL_FALSE, GL_FALSE,
+ offsetof(struct vertex, x), true);
+ _mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_GENERIC(0),
+ *buf_obj, 0, sizeof(struct vertex));
+ _mesa_enable_vertex_array_attrib(ctx, array_obj,
+ VERT_ATTRIB_GENERIC(0));
if (texcoord_size > 0) {
- _mesa_VertexAttribPointer(1, texcoord_size, GL_FLOAT, GL_FALSE,
- sizeof(struct vertex), OFFSET(tex));
- _mesa_EnableVertexAttribArray(1);
+ _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_GENERIC(1),
+ texcoord_size, GL_FLOAT, GL_RGBA,
+ GL_FALSE, GL_FALSE, GL_FALSE,
+ offsetof(struct vertex, tex), false);
+ _mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_GENERIC(1),
+ *buf_obj, 0, sizeof(struct vertex));
+ _mesa_enable_vertex_array_attrib(ctx, array_obj,
+ VERT_ATTRIB_GENERIC(1));
}
} else {
- _mesa_VertexPointer(vertex_size, GL_FLOAT, sizeof(struct vertex),
- OFFSET(x));
- _mesa_EnableClientState(GL_VERTEX_ARRAY);
+ _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_POS,
+ vertex_size, GL_FLOAT, GL_RGBA, GL_FALSE,
+ GL_FALSE, GL_FALSE,
+ offsetof(struct vertex, x), true);
+ _mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_POS,
+ *buf_obj, 0, sizeof(struct vertex));
+ _mesa_enable_vertex_array_attrib(ctx, array_obj, VERT_ATTRIB_POS);
if (texcoord_size > 0) {
- _mesa_TexCoordPointer(texcoord_size, GL_FLOAT,
- sizeof(struct vertex), OFFSET(tex));
- _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
+ _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_TEX(0),
+ vertex_size, GL_FLOAT, GL_RGBA, GL_FALSE,
+ GL_FALSE, GL_FALSE,
+ offsetof(struct vertex, tex), false);
+ _mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_TEX(0),
+ *buf_obj, 0, sizeof(struct vertex));
+ _mesa_enable_vertex_array_attrib(ctx, array_obj, VERT_ATTRIB_TEX(0));
}
if (color_size > 0) {
- _mesa_ColorPointer(color_size, GL_FLOAT,
- sizeof(struct vertex), OFFSET(r));
- _mesa_EnableClientState(GL_COLOR_ARRAY);
+ _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_COLOR0,
+ vertex_size, GL_FLOAT, GL_RGBA, GL_FALSE,
+ GL_FALSE, GL_FALSE,
+ offsetof(struct vertex, r), false);
+ _mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_COLOR0,
+ *buf_obj, 0, sizeof(struct vertex));
+ _mesa_enable_vertex_array_attrib(ctx, array_obj, VERT_ATTRIB_COLOR0);
}
}
} else {
_mesa_BindVertexArray(*VAO);
- _mesa_BindBuffer(GL_ARRAY_BUFFER, *VBO);
}
}
void
_mesa_meta_init(struct gl_context *ctx)
{
- ASSERT(!ctx->Meta);
+ assert(!ctx->Meta);
ctx->Meta = CALLOC_STRUCT(gl_meta_state);
}
{
GET_CURRENT_CONTEXT(old_context);
_mesa_make_current(ctx, NULL, NULL);
- _mesa_meta_glsl_blit_cleanup(&ctx->Meta->Blit);
- meta_glsl_clear_cleanup(&ctx->Meta->Clear);
- _mesa_meta_glsl_generate_mipmap_cleanup(&ctx->Meta->Mipmap);
+ _mesa_meta_glsl_blit_cleanup(ctx, &ctx->Meta->Blit);
+ meta_glsl_clear_cleanup(ctx, &ctx->Meta->Clear);
+ _mesa_meta_glsl_generate_mipmap_cleanup(ctx, &ctx->Meta->Mipmap);
cleanup_temp_texture(&ctx->Meta->TempTex);
- meta_decompress_cleanup(&ctx->Meta->Decompress);
- meta_drawpix_cleanup(&ctx->Meta->DrawPix);
+ meta_decompress_cleanup(ctx, &ctx->Meta->Decompress);
+ meta_drawpix_cleanup(ctx, &ctx->Meta->DrawPix);
if (old_context)
_mesa_make_current(old_context, old_context->WinSysDrawBuffer, old_context->WinSysReadBuffer);
else
save->API = ctx->API;
ctx->API = API_OPENGL_COMPAT;
+ /* Mesa's extension helper functions use the current context's API to look up
+ * the version required by an extension as a step in determining whether or
+ * not it has been advertised. Since meta aims to only be restricted by the
+ * driver capability (and not by whether or not an extension has been
+ * advertised), set the helper functions' Version variable to a value that
+ * will make the checks on the context API and version unconditionally pass.
+ */
+ save->ExtensionsVersion = ctx->Extensions.Version;
+ ctx->Extensions.Version = ~0;
+
/* Pausing transform feedback needs to be done early, or else we won't be
* able to change other state.
*/
/* Save the shader state from ctx->Shader (instead of ctx->_Shader) so
* that we don't have to worry about the current pipeline state.
*/
- for (i = 0; i <= MESA_SHADER_FRAGMENT; i++) {
+ for (i = 0; i < MESA_SHADER_STAGES; i++) {
_mesa_reference_shader_program(ctx, &save->Shader[i],
ctx->Shader.CurrentProgram[i]);
}
GLuint u, tgt;
save->ActiveUnit = ctx->Texture.CurrentUnit;
- save->ClientActiveUnit = ctx->Array.ActiveTexture;
save->EnvMode = ctx->Texture.Unit[0].EnvMode;
/* Disable all texture units */
/* set defaults for unit[0] */
_mesa_ActiveTexture(GL_TEXTURE0);
- _mesa_ClientActiveTexture(GL_TEXTURE0);
_mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
/* save vertex array object state */
_mesa_reference_vao(ctx, &save->VAO,
ctx->Array.VAO);
- _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj,
- ctx->Array.ArrayBufferObj);
/* set some default state? */
}
save->DepthNear = ctx->ViewportArray[0].Near;
save->DepthFar = ctx->ViewportArray[0].Far;
/* set depth range to default */
- _mesa_DepthRange(0.0, 1.0);
+ _mesa_set_depth_range(ctx, 0, 0.0, 1.0);
}
if (state & MESA_META_CLAMP_FRAGMENT_COLOR) {
void
_mesa_meta_end(struct gl_context *ctx)
{
+ assert(ctx->Meta->SaveStackDepth > 0);
+
struct save_state *save = &ctx->Meta->Save[ctx->Meta->SaveStackDepth - 1];
const GLbitfield state = save->SavedState;
int i;
- /* After starting a new occlusion query, initialize the results to the
- * values saved previously. The driver will then continue to increment
- * these values.
- */
+ /* Grab the result of the old occlusion query before starting it again. The
+ * old result is added to the result of the new query so the driver will
+ * continue adding where it left off. */
if (state & MESA_META_OCCLUSION_QUERY) {
if (save->CurrentOcclusionObject) {
- _mesa_BeginQuery(save->CurrentOcclusionObject->Target,
- save->CurrentOcclusionObject->Id);
- ctx->Query.CurrentOcclusionObject->Result = save->CurrentOcclusionObject->Result;
+ struct gl_query_object *q = save->CurrentOcclusionObject;
+ GLuint64EXT result;
+ if (!q->Ready)
+ ctx->Driver.WaitQuery(ctx, q);
+ result = q->Result;
+ _mesa_BeginQuery(q->Target, q->Id);
+ ctx->Query.CurrentOcclusionObject->Result += result;
}
}
if (state & MESA_META_SHADER) {
static const GLenum targets[] = {
GL_VERTEX_SHADER,
+ GL_TESS_CONTROL_SHADER,
+ GL_TESS_EVALUATION_SHADER,
GL_GEOMETRY_SHADER,
GL_FRAGMENT_SHADER,
+ GL_COMPUTE_SHADER,
};
+ STATIC_ASSERT(MESA_SHADER_STAGES == ARRAY_SIZE(targets));
bool any_shader;
}
any_shader = false;
- for (i = 0; i <= MESA_SHADER_FRAGMENT; i++) {
+ for (i = 0; i < MESA_SHADER_STAGES; i++) {
/* It is safe to call _mesa_use_shader_program even if the extension
* necessary for that program state is not supported. In that case,
* the saved program object must be NULL and the currently bound
if (state & MESA_META_TEXTURE) {
GLuint u, tgt;
- ASSERT(ctx->Texture.CurrentUnit == 0);
+ assert(ctx->Texture.CurrentUnit == 0);
/* restore texenv for unit[0] */
_mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, save->EnvMode);
/* restore current unit state */
_mesa_ActiveTexture(GL_TEXTURE0 + save->ActiveUnit);
- _mesa_ClientActiveTexture(GL_TEXTURE0 + save->ClientActiveUnit);
}
if (state & MESA_META_TRANSFORM) {
}
if (state & MESA_META_VERTEX) {
- /* restore vertex buffer object */
- _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, save->ArrayBufferObj->Name);
- _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj, NULL);
-
/* restore vertex array object */
_mesa_BindVertexArray(save->VAO->Name);
_mesa_reference_vao(ctx, &save->VAO, NULL);
_mesa_set_viewport(ctx, 0, save->ViewportX, save->ViewportY,
save->ViewportW, save->ViewportH);
}
- _mesa_DepthRange(save->DepthNear, save->DepthFar);
+ _mesa_set_depth_range(ctx, 0, save->DepthNear, save->DepthFar);
}
if (state & MESA_META_CLAMP_FRAGMENT_COLOR &&
_mesa_BindRenderbuffer(GL_RENDERBUFFER, save->RenderbufferName);
if (state & MESA_META_DRAW_BUFFERS) {
- _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers, save->ColorDrawBuffers, NULL);
+ _mesa_drawbuffers(ctx, ctx->DrawBuffer, ctx->Const.MaxDrawBuffers,
+ save->ColorDrawBuffers, NULL);
}
ctx->Meta->SaveStackDepth--;
ctx->API = save->API;
-}
-
-
-/**
- * Determine whether Mesa is currently in a meta state.
- */
-GLboolean
-_mesa_meta_in_progress(struct gl_context *ctx)
-{
- return ctx->Meta->SaveStackDepth != 0;
+ ctx->Extensions.Version = save->ExtensionsVersion;
}
{
GLboolean newTex = GL_FALSE;
- ASSERT(width <= tex->MaxSize);
- ASSERT(height <= tex->MaxSize);
+ assert(width <= tex->MaxSize);
+ assert(height <= tex->MaxSize);
if (width > tex->Width ||
height > tex->Height ||
}
void
-_mesa_meta_setup_ff_tnl_for_blit(GLuint *VAO, GLuint *VBO,
+_mesa_meta_setup_ff_tnl_for_blit(struct gl_context *ctx,
+ GLuint *VAO, struct gl_buffer_object **buf_obj,
unsigned texcoord_size)
{
- _mesa_meta_setup_vertex_objects(VAO, VBO, false, 2, texcoord_size, 0);
+ _mesa_meta_setup_vertex_objects(ctx, VAO, buf_obj, false, 2, texcoord_size,
+ 0);
/* setup projection matrix */
_mesa_MatrixMode(GL_PROJECTION);
const char *vs_source =
"#extension GL_AMD_vertex_shader_layer : enable\n"
"#extension GL_ARB_draw_instanced : enable\n"
- "attribute vec4 position;\n"
+ "#extension GL_ARB_explicit_attrib_location :enable\n"
+ "layout(location = 0) in vec4 position;\n"
"void main()\n"
"{\n"
"#ifdef GL_AMD_vertex_shader_layer\n"
" gl_Position = position;\n"
"}\n";
const char *fs_source =
- "uniform vec4 color;\n"
+ "#extension GL_ARB_explicit_attrib_location :enable\n"
+ "#extension GL_ARB_explicit_uniform_location :enable\n"
+ "layout(location = 0) uniform vec4 color;\n"
"void main()\n"
"{\n"
" gl_FragColor = color;\n"
GLuint vs, fs;
bool has_integer_textures;
- _mesa_meta_setup_vertex_objects(&clear->VAO, &clear->VBO, true, 3, 0, 0);
+ _mesa_meta_setup_vertex_objects(ctx, &clear->VAO, &clear->buf_obj, true,
+ 3, 0, 0);
if (clear->ShaderProg != 0)
return;
_mesa_DeleteShader(fs);
_mesa_AttachShader(clear->ShaderProg, vs);
_mesa_DeleteShader(vs);
- _mesa_BindAttribLocation(clear->ShaderProg, 0, "position");
_mesa_ObjectLabel(GL_PROGRAM, clear->ShaderProg, -1, "meta clear");
_mesa_LinkProgram(clear->ShaderProg);
- clear->ColorLocation = _mesa_GetUniformLocation(clear->ShaderProg, "color");
-
has_integer_textures = _mesa_is_gles3(ctx) ||
(_mesa_is_desktop_gl(ctx) && ctx->Const.GLSLVersion >= 130);
"#version 130\n"
"#extension GL_AMD_vertex_shader_layer : enable\n"
"#extension GL_ARB_draw_instanced : enable\n"
- "in vec4 position;\n"
+ "#extension GL_ARB_explicit_attrib_location :enable\n"
+ "layout(location = 0) in vec4 position;\n"
"void main()\n"
"{\n"
"#ifdef GL_AMD_vertex_shader_layer\n"
const char *fs_int_source =
ralloc_asprintf(shader_source_mem_ctx,
"#version 130\n"
- "uniform ivec4 color;\n"
+ "#extension GL_ARB_explicit_attrib_location :enable\n"
+ "#extension GL_ARB_explicit_uniform_location :enable\n"
+ "layout(location = 0) uniform ivec4 color;\n"
"out ivec4 out_color;\n"
"\n"
"void main()\n"
_mesa_DeleteShader(fs);
_mesa_AttachShader(clear->IntegerShaderProg, vs);
_mesa_DeleteShader(vs);
- _mesa_BindAttribLocation(clear->IntegerShaderProg, 0, "position");
/* Note that user-defined out attributes get automatically assigned
* locations starting from 0, so we don't need to explicitly
_mesa_ObjectLabel(GL_PROGRAM, clear->IntegerShaderProg, -1,
"integer clear");
_mesa_meta_link_program_with_debug(ctx, clear->IntegerShaderProg);
-
- clear->IntegerColorLocation =
- _mesa_GetUniformLocation(clear->IntegerShaderProg, "color");
}
}
static void
-meta_glsl_clear_cleanup(struct clear_state *clear)
+meta_glsl_clear_cleanup(struct gl_context *ctx, struct clear_state *clear)
{
if (clear->VAO == 0)
return;
_mesa_DeleteVertexArrays(1, &clear->VAO);
clear->VAO = 0;
- _mesa_DeleteBuffers(1, &clear->VBO);
- clear->VBO = 0;
+ _mesa_reference_buffer_object(ctx, &clear->buf_obj, NULL);
_mesa_DeleteProgram(clear->ShaderProg);
clear->ShaderProg = 0;
y1 = ((float) fb->_Ymax / fb->Height) * 2.0f - 1.0f;
z = -invert_z(ctx->Depth.Clear);
} else {
- _mesa_meta_setup_vertex_objects(&clear->VAO, &clear->VBO, false, 3, 0, 4);
+ _mesa_meta_setup_vertex_objects(ctx, &clear->VAO, &clear->buf_obj, false,
+ 3, 0, 4);
x0 = (float) fb->_Xmin;
y0 = (float) fb->_Ymin;
if (fb->_IntegerColor) {
assert(glsl);
_mesa_UseProgram(clear->IntegerShaderProg);
- _mesa_Uniform4iv(clear->IntegerColorLocation, 1,
- ctx->Color.ClearColor.i);
+ _mesa_Uniform4iv(0, 1, ctx->Color.ClearColor.i);
} else if (glsl) {
_mesa_UseProgram(clear->ShaderProg);
- _mesa_Uniform4fv(clear->ColorLocation, 1,
- ctx->Color.ClearColor.f);
+ _mesa_Uniform4fv(0, 1, ctx->Color.ClearColor.f);
}
/* GL_COLOR_BUFFER_BIT */
_mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE);
}
else {
- ASSERT(metaSave & MESA_META_COLOR_MASK);
+ assert(metaSave & MESA_META_COLOR_MASK);
_mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
}
}
/* upload new vertex data */
- _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts,
- GL_DYNAMIC_DRAW_ARB);
+ _mesa_buffer_data(ctx, clear->buf_obj, GL_NONE, sizeof(verts), verts,
+ GL_DYNAMIC_DRAW, __func__);
/* draw quad(s) */
if (fb->MaxNumLayers > 0) {
MESA_META_VERTEX |
MESA_META_VIEWPORT));
- _mesa_meta_setup_vertex_objects(©pix->VAO, ©pix->VBO, false,
+ _mesa_meta_setup_vertex_objects(ctx, ©pix->VAO, ©pix->buf_obj, false,
3, 2, 0);
/* Silence valgrind warnings about reading uninitialized stack. */
verts[3].tex[1] = tex->Ttop;
/* upload new vertex data */
- _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
+ _mesa_buffer_sub_data(ctx, copypix->buf_obj, 0, sizeof(verts), verts,
+ __func__);
}
_mesa_set_enable(ctx, tex->Target, GL_TRUE);
}
static void
-meta_drawpix_cleanup(struct drawpix_state *drawpix)
+meta_drawpix_cleanup(struct gl_context *ctx, struct drawpix_state *drawpix)
{
if (drawpix->VAO != 0) {
_mesa_DeleteVertexArrays(1, &drawpix->VAO);
drawpix->VAO = 0;
- _mesa_DeleteBuffers(1, &drawpix->VBO);
- drawpix->VBO = 0;
+ _mesa_reference_buffer_object(ctx, &drawpix->buf_obj, NULL);
}
if (drawpix->StencilFP != 0) {
newTex = _mesa_meta_alloc_texture(tex, width, height, texIntFormat);
- _mesa_meta_setup_vertex_objects(&drawpix->VAO, &drawpix->VBO, false,
+ _mesa_meta_setup_vertex_objects(ctx, &drawpix->VAO, &drawpix->buf_obj, false,
3, 2, 0);
/* Silence valgrind warnings about reading uninitialized stack. */
}
/* upload new vertex data */
- _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts),
- verts, GL_DYNAMIC_DRAW_ARB);
+ _mesa_buffer_data(ctx, drawpix->buf_obj, GL_NONE, sizeof(verts), verts,
+ GL_DYNAMIC_DRAW, __func__);
/* set given unpack params */
ctx->Unpack = *unpack;
MESA_META_VERTEX |
MESA_META_VIEWPORT));
- _mesa_meta_setup_vertex_objects(&bitmap->VAO, &bitmap->VBO, false, 3, 2, 4);
+ _mesa_meta_setup_vertex_objects(ctx, &bitmap->VAO, &bitmap->buf_obj, false,
+ 3, 2, 4);
newTex = _mesa_meta_alloc_texture(tex, width, height, texIntFormat);
}
/* upload new vertex data */
- _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
+ _mesa_buffer_sub_data(ctx, bitmap->buf_obj, 0, sizeof(verts), verts,
+ __func__);
}
/* choose different foreground/background alpha values */
/**
* Compute the texture coordinates for the four vertices of a quad for
- * drawing a 2D texture image or slice of a cube/3D texture.
+ * drawing a 2D texture image or slice of a cube/3D texture. The offset
+ * and width, height specify a sub-region of the 2D image.
+ *
* \param faceTarget GL_TEXTURE_1D/2D/3D or cube face name
* \param slice slice of a 1D/2D array texture or 3D texture
- * \param width width of the texture image
- * \param height height of the texture image
+ * \param xoffset X position of sub texture
+ * \param yoffset Y position of sub texture
+ * \param width width of the sub texture image
+ * \param height height of the sub texture image
+ * \param total_width total width of the texture image
+ * \param total_height total height of the texture image
+ * \param total_depth total depth of the texture image
* \param coords0/1/2/3 returns the computed texcoords
*/
void
_mesa_meta_setup_texture_coords(GLenum faceTarget,
GLint slice,
+ GLint xoffset,
+ GLint yoffset,
GLint width,
GLint height,
- GLint depth,
+ GLint total_width,
+ GLint total_height,
+ GLint total_depth,
GLfloat coords0[4],
GLfloat coords1[4],
GLfloat coords2[4],
GLfloat coords3[4])
{
- static const GLfloat st[4][2] = {
- {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}
- };
+ float st[4][2];
GLuint i;
+ const float s0 = (float) xoffset / (float) total_width;
+ const float s1 = (float) (xoffset + width) / (float) total_width;
+ const float t0 = (float) yoffset / (float) total_height;
+ const float t1 = (float) (yoffset + height) / (float) total_height;
GLfloat r;
+ /* setup the reference texcoords */
+ st[0][0] = s0;
+ st[0][1] = t0;
+ st[1][0] = s1;
+ st[1][1] = t0;
+ st[2][0] = s1;
+ st[2][1] = t1;
+ st[3][0] = s0;
+ st[3][1] = t1;
+
if (faceTarget == GL_TEXTURE_CUBE_MAP_ARRAY)
faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice % 6;
case GL_TEXTURE_3D:
case GL_TEXTURE_2D_ARRAY:
if (faceTarget == GL_TEXTURE_3D) {
- assert(slice < depth);
- assert(depth >= 1);
- r = (slice + 0.5f) / depth;
+ assert(slice < total_depth);
+ assert(total_depth >= 1);
+ r = (slice + 0.5f) / total_depth;
}
else if (faceTarget == GL_TEXTURE_2D_ARRAY)
r = (float) slice;
else
r = 0.0F;
- coords0[0] = 0.0F; /* s */
- coords0[1] = 0.0F; /* t */
+ coords0[0] = st[0][0]; /* s */
+ coords0[1] = st[0][1]; /* t */
coords0[2] = r; /* r */
- coords1[0] = 1.0F;
- coords1[1] = 0.0F;
+ coords1[0] = st[1][0];
+ coords1[1] = st[1][1];
coords1[2] = r;
- coords2[0] = 1.0F;
- coords2[1] = 1.0F;
+ coords2[0] = st[2][0];
+ coords2[1] = st[2][1];
coords2[2] = r;
- coords3[0] = 0.0F;
- coords3[1] = 1.0F;
+ coords3[0] = st[3][0];
+ coords3[1] = st[3][1];
coords3[2] = r;
break;
case GL_TEXTURE_RECTANGLE_ARB:
- coords0[0] = 0.0F; /* s */
- coords0[1] = 0.0F; /* t */
+ coords0[0] = (float) xoffset; /* s */
+ coords0[1] = (float) yoffset; /* t */
coords0[2] = 0.0F; /* r */
- coords1[0] = (float) width;
- coords1[1] = 0.0F;
+ coords1[0] = (float) (xoffset + width);
+ coords1[1] = (float) yoffset;
coords1[2] = 0.0F;
- coords2[0] = (float) width;
- coords2[1] = (float) height;
+ coords2[0] = (float) (xoffset + width);
+ coords2[1] = (float) (yoffset + height);
coords2[2] = 0.0F;
- coords3[0] = 0.0F;
- coords3[1] = (float) height;
+ coords3[0] = (float) xoffset;
+ coords3[1] = (float) (yoffset + height);
coords3[2] = 0.0F;
break;
case GL_TEXTURE_1D_ARRAY:
- coords0[0] = 0.0F; /* s */
+ coords0[0] = st[0][0]; /* s */
coords0[1] = (float) slice; /* t */
coords0[2] = 0.0F; /* r */
- coords1[0] = 1.0f;
+ coords1[0] = st[1][0];
coords1[1] = (float) slice;
coords1[2] = 0.0F;
- coords2[0] = 1.0F;
+ coords2[0] = st[2][0];
coords2[1] = (float) slice;
coords2[2] = 0.0F;
- coords3[0] = 0.0F;
+ coords3[0] = st[3][0];
coords3[1] = (float) slice;
coords3[2] = 0.0F;
break;
* are too strict for CopyTexImage. We know meta will be fine with format
* changes.
*/
- mask = _mesa_meta_BlitFramebuffer(ctx, x, y,
+ mask = _mesa_meta_BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
+ x, y,
x + width, y + height,
xoffset, yoffset,
xoffset + width, yoffset + height,
}
static void
-meta_decompress_cleanup(struct decompress_state *decompress)
+meta_decompress_cleanup(struct gl_context *ctx,
+ struct decompress_state *decompress)
{
meta_decompress_fbo_cleanup(&decompress->byteFBO);
meta_decompress_fbo_cleanup(&decompress->floatFBO);
if (decompress->VAO != 0) {
_mesa_DeleteVertexArrays(1, &decompress->VAO);
- _mesa_DeleteBuffers(1, &decompress->VBO);
+ _mesa_reference_buffer_object(ctx, &decompress->buf_obj, NULL);
}
if (decompress->Sampler != 0)
decompress_texture_image(struct gl_context *ctx,
struct gl_texture_image *texImage,
GLuint slice,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
GLenum destFormat, GLenum destType,
GLvoid *dest)
{
struct decompress_state *decompress = &ctx->Meta->Decompress;
struct decompress_fbo_state *decompress_fbo;
struct gl_texture_object *texObj = texImage->TexObject;
- const GLint width = texImage->Width;
- const GLint height = texImage->Height;
- const GLint depth = texImage->Height;
const GLenum target = texObj->Target;
GLenum rbFormat;
GLenum faceTarget;
}
if (use_glsl_version) {
- _mesa_meta_setup_vertex_objects(&decompress->VAO, &decompress->VBO, true,
+ _mesa_meta_setup_vertex_objects(ctx, &decompress->VAO,
+ &decompress->buf_obj, true,
2, 4, 0);
- _mesa_meta_setup_blit_shader(ctx, target, &decompress->shaders);
+ _mesa_meta_setup_blit_shader(ctx, target, false, &decompress->shaders);
} else {
- _mesa_meta_setup_ff_tnl_for_blit(&decompress->VAO, &decompress->VBO, 3);
+ _mesa_meta_setup_ff_tnl_for_blit(ctx, &decompress->VAO,
+ &decompress->buf_obj, 3);
}
if (!decompress->Sampler) {
/* Silence valgrind warnings about reading uninitialized stack. */
memset(verts, 0, sizeof(verts));
- _mesa_meta_setup_texture_coords(faceTarget, slice, width, height, depth,
+ _mesa_meta_setup_texture_coords(faceTarget, slice,
+ xoffset, yoffset, width, height,
+ texImage->Width, texImage->Height,
+ texImage->Depth,
verts[0].tex,
verts[1].tex,
verts[2].tex,
_mesa_set_viewport(ctx, 0, 0, 0, width, height);
/* upload new vertex data */
- _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
+ _mesa_buffer_sub_data(ctx, decompress->buf_obj, 0, sizeof(verts), verts,
+ __func__);
/* setup texture state */
_mesa_BindTexture(target, texObj->Name);
/* read pixels from renderbuffer */
{
GLenum baseTexFormat = texImage->_BaseFormat;
- GLenum destBaseFormat = _mesa_base_tex_format(ctx, destFormat);
+ GLenum destBaseFormat = _mesa_unpack_format_to_base_format(destFormat);
/* The pixel transfer state will be set to default values at this point
* (see MESA_META_PIXEL_TRANSFER) so pixel transfer ops are effectively
* returned as red and two-channel texture values are returned as
* red/alpha.
*/
- if ((baseTexFormat == GL_LUMINANCE ||
- baseTexFormat == GL_LUMINANCE_ALPHA ||
- baseTexFormat == GL_INTENSITY) ||
+ if (_mesa_need_luminance_to_rgb_conversion(baseTexFormat,
+ destBaseFormat) ||
/* If we're reading back an RGB(A) texture (using glGetTexImage) as
* luminance then we need to return L=tex(R).
*/
- ((baseTexFormat == GL_RGBA ||
- baseTexFormat == GL_RGB ||
- baseTexFormat == GL_RG) &&
- (destBaseFormat == GL_LUMINANCE ||
- destBaseFormat == GL_LUMINANCE_ALPHA ||
- destBaseFormat == GL_LUMINANCE_INTEGER_EXT ||
- destBaseFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT))) {
+ _mesa_need_rgb_to_luminance_conversion(baseTexFormat,
+ destBaseFormat)) {
/* Green and blue must be zero */
_mesa_PixelTransferf(GL_GREEN_SCALE, 0.0f);
_mesa_PixelTransferf(GL_BLUE_SCALE, 0.0f);
* from core Mesa.
*/
void
-_mesa_meta_GetTexImage(struct gl_context *ctx,
- GLenum format, GLenum type, GLvoid *pixels,
- struct gl_texture_image *texImage)
+_mesa_meta_GetTexSubImage(struct gl_context *ctx,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, GLvoid *pixels,
+ struct gl_texture_image *texImage)
{
if (_mesa_is_format_compressed(texImage->TexFormat)) {
GLuint slice;
bool result = true;
- for (slice = 0; slice < texImage->Depth; slice++) {
+ for (slice = 0; slice < depth; slice++) {
void *dst;
if (texImage->TexObject->Target == GL_TEXTURE_2D_ARRAY
|| texImage->TexObject->Target == GL_TEXTURE_CUBE_MAP_ARRAY) {
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);
+ dst = _mesa_image_address3d(&packing, pixels, width, height,
+ format, type, slice, 0, 0);
}
else {
dst = pixels;
}
result = decompress_texture_image(ctx, texImage, slice,
+ xoffset, yoffset, width, height,
format, type, dst);
if (!result)
break;
return;
}
- _mesa_GetTexImage_sw(ctx, format, type, pixels, texImage);
+ _mesa_GetTexSubImage_sw(ctx, xoffset, yoffset, zoffset,
+ width, height, depth, format, type, pixels, texImage);
}
if (drawtex->VAO == 0) {
/* one-time setup */
- GLint active_texture;
+ struct gl_vertex_array_object *array_obj;
/* create vertex array object */
_mesa_GenVertexArrays(1, &drawtex->VAO);
_mesa_BindVertexArray(drawtex->VAO);
+ array_obj = _mesa_lookup_vao(ctx, drawtex->VAO);
+ assert(array_obj != NULL);
+
/* create vertex array buffer */
- _mesa_GenBuffers(1, &drawtex->VBO);
- _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, drawtex->VBO);
- _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts),
- NULL, GL_DYNAMIC_DRAW_ARB);
+ drawtex->buf_obj = ctx->Driver.NewBufferObject(ctx, 0xDEADBEEF);
+ if (drawtex->buf_obj == NULL)
+ return;
- /* client active texture is not part of the array object */
- active_texture = ctx->Array.ActiveTexture;
+ _mesa_buffer_data(ctx, drawtex->buf_obj, GL_NONE, sizeof(verts), verts,
+ GL_DYNAMIC_DRAW, __func__);
/* setup vertex arrays */
- _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
- _mesa_EnableClientState(GL_VERTEX_ARRAY);
+ _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_POS,
+ 3, GL_FLOAT, GL_RGBA, GL_FALSE,
+ GL_FALSE, GL_FALSE,
+ offsetof(struct vertex, x), true);
+ _mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_POS,
+ drawtex->buf_obj, 0, sizeof(struct vertex));
+ _mesa_enable_vertex_array_attrib(ctx, array_obj, VERT_ATTRIB_POS);
+
+
for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
- _mesa_ClientActiveTexture(GL_TEXTURE0 + i);
- _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(st[i]));
- _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
+ _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_TEX(i),
+ 2, GL_FLOAT, GL_RGBA, GL_FALSE,
+ GL_FALSE, GL_FALSE,
+ offsetof(struct vertex, st[i]), true);
+ _mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_TEX(i),
+ drawtex->buf_obj, 0, sizeof(struct vertex));
+ _mesa_enable_vertex_array_attrib(ctx, array_obj, VERT_ATTRIB_TEX(i));
}
-
- /* restore client active texture */
- _mesa_ClientActiveTexture(GL_TEXTURE0 + active_texture);
}
else {
_mesa_BindVertexArray(drawtex->VAO);
- _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, drawtex->VBO);
}
/* vertex positions, texcoords */
verts[3].st[i][1] = t1;
}
- _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
+ _mesa_buffer_sub_data(ctx, drawtex->buf_obj, 0, sizeof(verts), verts,
+ __func__);
}
_mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);