Changeset 54210 in vbox for trunk/src/VBox/Devices/Graphics
- Timestamp:
- Feb 15, 2015 3:58:41 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp
r54166 r54210 179 179 #endif 180 180 181 /** @def VMSVGA3D_CLEAR_LAST_ERRORS 182 * Clears all pending OpenGL errors. 183 * 184 * If I understood this correctly, OpenGL maintains a bitmask internally and 185 * glGetError gets the next bit (clearing it) from the bitmap and translates it 186 * into a GL_XXX constant value which it then returns. A single OpenGL call can 187 * set more than one bit, and they stick around across calls, from what I 188 * understand. 189 * 190 * So in order to be able to use glGetError to check whether a function 191 * succeeded, we need to call glGetError until all error bits have been cleared. 192 * This macro does that (in all types of builds). 193 * 194 * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS 195 */ 196 #define VMSVGA3D_CLEAR_GL_ERRORS() \ 197 do { \ 198 if (RT_UNLIKELY(glGetError() != GL_NO_ERROR)) /* predict no errors pending */ \ 199 { \ 200 uint32_t iErrorClearingLoopsLeft = 64; \ 201 while (glGetError() != GL_NO_ERROR && iErrorClearingLoopsLeft > 0) \ 202 iErrorClearingLoopsLeft--; \ 203 } \ 204 } while (0) 205 206 /** @def VMSVGA3D_GET_LAST_GL_ERROR 207 * Gets the last OpenGL error, stores it in a_pContext->lastError and returns 208 * it. 209 * 210 * @returns Same as glGetError. 211 * @param a_pContext The context to store the error in. 212 * 213 * @sa VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN 214 */ 215 #define VMSVGA3D_GET_GL_ERROR(a_pContext) ((a_pContext)->lastError = glGetError()) 216 217 /** @def VMSVGA3D_GL_SUCCESS 218 * Checks whether VMSVGA3D_GET_LAST_GL_ERROR() return GL_NO_ERROR. 219 * 220 * Will call glGetError() and store the result in a_pContext->lastError. 221 * Will predict GL_NO_ERROR outcome. 222 * 223 * @returns True on success, false on error. 224 * @parm a_pContext The context to store the error in. 225 * 226 * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_COMPLAIN 227 */ 228 #define VMSVGA3D_GL_IS_SUCCESS(a_pContext) RT_LIKELY((((a_pContext)->lastError = glGetError()) == GL_NO_ERROR)) 229 230 /** @def VMSVGA3D_GL_COMPLAIN 231 * Complains about one or more OpenGL errors (first in a_pContext->lastError). 232 * 233 * Strict builds will trigger an assertion, while other builds will put the 234 * first few occurences in the release log. 235 * 236 * All GL errors will be cleared after invocation. Assumes lastError 237 * is an error, will not check for GL_NO_ERROR. 238 * 239 * @param a_pState The 3D state structure. 240 * @param a_pContext The context that holds the first error. 241 * @param a_LogRelDetails Argument list for LogRel or similar that describes 242 * the operation in greater detail. 243 * 244 * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS 245 */ 246 #ifdef VBOX_STRICT 247 # define VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails) \ 248 do { \ 249 AssertMsg((a_pState)->idActiveContext == (a_pContext)->id, \ 250 ("idActiveContext=%#x id=%#x\n", (a_pState)->idActiveContext, (a_pContext)->id)); \ 251 RTAssertMsg2Weak a_LogRelDetails; \ 252 GLenum iNextError; \ 253 while ((iNextError = glGetError()) != GL_NO_ERROR) \ 254 RTAssertMsg2Weak("next error: %#x\n", iNextError); \ 255 AssertMsgFailed(("first error: %#x (idActiveContext=%#x)\n", (a_pContext)->lastError, (a_pContext)->id)); \ 256 } while (0) 257 #else 258 # define VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails) \ 259 do { \ 260 LogRelMax(32, ("VMSVGA3d: OpenGL error %#x (idActiveContext=%#x) on line %u ", (a_pContext)->lastError, (a_pContext)->id)); \ 261 GLenum iNextError; \ 262 while ((iNextError = glGetError()) != GL_NO_ERROR) \ 263 LogRelMax(32, (" - also error %#x ", iNextError)); \ 264 LogRelMax(32, a_LogRelDetails); \ 265 } while (0) 266 #endif 267 268 /** @def VMSVGA3D_GL_GET_AND_COMPLAIN 269 * Combination of VMSVGA3D_GET_GL_ERROR and VMSVGA3D_GL_COMPLAIN, assuming that 270 * there is a pending error. 271 * 272 * @param a_pState The 3D state structure. 273 * @param a_pContext The context that holds the first error. 274 * 275 * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN 276 */ 277 #define VMSVGA3D_GL_GET_AND_COMPLAIN(a_pState, a_pContext, a_LogRelDetails) \ 278 do { \ 279 VMSVGA3D_GET_GL_ERROR(a_pContext); \ 280 VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails); \ 281 } while (0) 282 283 181 284 /** @def VMSVGA3D_CHECK_LAST_ERROR 182 285 * Checks that the last OpenGL error code indicates success. … … 186 289 * 187 290 * @parm pState The VMSVGA3d state. 188 * @parm pContext The newcontext.291 * @parm pContext The context. 189 292 * 190 * @todo Re vamp this to include the OpenGL operation so we can see what went191 * wrong. Maybe include a few of the first occurances in the release192 * log of regularbuilds.293 * @todo Replace with proper error handling, it's crazy to return 294 * VERR_INTERNAL_ERROR in strict builds and just barge on ahead in 295 * release builds. 193 296 */ 194 297 #ifdef VBOX_STRICT … … 2980 3083 case SVGA3D_SURFACE_HINT_INDEXBUFFER: 2981 3084 { 2982 uint8_t *pData;2983 unsigned uDestOffset;2984 2985 3085 Assert(pBoxes[i].h == 1); 2986 3086 3087 VMSVGA3D_CLEAR_GL_ERRORS(); 2987 3088 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, pSurface->oglId.buffer); 2988 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext); 2989 2990 pData = (uint8_t *)pState->ext.glMapBuffer(GL_ARRAY_BUFFER, (transfer == SVGA3D_READ_HOST_VRAM) ? GL_READ_ONLY : GL_WRITE_ONLY); 2991 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext); 2992 Assert(pData); 2993 2994 uDestOffset = pBoxes[i].x * pSurface->cbBlock + pBoxes[i].y * pMipLevel->cbSurfacePitch; 2995 AssertReturn(uDestOffset + pBoxes[i].w * pSurface->cbBlock + (pBoxes[i].h - 1) * pMipLevel->cbSurfacePitch <= pMipLevel->cbSurface, VERR_INTERNAL_ERROR); 2996 2997 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)); 2998 2999 rc = vmsvgaGMRTransfer(pThis, 3000 transfer, 3001 pData + uDestOffset, 3002 pMipLevel->cbSurfacePitch, 3003 guest.ptr, 3004 pBoxes[i].srcx * pSurface->cbBlock + pBoxes[i].srcy * cbSrcPitch, 3005 cbSrcPitch, 3006 pBoxes[i].w * pSurface->cbBlock, 3007 pBoxes[i].h); 3008 AssertRC(rc); 3009 3010 Log4(("first line:\n%.*Rhxd\n", cbSrcPitch, pData)); 3011 3012 pState->ext.glUnmapBuffer(GL_ARRAY_BUFFER); 3013 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext); 3014 3089 if (VMSVGA3D_GL_IS_SUCCESS(pContext)) 3090 { 3091 GLenum enmGlTransfer = (transfer == SVGA3D_READ_HOST_VRAM) ? GL_READ_ONLY : GL_WRITE_ONLY; 3092 uint8_t *pbData = (uint8_t *)pState->ext.glMapBuffer(GL_ARRAY_BUFFER, enmGlTransfer); 3093 if (RT_LIKELY(pbData != NULL)) 3094 { 3095 unsigned offDst = pBoxes[i].x * pSurface->cbBlock + pBoxes[i].y * pMipLevel->cbSurfacePitch; 3096 if (RT_LIKELY( offDst + pBoxes[i].w * pSurface->cbBlock + (pBoxes[i].h - 1) * pMipLevel->cbSurfacePitch 3097 <= pMipLevel->cbSurface)) 3098 { 3099 Log(("Lock %s memory for rectangle (%d,%d)(%d,%d)\n", (fVertex) ? "vertex" : "index", 3100 pBoxes[i].x, pBoxes[i].y, pBoxes[i].x + pBoxes[i].w, pBoxes[i].y + pBoxes[i].h)); 3101 3102 rc = vmsvgaGMRTransfer(pThis, 3103 transfer, 3104 pbData + offDst, 3105 pMipLevel->cbSurfacePitch, 3106 guest.ptr, 3107 pBoxes[i].srcx * pSurface->cbBlock + pBoxes[i].srcy * cbSrcPitch, 3108 cbSrcPitch, 3109 pBoxes[i].w * pSurface->cbBlock, 3110 pBoxes[i].h); 3111 AssertRC(rc); 3112 3113 Log4(("first line:\n%.*Rhxd\n", cbSrcPitch, pbData)); 3114 } 3115 else 3116 { 3117 AssertFailed(); 3118 rc = VERR_INTERNAL_ERROR; 3119 } 3120 3121 pState->ext.glUnmapBuffer(GL_ARRAY_BUFFER); 3122 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext); 3123 } 3124 else 3125 VMSVGA3D_GL_GET_AND_COMPLAIN(pState, pContext, ("glMapBuffer(GL_ARRAY_BUFFER, %#x) -> NULL\n", enmGlTransfer)); 3126 } 3127 else 3128 VMSVGA3D_GL_COMPLAIN(pState, pContext, ("glBindBuffer(GL_ARRAY_BUFFER, %#x)\n", pSurface->oglId.buffer)); 3015 3129 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, 0); 3016 3130 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
Note:
See TracChangeset
for help on using the changeset viewer.