DevVGA-SVGA3d-ogl.cpp revision c6ade8a5a12fad69394e7223b7ea170bd729f0f4
1881dc979c443212bf91478a1799b23a43d8666fvboxsync * DevVMWare - VMWare SVGA device
1881dc979c443212bf91478a1799b23a43d8666fvboxsync * Copyright (C) 2013-2014 Oracle Corporation
1881dc979c443212bf91478a1799b23a43d8666fvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
1881dc979c443212bf91478a1799b23a43d8666fvboxsync * available from http://www.virtualbox.org. This file is free software;
1881dc979c443212bf91478a1799b23a43d8666fvboxsync * you can redistribute it and/or modify it under the terms of the GNU
1881dc979c443212bf91478a1799b23a43d8666fvboxsync * General Public License (GPL) as published by the Free Software
1881dc979c443212bf91478a1799b23a43d8666fvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
1881dc979c443212bf91478a1799b23a43d8666fvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
1881dc979c443212bf91478a1799b23a43d8666fvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1881dc979c443212bf91478a1799b23a43d8666fvboxsync/*******************************************************************************
1881dc979c443212bf91478a1799b23a43d8666fvboxsync* Header Files *
1881dc979c443212bf91478a1799b23a43d8666fvboxsync*******************************************************************************/
/* should go BEFORE any other DevVGA include to make all DevVGA.h config defines be visible */
#include "DevVGA.h"
#include "DevVGA-SVGA.h"
#include "DevVGA-SVGA3d.h"
#include "vmsvga/svga_reg.h"
#include "vmsvga/svga3d_reg.h"
#include "vmsvga/svga3d_shaderdefs.h"
#ifdef RT_OS_WINDOWS
# include "vmsvga_glext/wglext.h"
# include "DevVGA-SVGA3d-cocoa.h"
/* work around conflicting definition of GLhandleARB in VMware's glext.h */
typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
#include "vmsvga_glext/glext.h"
#include "shaderlib/shaderlib.h"
#include <stdlib.h>
#include <math.h>
#include <float.h>
#ifdef RT_OS_WINDOWS
# include <dlfcn.h>
#define D3D_TO_OGL_Y_COORD(ptrSurface, y_coordinate) (ptrSurface->pMipmapLevels[0].size.height - (y_coordinate))
#define D3D_TO_OGL_Y_COORD_MIPLEVEL(ptrMipLevel, y_coordinate) (ptrMipLevel->size.height - (y_coordinate))
#define OPENGL_INVALID_ID 0
#ifdef RT_OS_WINDOWS
#ifdef VBOX_STRICT
AssertMsgReturn((pContext)->lastError == GL_NO_ERROR, ("%s (%d): last error 0x%x\n", __FUNCTION__, __LINE__, (pContext)->lastError), VERR_INTERNAL_ERROR); \
#ifdef VBOX_STRICT
AssertMsg((pContext)->lastError == GL_NO_ERROR, ("%s (%d): last error 0x%x\n", __FUNCTION__, __LINE__, (pContext)->lastError)); \
void *pSurfaceData;
bool fDirty;
} oglId;
bool fDirty;
void *pShaderProgram;
void *pVertexShader;
void *pPixelShader;
bool fValid;
bool fValid;
bool fValid;
bool fEnabled;
bool fValidData;
bool fValid;
#ifdef RT_OS_WINDOWS
bool fMapped;
void *pShaderContext;
/* Keep track of the internal state to be able to recreate the context properly (save/restore, window resize). */
} state;
#ifdef RT_OS_WINDOWS
#ifdef RT_OS_WINDOWS
bool bTerminate;
float fGLVersion;
bool fEXT_stencil_two_side;
} ext;
bool fS3TCSupported;
} caps;
#ifdef RT_OS_WINDOWS
static int vmsvga3dCreateTexture(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, uint32_t idAssociatedContext, PVMSVGA3DSURFACE pSurface);
static void vmsvgaColor2GLFloatArray(uint32_t color, GLfloat *pRed, GLfloat *pGreen, GLfloat *pBlue, GLfloat *pAlpha);
int rc;
#ifdef RT_OS_WINDOWS
return rc;
rc = RTThreadCreate(&pState->pWindowThread, vmsvga3dWindowThread, pState->WndRequestSem, 0, RTTHREADTYPE_GUI, 0, "VMSVGA3DWND");
AssertMsgFailed(("%s: Async IO Thread creation for 3d window handling failed rc=%d\n", __FUNCTION__, rc));
return rc;
return VINF_SUCCESS;
/* We must delay window creation until the PowerOn phase. Init is too early and will cause failures. */
int rc;
/* OpenGL function calls aren't possible without a valid current context, so create a fake one here. */
LogRel(("VMSVGA3d: OpenGL version: %s\nOpenGL Vendor: %s\nOpenGL Renderer: %s\n", glGetString(GL_VERSION), glGetString(GL_VENDOR), glGetString(GL_RENDERER)));
LogRel(("VMSVGA3d: OpenGL shader language version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)));
pState->ext.glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)OGLGETPROCADDRESS("glBindRenderbuffer");
pState->ext.glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)OGLGETPROCADDRESS("glDeleteRenderbuffers");
pState->ext.glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)OGLGETPROCADDRESS("glGenRenderbuffers");
pState->ext.glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)OGLGETPROCADDRESS("glRenderbufferStorage");
pState->ext.glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)OGLGETPROCADDRESS("glGetRenderbufferParameteriv");
pState->ext.glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)OGLGETPROCADDRESS("glDeleteFramebuffers");
pState->ext.glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)OGLGETPROCADDRESS("glCheckFramebufferStatus");
pState->ext.glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)OGLGETPROCADDRESS("glFramebufferTexture1D");
pState->ext.glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)OGLGETPROCADDRESS("glFramebufferTexture2D");
pState->ext.glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)OGLGETPROCADDRESS("glFramebufferTexture3D");
pState->ext.glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)OGLGETPROCADDRESS("glFramebufferRenderbuffer");
pState->ext.glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)OGLGETPROCADDRESS("glGetFramebufferAttachmentParameteriv");
pState->ext.glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)OGLGETPROCADDRESS("glRenderbufferStorageMultisample");
pState->ext.glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)OGLGETPROCADDRESS("glFramebufferTextureLayer");
AssertMsgReturn(pState->ext.glPointParameterf, ("glPointParameterf missing"), VERR_NOT_IMPLEMENTED);
pState->ext.glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)OGLGETPROCADDRESS("glBlendEquationSeparate");
AssertMsgReturn(pState->ext.glBlendEquationSeparate, ("glBlendEquationSeparate missing"), VERR_NOT_IMPLEMENTED);
pState->ext.glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)OGLGETPROCADDRESS("glBlendFuncSeparate");
AssertMsgReturn(pState->ext.glBlendFuncSeparate, ("glBlendFuncSeparate missing"), VERR_NOT_IMPLEMENTED);
pState->ext.glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)OGLGETPROCADDRESS("glStencilOpSeparate");
AssertMsgReturn(pState->ext.glStencilOpSeparate, ("glStencilOpSeparate missing"), VERR_NOT_IMPLEMENTED);
pState->ext.glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC)OGLGETPROCADDRESS("glStencilFuncSeparate");
AssertMsgReturn(pState->ext.glStencilFuncSeparate, ("glStencilFuncSeparate missing"), VERR_NOT_IMPLEMENTED);
pState->ext.glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)OGLGETPROCADDRESS("glEnableVertexAttribArray");
AssertMsgReturn(pState->ext.glEnableVertexAttribArray, ("glEnableVertexAttribArray missing"), VERR_NOT_IMPLEMENTED);
pState->ext.glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)OGLGETPROCADDRESS("glDisableVertexAttribArray");
AssertMsgReturn(pState->ext.glDisableVertexAttribArray, ("glDisableVertexAttribArray missing"), VERR_NOT_IMPLEMENTED);
pState->ext.glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)OGLGETPROCADDRESS("glVertexAttribPointer");
AssertMsgReturn(pState->ext.glVertexAttribPointer, ("glVertexAttribPointer missing"), VERR_NOT_IMPLEMENTED);
AssertMsgReturn(pState->ext.glFogCoordPointer, ("glFogCoordPointer missing"), VERR_NOT_IMPLEMENTED);
pState->ext.glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC)OGLGETPROCADDRESS("glClientActiveTexture");
AssertMsgReturn(pState->ext.glClientActiveTexture, ("glClientActiveTexture missing"), VERR_NOT_IMPLEMENTED);
AssertMsgReturn(pState->ext.glGetProgramivARB, ("glGetProgramivARB missing"), VERR_NOT_IMPLEMENTED);
pState->ext.glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)OGLGETPROCADDRESS("glDrawElementsBaseVertex");
pState->ext.glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)OGLGETPROCADDRESS("glDrawElementsInstancedBaseVertex");
#ifdef DEBUG_bird
if (pState->fGLVersion >= 3.1) /* darwin: Requires GL 3.1, so triggers on older mac os x versions. */
pState->ext.glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &pState->caps.maxFragmentShaderTemps);
pState->ext.glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &pState->caps.maxFragmentShaderInstructions);
pState->ext.glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &pState->caps.maxVertexShaderTemps);
pState->ext.glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &pState->caps.maxVertexShaderInstructions);
|| vmsvga3dCheckGLExtension("GL_ARB_shader_texture_lod")) /* Wine claims this suggests SM 3.0 support */
#ifndef RT_OS_DARWIN
return VERR_NOT_IMPLEMENTED;
return VERR_NOT_IMPLEMENTED;
return VINF_SUCCESS;
return VINF_SUCCESS;
int rc;
#ifdef RT_OS_WINDOWS
rc = vmsvga3dSendThreadMessage(pState->pWindowThread, pState->WndRequestSem, WM_VMSVGA3D_EXIT, 0, 0);
return VINF_SUCCESS;
#define VMSVGA3D_OPENGL
#include "DevVGA-SVGA3d-shared.h"
switch (idx3dCaps)
switch (idx3dCaps)
return result;
return result;
*pu32Val = 0;
switch (idx3dCaps)
case SVGA3D_DEVCAP_3D:
case SVGA3D_DEVCAP_MAX_LIGHTS:
*pu32Val = 0;
return rc;
switch (format)
case SVGA3D_X8R8G8B8:
case SVGA3D_A8R8G8B8:
case SVGA3D_R5G6B5:
case SVGA3D_X1R5G5B5:
case SVGA3D_A1R5G5B5:
case SVGA3D_A4R4G4B4:
case SVGA3D_Z_D32:
case SVGA3D_Z_D16:
case SVGA3D_Z_D24S8:
case SVGA3D_Z_D15S1:
case SVGA3D_Z_D24X8:
case SVGA3D_Z_DF16:
case SVGA3D_Z_DF24:
case SVGA3D_Z_D24S8_INT:
case SVGA3D_DXT1:
case SVGA3D_DXT3:
case SVGA3D_DXT5:
case SVGA3D_LUMINANCE8:
case SVGA3D_LUMINANCE16:
case SVGA3D_LUMINANCE4_ALPHA4:
case SVGA3D_LUMINANCE8_ALPHA8:
pSurface->typeGL = GL_UNSIGNED_BYTE; /* unsigned_short causes issues even though this type should be 16-bit */
case SVGA3D_ALPHA8:
case SVGA3D_BUMPU8V8:
return D3DFMT_V8U8;
case SVGA3D_BUMPL6V5U5:
return D3DFMT_L6V5U5;
case SVGA3D_BUMPX8L8V8U8:
return D3DFMT_X8L8V8U8;
case SVGA3D_BUMPL8V8U8:
case SVGA3D_V8U8:
return D3DFMT_V8U8;
case SVGA3D_Q8W8V8U8:
return D3DFMT_Q8W8V8U8;
case SVGA3D_CxV8U8:
return D3DFMT_CxV8U8;
case SVGA3D_X8L8V8U8:
return D3DFMT_X8L8V8U8;
case SVGA3D_A2W10V10U10:
return D3DFMT_A2W10V10U10;
case SVGA3D_A2R10G10B10:
case SVGA3D_R_S10E5:
case SVGA3D_R_S23E8:
case SVGA3D_RG_S10E5:
case SVGA3D_RG_S23E8:
case SVGA3D_BUFFER:
return D3DFMT_UNKNOWN;
case SVGA3D_V16U16:
return D3DFMT_V16U16;
case SVGA3D_G16R16:
case SVGA3D_A16B16G16R16:
case SVGA3D_UYVY:
return D3DFMT_UYVY;
case SVGA3D_YUY2:
return D3DFMT_YUY2;
case SVGA3D_NV12:
case SVGA3D_AYUV:
case SVGA3D_BC4_UNORM:
case SVGA3D_BC5_UNORM:
return D3DMULTISAMPLE_NONE;
int vmsvga3dSurfaceDefine(PVGASTATE pThis, uint32_t sid, uint32_t surfaceFlags, SVGA3dSurfaceFormat format, SVGA3dSurfaceFace face[SVGA3D_MAX_SURFACE_FACES],
uint32_t multisampleCount, SVGA3dTextureFilter autogenFilter, uint32_t cMipLevels, SVGA3dSize *pMipLevelSize)
Log(("vmsvga3dSurfaceDefine: sid=%x surfaceFlags=%x format=%s (%x) multiSampleCount=%d autogenFilter=%d, cMipLevels=%d size=(%d,%d,%d)\n",
sid, surfaceFlags, vmsvgaSurfaceType2String(format), format, multisampleCount, autogenFilter, cMipLevels, pMipLevelSize->width, pMipLevelSize->height, pMipLevelSize->depth));
AssertReturn(!(surfaceFlags & SVGA3D_SURFACE_CUBEMAP) || cMipLevels == face[0].numMipLevels * 6, VERR_INVALID_PARAMETER);
AssertReturn((surfaceFlags & SVGA3D_SURFACE_CUBEMAP) || cMipLevels == face[0].numMipLevels, VERR_INVALID_PARAMETER);
pState->paSurface = (PVMSVGA3DSURFACE )RTMemRealloc(pState->paSurface, sizeof(VMSVGA3DSURFACE) * (sid + 1));
memset(&pState->paSurface[pState->cSurfaces], 0, sizeof(VMSVGA3DSURFACE) * (sid + 1 - pState->cSurfaces));
/* The surface type is sort of undefined now, even though the hints and format can help to clear that up.
switch (format)
case SVGA3D_Z_D32:
case SVGA3D_Z_D16:
case SVGA3D_Z_D24S8:
case SVGA3D_Z_D15S1:
case SVGA3D_Z_D24X8:
case SVGA3D_Z_DF16:
case SVGA3D_Z_DF24:
case SVGA3D_Z_D24S8_INT:
case SVGA3D_DXT1:
case SVGA3D_DXT2:
case SVGA3D_DXT3:
case SVGA3D_DXT4:
case SVGA3D_DXT5:
case SVGA3D_BUMPU8V8:
case SVGA3D_BUMPL6V5U5:
case SVGA3D_BUMPX8L8V8U8:
case SVGA3D_BUMPL8V8U8:
case SVGA3D_V8U8:
case SVGA3D_Q8W8V8U8:
case SVGA3D_CxV8U8:
case SVGA3D_X8L8V8U8:
case SVGA3D_A2W10V10U10:
case SVGA3D_V16U16:
case SVGA3D_X8R8G8B8:
case SVGA3D_A8R8G8B8:
case SVGA3D_R5G6B5:
case SVGA3D_X1R5G5B5:
case SVGA3D_A1R5G5B5:
case SVGA3D_A4R4G4B4:
case SVGA3D_LUMINANCE8:
case SVGA3D_LUMINANCE4_ALPHA4:
case SVGA3D_LUMINANCE16:
case SVGA3D_LUMINANCE8_ALPHA8:
case SVGA3D_A2R10G10B10:
case SVGA3D_ALPHA8:
case SVGA3D_R_S10E5:
case SVGA3D_R_S23E8:
case SVGA3D_RG_S10E5:
case SVGA3D_RG_S23E8:
case SVGA3D_G16R16:
case SVGA3D_A16B16G16R16:
case SVGA3D_UYVY:
case SVGA3D_YUY2:
case SVGA3D_NV12:
case SVGA3D_AYUV:
case SVGA3D_BC4_UNORM:
case SVGA3D_BC5_UNORM:
case SVGA3D_BUFFER:
pSurface->pMipmapLevels = (PVMSVGA3DMIPMAPLEVEL)RTMemAllocZ(cMipLevels * sizeof(VMSVGA3DMIPMAPLEVEL));
switch (surfaceFlags & (SVGA3D_SURFACE_HINT_INDEXBUFFER | SVGA3D_SURFACE_HINT_VERTEXBUFFER | SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP))
case SVGA3D_SURFACE_CUBEMAP:
Log(("vmsvga3dSurfaceDefine: face %d mip level %d (%d,%d,%d)\n", iFace, i, pSurface->pMipmapLevels[idx].size.width, pSurface->pMipmapLevels[idx].size.height, pSurface->pMipmapLevels[idx].size.depth));
Log(("vmsvga3dSurfaceDefine: cbPitch=%x cbBlock=%x \n", pSurface->cbBlock * pSurface->pMipmapLevels[idx].size.width, pSurface->cbBlock));
pSurface->pMipmapLevels[idx].cbSurfacePitch = pSurface->cbBlock * pSurface->pMipmapLevels[idx].size.width;
pSurface->pMipmapLevels[idx].cbSurface = pSurface->pMipmapLevels[idx].cbSurfacePitch * pSurface->pMipmapLevels[idx].size.height * pSurface->pMipmapLevels[idx].size.depth;
return VINF_SUCCESS;
switch (pSurface->flags & (SVGA3D_SURFACE_HINT_INDEXBUFFER | SVGA3D_SURFACE_HINT_VERTEXBUFFER | SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP))
case SVGA3D_SURFACE_CUBEMAP:
case SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_HINT_TEXTURE: /* @todo actual texture surface not supported */
return VINF_SUCCESS;
int vmsvga3dSurfaceCopy(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3dSurfaceImageId src, uint32_t cCopyBoxes, SVGA3dCopyBox *pBox)
AssertReturn(sidSrc < pState->cSurfaces && pState->paSurface[sidSrc].id == sidSrc, VERR_INVALID_PARAMETER);
AssertReturn(sidDest < pState->cSurfaces && pState->paSurface[sidDest].id == sidDest, VERR_INVALID_PARAMETER);
return VINF_SUCCESS;
static int vmsvga3dCreateTexture(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, uint32_t idAssociatedContext, PVMSVGA3DSURFACE pSurface)
Log(("vmsvga3dCreateTexture: sync dirty texture mipmap level %d (pitch %x)\n", i, pSurface->pMipmapLevels[i].cbSurfacePitch));
NULL);
return VINF_SUCCESS;
int vmsvga3dSurfaceStretchBlt(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3dBox destBox, SVGA3dSurfaceImageId src, SVGA3dBox srcBox, SVGA3dStretchBltMode mode)
AssertReturn(sidSrc < pState->cSurfaces && pState->paSurface[sidSrc].id == sidSrc, VERR_INVALID_PARAMETER);
AssertReturn(sidDest < pState->cSurfaces && pState->paSurface[sidDest].id == sidDest, VERR_INVALID_PARAMETER);
Log(("vmsvga3dSurfaceStretchBlt: src sid=%x (%d,%d)(%d,%d) dest sid=%x (%d,%d)(%d,%d) mode=%x\n", src.sid, srcBox.x, srcBox.y, srcBox.x + srcBox.w, srcBox.y + srcBox.h, dest.sid, destBox.x, destBox.y, destBox.x + destBox.w, destBox.y + destBox.h, mode));
Log(("vmsvga3dSurfaceStretchBlt: unknown src surface id=%x type=%d format=%d -> create texture\n", sidSrc, pSurfaceSrc->flags, pSurfaceSrc->format));
Log(("vmsvga3dSurfaceStretchBlt: unknown dest surface id=%x type=%d format=%d -> create texture\n", sidDest, pSurfaceDest->flags, pSurfaceDest->format));
pState->ext.glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pSurfaceSrc->oglId.texture, src.mipmap);
pState->ext.glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pSurfaceDest->oglId.texture, dest.mipmap);
Log(("src conv. (%d,%d)(%d,%d); dest conv (%d,%d)(%d,%d)\n", srcBox.x, D3D_TO_OGL_Y_COORD(pSurfaceSrc, srcBox.y + srcBox.h),
srcBox.x + srcBox.w, D3D_TO_OGL_Y_COORD(pSurfaceSrc, srcBox.y), destBox.x, D3D_TO_OGL_Y_COORD(pSurfaceDest, destBox.y + destBox.h),
#ifdef MANUAL_FLIP_SURFACE_DATA
srcBox.y,
#ifdef MANUAL_FLIP_SURFACE_DATA
destBox.x,
#ifdef MANUAL_FLIP_SURFACE_DATA
destBox.y,
#ifdef MANUAL_FLIP_SURFACE_DATA
return VINF_SUCCESS;
int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceImageId host, SVGA3dTransferType transfer, uint32_t cCopyBoxes, SVGA3dCopyBox *pBoxes)
Log(("vmsvga3dSurfaceDMA TEXTURE guestptr gmr=%x offset=%x pitch=%x host sid=%x face=%d mipmap=%d transfer=%x cCopyBoxes=%d\n", guest.ptr.gmrId, guest.ptr.offset, guest.pitch, host.sid, host.face, host.mipmap, transfer, cCopyBoxes));
Log(("vmsvga3dSurfaceDMA guestptr gmr=%x offset=%x pitch=%x host sid=%x face=%d mipmap=%d transfer=%x cCopyBoxes=%d\n", guest.ptr.gmrId, guest.ptr.offset, guest.pitch, host.sid, host.face, host.mipmap, transfer, cCopyBoxes));
for (unsigned i = 0; i < cCopyBoxes; i++)
unsigned uDestOffset;
unsigned cbSrcPitch;
Log(("Copy box %d (%d,%d,%d)(%d,%d,%d) dest (%d,%d)\n", i, pBoxes[i].srcx, pBoxes[i].srcy, pBoxes[i].srcz, pBoxes[i].w, pBoxes[i].h, pBoxes[i].d, pBoxes[i].x, pBoxes[i].y));
if ( !pBoxes[i].w
|| !pBoxes[i].h
|| !pBoxes[i].d
uDestOffset = pBoxes[i].x * pSurface->cbBlock + pBoxes[i].y * pMipLevel->cbSurfacePitch + pBoxes[i].z * pMipLevel->size.height * pMipLevel->cbSurfacePitch;
AssertReturn(uDestOffset + pBoxes[i].w * pSurface->cbBlock * pBoxes[i].h * pBoxes[i].d <= pMipLevel->cbSurface, VERR_INTERNAL_ERROR);
#ifdef MANUAL_FLIP_SURFACE_DATA
#ifdef MANUAL_FLIP_SURFACE_DATA
Log(("vmsvga3dSurfaceDMA invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->paContext[cid].id));
for (unsigned i = 0; i < cCopyBoxes; i++)
bool fVertex = false;
unsigned cbSrcPitch;
if ( !pBoxes[i].w
|| !pBoxes[i].h
Log(("Copy box %d (%d,%d,%d)(%d,%d,%d) dest (%d,%d)\n", i, pBoxes[i].srcx, pBoxes[i].srcy, pBoxes[i].srcz, pBoxes[i].w, pBoxes[i].h, pBoxes[i].d, pBoxes[i].x, pBoxes[i].y));
switch (pSurface->flags & (SVGA3D_SURFACE_HINT_INDEXBUFFER | SVGA3D_SURFACE_HINT_VERTEXBUFFER | SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP))
unsigned uDestOffset = 0;
AssertReturn(uDestOffset + pBoxes[i].w * pSurface->cbBlock + (pBoxes[i].h - 1) * pMipLevel->cbSurfacePitch <= pMipLevel->cbSurface, VERR_INTERNAL_ERROR);
#ifdef MANUAL_FLIP_SURFACE_DATA
#ifdef MANUAL_FLIP_SURFACE_DATA
pBufferStart = pDoubleBuffer + cbSurfacePitch * pBoxes[i].h - cbSurfacePitch; /* flip image during copy */
#ifdef MANUAL_FLIP_SURFACE_DATA
pBoxes[i].h);
Log(("vmsvga3dSurfaceDMA: copy texture mipmap level %d (pitch %x)\n", host.mipmap, pMipLevel->cbSurfacePitch));
pBoxes[i].x,
pBoxes[i].y,
pBoxes[i].w,
pBoxes[i].h,
unsigned uDestOffset;
pData = (uint8_t *)pState->ext.glMapBuffer(GL_ARRAY_BUFFER, (transfer == SVGA3D_READ_HOST_VRAM) ? GL_READ_ONLY : GL_WRITE_ONLY);
AssertReturn(uDestOffset + pBoxes[i].w * pSurface->cbBlock + (pBoxes[i].h - 1) * pMipLevel->cbSurfacePitch <= pMipLevel->cbSurface, VERR_INTERNAL_ERROR);
Log(("Lock %s memory for rectangle (%d,%d)(%d,%d)\n", (fVertex) ? "vertex" : "index", pBoxes[i].x, pBoxes[i].y, pBoxes[i].x + pBoxes[i].w, pBoxes[i].y + pBoxes[i].h));
pBoxes[i].h);
AssertFailed();
return rc;
int vmsvga3dSurfaceBlitToScreen(PVGASTATE pThis, uint32_t dest, SVGASignedRect destRect, SVGA3dSurfaceImageId src, SVGASignedRect srcRect, uint32_t cRects, SVGASignedRect *pRect)
Log(("vmsvga3dSurfaceBlitToScreen: dest=%d (%d,%d)(%d,%d) surface=%x (face=%d, mipmap=%d) (%d,%d)(%d,%d) cRects=%d\n", dest, destRect.left, destRect.top, destRect.right, destRect.bottom, src.sid, src.face, src.mipmap, srcRect.left, srcRect.top, srcRect.right, srcRect.bottom, cRects));
Log(("vmsvga3dSurfaceBlitToScreen: clipping rect %d (%d,%d)(%d,%d)\n", i, pRect[i].left, pRect[i].top, pRect[i].right, pRect[i].bottom));
AssertReturn(destRect.right - destRect.left == srcRect.right - srcRect.left && destRect.bottom - destRect.top == srcRect.bottom - srcRect.top, VERR_INVALID_PARAMETER);
if (cRects == 0)
box.z = 0;
return VINF_SUCCESS;
box.z = 0;
box.z = 0;
return VINF_SUCCESS;
return VERR_INVALID_PARAMETER;
Log(("vmsvga3dGenerateMipmaps: unknown src surface id=%x type=%d format=%d -> create texture\n", sid, pSurface->flags, pSurface->format));
AssertFailed();
return VINF_SUCCESS;
uint32_t x;
uint32_t y;
} srcViewPort;
Log(("vmsvga3dCommandPresent: rectangle %d src=(%d,%d) (%d,%d)(%d,%d)\n", i, pRect[i].srcx, pRect[i].srcy, pRect[i].x, pRect[i].y, pRect[i].x + pRect[i].w, pRect[i].y + pRect[i].h));
return VERR_INVALID_PARAMETER;
LogFlow(("size (%d vs %d) (%d vs %d) multiplier %d\n", pSurface->pMipmapLevels[0].size.width, pThis->svga.uWidth, pSurface->pMipmapLevels[0].size.height, pThis->svga.uHeight, (int)(xMultiplier * 100.0), (int)(yMultiplier * 100.0)));
if (cRects == 0)
glPushMatrix();
glPushMatrix();
vertexTop = ((uint32_t)pThis->svga.uHeight >= pRect[i].y + pRect[i].h) ? pThis->svga.uHeight - pRect[i].y - pRect[i].h : 0;
Log(("vertex (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n", vertexLeft, vertexBottom, vertexLeft, vertexTop, vertexRight, vertexTop, vertexRight, vertexBottom));
Log(("texture (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n", pRect[i].srcx, pSurface->pMipmapLevels[0].size.height - (pRect[i].srcy + pRect[i].h), pRect[i].srcx, pSurface->pMipmapLevels[0].size.height - pRect[i].srcy, pRect[i].srcx + pRect[i].w, pSurface->pMipmapLevels[0].size.height - pRect[i].srcy, pRect[i].srcx + pRect[i].w, pSurface->pMipmapLevels[0].size.height - (pRect[i].srcy + pRect[i].h)));
glEnd();
glPopMatrix();
glPopMatrix();
pState->ext.glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pSurface->oglId.texture, 0 /* level 0 */);
if (cRects == 0)
srcViewPort.y,
pSurface->pMipmapLevels[0].size.width - RT_MAX(pRect[i].srcy, srcViewPort.y), /* exclusive. (reverse to flip the image) */
pSurface->pMipmapLevels[0].size.width - RT_MIN(pRect[i].srcy + pRect[i].h, srcViewPort.y + srcViewPort.cy),
pThis->svga.uHeight - (RT_MIN(pRect[i].y + pRect[i].h, pThis->svga.viewport.y + pThis->svga.viewport.cy) - pThis->svga.viewport.y), /* exclusive. */
RT_MIN(pRect[i].x + pRect[i].w, pThis->svga.viewport.x + pThis->svga.viewport.cx) - pThis->svga.viewport.x, /* exclusive. */
#ifdef RT_OS_WINDOWS
return VINF_SUCCESS;
#ifdef RT_OS_LINUX
return VINF_SUCCESS;
int rc;
pState->paContext = (PVMSVGA3DCONTEXT)RTMemRealloc(pState->paContext, sizeof(VMSVGA3DCONTEXT) * (cid + 1));
memset(&pState->paContext[pState->cContexts], 0, sizeof(VMSVGA3DCONTEXT) * (cid + 1 - pState->cContexts));
#ifdef RT_OS_WINDOWS
# ifdef DEBUG_GFX_WINDOW
# ifdef DEBUG_GFX_WINDOW
cs.x = 0;
cs.y = 0;
rc = vmsvga3dSendThreadMessage(pState->pWindowThread, pState->WndRequestSem, WM_VMSVGA3D_CREATEWINDOW, (WPARAM)&pContext->hwnd, (LPARAM)&cs);
AssertMsgReturn(pContext->hdc, ("GetDC %x failed with %d\n", pContext->hwnd, GetLastError()), VERR_INTERNAL_ERROR);
int pixelFormat;
AssertMsgReturn(pixelFormat != 0, ("ChoosePixelFormat failed with %d\n", GetLastError()), VERR_INTERNAL_ERROR);
AssertMsgReturn(ret == TRUE, ("SetPixelFormat failed with %d\n", GetLastError()), VERR_INTERNAL_ERROR);
AssertMsgReturn(pContext->hglrc, ("wglCreateContext %x failed with %d\n", pContext->hdc, GetLastError()), VERR_INTERNAL_ERROR);
/* Find the first active context to share the display list with (necessary for sharing e.g. textures between contexts). */
/* Find the first active context to share the display list with (necessary for sharing e.g. textures between contexts). */
AssertMsgReturn(ret && glxMajor == 1 && glxMinor >= 3, ("glX >=1.3 not present"), VERR_INTERNAL_ERROR);
rc = RTThreadCreate(&pState->pWindowThread, vmsvga3dXEventThread, pState, 0, RTTHREADTYPE_GUI, RTTHREADFLAGS_WAITABLE, "VMSVGA3DXEVENT");
AssertMsgFailed(("%s: Async IO Thread creation for 3d window handling failed rc=%d\n", __FUNCTION__, rc));
return rc;
int attrib[] =
swa.colormap = XCreateColormap(pState->display, XDefaultRootWindow(pState->display), vi->visual, AllocNone);
pContext->window = XCreateWindow(pState->display, hostWindow,//XDefaultRootWindow(pState->display),//hostWindow,
/* Find the first active context to share the display list with (necessary for sharing e.g. textures between contexts). */
glClearIndex(0);
return VINF_SUCCESS;
vmsvga3dShaderDestroy(pThis, pContext->paPixelShader[i].cid, pContext->paPixelShader[i].id, pContext->paPixelShader[i].type);
vmsvga3dShaderDestroy(pThis, pContext->paVertexShader[i].cid, pContext->paVertexShader[i].id, pContext->paVertexShader[i].type);
#ifdef RT_OS_WINDOWS
int rc = vmsvga3dSendThreadMessage(pState->pWindowThread, pState->WndRequestSem, WM_VMSVGA3D_DESTROYWINDOW, (WPARAM)pContext->hwnd, 0);
AssertFailed();
return VINF_SUCCESS;
#ifdef RT_OS_WINDOWS
int rc = vmsvga3dSendThreadMessage(pState->pWindowThread, pState->WndRequestSem, WM_VMSVGA3D_RESIZEWINDOW, (WPARAM)pContext->hwnd, (LPARAM)&cs);
return VINF_SUCCESS;
bool fModelViewChanged = false;
return VERR_INVALID_PARAMETER;
memcpy(pContext->state.aTransformState[type].matrix, matrix, sizeof(pContext->state.aTransformState[type].matrix));
Log(("Matrix [%d %d %d %d]\n", (int)(matrix[0] * 10.0), (int)(matrix[1] * 10.0), (int)(matrix[2] * 10.0), (int)(matrix[3] * 10.0)));
Log((" [%d %d %d %d]\n", (int)(matrix[4] * 10.0), (int)(matrix[5] * 10.0), (int)(matrix[6] * 10.0), (int)(matrix[7] * 10.0)));
Log((" [%d %d %d %d]\n", (int)(matrix[8] * 10.0), (int)(matrix[9] * 10.0), (int)(matrix[10] * 10.0), (int)(matrix[11] * 10.0)));
Log((" [%d %d %d %d]\n", (int)(matrix[12] * 10.0), (int)(matrix[13] * 10.0), (int)(matrix[14] * 10.0), (int)(matrix[15] * 10.0)));
switch (type)
case SVGA3D_TRANSFORM_VIEW:
fModelViewChanged = true;
int rc = ShaderTransformProjection(pContext->state.RectViewPort.w, pContext->state.RectViewPort.h, matrix);
return VERR_INVALID_PARAMETER;
case SVGA3D_TRANSFORM_WORLD:
fModelViewChanged = true;
case SVGA3D_TRANSFORM_WORLD1:
case SVGA3D_TRANSFORM_WORLD2:
case SVGA3D_TRANSFORM_WORLD3:
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
if (fModelViewChanged)
return VINF_SUCCESS;
Log(("vmsvga3dSetZRange cid=%x min=%d max=%d\n", cid, (uint32_t)(zRange.min * 100.0), (uint32_t)(zRange.max * 100.0)));
return VERR_INVALID_PARAMETER;
return VINF_SUCCESS;
switch (blendOp)
case SVGA3D_BLENDOP_ZERO:
return GL_ZERO;
case SVGA3D_BLENDOP_ONE:
return GL_ONE;
case SVGA3D_BLENDOP_SRCCOLOR:
return GL_SRC_COLOR;
return GL_ONE_MINUS_SRC_COLOR;
case SVGA3D_BLENDOP_SRCALPHA:
return GL_SRC_ALPHA;
return GL_ONE_MINUS_SRC_ALPHA;
case SVGA3D_BLENDOP_DESTALPHA:
return GL_DST_ALPHA;
return GL_ONE_MINUS_DST_ALPHA;
case SVGA3D_BLENDOP_DESTCOLOR:
return GL_DST_COLOR;
return GL_ONE_MINUS_DST_COLOR;
return GL_SRC_ALPHA_SATURATE;
AssertFailed();
return GL_ONE;
switch (blendEq)
case SVGA3D_BLENDEQ_ADD:
return GL_FUNC_ADD;
case SVGA3D_BLENDEQ_SUBTRACT:
return GL_FUNC_SUBTRACT;
return GL_FUNC_REVERSE_SUBTRACT;
case SVGA3D_BLENDEQ_MINIMUM:
return GL_MIN;
case SVGA3D_BLENDEQ_MAXIMUM:
return GL_MAX;
AssertFailed();
return GL_FUNC_ADD;
switch (cmpFunc)
case SVGA3D_CMP_NEVER:
return GL_NEVER;
case SVGA3D_CMP_LESS:
return GL_LESS;
case SVGA3D_CMP_EQUAL:
return GL_EQUAL;
case SVGA3D_CMP_LESSEQUAL:
return GL_LEQUAL;
case SVGA3D_CMP_GREATER:
return GL_GREATER;
case SVGA3D_CMP_NOTEQUAL:
return GL_NOTEQUAL;
case SVGA3D_CMP_GREATEREQUAL:
return GL_GEQUAL;
case SVGA3D_CMP_ALWAYS:
return GL_ALWAYS;
AssertFailed();
return GL_LESS;
switch (stencilOp)
case SVGA3D_STENCILOP_KEEP:
return GL_KEEP;
case SVGA3D_STENCILOP_ZERO:
return GL_ZERO;
case SVGA3D_STENCILOP_REPLACE:
return GL_REPLACE;
case SVGA3D_STENCILOP_INCRSAT:
return GL_INCR_WRAP;
case SVGA3D_STENCILOP_DECRSAT:
return GL_DECR_WRAP;
case SVGA3D_STENCILOP_INVERT:
return GL_INVERT;
case SVGA3D_STENCILOP_INCR:
return GL_INCR;
case SVGA3D_STENCILOP_DECR:
return GL_DECR;
AssertFailed();
return GL_KEEP;
int vmsvga3dSetRenderState(PVGASTATE pThis, uint32_t cid, uint32_t cRenderStates, SVGA3dRenderState *pRenderState)
return VERR_INVALID_PARAMETER;
for (unsigned i = 0; i < cRenderStates; i++)
Log(("vmsvga3dSetRenderState: cid=%d state=%s (%d) val=%x\n", cid, vmsvga3dGetRenderStateName(pRenderState[i].state), pRenderState[i].state, pRenderState[i].uintValue));
case SVGA3D_FOGFUNC_EXP:
case SVGA3D_FOGFUNC_EXP2:
case SVGA3D_FOGFUNC_LINEAR:
case SVGA3D_FOGTYPE_VERTEX:
case SVGA3D_FOGTYPE_PIXEL:
case SVGA3D_FILLMODE_POINT:
case SVGA3D_FILLMODE_LINE:
case SVGA3D_FILLMODE_FILL:
case SVGA3D_SHADEMODE_FLAT:
case SVGA3D_SHADEMODE_SMOOTH:
AssertMsgFailedReturn(("Unexpected shade mode %d\n", pRenderState[i].uintValue), VERR_INTERNAL_ERROR);
case SVGA3D_RS_SRCBLEND:
case SVGA3D_RS_DSTBLEND:
case SVGA3D_RS_SRCBLENDALPHA:
case SVGA3D_RS_DSTBLENDALPHA:
AssertFailed();
pState->ext.glBlendEquationSeparate(vmsvga3dBlendEquation2GL(pContext->state.aRenderState[SVGA3D_RS_BLENDEQUATION].uintValue),
case SVGA3D_FACE_NONE:
case SVGA3D_FACE_FRONT:
case SVGA3D_FACE_BACK:
case SVGA3D_FACE_FRONT_BACK:
AssertMsgFailedReturn(("Unexpected cull mode %d\n", pRenderState[i].uintValue), VERR_INTERNAL_ERROR);
val = 0;
AssertFailed();
AssertFailed();
/* @todo SVGA3D_RS_STENCILFAIL/ZFAIL/PASS for front & back faces
* SVGA3D_RS_CCWSTENCILFAIL/ZFAIL/PASS for back faces ??
/* @todo SVGA3D_RS_STENCILFAIL/ZFAIL/PASS for front & back faces
* SVGA3D_RS_CCWSTENCILFAIL/ZFAIL/PASS for back faces ??
AssertFailed();
/* @todo setup a view matrix to scale the world space by -1 in the z-direction for right handed coordinates. */
AssertFailed();
AssertFailed();
AssertFailed();
if (enableCap != ~0U)
if (val)
return VINF_SUCCESS;
int vmsvga3dSetRenderTarget(PVGASTATE pThis, uint32_t cid, SVGA3dRenderTargetType type, SVGA3dSurfaceImageId target)
return VERR_INVALID_PARAMETER;
switch (type)
case SVGA3D_RT_DEPTH:
case SVGA3D_RT_STENCIL:
pState->ext.glFramebufferRenderbuffer(GL_FRAMEBUFFER, (type == SVGA3D_RT_DEPTH) ? GL_DEPTH_ATTACHMENT : GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
case SVGA3D_RT_COLOR0:
case SVGA3D_RT_COLOR1:
case SVGA3D_RT_COLOR2:
case SVGA3D_RT_COLOR3:
case SVGA3D_RT_COLOR4:
case SVGA3D_RT_COLOR5:
case SVGA3D_RT_COLOR6:
case SVGA3D_RT_COLOR7:
pState->ext.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + type - SVGA3D_RT_COLOR0, 0, 0, 0);
return VINF_SUCCESS;
AssertReturn(target.sid < pState->cSurfaces && pState->paSurface[target.sid].id == target.sid, VERR_INVALID_PARAMETER);
switch (type)
case SVGA3D_RT_DEPTH:
case SVGA3D_RT_STENCIL:
Log(("vmsvga3dSetRenderTarget: create renderbuffer to be used as render target; surface id=%x type=%d format=%d\n", target.sid, pRenderTarget->flags, pRenderTarget->internalFormatGL));
pState->ext.glFramebufferRenderbuffer(GL_FRAMEBUFFER, (type == SVGA3D_RT_DEPTH) ? GL_DEPTH_ATTACHMENT : GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, pRenderTarget->oglId.renderbuffer);
case SVGA3D_RT_COLOR0:
case SVGA3D_RT_COLOR1:
case SVGA3D_RT_COLOR2:
case SVGA3D_RT_COLOR3:
case SVGA3D_RT_COLOR4:
case SVGA3D_RT_COLOR5:
case SVGA3D_RT_COLOR6:
case SVGA3D_RT_COLOR7:
Log(("vmsvga3dSetRenderTarget: create texture to be used as render target; surface id=%x type=%d format=%d -> create texture\n", target.sid, pRenderTarget->flags, pRenderTarget->format));
pState->ext.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + type - SVGA3D_RT_COLOR0, GL_TEXTURE_2D, pRenderTarget->oglId.texture, target.mipmap);
#ifdef DEBUG
return VINF_SUCCESS;
switch (value)
case SVGA3D_TC_DISABLE:
return D3DTOP_DISABLE;
case SVGA3D_TC_SELECTARG1:
return D3DTOP_SELECTARG1;
case SVGA3D_TC_SELECTARG2:
return D3DTOP_SELECTARG2;
case SVGA3D_TC_MODULATE:
return D3DTOP_MODULATE;
case SVGA3D_TC_ADD:
return D3DTOP_ADD;
case SVGA3D_TC_ADDSIGNED:
return D3DTOP_ADDSIGNED;
case SVGA3D_TC_SUBTRACT:
return D3DTOP_SUBTRACT;
return D3DTOP_BLENDTEXTUREALPHA;
return D3DTOP_BLENDDIFFUSEALPHA;
return D3DTOP_BLENDCURRENTALPHA;
return D3DTOP_BLENDFACTORALPHA;
case SVGA3D_TC_MODULATE2X:
return D3DTOP_MODULATE2X;
case SVGA3D_TC_MODULATE4X:
return D3DTOP_MODULATE4X;
case SVGA3D_TC_DSDT:
return D3DTOP_DISABLE;
case SVGA3D_TC_DOTPRODUCT3:
return D3DTOP_DOTPRODUCT3;
return D3DTOP_BLENDTEXTUREALPHAPM;
case SVGA3D_TC_ADDSIGNED2X:
return D3DTOP_ADDSIGNED2X;
case SVGA3D_TC_ADDSMOOTH:
return D3DTOP_ADDSMOOTH;
case SVGA3D_TC_PREMODULATE:
return D3DTOP_PREMODULATE;
return D3DTOP_MODULATEALPHA_ADDCOLOR;
return D3DTOP_MODULATECOLOR_ADDALPHA;
return D3DTOP_MODULATEINVALPHA_ADDCOLOR;
return D3DTOP_MODULATEINVCOLOR_ADDALPHA;
return D3DTOP_BUMPENVMAPLUMINANCE;
case SVGA3D_TC_MULTIPLYADD:
return D3DTOP_MULTIPLYADD;
case SVGA3D_TC_LERP:
return D3DTOP_LERP;
AssertFailed();
return D3DTOP_DISABLE;
switch (value)
case SVGA3D_TA_CONSTANT:
return D3DTA_CONSTANT;
case SVGA3D_TA_PREVIOUS:
case SVGA3D_TA_DIFFUSE:
return D3DTA_DIFFUSE;
case SVGA3D_TA_TEXTURE:
return D3DTA_TEXTURE;
case SVGA3D_TA_SPECULAR:
return D3DTA_SPECULAR;
AssertFailed();
switch (value)
case SVGA3D_TEX_TRANSFORM_OFF:
return D3DTTFF_DISABLE;
case SVGA3D_TEX_TRANSFORM_S:
case SVGA3D_TEX_TRANSFORM_T:
case SVGA3D_TEX_TRANSFORM_R:
case SVGA3D_TEX_TRANSFORM_Q:
case SVGA3D_TEX_PROJECTED:
return D3DTTFF_PROJECTED;
AssertFailed();
switch (value)
case SVGA3D_TEX_ADDRESS_WRAP:
return GL_REPEAT;
return GL_MIRRORED_REPEAT;
case SVGA3D_TEX_ADDRESS_CLAMP:
return GL_CLAMP_TO_EDGE;
return GL_CLAMP_TO_BORDER;
AssertFailed();
case SVGA3D_TEX_ADDRESS_EDGE:
AssertFailed();
switch (value)
case SVGA3D_TEX_FILTER_NONE:
case SVGA3D_TEX_FILTER_LINEAR:
return GL_LINEAR;
return GL_NEAREST;
AssertFailed();
int vmsvga3dSetTextureState(PVGASTATE pThis, uint32_t cid, uint32_t cTextureStates, SVGA3dTextureState *pTextureState)
return VERR_INVALID_PARAMETER;
for (unsigned i = 0; i < cTextureStates; i++)
Log(("vmsvga3dSetTextureState: cid=%x stage=%d type=%s (%x) val=%x\n", cid, pTextureState[i].stage, vmsvga3dTextureStateToString(pTextureState[i].name), pTextureState[i].name, pTextureState[i].value));
Log(("SVGA3D_TS_BIND_TEXTURE: stage %d, texture surface id=%x\n", pTextureState[i].stage, pTextureState[i].value));
Log(("SVGA3D_TS_BIND_TEXTURE: stage %d, texture surface id=%x (%d,%d)\n", pTextureState[i].stage, pTextureState[i].value, pSurface->pMipmapLevels[0].size.width, pSurface->pMipmapLevels[0].size.height));
Log(("CreateTexture (%d,%d) level=%d\n", pSurface->pMipmapLevels[0].size.width, pSurface->pMipmapLevels[0].size.height, pSurface->faces[0].numMipLevels));
glTexParameterfv(GL_TEXTURE_2D /* @todo flexible type */, GL_TEXTURE_BORDER_COLOR, color); /* Identical; default 0.0 identical too */
glTexParameterf(GL_TEXTURE_2D /* @todo flexible type */, GL_TEXTURE_LOD_BIAS, pTextureState[i].value); /* Identical; default 0.0 identical too */
AssertFailed();
if (textureType != ~0U)
return VINF_SUCCESS;
return VERR_INVALID_PARAMETER;
switch (face)
case SVGA3D_FACE_NONE:
case SVGA3D_FACE_FRONT:
case SVGA3D_FACE_BACK:
case SVGA3D_FACE_FRONT_BACK:
return VINF_SUCCESS;
float QuadAttenuation;
return VERR_INVALID_PARAMETER;
AssertFailed();
glPushMatrix();
case SVGA3D_LIGHTTYPE_POINT:
glLightf(GL_LIGHT0 + index, GL_QUADRATIC_ATTENUATION, (QuadAttenuation < pData->attenuation2) ? pData->attenuation2 : QuadAttenuation);
case SVGA3D_LIGHTTYPE_SPOT1:
glLightf(GL_LIGHT0 + index, GL_QUADRATIC_ATTENUATION, (QuadAttenuation < pData->attenuation2) ? pData->attenuation2 : QuadAttenuation);
glLightfv(GL_LIGHT0 + index, GL_POSITION, position); /* Note gl uses w position of 0 for direction! */
case SVGA3D_LIGHTTYPE_SPOT2:
return VERR_INVALID_PARAMETER;
glPopMatrix();
return VINF_SUCCESS;
return VERR_INVALID_PARAMETER;
AssertFailed();
if (enabled)
return VINF_SUCCESS;
return VERR_INVALID_PARAMETER;
vmsvga3dSetTransform(pThis, cid, SVGA3D_TRANSFORM_PROJECTION, pContext->state.aTransformState[SVGA3D_TRANSFORM_PROJECTION].matrix);
return VINF_SUCCESS;
Log(("vmsvga3dSetClipPlane cid=%x %d (%d,%d)(%d,%d)\n", cid, index, (unsigned)(plane[0] * 100.0), (unsigned)(plane[1] * 100.0), (unsigned)(plane[2] * 100.0), (unsigned)(plane[3] * 100.0)));
return VERR_INVALID_PARAMETER;
/* @todo clip plane affected by model view in OpenGL & view in D3D + vertex shader -> not transformed (see Wine; state.c clipplane) */
return VINF_SUCCESS;
Log(("vmsvga3dSetScissorRect cid=%x (%d,%d)(%d,%d)\n", cid, pRect->x, pRect->y, pRect->w, pRect->h));
return VERR_INVALID_PARAMETER;
return VINF_SUCCESS;
static void vmsvgaColor2GLFloatArray(uint32_t color, GLfloat *pRed, GLfloat *pGreen, GLfloat *pBlue, GLfloat *pAlpha)
int vmsvga3dCommandClear(PVGASTATE pThis, uint32_t cid, SVGA3dClearFlag clearFlag, uint32_t color, float depth, uint32_t stencil, uint32_t cRects, SVGA3dRect *pRect)
Log(("vmsvga3dCommandClear cid=%x clearFlag=%x color=%x depth=%d stencil=%x cRects=%d\n", cid, clearFlag, color, (uint32_t)(depth * 100.0), stencil, cRects));
return VERR_INVALID_PARAMETER;
if (cRects)
for (unsigned i=0; i < cRects; i++)
Log(("vmsvga3dCommandClear: rect %d (%d,%d)(%d,%d)\n", i, pRect[i].x, pRect[i].y, pRect[i].x + pRect[i].w, pRect[i].y + pRect[i].h));
glPopAttrib();
return VINF_SUCCESS;
int vmsvga3dVertexDecl2OGL(SVGA3dVertexArrayIdentity &identity, GLint &size, GLenum &type, GLboolean &normalized)
case SVGA3D_DECLTYPE_FLOAT1:
case SVGA3D_DECLTYPE_FLOAT2:
case SVGA3D_DECLTYPE_FLOAT3:
case SVGA3D_DECLTYPE_FLOAT4:
case SVGA3D_DECLTYPE_D3DCOLOR:
case SVGA3D_DECLTYPE_UBYTE4N:
case SVGA3D_DECLTYPE_UBYTE4:
case SVGA3D_DECLTYPE_SHORT2N:
case SVGA3D_DECLTYPE_SHORT2:
case SVGA3D_DECLTYPE_SHORT4N:
case SVGA3D_DECLTYPE_SHORT4:
case SVGA3D_DECLTYPE_USHORT4N:
case SVGA3D_DECLTYPE_USHORT2N:
case SVGA3D_DECLTYPE_UDEC3:
case SVGA3D_DECLTYPE_DEC3N:
normalized = true;
return VINF_SUCCESS;
int vmsvga3dPrimitiveType2OGL(SVGA3dPrimitiveType PrimitiveType, GLenum *pMode, uint32_t cPrimitiveCount, uint32_t *pcVertices)
switch (PrimitiveType)
return VERR_INVALID_PARAMETER;
return VINF_SUCCESS;
int vmsvga3dDrawPrimitivesProcessVertexDecls(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, uint32_t iVertexDeclBase, uint32_t numVertexDecls, SVGA3dVertexDecl *pVertexDecl)
AssertReturn(sidVertex < pState->cSurfaces && pState->paSurface[sidVertex].id == sidVertex, VERR_INVALID_PARAMETER);
Log(("vmsvga3dDrawPrimitives: create vertex buffer fDirty=%d size=%x bytes\n", pVertexSurface->fDirty, pVertexSurface->pMipmapLevels[0].cbSurface));
pState->ext.glBufferData(GL_ARRAY_BUFFER, pVertexSurface->pMipmapLevels[0].cbSurface, pVertexSurface->pMipmapLevels[0].pSurfaceData, GL_DYNAMIC_DRAW);
Log(("vmsvga3dDrawPrimitives: array index %d type=%s (%d) method=%s (%d) usage=%s (%d) usageIndex=%d stride=%d offset=%d\n", index, vmsvgaDeclType2String(pVertexDecl[iVertex].identity.type), pVertexDecl[iVertex].identity.type, vmsvgaDeclMethod2String(pVertexDecl[iVertex].identity.method), pVertexDecl[iVertex].identity.method, vmsvgaDeclUsage2String(pVertexDecl[iVertex].identity.usage), pVertexDecl[iVertex].identity.usage, pVertexDecl[iVertex].identity.usageIndex, pVertexDecl[iVertex].array.stride, pVertexDecl[iVertex].array.offset));
pState->ext.glVertexAttribPointer(index, size, type, normalized, pVertexDecl[iVertex].array.stride, (const GLvoid *)pVertexDecl[iVertex].array.offset);
glVertexPointer(size, type, pVertexDecl[iVertex].array.stride, (const GLvoid *)pVertexDecl[iVertex].array.offset);
AssertFailed();
AssertFailed();
case SVGA3D_DECLUSAGE_NORMAL:
glNormalPointer(type, pVertexDecl[iVertex].array.stride, (const GLvoid *)pVertexDecl[iVertex].array.offset);
case SVGA3D_DECLUSAGE_PSIZE:
AssertFailed();
glTexCoordPointer(size, type, pVertexDecl[iVertex].array.stride, (const GLvoid *)pVertexDecl[iVertex].array.offset);
case SVGA3D_DECLUSAGE_TANGENT:
AssertFailed();
AssertFailed();
AssertFailed();
glColorPointer(size, type, pVertexDecl[iVertex].array.stride, (const GLvoid *)pVertexDecl[iVertex].array.offset);
case SVGA3D_DECLUSAGE_FOG:
pState->ext.glFogCoordPointer(type, pVertexDecl[iVertex].array.stride, (const GLvoid *)pVertexDecl[iVertex].array.offset);
case SVGA3D_DECLUSAGE_DEPTH:
AssertFailed();
case SVGA3D_DECLUSAGE_SAMPLE:
AssertFailed();
#ifdef LOG_ENABLED
return VINF_SUCCESS;
int vmsvga3dDrawPrimitivesCleanupVertexDecls(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, uint32_t iVertexDeclBase, uint32_t numVertexDecls, SVGA3dVertexDecl *pVertexDecl)
case SVGA3D_DECLUSAGE_NORMAL:
case SVGA3D_DECLUSAGE_PSIZE:
case SVGA3D_DECLUSAGE_TANGENT:
case SVGA3D_DECLUSAGE_FOG:
case SVGA3D_DECLUSAGE_DEPTH:
case SVGA3D_DECLUSAGE_SAMPLE:
return VINF_SUCCESS;
int vmsvga3dDrawPrimitives(PVGASTATE pThis, uint32_t cid, uint32_t numVertexDecls, SVGA3dVertexDecl *pVertexDecl, uint32_t numRanges, SVGA3dPrimitiveRange *pRange, uint32_t cVertexDivisor, SVGA3dVertexDivisor *pVertexDivisor)
Log(("vmsvga3dDrawPrimitives cid=%x numVertexDecls=%d numRanges=%d, cVertexDivisor=%d\n", cid, numVertexDecls, numRanges, cVertexDivisor));
return VERR_INVALID_PARAMETER;
iCurrentVertex = 0;
rc = vmsvga3dDrawPrimitivesProcessVertexDecls(pState, pContext, iCurrentVertex, iVertex - iCurrentVertex, &pVertexDecl[iCurrentVertex]);
unsigned cVertices;
Log(("Primitive %d: type %s\n", iPrimitive, vmsvga3dPrimitiveType2String(pRange[iPrimitive].primType)));
rc = vmsvga3dPrimitiveType2OGL(pRange[iPrimitive].primType, &modeDraw, pRange[iPrimitive].primitiveCount, &cVertices);
goto internal_error;
AssertMsg(pRange[iPrimitive].indexWidth == sizeof(uint32_t) || pRange[iPrimitive].indexWidth == sizeof(uint16_t), ("Unsupported primitive width %d\n", pRange[iPrimitive].indexWidth));
goto internal_error;
Log(("vmsvga3dDrawPrimitives: create index buffer fDirty=%d size=%x bytes\n", pIndexSurface->fDirty, pIndexSurface->pMipmapLevels[0].cbSurface));
pState->ext.glBufferData(GL_ELEMENT_ARRAY_BUFFER, pIndexSurface->pMipmapLevels[0].cbSurface, pIndexSurface->pMipmapLevels[0].pSurfaceData, GL_DYNAMIC_DRAW);
if (!pIndexSurface)
Log(("DrawPrimitive %x cPrimitives=%d cVertices=%d index index bias=%d\n", modeDraw, pRange[iPrimitive].primitiveCount, cVertices, pRange[iPrimitive].indexBias));
Log(("DrawIndexedPrimitive %x cPrimitives=%d cVertices=%d hint.first=%d hint.last=%d index offset=%d primitivecount=%d index width=%d index bias=%d\n", modeDraw, pRange[iPrimitive].primitiveCount, cVertices, pVertexDecl[0].rangeHint.first, pVertexDecl[0].rangeHint.last, pRange[iPrimitive].indexArray.offset, pRange[iPrimitive].primitiveCount, pRange[iPrimitive].indexWidth, pRange[iPrimitive].indexBias));
iCurrentVertex = 0;
rc = vmsvga3dDrawPrimitivesCleanupVertexDecls(pState, pContext, iCurrentVertex, iVertex - iCurrentVertex, &pVertexDecl[iCurrentVertex]);
#ifdef DEBUG
AssertMsg(pTexture->oglId.texture == (GLuint)activeTexture, ("%x vs %x unit %d - %d\n", pTexture->oglId.texture, activeTexture, i, activeTextureUnit - GL_TEXTURE0));
#ifdef DEBUG_GFX_WINDOW
return rc;
int vmsvga3dShaderDefine(PVGASTATE pThis, uint32_t cid, uint32_t shid, SVGA3dShaderType type, uint32_t cbData, uint32_t *pShaderData)
int rc;
Log(("vmsvga3dShaderDefine cid=%x shid=%x type=%s cbData=%x\n", cid, shid, (type == SVGA3D_SHADERTYPE_VS) ? "VERTEX" : "PIXEL", cbData));
return VERR_INVALID_PARAMETER;
pContext->paVertexShader = (PVMSVGA3DSHADER)RTMemRealloc(pContext->paVertexShader, sizeof(VMSVGA3DSHADER) * (shid + 1));
memset(&pContext->paVertexShader[pContext->cVertexShaders], 0, sizeof(VMSVGA3DSHADER) * (shid + 1 - pContext->cVertexShaders));
pContext->paPixelShader = (PVMSVGA3DSHADER)RTMemRealloc(pContext->paPixelShader, sizeof(VMSVGA3DSHADER) * (shid + 1));
memset(&pContext->paPixelShader[pContext->cPixelShaders], 0, sizeof(VMSVGA3DSHADER) * (shid + 1 - pContext->cPixelShaders));
switch (type)
case SVGA3D_SHADERTYPE_VS:
rc = ShaderCreateVertexShader(pContext->pShaderContext, (const uint32_t *)pShaderData, &pShader->u.pVertexShader);
case SVGA3D_SHADERTYPE_PS:
rc = ShaderCreatePixelShader(pContext->pShaderContext, (const uint32_t *)pShaderData, &pShader->u.pPixelShader);
return rc;
int rc;
Log(("vmsvga3dShaderDestroy cid=%x shid=%x type=%s\n", cid, shid, (type == SVGA3D_SHADERTYPE_VS) ? "VERTEX" : "PIXEL"));
return VERR_INVALID_PARAMETER;
if (pShader)
return VINF_SUCCESS;
int rc;
Log(("vmsvga3dShaderSet cid=%x type=%s shid=%d\n", cid, (type == SVGA3D_SHADERTYPE_VS) ? "VERTEX" : "PIXEL", shid));
return VERR_INVALID_PARAMETER;
return VINF_SUCCESS;
int vmsvga3dShaderSetConst(PVGASTATE pThis, uint32_t cid, uint32_t reg, SVGA3dShaderType type, SVGA3dShaderConstType ctype, uint32_t cRegisters, uint32_t *pValues)
int rc;
Log(("vmsvga3dShaderSetConst cid=%x reg=%x type=%s cregs=%d ctype=%x\n", cid, reg, (type == SVGA3D_SHADERTYPE_VS) ? "VERTEX" : "PIXEL", cRegisters, ctype));
return VERR_INVALID_PARAMETER;
#ifdef LOG_ENABLED
switch (ctype)
case SVGA3D_CONST_TYPE_FLOAT:
Log(("Constant %d: value=%d-%d-%d-%d\n", reg + i, (int)(pValuesF[i*4 + 0] * 100.0), (int)(pValuesF[i*4 + 1] * 100.0), (int)(pValuesF[i*4 + 2] * 100.0), (int)(pValuesF[i*4 + 3] * 100.0)));
case SVGA3D_CONST_TYPE_INT:
Log(("Constant %d: value=%x-%x-%x-%x\n", reg + i, pValues[i*4 + 0], pValues[i*4 + 1], pValues[i*4 + 2], pValues[i*4 + 3]));
case SVGA3D_CONST_TYPE_BOOL:
Log(("Constant %d: value=%x-%x-%x-%x\n", reg + i, pValues[i*4 + 0], pValues[i*4 + 1], pValues[i*4 + 2], pValues[i*4 + 3]));
vmsvga3dSaveShaderConst(pContext, reg + i, type, ctype, pValues[i*4 + 0], pValues[i*4 + 1], pValues[i*4 + 2], pValues[i*4 + 3]);
switch (type)
case SVGA3D_SHADERTYPE_VS:
switch (ctype)
case SVGA3D_CONST_TYPE_FLOAT:
rc = ShaderSetVertexShaderConstantF(pContext->pShaderContext, reg, (const float *)pValues, cRegisters);
case SVGA3D_CONST_TYPE_INT:
rc = ShaderSetVertexShaderConstantI(pContext->pShaderContext, reg, (const int32_t *)pValues, cRegisters);
case SVGA3D_CONST_TYPE_BOOL:
rc = ShaderSetVertexShaderConstantB(pContext->pShaderContext, reg, (const uint8_t *)pValues, cRegisters);
case SVGA3D_SHADERTYPE_PS:
switch (ctype)
case SVGA3D_CONST_TYPE_FLOAT:
rc = ShaderSetPixelShaderConstantF(pContext->pShaderContext, reg, (const float *)pValues, cRegisters);
case SVGA3D_CONST_TYPE_INT:
rc = ShaderSetPixelShaderConstantI(pContext->pShaderContext, reg, (const int32_t *)pValues, cRegisters);
case SVGA3D_CONST_TYPE_BOOL:
rc = ShaderSetPixelShaderConstantB(pContext->pShaderContext, reg, (const uint8_t *)pValues, cRegisters);
return VINF_SUCCESS;
AssertFailed();
return VERR_NOT_IMPLEMENTED;
AssertFailed();
return VERR_NOT_IMPLEMENTED;
int vmsvga3dQueryWait(PVGASTATE pThis, uint32_t cid, SVGA3dQueryType type, SVGAGuestPtr guestResult)
AssertFailed();
return VERR_NOT_IMPLEMENTED;