/* $Id$ */
/** @file
* VBox OpenGL DRI driver functions
*/
/*
* Copyright (C) 2009-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
* --------------------------------------------------------------------
*
* following copyright notice:
*
* Copyright 2000 VA Linux Systems Inc., Fremont, California.
*
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Original rewrite:
* Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
*
* Authors:
* Gareth Hughes <gareth@valinux.com>
*/
#include "cr_error.h"
#include "cr_gl.h"
#include "stub.h"
#include "dri_drv.h"
#include "DD_gl.h"
/** @todo some of those are or'ed with GL_VERSIONS and ain't needed here*/
#define need_GL_ARB_occlusion_query
#define need_GL_ARB_point_parameters
#define need_GL_NV_point_sprite
#define need_GL_ARB_texture_compression
#define need_GL_ARB_transpose_matrix
#define need_GL_ARB_vertex_buffer_object
#define need_GL_ARB_vertex_program
#define need_GL_ARB_window_pos
#define need_GL_EXT_blend_color
#define need_GL_EXT_blend_minmax
#define need_GL_EXT_blend_func_separate
#define need_GL_EXT_fog_coord
#define need_GL_EXT_multi_draw_arrays
#define need_GL_EXT_secondary_color
#define need_GL_EXT_texture_object
#define need_GL_EXT_texture3D
#define need_GL_VERSION_1_3
#define need_GL_VERSION_1_4
#define need_GL_VERSION_1_5
#include "drivers/dri/common/extension_helper.h"
/** @todo add more which are supported by chromium like GL_NV_vertex_program etc.*/
{ "GL_ARB_depth_texture", NULL },
{ "GL_ARB_fragment_program", NULL },
{ "GL_ARB_multitexture", NULL },
{ "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions },
{ "GL_ARB_point_parameters", GL_ARB_point_parameters_functions },
{ "GL_NV_point_sprite", GL_NV_point_sprite_functions },
{ "GL_ARB_shadow", NULL },
{ "GL_ARB_shadow_ambient", NULL },
{ "GL_ARB_texture_border_clamp", NULL },
{ "GL_ARB_texture_compression", GL_ARB_texture_compression_functions },
{ "GL_ARB_texture_cube_map", NULL },
{ "GL_ARB_texture_env_add", NULL },
{ "GL_ARB_texture_env_combine", NULL },
{ "GL_EXT_texture_env_combine", NULL },
{ "GL_ARB_texture_env_crossbar", NULL },
{ "GL_ARB_texture_env_dot3", NULL },
{ "GL_EXT_texture_env_dot3", NULL },
{ "GL_ARB_texture_mirrored_repeat", NULL },
{ "GL_ARB_texture_non_power_of_two", NULL },
{ "GL_ARB_transpose_matrix", GL_ARB_transpose_matrix_functions },
{ "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions },
{ "GL_ARB_vertex_program", GL_ARB_vertex_program_functions },
{ "GL_ARB_window_pos", GL_ARB_window_pos_functions },
{ "GL_EXT_blend_color", GL_EXT_blend_color_functions },
{ "GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions },
{ "GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions },
{ "GL_EXT_blend_subtract", NULL },
{ "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
{ "GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions },
{ "GL_EXT_secondary_color", GL_EXT_secondary_color_functions },
{ "GL_EXT_shadow_funcs", NULL },
{ "GL_EXT_stencil_wrap", NULL },
{ "GL_EXT_texture_edge_clamp", NULL },
{ "GL_EXT_texture_filter_anisotropic", NULL },
{ "GL_EXT_texture_lod_bias", NULL },
{ "GL_EXT_texture_object", GL_EXT_texture_object_functions },
{ "GL_EXT_texture3D", GL_EXT_texture3D_functions },
{ "GL_NV_texgen_reflection", NULL },
{ "GL_ARB_texture_rectangle", NULL },
{ "GL_SGIS_generate_mipmap", NULL },
};
static void
{
/** @todo have to check extensions supported by host here first */
}
/* This callback tells us that Mesa's internal state has changed. We probably
* don't need to handle this ourselves, so just pass it on to other parts of
* Mesa we may be using, as the swrast driver and others do */
static void
{
}
#if 0 /* See comment in vboxdriInitFuncs */
static void
{
/*do something, note it's obsolete*/
}
static void
{
/*do something, note it's obsolete*/
}
static void
{
//__GLcontextRec::ErrorValue contains the error value.
}
#endif
static void
const struct gl_pixelstore_attrib *unpack,
{
}
static void
const struct gl_pixelstore_attrib *unpack,
{
}
static void
{
}
static void
const struct gl_pixelstore_attrib *unpack,
{
}
static void
const struct gl_pixelstore_attrib *packing,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
}
static void
const struct gl_pixelstore_attrib *packing,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
}
static void
const struct gl_pixelstore_attrib *packing,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
}
static void
const struct gl_pixelstore_attrib *packing,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
}
static void
const struct gl_pixelstore_attrib *packing,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
}
static void
const struct gl_pixelstore_attrib *packing,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
}
static void
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
}
static void
struct gl_texture_object *tObj)
{
}
static GLboolean
{
}
static void
{
}
static void
{
}
static void
{
}
static void
{
}
static void
{
}
/*@todo Enable or disable server-side gl capabilities, not related to glEnable? */
static void
{
if (state)
else
}
static void
{
}
static void
struct gl_texture_object *texObj,
{
}
/*Note, checking glGetError before and after those calls is the only way
*to return if we succeeded to get value or not, but it will add 2 sync calls and
*will reset glGetError value returned in case application calls it explicitly
*/
static GLboolean
{
return GL_TRUE;
}
static GLboolean
{
return GL_TRUE;
}
static GLboolean
{
return GL_TRUE;
}
static GLboolean
{
return GL_TRUE;
}
static GLboolean
{
return GL_TRUE;
}
/** @todo
* change stub's createcontext to reuse driver private part of mesa's ctx to store stub ctx info.
*/
static void
{
#if 0
/* I assume that we don't need to change these. In that case, prefer the
* default implementation over a stub. */
#endif
/* framebuffer/image functions */
// driver->RasterPos = VBOX_GL_FUNC(RasterPos); /* No such element in *driver */
/* Texture functions */
/** @todo deal with texnames and gl_texture_object pointers which are passed here*/
// driver->GenerateMipmap = VBOX_GL_FUNC(GenerateMipmap); /** @todo or NULL */
// driver->TestProxyTexImage = vboxDDTestProxyTexImage; /** @todo just pass to glTexImage as we take care or proxy textures there */
// driver->CompressedTexImage1D = VBOX_GL_FUNC(CompressedTexImage1D);
// driver->CompressedTexImage2D = VBOX_GL_FUNC(CompressedTexImage2D);
// driver->CompressedTexImage3D = VBOX_GL_FUNC(CompressedTexImage3D);
// driver->CompressedTexSubImage1D = VBOX_GL_FUNC(CompressedTexSubImage1D);
// driver->CompressedTexSubImage2D = VBOX_GL_FUNC(CompressedTexSubImage2D);
// driver->CompressedTexSubImage3D = VBOX_GL_FUNC(CompressedTexSubImage3D);
// driver->GetCompressedTexImage = VBOX_GL_FUNC(GetCompressedTexImage);
// driver->CompressedTextureSize = NULL; /** @todo */
// driver->NewTextureObject = vboxDDNewTextureObject; /** @todo */
// driver->DeleteTexture = vboxDDDeleteTexture; /** @todo */
// driver->NewTextureImage = vboxDDNewTextureImage; /** @todo */
// driver->FreeTexImageData = vboxDDFreeTexImageData; /** @todo */
// driver->MapTexture = vboxDDMapTexture; /** @todo */
// driver->UnmapTexture = vboxDDUnmapTexture; /** @todo */
// driver->TextureMemCpy = vboxDDTextureMemCpy; /** @todo */
// driver->UpdateTexturePalette = vboxDDUpdateTexturePalette; /** @todo */
/* imaging */
/*driver->CopyColorTable = _swrast_CopyColorTable;
driver->CopyColorSubTable = _swrast_CopyColorSubTable;
driver->CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
driver->CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;*/
// driver->NewProgram = _mesa_new_program; /** @todo */
// driver->DeleteProgram = _mesa_delete_program; /** @todo */
// driver->GetProgramRegister = _mesa_get_program_register; /** @todo */
#endif /* FEATURE_MESA_program_debug */
/* simple state commands */
// driver->BlendEquationSeparate = VBOX_GL_FUNC(BlendEquationSeparate); /** @todo */
// driver->DrawBuffers = VBOX_GL_FUNC(DrawBuffers); /** @todo */
// driver->LogicOpcode = VBOX_GL_FUNC(LogicOpcode); /** @todo */
// driver->StencilFuncSeparate = VBOX_GL_FUNC(StencilFuncSeparate); /** @todo */
// driver->StencilOpSeparate = VBOX_GL_FUNC(StencilOpSeparate); /** @todo */
// driver->StencilMaskSeparate = VBOX_GL_FUNC(StencilMaskSeparate); /** @todo */
// driver->TextureMatrix = VBOX_GL_FUNC(TextureMatrix); /** @todo */
/* vertex arrays */
// driver->VertexAttribPointer = VBOX_GL_FUNC(VertexAttribPointer); /** @todo */
// driver->LockArraysEXT = VBOX_GL_FUNC(LockArraysEXT); /** @todo */
// driver->UnlockArraysEXT = VBOX_GL_FUNC(UnlockArraysEXT); /** @todo */
/* state queries */
/** @todo */
// driver->NewBufferObject = _mesa_new_buffer_object;
// driver->DeleteBuffer = _mesa_delete_buffer_object;
// driver->BindBuffer = NULL;
// driver->BufferData = _mesa_buffer_data;
// driver->BufferSubData = _mesa_buffer_subdata;
// driver->GetBufferSubData = _mesa_buffer_get_subdata;
// driver->MapBuffer = _mesa_buffer_map;
// driver->UnmapBuffer = _mesa_buffer_unmap;
#endif
/** @todo */
// driver->NewFramebuffer = _mesa_new_framebuffer;
// driver->NewRenderbuffer = _mesa_new_soft_renderbuffer;
// driver->RenderTexture = _mesa_render_texture;
// driver->FinishRenderTexture = _mesa_finish_render_texture;
// driver->FramebufferRenderbuffer = _mesa_framebuffer_renderbuffer;
#endif
/** @todo */
// driver->BlitFramebuffer = _swrast_BlitFramebuffer;
#endif
/* query objects */
// driver->NewQueryObject = VBOX_GL_FUNC(NewQueryObject); /** @todo */
// driver->DeleteQuery = VBOX_GL_FUNC(DeleteQuery); /** @todo */
// driver->BeginQuery = VBOX_GL_FUNC(BeginQuery); /** @todo */
// driver->EndQuery = VBOX_GL_FUNC(EndQuery); /** @todo */
// driver->WaitQuery = VBOX_GL_FUNC(WaitQuery); /** @todo */
/* APPLE_vertex_array_object */
/*
driver->NewArrayObject = _mesa_new_array_object;
driver->DeleteArrayObject = _mesa_delete_array_object;
driver->BindArrayObject = NULL;
*/
/* T&L stuff */
driver->CurrentExecPrimitive = 0;
driver->CurrentSavePrimitive = 0;
driver->SaveNeedFlush = 0;
// driver->ProgramStringNotify = _tnl_program_string; /** @todo */
/* display list */
// driver->BeginCallList = VBOX_GL_FUNC(BeginCallList); /** @todo */
// driver->EndCallList = VBOX_GL_FUNC(EndCallList); /** @todo */
/* shaders */
/*
driver->AttachShader = _mesa_attach_shader;
driver->BindAttribLocation = _mesa_bind_attrib_location;
driver->CompileShader = _mesa_compile_shader;
driver->CreateProgram = _mesa_create_program;
driver->CreateShader = _mesa_create_shader;
driver->DeleteProgram2 = _mesa_delete_program2;
driver->DeleteShader = _mesa_delete_shader;
driver->DetachShader = _mesa_detach_shader;
driver->GetActiveAttrib = _mesa_get_active_attrib;
driver->GetActiveUniform = _mesa_get_active_uniform;
driver->GetAttachedShaders = _mesa_get_attached_shaders;
driver->GetAttribLocation = _mesa_get_attrib_location;
driver->GetHandle = _mesa_get_handle;
driver->GetProgramiv = _mesa_get_programiv;
driver->GetProgramInfoLog = _mesa_get_program_info_log;
driver->GetShaderiv = _mesa_get_shaderiv;
driver->GetShaderInfoLog = _mesa_get_shader_info_log;
driver->GetShaderSource = _mesa_get_shader_source;
driver->GetUniformfv = _mesa_get_uniformfv;
driver->GetUniformiv = _mesa_get_uniformiv;
driver->GetUniformLocation = _mesa_get_uniform_location;
driver->IsProgram = _mesa_is_program;
driver->IsShader = _mesa_is_shader;
driver->LinkProgram = _mesa_link_program;
driver->ShaderSource = _mesa_shader_source;
driver->Uniform = _mesa_uniform;
driver->UniformMatrix = _mesa_uniform_matrix;
driver->UseProgram = _mesa_use_program;
driver->ValidateProgram = _mesa_validate_program;
*/
}
static void
{
}
static void
{
}
static void
{
}
/** @todo not sure we need it from start*/
{ __DRI_TEX_OFFSET },
};
/* This DRI extension is required to support EXT_texture_from_pixmap,
* which in turn is required by compiz.
*/
};
/* List of DRI extensions supported by VBox DRI driver */
};
unsigned depth_bits,
unsigned stencil_bits,
{
/* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
* enough to add support. Basically, if a context is created with an
* fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
* will never be used.
*/
if(deep) {
depth_bits_array[0] = 0;
stencil_bits_array[0] = 0;
} else {
depth_bits_array[0] = depth_bits;
depth_bits_array[1] = 0;
depth_bits_array[3] = 0;
stencil_bits_array[0] = 0;
stencil_bits_array[1] = 0;
}
return driCreateConfigs(
db_modes, 2);
}
/**
* This is the driver specific part of the createNewScreen entry point.
* Called when using legacy DRI.
*
* return the __GLcontextModes supported by this driver
*/
{
//PVBoxDRI = (PVBoxDRI) psp->pDevPrivate;
/* Initialise our call table in chromium. */
if (!stubInit())
{
crDebug("vboxdriInitScreen: stubInit failed");
return NULL;
}
if ( ! driCheckDriDdxDrmVersions2( "tdfx",
return NULL;
/* Calling driInitExtensions here, with a NULL context pointer,
* does not actually enable the extensions. It just makes sure
* that all the dispatch offsets for all the extensions that
* *might* be enables are known. This is needed because the
* dispatch offsets need to be known when _mesa_context_create is
* called, but we can't enable the extensions until we have a
* context pointer.
*
* Hello chicken. Hello egg. How are you two today?
*/
/** @todo check size of DRIRec (passed from X.Org driver), allocate private
* structure if necessary, parse options if necessary, map VRAM if
* necessary. */
/* Initialise VtxFmt call table. */
/*return (const __DRIconfig **)
vboxdriFillInModes(psp, dri_priv->cpp * 8,
(dri_priv->cpp == 2) ? 16 : 24,
(dri_priv->cpp == 2) ? 0 : 8, 1);*/
/** @todo This should depend on what the host can do, not the guest.
* However, we will probably want to discover that in the X.Org driver,
* not here. */
}
static void
{
crDebug("vboxdriDestroyScreen");
#if 0 /* From the tdfx driver */
/* free all option information */
#endif
}
static GLboolean
void *sharedContextPrivate)
{
//__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
#if 0 /* We shouldn't need this sort of thing. */
#endif
/* We should be allocating a private context structure, where we will
* remember the Mesa context (ctx) among other things. The TDFX driver
* also saves importand information in driContextPriv in there - is this
* not always available to us? */
//driContextPriv->driverPrivate = vboxctx;
/* Initialise the default driver functions then plug in our vbox ones,
* which will actually replace most of the defaults. */
/** @todo we should also pass some information from the visual back to the
* host. */
/* Allocate context information for Mesa. */
if (sharedContextPrivate)
else
/** @todo save ctx, or be more confident that we can don't need to. */
if (!ctx)
{
crDebug("vboxdriCreateContext: _mesa_create_context failed");
return GL_FALSE;
}
/* The TDFX driver parses its configuration files here, via
* driParseConfigFiles. We will probably get any information via guest
* properties. */
/* Set various context configuration. We take these values from the
* TDFX driver. */
/** @r=Leonid, stub.spu->dispatch_table.GetIntegerv(GL_MAX_TEXTURE_UNITS_ARB,&value) etc.
* Those would be cached where possible, see include/state/cr_limits.h, VBoxOGLgen/packspu_get.c
* Note, that ctx->Const.MaxTextureImageUnits is *not* related to GL_MAX_TEXTURE_UNITS_ARB,
* use GL_MAX_TEXTURE_IMAGE_UNITS_ARB instead.
* Also, those could fail if we haven't made ctx in our stub yet.
*/
/* No wide points.
*/
/* Disable wide lines as we can't antialias them correctly in
* hardware.
*/
/** @note That applies to the TDFX, not to us, but as I don't yet know
* what to use instead I am leaving the values for now. */
/* Initialize the software rasterizer and helper modules - again, TDFX */
/* Install the customized pipeline, TDFX */
/* Configure swrast and T&L to match hardware characteristics, TDFX */
/*ctx->DriverCtx = ;*/
/* This was *not* in the TDFX driver. */
return GL_TRUE;
}
static void
{
// glXDestroyContext(driContextPriv->driverPrivate);
//_mesa_destroy_context ?
}
/**
* This is called when we need to set up GL rendering to a new X window.
*/
static GLboolean
{
return GL_FALSE;
}
static void
{
}
static void
{
}
{
return GL_FALSE;
}
{
return GL_TRUE;
}
/* This structure is used by dri_util from mesa, don't rename it! */
.GetSwapInfo = NULL,
.WaitForMSC = NULL,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL,
.CopySubBuffer = NULL,
.GetDrawableMSC = NULL,
.InitScreen2 = NULL
};