VirtualBox

Changeset 56922 in vbox


Ignore:
Timestamp:
Jul 13, 2015 10:23:52 AM (9 years ago)
Author:
vboxsync
Message:

3D: Display List: Expando SPU and DLM module code significantly reworked (diff unreadable); first revision when glxgears can be saved and successfully restored; more testing and debugging needed; prelimenary tested ane enabled for Mac hosts only.

Location:
trunk/src/VBox
Files:
1 deleted
8 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_version.h

    r55765 r56922  
    4646#define SHCROGL_SSM_VERSION_WITH_PEND_CMD_INFO                      47
    4747#define SHCROGL_SSM_VERSION_WITH_SEPARATE_DEPTH_STENCIL_BUFFERS     48
    48 #define SHCROGL_SSM_VERSION                                         48
     48#define SHCROGL_SSM_VERSION_WITH_DISPLAY_LISTS                      49
     49#define SHCROGL_SSM_VERSION                                         49
    4950
    5051/* These define the Chromium release number.
  • trunk/src/VBox/HostServices/SharedOpenGL/Makefile.kmk

    r56602 r56922  
    3131
    3232ifeq ($(KBUILD_TARGET),darwin)
    33  #VBOX_WITH_CR_DISPLAY_LISTS=1
     33 VBOX_WITH_CR_DISPLAY_LISTS=1
    3434endif
    3535
     
    290290        dlm/dlm.c \
    291291        dlm/dlm_arrays.c \
    292         dlm/dlm_bbox.c \
    293         dlm/dlm_calllist.c \
     292        dlm/dlm_state.c \
    294293        dlm/dlm_checklist.c \
    295294        dlm/dlm_error.c \
     
    310309                | $$(dir $$@)
    311310        $(call MSG_GENERATE,python,$@,$<)
    312         $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< header $(VBOX_PATH_CROGL_GLAPI) > $@
     311        $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< header $(<D) $(VBOX_PATH_CROGL_GLAPI) > $@
    313312
    314313$(VBOX_PATH_CROGL_GENFILES)/dlm_generated.h: \
     
    350349        $(PATH_STAGE_LIB)/VBoxOGLhostspuload$(VBOX_SUFF_LIB) \
    351350        $(VBOX_LIB_OGL_HOSTCRUTIL) \
    352         $(LIB_RUNTIME)
     351        $(LIB_RUNTIME) \
     352        $(LIB_VMM)
    353353#
    354354# Generate files for VBoxOGLexpandospu.
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c

    r56473 r56922  
    16831683    }
    16841684
     1685    rc = crServerPendSaveState(pSSM);
     1686    AssertRCReturn(rc, rc);
     1687
     1688    rc = CrPMgrSaveState(pSSM);
     1689    AssertRCReturn(rc, rc);
     1690
    16851691#ifdef VBOX_WITH_CR_DISPLAY_LISTS
    16861692    if (cr_server.head_spu->dispatch_table.spu_save_state)
    16871693    {
    1688         rc = cr_server.head_spu->dispatch_table.spu_save_state("NULL");
     1694        rc = cr_server.head_spu->dispatch_table.spu_save_state((void *)pSSM);
    16891695        AssertRCReturn(rc, rc);
    16901696    }
     
    16921698        crDebug("Do not save %s SPU state: no interface exported.", cr_server.head_spu->name);
    16931699#endif
    1694 
    1695     rc = crServerPendSaveState(pSSM);
    1696     AssertRCReturn(rc, rc);
    1697 
    1698     rc = CrPMgrSaveState(pSSM);
    1699     AssertRCReturn(rc, rc);
    17001700
    17011701    /* all context gl error states should have now be synced with chromium erro states,
     
    24812481    }
    24822482
     2483#ifdef VBOX_WITH_CR_DISPLAY_LISTS
     2484    if (version >= SHCROGL_SSM_VERSION_WITH_DISPLAY_LISTS)
     2485    {
     2486        if (cr_server.head_spu->dispatch_table.spu_load_state)
     2487        {
     2488            rc = cr_server.head_spu->dispatch_table.spu_load_state((void *)pSSM);
     2489            AssertRCReturn(rc, rc);
     2490        }
     2491        else
     2492            crDebug("Do not load %s SPU state: no interface exported.", cr_server.head_spu->name);
     2493    }
     2494#endif
     2495
    24832496    while ((err = cr_server.head_spu->dispatch_table.GetError()) != GL_NO_ERROR)
    24842497        crWarning("crServer: glGetError %d after loading snapshot", err);
  • trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm.c

    r56566 r56922  
    229229        state->currentListMode = GL_FALSE;
    230230        state->listBase = 0;
    231         state->replayState = CRDLM_IMMEDIATE;
    232231       
    233232        /* Increment the use count of the DLM provided.  This guarantees that
     
    321320}
    322321
    323 /* Return whether the current thread is involved in playback.
    324  * This is useful for some routines to selectively choose their
    325  * unpack state, for example (as replayed DLM functions must be
    326  * unpacked with crStateNativePixelPacking instead of the
    327  * normal unpack state, for example.
    328  */
    329 CRDLMReplayState DLM_APIENTRY crDLMGetReplayState(void)
    330 {
    331     CRDLMContextState *listState = CURRENT_STATE();
    332     if (listState) {
    333         return listState->replayState;
    334     }
    335     else {
    336         return CRDLM_IMMEDIATE;
    337     }
    338 }
    339 
    340322/**
    341323 *
     
    365347{
    366348    CRDLMContextState *listState = CURRENT_STATE();
    367     if (listState) {
    368         CRDLMReplayState oldReplayState = listState->replayState;
    369         listState->replayState = CRDLM_REPLAY_ALL_FUNCTIONS;
    370         crDLMReplayDLMList(listState->dlm, listIdentifier, dispatchTable);
    371         listState->replayState = oldReplayState;
    372     }
     349    if (listState)
     350        crDLMReplayDLMList(listState->dlm, listIdentifier, dispatchTable);
    373351}
    374352
     
    398376{
    399377    CRDLMContextState *listState = CURRENT_STATE();
    400     if (listState) {
    401         CRDLMReplayState oldReplayState = listState->replayState;
    402         listState->replayState = CRDLM_REPLAY_STATE_FUNCTIONS;
    403         crDLMReplayDLMListState(listState->dlm, listIdentifier, dispatchTable);
    404         listState->replayState = oldReplayState;
    405     }
     378    if (listState)
     379        crDLMReplayDLMListState(listState->dlm, listIdentifier, dispatchTable);
    406380}
    407381
     
    565539};
    566540
    567 static void getRefsCallback(unsigned long key, void *data, void *dataPtr2)
    568 {
    569     struct getRefsCallbackParms *cbParms =
    570         (struct getRefsCallbackParms *)dataPtr2;
    571 
    572     /* Count the total number of references */
    573     cbParms->totalCount++;
    574 
    575     /* If we haven't yet reached the desired offset, decrement it */
    576     if (cbParms->remainingOffset > 0) {
    577         cbParms->remainingOffset--;
    578     }
    579     else if (cbParms->remainingCount > 0) {
    580          /* Store data until we've stored all we can.
    581          */
    582         *(cbParms->buffer++) = key;
    583         cbParms->remainingCount--;
    584     }
    585 }
    586 
    587 int DLM_APIENTRY crDLMGetReferences(CRDLM *dlm, unsigned long listIdentifier,
    588     int firstIndex, int sizeofBuffer, unsigned int *buffer)
    589 {
    590     DLMListInfo *listInfo;
    591 
    592     listInfo = (DLMListInfo *) crHashtableSearch(dlm->displayLists, listIdentifier);
    593     if (listInfo) {
    594         struct getRefsCallbackParms cbParms;
    595 
    596         cbParms.remainingOffset = firstIndex;
    597         cbParms.remainingCount = sizeofBuffer;
    598         cbParms.buffer = buffer;
    599         cbParms.totalCount = 0;
    600 
    601         crHashtableWalk(listInfo->references, getRefsCallback, (void *)&cbParms);
    602 
    603         return cbParms.totalCount;
    604     }
    605     else {
    606         /* No list exists; it therefore has no references */
    607         return 0;
    608     }
    609 }
    610 
    611541/*
    612542 * Return id of list currently being compiled.  Returns 0 of there's no
     
    644574                (*ErrorCallback)(line, file, error, info);
    645575}
    646 
    647 static void crDLMSaveListsCb(unsigned long key, void *pData1, void *pData2 /* unused */ )
    648 {
    649     DLMListInfo *pListInfo = (DLMListInfo*)pData1;
    650 
    651     if (pListInfo)
    652     {
    653         crDebug("Saving Display Lists: found ID=%u, numInstances=%d, references=%p.",
    654             key, pListInfo->numInstances, pListInfo->references);
    655 
    656         DLMInstanceList *pInstance = pListInfo->first;
    657         while (pInstance) {
    658             crDebug("\t%p", pInstance->execute);
    659             pInstance = pInstance->next;
    660         }
    661     }
    662     else
    663         crError("Saving Display Lists: found record with no data. Skipping.");
    664 }
    665 
    666 int32_t DLM_APIENTRY crDLMSaveState(void)
    667 {
    668     CRDLMContextState *pListState = CURRENT_STATE();
    669 
    670     if (pListState)
    671         crHashtableWalk(pListState->dlm->displayLists, crDLMSaveListsCb, (void *)NULL);
    672     else
    673         crDebug("Saving Display Lists: no data to save.");
    674 
    675     return 0;
    676 }
  • trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_generated.py

    r56473 r56922  
    126126
    127127def wrap_execute(functionName):
    128         params = apiutil.Parameters(functionName)
    129         print 'static void execute%s(DLMInstanceList *x, SPUDispatchTable *dispatchTable)' % functionName
    130         print '{'
    131         if len(params) > 0:
    132             print '\tstruct instance%s *instance = (struct instance%s *)x;' % (functionName, functionName)
    133         print '\tif (dispatchTable->%s != NULL) {' % (functionName)
    134         print '\t\tdispatchTable->%s(%s);' % (functionName, InstanceCallString(params))
    135         print '\t}'
    136         print '\telse {'
    137         print '\t\tcrWarning("DLM warning: execute%s called with NULL dispatch entry");' % (functionName)
    138         print '\t}'
    139         print '}'
    140 
    141 def generate_bbox_code(functionName):
    142         assert functionName[0:6] == "Vertex"
    143         pattern = "(VertexAttribs|VertexAttrib|Vertex)(1|2|3|4)(N?)(f|d|i|s|b|ub|us|ui)(v?)"
    144         m = re.match(pattern, functionName)
    145         if m:
    146                 name = m.group(1)
    147                 size = int(m.group(2))
    148                 normalize = m.group(3)
    149                 type = m.group(4)
    150                 vector = m.group(5)
    151 
    152                 # only update bbox for vertex attribs if index == 0
    153                 if name == "VertexAttrib":
    154                         test = "if (index == 0) {"
    155                 elif name == "VertexAttribs":
    156                         test = "if (index == 0) {"
    157                 else:
    158                         assert name == "Vertex"
    159                         test = "{"
    160 
    161                 # find names of the X, Y, Z, W values
    162                 xName = ""
    163                 yName = ""
    164                 zName = "0.0"
    165                 wName = ""
    166                 if vector == "v":
    167                         xName = "v[0]"
    168                         if size > 1:
    169                                 yName = "v[1]"
    170                         if size > 2:
    171                                 zName = "v[2]"
    172                         if size > 3:
    173                                 wName = "v[3]"
    174                 else:
    175                         xName = "x"
    176                         if size > 1:
    177                                 yName = "y"
    178                         if size > 2:
    179                                 zName = "z"
    180                         if size > 3:
    181                                 wName = "w"
    182 
    183                 # start emitting code
    184                 print '\t%s' % test
    185 
    186                 if normalize == "N":
    187                         if type == "b":
    188                                 denom = "128.0f"
    189                         elif type == "s":
    190                                 denom = "32768.0f"
    191                         elif type == "i":
    192                                 denom = "2147483647.0f"
    193                         elif type == "ub":
    194                                 denom = "255.0f"
    195                         elif type == "us":
    196                                 denom = "65535.0f"
    197                         elif type == "ui":
    198                                 denom = "4294967295.0f"
    199                        
    200                         print '\t\tGLfloat nx = (GLfloat) %s / %s;' % (xName, denom)
    201                         xName = "nx"
    202                         if yName:
    203                                 print '\t\tGLfloat ny = (GLfloat) %s / %s;' % (yName, denom)
    204                                 yName = "ny"
    205                         if zName:
    206                                 print '\t\tGLfloat nz = (GLfloat) %s / %s;' % (zName, denom)
    207                                 zName = "nz"
    208                         if 0 and wName:
    209                                 print '\t\tGLfloat nw = (GLfloat) %s / %s;' % (wName, denom)
    210                                 wName = "nw"
    211 
    212                 if xName:
    213                         print '\t\tif (%s < state->currentListInfo->bbox.xmin)' % xName
    214                         print '\t\t\tstate->currentListInfo->bbox.xmin = %s;' % xName
    215                         print '\t\tif (%s > state->currentListInfo->bbox.xmax)' % xName
    216                         print '\t\t\tstate->currentListInfo->bbox.xmax = %s;' % xName
    217                 if yName:
    218                         print '\t\tif (%s < state->currentListInfo->bbox.ymin)' % yName
    219                         print '\t\t\tstate->currentListInfo->bbox.ymin = %s;' % yName
    220                         print '\t\tif (%s > state->currentListInfo->bbox.ymax)' % yName
    221                         print '\t\t\tstate->currentListInfo->bbox.ymax = %s;' % yName
    222                 if zName:
    223                         print '\t\tif (%s < state->currentListInfo->bbox.zmin)' % zName
    224                         print '\t\t\tstate->currentListInfo->bbox.zmin = %s;' % zName
    225                         print '\t\tif (%s > state->currentListInfo->bbox.zmax)' % zName
    226                         print '\t\t\tstate->currentListInfo->bbox.zmax = %s;' % zName
    227                 # XXX what about divide by W if we have 4 components?
    228                 print '\t}'
    229                        
    230         else:
    231                 print ' /* bbox error for %s !!!!! */' % functionName
     128
     129    params = apiutil.Parameters(functionName)
     130    (pointers, _, pointerarg, _, _, _) = GetPointerInfo(functionName)
     131
     132    print 'static void execute%s(DLMInstanceList *x, SPUDispatchTable *dispatchTable)' % functionName
     133    print '{'
     134    if len(params) > 0:
     135        print '    struct instance%s *instance = (struct instance%s *)x;' % (functionName, functionName)
     136
     137    if len(pointers) == 1:
     138        print '    instance->%s = instance->%s;' % (params[pointers[0]][0], pointerarg)
     139
     140    print '    if (dispatchTable->%s != NULL)' % (functionName)
     141    print '        dispatchTable->%s(%s);' % (functionName, InstanceCallString(params))
     142    print '    else'
     143    print '        crWarning("DLM warning: execute%s called with NULL dispatch entry");' % (functionName)
     144    print '}'
    232145
    233146# These code snippets isolate the code required to add a given instance
     
    239152    print '%sinstance->stateNext = NULL;' % pad
    240153    print '%sif (!state->currentListInfo->first) {' % pad
    241     print '%s\tstate->currentListInfo->first = (DLMInstanceList *)instance;' % pad
     154    print '%s    state->currentListInfo->first = (DLMInstanceList *)instance;' % pad
    242155    print '%s}' % pad
    243156    print '%selse {' % pad
    244     print '%s\tstate->currentListInfo->last->next = (DLMInstanceList *)instance;' % pad
     157    print '%s  state->currentListInfo->last->next = (DLMInstanceList *)instance;' % pad
    245158    print '%s}' % pad
    246159    print '%sstate->currentListInfo->last = (DLMInstanceList *)instance;' % pad
     
    250163    print '%s/* Instances that change state have to be added to the state list as well. */' % pad
    251164    print '%sif (!state->currentListInfo->stateFirst) {' % pad
    252     print '%s\tstate->currentListInfo->stateFirst = (DLMInstanceList *)instance;' % pad
     165    print '%s    state->currentListInfo->stateFirst = (DLMInstanceList *)instance;' % pad
    253166    print '%s}' % pad
    254167    print '%selse {' % pad
    255     print '%s\tstate->currentListInfo->stateLast->stateNext = (DLMInstanceList *)instance;' % pad
     168    print '%s    state->currentListInfo->stateLast->stateNext = (DLMInstanceList *)instance;' % pad
    256169    print '%s}' % pad
    257170    print '%sstate->currentListInfo->stateLast = (DLMInstanceList *)instance;' % pad
     
    262175# being compiled.
    263176def wrap_compile(functionName):
    264         params = apiutil.Parameters(functionName)
    265         return_type = apiutil.ReturnType(functionName)
    266         # Make sure the return type is void.  It's nonsensical to compile
    267         # an element with any other return type.
    268         if return_type != 'void':
    269                 print '/* Nonsense: DL function %s has a %s return type?!? */' % (functionName, return_type)
    270         #       return
    271         # Define a structure to hold all the parameters.  Note that the
    272         # top parameters must exactly match the DLMInstanceList structure
    273         # in include/cr_dlm.h, or everything will break horribly.
    274         # Start off by getting all the pointer info we could ever use
    275         # from the parameters
    276         (pointers, pointername, pointerarg, pointertype, pointersize, pointercomment) = GetPointerInfo(functionName)
    277 
    278         # Finally, the compile wrapper.  This one will diverge strongly
    279         # depending on whether or not there are pointer parameters.
    280         callstring = apiutil.MakeCallString(params)
    281         argstring = apiutil.MakeDeclarationString(params)
    282         props = apiutil.Properties(functionName)
    283         if "useclient" in props or "pixelstore" in props:
    284                 callstring += ", c"
    285                 argstring += ", CRClientState *c"
    286         print 'void DLM_APIENTRY crDLMCompile%s( %s )' % (functionName, argstring)
    287         print '{'
    288         print ' CRDLMContextState *state = CURRENT_STATE();'
    289         print ' struct instance%s *instance;' % (functionName)
    290        
    291         # The calling SPU is supposed to verify that the element is supposed to be
    292         # compiled before it is actually compiled; typically, this is done based
    293         # on whether a glNewList has been executed more recently than a glEndList.
    294         # But some functions are dual-natured, sometimes being compiled, and sometimes
    295         # being executed immediately.  We can check for this here.
    296         if "checklist" in apiutil.ChromiumProps(functionName):
    297             print '\tif (crDLMCheckList%s(%s)) {' % (functionName, apiutil.MakeCallString(params))
    298             print '\t\tcrdlm_error(__LINE__, __FILE__, GL_INVALID_OPERATION,'
    299             print '\t\t    "this instance of function %s should not be compiled");' % functionName;
    300             print '\t\treturn;'
    301             print '\t}'
    302 
    303         if len(pointers) > 1 or pointersize == 'special':
    304                 # Pass NULL, to just allocate space
    305                 print '\tinstance = crCalloc(sizeof(struct instance%s) + crdlm_pointers_%s(NULL, %s));' % (functionName, functionName, callstring)
    306         else:
    307                 print '\tinstance = crCalloc(sizeof(struct instance%s));' % (functionName)
    308         print '\tif (!instance) {'
    309         print '\t\tcrdlm_error(__LINE__, __FILE__, GL_OUT_OF_MEMORY,'
    310         print '\t\t\t"out of memory adding %s to display list");' % (functionName)
    311         print '\t\treturn;'
    312         print '\t}'
    313 
    314         # Put in the fields that must always exist
    315         print '\tinstance->execute = execute%s;' % functionName
    316 
    317         # Apply all the simple (i.e. non-pointer) parameters
    318         for index in range(len(params)):
    319                 if index not in pointers:
    320                         name = params[index][0]
    321                         print '\tinstance->%s = %s;' % (name, name)
    322        
    323         # We need to know instance size in bytes in order to save its state later.
    324         print '\tinstance->cbInstance = sizeof(struct instance%s);' % functionName
    325        
    326         # Set OPCODE.
    327         print '\tinstance->iVBoxOpCode = VBOX_DL_OPCODE_%s;' % functionName
    328        
    329         # If there's a pointer parameter, apply it.
    330         if len(pointers) == 1:
    331                 print '\tif (%s == NULL) {' % (params[pointers[0]][0])
    332                 print '\t\tinstance->%s = NULL;' % (params[pointers[0]][0])
    333                 print '\t}'
    334                 print '\telse {'
    335                 print '\t\tinstance->%s = instance->%s;' % (params[pointers[0]][0], pointerarg)
    336                 print '\t}'
    337                 if pointersize == 'special':
    338                         print '\tinstance->cbInstance += crdlm_pointers_%s(instance, %s);' % (functionName, callstring)
    339                 else:
    340                         print '\tcrMemcpy((void *)instance->%s, (void *) %s, %s*sizeof(%s));' % (params[pointers[0]][0], params[pointers[0]][0], pointersize, pointertype)
    341         elif len(pointers) == 2:
    342                 # this seems to work
    343                 print '\tinstance->cbInstance += crdlm_pointers_%s(instance, %s);' % (functionName, callstring)
    344         elif len(pointers) > 2:
    345                 print "#error don't know how to handle pointer parameters for %s" % (functionName)
    346        
    347         # Add the element to the current display list
    348         AddInstanceToList('\t')
    349         # If the element is a state-changing element, add it to the current state list
    350         if apiutil.SetsTrackedState(functionName):
    351             AddInstanceToStateList('\t')
    352 
    353         # XXX might need a better test here
    354         if functionName[0:6] == "Vertex":
    355                 generate_bbox_code(functionName)
    356 
    357         print '}'
     177    params = apiutil.Parameters(functionName)
     178    return_type = apiutil.ReturnType(functionName)
     179    # Make sure the return type is void.  It's nonsensical to compile
     180    # an element with any other return type.
     181    if return_type != 'void':
     182        print '/* Nonsense: DL function %s has a %s return type?!? */' % (functionName, return_type)
     183
     184    # Define a structure to hold all the parameters.  Note that the
     185    # top parameters must exactly match the DLMInstanceList structure
     186    # in include/cr_dlm.h, or everything will break horribly.
     187    # Start off by getting all the pointer info we could ever use
     188    # from the parameters
     189    (pointers, pointername, pointerarg, pointertype, pointersize, pointercomment) = GetPointerInfo(functionName)
     190
     191    # Finally, the compile wrapper.  This one will diverge strongly
     192    # depending on whether or not there are pointer parameters.
     193    callstring = apiutil.MakeCallString(params)
     194    argstring = apiutil.MakeDeclarationString(params)
     195    props = apiutil.Properties(functionName)
     196    if "useclient" in props or "pixelstore" in props:
     197        callstring += ", c"
     198        argstring += ", CRClientState *c"
     199    print 'void DLM_APIENTRY crDLMCompile%s( %s )' % (functionName, argstring)
     200    print '{'
     201    print '    CRDLMContextState *state = CURRENT_STATE();'
     202    print '    struct instance%s *instance;' % (functionName)
     203
     204    # The calling SPU is supposed to verify that the element is supposed to be
     205    # compiled before it is actually compiled; typically, this is done based
     206    # on whether a glNewList has been executed more recently than a glEndList.
     207    # But some functions are dual-natured, sometimes being compiled, and sometimes
     208    # being executed immediately.  We can check for this here.
     209    if "checklist" in apiutil.ChromiumProps(functionName):
     210        print '    if (crDLMCheckList%s(%s))' % (functionName, apiutil.MakeCallString(params))
     211        print '    {'
     212        print '        crdlm_error(__LINE__, __FILE__, GL_INVALID_OPERATION,'
     213        print '            "this instance of function %s should not be compiled");' % functionName;
     214        print '        return;'
     215        print '    }'
     216
     217    if len(pointers) > 1 or pointersize == 'special':
     218        # Pass NULL, to just allocate space
     219        print '    instance = crCalloc(sizeof(struct instance%s) + crdlm_pointers_%s(NULL, %s));' % (functionName, functionName, callstring)
     220    else:
     221        print '    instance = crCalloc(sizeof(struct instance%s));' % (functionName)
     222    print '    if (!instance)'
     223    print '    {'
     224    print '        crdlm_error(__LINE__, __FILE__, GL_OUT_OF_MEMORY,'
     225    print '            "out of memory adding %s to display list");' % (functionName)
     226    print '        return;'
     227    print '    }'
     228
     229    # Put in the fields that must always exist
     230    print '    instance->execute = execute%s;' % functionName
     231
     232    # Apply all the simple (i.e. non-pointer) parameters
     233    for index in range(len(params)):
     234        if index not in pointers:
     235            name = params[index][0]
     236            print '    instance->%s = %s;' % (name, name)
     237
     238    # We need to know instance size in bytes in order to save its state later.
     239    print '    instance->cbInstance = sizeof(struct instance%s);' % functionName
     240
     241    # Set OPCODE.
     242    print '    instance->iVBoxOpCode = VBOX_DL_OPCODE_%s;' % functionName
     243
     244    # If there's a pointer parameter, apply it.
     245    if len(pointers) == 1:
     246
     247        print '    if (%s == NULL)' % (params[pointers[0]][0])
     248        print '        instance->%s = NULL;' % (params[pointers[0]][0])
     249        print '    else'
     250        print '        instance->%s = instance->%s;' % (params[pointers[0]][0], pointerarg)
     251
     252        if pointersize == 'special':
     253            print '    instance->cbInstance += crdlm_pointers_%s(instance, %s);' % (functionName, callstring)
     254        else:
     255            print '    crMemcpy((void *)instance->%s, (void *) %s, %s*sizeof(%s));' % (params[pointers[0]][0], params[pointers[0]][0], pointersize, pointertype)
     256    elif len(pointers) == 2:
     257        # this seems to work
     258        print '    instance->cbInstance += crdlm_pointers_%s(instance, %s);' % (functionName, callstring)
     259    elif len(pointers) > 2:
     260        print "#error don't know how to handle pointer parameters for %s" % (functionName)
     261
     262    # Add the element to the current display list
     263    AddInstanceToList('    ')
     264    # If the element is a state-changing element, add it to the current state list
     265    if apiutil.SetsTrackedState(functionName):
     266        AddInstanceToStateList('    ')
     267    print '}'
    358268
    359269whichfile=sys.argv[1]
     
    361271    print """#ifndef _DLM_GENERATED_H
    362272#define _DLM_GENERATED_H
     273
     274#include <VBox/VBoxUhgsmi.h>
    363275
    364276/* DO NOT EDIT.  This file is auto-generated by dlm_generated.py. */
     
    417329                    wrap_execute(func_name)
    418330                    wrap_compile(func_name)
    419                 # All others just pass through
     331
     332
     333# Generate mapping between OPCODE and routines to be executed.
     334
     335if whichfile == "headers":
     336    # Execute routine prototype needed to add static array of routines.
     337    print ''
     338    print 'struct DLMInstanceList;'
     339    print 'typedef void (*VBoxDLMExecuteFn)(struct DLMInstanceList *instance, SPUDispatchTable *dispatchTable);'
     340    print ''
     341    print 'extern VBoxDLMExecuteFn g_VBoxDLMExecuteFns[VBOX_DL_OPCODE_MAX];'
     342    print ''
     343else:
     344    print ''
     345    print 'VBoxDLMExecuteFn g_VBoxDLMExecuteFns[] = {'
     346
     347    for func_name in keys:
     348        if apiutil.CanCompile(func_name) and not apiutil.FindSpecial("dlm", func_name):
     349            print '    execute%s,' % func_name
     350
     351    print '};'
     352    print ''
    420353
    421354if whichfile == 'headers':
  • trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_header.py

    r56566 r56922  
    88mode = sys.argv[1]
    99
    10 keys = apiutil.GetDispatchedFunctions(sys.argv[2]+"/APIspec.txt")
     10keys = apiutil.GetDispatchedFunctions(sys.argv[3]+"/APIspec.txt")
    1111
    1212# Any new function implemented in the DLM has to have an entry added here.
     
    2121        ('void DLM_APIENTRY', 'crDLMSetCurrentState', 'CRDLMContextState *state'),
    2222        ('CRDLMContextState DLM_APIENTRY *', 'crDLMGetCurrentState', 'void'),
    23         ('CRDLMReplayState DLM_APIENTRY', 'crDLMGetReplayState', 'void'),
    2423        ('void DLM_APIENTRY', 'crDLMSetupClientState', 'SPUDispatchTable *dispatchTable'),
    2524        ('void DLM_APIENTRY', 'crDLMRestoreClientState', 'CRClientState *clientState, SPUDispatchTable *dispatchTable'),
     
    3736        ('void DLM_APIENTRY', 'crDLMReplayListsState', 'GLsizei n, GLenum type, const GLvoid *lists, SPUDispatchTable *dispatchTable'),
    3837        ('CRDLMError DLM_APIENTRY', 'crDLMDeleteListContent', 'CRDLM *dlm, unsigned long listIdentifier'),
    39         ('int DLM_APIENTRY', 'crDLMGetReferences', 'CRDLM *dlm, unsigned long listIdentifier, int firstIndex, int sizeofBuffer, unsigned int *buffer'),
    4038        ('void DLM_APIENTRY', 'crDLMComputeBoundingBox', 'unsigned long listId'),
    4139        ('GLuint DLM_APIENTRY', 'crDLMGetCurrentList', 'void'),
     
    5048        ('GLboolean DLM_APIENTRY', 'crDLMIsList', 'GLuint list, SPUDispatchTable *dispatchTable'),
    5149        ('GLuint DLM_APIENTRY', 'crDLMGenLists', 'GLsizei range, SPUDispatchTable *dispatchTable'),
    52         ('int32_t DLM_APIENTRY', 'crDLMSaveState', 'void'),
     50        ('int32_t DLM_APIENTRY', 'crDLMSaveState', 'CRDLM *dlm, PSSMHANDLE pSSM'),
     51        ('bool DLM_APIENTRY', 'crDLMLoadState', 'CRDLM *dlm, PSSMHANDLE pSSM, SPUDispatchTable *dispatchTable'),
    5352        #('void DLM_APIENTRY', 'crDLMListSent', 'CRDLM *dlm, unsigned long listIdentifier'),
    5453        #('GLboolean DLM_APIENTRY', 'crDLMIsListSent', 'CRDLM *dlm, unsigned long listIdentifier'),
     
    7776#include "cr_threads.h"
    7877#endif
     78#include <VBox/types.h>
    7979""" % os.path.basename(sys.argv[0])
    8080
     
    8484
    8585    for func_name in keys:
    86         print "    VBOX_DL_OPCODE_%s," % func_name
    87 
     86        if apiutil.CanCompile(func_name) and not apiutil.FindSpecial("dlm", func_name):
     87            print "    VBOX_DL_OPCODE_%s," % func_name
     88
     89    print "    VBOX_DL_OPCODE_MAX,"
    8890    print "} VBoxDLOpCode;"
    8991
     
    111113
    112114typedef struct {
    113         DLMInstanceList *first, *last;
    114         int numInstances;
    115         DLMInstanceList *stateFirst, *stateLast;
    116         CRHashTable *references; /* display lists that this display list calls */
    117         CRDLMBounds bbox;
    118         GLboolean listSent;
    119         GLuint hwid;
     115    DLMInstanceList *first, *last;
     116    uint32_t         numInstances;
     117    DLMInstanceList *stateFirst, *stateLast;
     118    GLuint           hwid;
    120119} DLMListInfo;
    121120
     
    160159        GLenum currentListMode;         /* GL_COMPILE or GL_COMPILE_AND_EXECUTE */
    161160        GLuint listBase;
    162         CRDLMReplayState replayState;   /* CRDLM_IMMEDIATE, CRDLM_REPLAY_STATE_FUNCTIONS, or CRDLM_REPLAY_ALL_FUNCTIONS */
    163161
    164162} CRDLMContextState;
  • trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_lists.c

    r56566 r56922  
    77 *   glListBase and glIsList.
    88 *
    9  * Privide OpenGL IDs mapping between host and guest.
     9 * Provide OpenGL IDs mapping between host and guest.
    1010 */
    1111
     
    5757        crdlmFreeDisplayListElements(pListInfo->first);
    5858        pListInfo->first = pListInfo->last = NULL;
    59 
    60         /* The references list has no allocated information; it's
    61          * just a set of entries.  So we don't need to free any
    62          * information as each entry is deleted.
    63          */
    64         crFreeHashtable(pListInfo->references, NULL);
    6559
    6660        /* Free host OpenGL resources. */
     
    191185                    listInfo->first = listInfo->last = NULL;
    192186                    listInfo->stateFirst = listInfo->stateLast = NULL;
    193                     listInfo->references = crAllocHashtable();
    194                     if (listInfo->references)
    195                     {
    196                         listInfo->numInstances = 0;
    197                         listInfo->listSent = GL_FALSE;
    198                         listInfo->bbox.xmin = FLT_MAX;
    199                         listInfo->bbox.xmax = -FLT_MAX;
    200                         listInfo->bbox.ymin = FLT_MAX;
    201                         listInfo->bbox.ymax = -FLT_MAX;
    202                         listInfo->bbox.zmin = FLT_MAX;
    203                         listInfo->bbox.zmax = -FLT_MAX;
    204 
    205                         listState->currentListInfo = listInfo;
    206                         listState->currentListIdentifier = list;
    207                         listState->currentListMode = mode;
    208 
    209                         dispatchTable->NewList(listInfo->hwid, mode);
    210 
    211                         crDebug("DLM: create new list with [guest, host] ID pair [%u, %u].", list, listInfo->hwid);
    212 
    213                         return;
    214                     }
    215                     else
    216                         crDebug("DLM: Could not allocate memory in NewList.");
     187
     188                    listInfo->numInstances = 0;
     189
     190                    listState->currentListInfo = listInfo;
     191                    listState->currentListIdentifier = list;
     192                    listState->currentListMode = mode;
     193
     194                    dispatchTable->NewList(listInfo->hwid, mode);
     195
     196                    crDebug("DLM: create new list with [guest, host] ID pair [%u, %u].", list, listInfo->hwid);
     197
     198                    return;
    217199                }
    218200                else
  • trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_state.c

    r56921 r56922  
    11/* $Id$ */
     2/** @file
     3 * Implementation of saving and restoring Display Lists.
     4 */
     5
     6/*
     7 * Copyright (C) 2015 Oracle Corporation
     8 *
     9 * This file is part of VirtualBox Open Source Edition (OSE), as
     10 * available from http://www.virtualbox.org. This file is free software;
     11 * you can redistribute it and/or modify it under the terms of the GNU
     12 * General Public License (GPL) as published by the Free Software
     13 * Foundation, in version 2 as it comes in the "COPYING" file of the
     14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
     15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
     16 */
     17
     18#include "cr_mem.h"
     19#include "cr_dlm.h"
     20#include "dlm.h"
     21#include "dlm_generated.h"
     22
     23#include "VBox/vmm/ssm.h"
     24#include "iprt/err.h"
     25
     26
     27typedef struct {
     28
     29    PSSMHANDLE pSSM;
     30    uint32_t   err;
     31
     32} CRDLMSaveListsCbArg;
     33
     34static void crDLMSaveListsCb(unsigned long key, void *pData1, void *pData2)
     35{
     36    DLMListInfo         *pListInfo      = (DLMListInfo*)pData1;
     37    CRDLMSaveListsCbArg *pArg           = (CRDLMSaveListsCbArg *)pData2;
     38    PSSMHANDLE           pSSM           = pArg->pSSM;
     39    DLMInstanceList     *pInstance      = pListInfo->first;
     40    uint32_t             cInstanceCheck = 0;
     41    int32_t              rc;
     42
     43    crDebug("Saving Display Lists: found ID=%u, numInstances=%d.", key, pListInfo->numInstances);
     44
     45    /* Store Display List length. */
     46    rc = SSMR3PutU32(pSSM, pListInfo->numInstances);
     47    if (RT_SUCCESS(rc))
     48    {
     49        /* Store Display List (guest) ID. */
     50        rc = SSMR3PutU32(pSSM, (uint32_t)key);
     51        if (RT_SUCCESS(rc))
     52        {
     53            /* Store each Display List item one by one. */
     54            while (pInstance)
     55            {
     56                /* Let's count each list item and compare total number with pListInfo->numInstances.
     57                 * This is simple consistency check. */
     58                cInstanceCheck++;
     59
     60                /* Store instance data size. */
     61                rc = SSMR3PutU32(pSSM, (uint32_t)pInstance->cbInstance);
     62                if (RT_SUCCESS(rc))
     63                {
     64                    rc = SSMR3PutMem(pSSM, pInstance, pInstance->cbInstance);
     65                    if (RT_SUCCESS(rc))
     66                    {
     67                        /* We just stored all we need. Let's move on to the next list element. */
     68                        pInstance = pInstance->next;
     69                        continue;
     70                    }
     71                }
     72
     73                crError("Saving Display Lists: can't store data.");
     74
     75                pArg->err = 1;
     76                return;
     77            }
     78
     79            if (cInstanceCheck == pListInfo->numInstances)
     80                return;
     81
     82            crError("Saving Display Lists: list currupted.");
     83        }
     84    }
     85
     86    pArg->err = 1;
     87}
     88
     89int32_t DLM_APIENTRY crDLMSaveState(CRDLM *dlm, PSSMHANDLE pSSM)
     90{
     91    uint32_t ui32;
     92    int32_t  rc;
     93
     94    CRDLMSaveListsCbArg arg;
     95
     96    arg.pSSM = pSSM;
     97    arg.err = 0;
     98
     99    /* Save number of Display Lists assigned to current DLM context. */
     100    ui32 = (uint32_t)crHashtableNumElements(dlm->displayLists);
     101    rc = SSMR3PutU32(pSSM, ui32); AssertRCReturn(rc, rc);
     102
     103    crHashtableWalk(dlm->displayLists, crDLMSaveListsCb, (void *)&arg);
     104
     105    return arg.err == 0;
     106}
     107
     108static VBoxDLMExecuteFn crDLMGetExecuteRoutine(VBoxDLOpCode opcode)
     109{
     110    if (opcode < VBOX_DL_OPCODE_MAX)
     111        return g_VBoxDLMExecuteFns[opcode];
     112
     113    crError("Restoring Display Lists: Invalid opcode %u.", opcode);
     114
     115    return NULL;
     116}
     117
     118static bool
     119crDLMLoadListInstance(PSSMHANDLE pSSM, DLMListInfo *pListInfo, SPUDispatchTable *dispatchTable)
     120{
     121    uint32_t         cbInstance = 0;
     122    DLMInstanceList *pInstance;
     123    int32_t          rc;
     124
     125    /* Get Display List item size. */
     126    rc = SSMR3GetU32(pSSM, &cbInstance);
     127    if (RT_SUCCESS(rc))
     128    {
     129        /* Allocate memory for the item, initialize it and put into the list. */
     130        pInstance = crCalloc(cbInstance);
     131        if (pInstance)
     132        {
     133            crMemset(pInstance, 0, cbInstance);
     134
     135            rc = SSMR3GetMem(pSSM, pInstance, cbInstance); AssertRCReturn(rc, rc);
     136            if (RT_SUCCESS(rc))
     137            {
     138                pInstance->execute = crDLMGetExecuteRoutine(pInstance->iVBoxOpCode);
     139                if (pInstance->execute)
     140                {
     141                    pInstance->execute(pInstance, dispatchTable);
     142
     143                    pInstance->next         = NULL;
     144                    pInstance->stateNext    = NULL;
     145                    pInstance->cbInstance   = cbInstance;
     146
     147                    pListInfo->numInstances++;
     148
     149                    if (!pListInfo->first)
     150                        pListInfo->first = pInstance;
     151
     152                    if (pListInfo->last)
     153                        pListInfo->last->next = pInstance;
     154
     155                    pListInfo->last = pInstance;
     156
     157                    return true;
     158                }
     159                else
     160                    crError("Restoring Display Lists: unknown list item (opcode=%u).", pInstance->iVBoxOpCode);
     161            }
     162            else
     163                crError("Restoring Display Lists: can't read list element size.");
     164        }
     165        else
     166            crError("Restoring Display Lists: not enough memory, aborting.");
     167    }
     168    else
     169        crError("Restoring Display Lists: saved state file might be corrupted.");
     170
     171    return false;
     172}
     173
     174static bool
     175crDLMLoadList(CRDLM *dlm, PSSMHANDLE pSSM, SPUDispatchTable *dispatchTable)
     176{
     177    uint32_t cElements = 0;
     178    uint32_t idList    = 0;
     179    uint32_t i;
     180    int32_t  rc;
     181
     182    /* Restore Display List length. */
     183    rc = SSMR3GetU32(pSSM, &cElements);
     184    if (RT_SUCCESS(rc))
     185    {
     186        /* Restore Display List ID. */
     187        rc = SSMR3GetU32(pSSM, &idList);
     188        if (RT_SUCCESS(rc))
     189        {
     190            /* Initialize new list data and start recording it. */
     191            DLMListInfo *pListInfo;
     192
     193            pListInfo = (DLMListInfo *)crCalloc(sizeof(DLMListInfo));
     194            if (pListInfo)
     195            {
     196                GLuint hwid;
     197
     198                crMemset(pListInfo, 0, sizeof(DLMListInfo));
     199
     200                hwid = dispatchTable->GenLists(1);
     201                if (hwid > 0)
     202                {
     203                    bool               fSuccess = true;
     204                    CRDLMContextState *pDLMContextState;
     205
     206                    pListInfo->numInstances = 0;
     207                    pListInfo->stateFirst   = pListInfo->stateLast = NULL;
     208                    pListInfo->hwid         = hwid;
     209
     210                    dispatchTable->NewList(hwid, GL_COMPILE);
     211
     212                    /* Fake list state in order to prevent expando SPU from double caching. */
     213                    pDLMContextState = crDLMGetCurrentState();
     214                    pDLMContextState->currentListMode = GL_FALSE;
     215
     216                    crDebug("Restoring Display Lists:\t%u elements to restore.", cElements);
     217
     218                    /* Iterate over list instances. */
     219                    for (i = 0; i < cElements; i++)
     220                    {
     221                        fSuccess = crDLMLoadListInstance(pSSM, pListInfo, dispatchTable);
     222                        if (!fSuccess)
     223                            break;
     224                    }
     225
     226                    dispatchTable->EndList();
     227
     228                    if (fSuccess)
     229                    {
     230                        /* Add list to cache. */
     231                        crHashtableReplace(dlm->displayLists, idList, pListInfo, NULL);
     232                        return true;
     233                    }
     234                    else
     235                        crError("Restoring Display Lists: some elements could not be restored.");
     236                }
     237                else
     238                    crError("Restoring Display Lists: can't allocate hwid for list %u.", idList);
     239
     240                crFree(pListInfo);
     241            }
     242            else
     243                crError("Restoring Display Lists: can't allocate memory.");
     244        }
     245        else
     246            crError("Restoring Display Lists: can't get list ID.");
     247    }
     248    else
     249        crError("Restoring Display Lists: can't get number of elements in list.");
     250
     251    return false;
     252}
     253
     254
     255bool DLM_APIENTRY
     256crDLMLoadState(CRDLM *dlm, PSSMHANDLE pSSM, SPUDispatchTable *dispatchTable)
     257{
     258    uint32_t cLists = 0;
     259    uint32_t i;
     260    int32_t  rc;
     261    bool     fSuccess = true;
     262
     263    /* Get number of Display Lists assigned to current DLM context. */
     264    rc = SSMR3GetU32(pSSM, &cLists);
     265    if (RT_SUCCESS(rc))
     266    {
     267        crDebug("Restoring Display Lists: %u lists to restore.", cLists);
     268
     269        for (i = 0; i < cLists; i++)
     270        {
     271            fSuccess = crDLMLoadList(dlm, pSSM, dispatchTable);
     272            if (!fSuccess)
     273                break;
     274        }
     275    }
     276    else
     277        crError("Restoring Display Lists: can't get number of lists.");
     278
     279    return fSuccess;
     280}
     281
     282
     283
     284
     285
     286
     287
    2288#if 0
    3289
  • trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu_init.c

    r56473 r56922  
    1010#include "cr_dlm.h"
    1111#include "cr_hash.h"
     12#include "cr_mem.h"
    1213#include "expandospu.h"
    1314
     15/* This magic number is used for SSM data consistency check. */
     16#define VBOX_EXPANDOSPU_SSM_MAGIC           0x3d3d3d3d
     17/* Modify VBox Expando SPU SSM version if SSM data structure changed. */
     18#define VBOX_EXPANDOSPU_SSM_VERSION_ONE     1
     19#define VBOX_EXPANDOSPU_SSM_VERSION         VBOX_EXPANDOSPU_SSM_VERSION_ONE
     20
    1421ExpandoSPU expando_spu;
    1522
    1623static SPUFunctions expando_functions = {
    17         NULL, /* CHILD COPY */
    18         NULL, /* DATA */
    19         _cr_expando_table /* THE ACTUAL FUNCTIONS */
     24    NULL,              /* CHILD COPY */
     25    NULL,              /* DATA */
     26    _cr_expando_table  /* THE ACTUAL FUNCTIONS */
    2027};
     28
     29/*
     30 * Structure of SSM data:
     31 *
     32 * <VBOX_EXPANDOSPU_SSM_MAGIC>
     33 * <VBOX_EXPANDOSPU_SSM_VERSION>
     34 * <Number of Expando SPU contexts>
     35 *
     36 *     <Context ID>
     37 *     <CRDLMContextState structure>
     38 *         <DLM module data>
     39 *
     40 *     <Next context...>
     41 *
     42 * <VBOX_EXPANDOSPU_SSM_MAGIC>
     43 */
     44
     45static void
     46expandoSPUSaveContextCb(unsigned long id, void *pData1, void *pData2)
     47{
     48    uint32_t   ui32 = (uint32_t)id;
     49    PSSMHANDLE pSSM = (PSSMHANDLE)pData2;
     50    int32_t    rc;
     51
     52    ExpandoContextState *pExpandoContextState = (ExpandoContextState *)pData1;
     53    CRDLMContextState    dlmContextState;
     54
     55    /* Save context ID. */
     56    rc = SSMR3PutU32(pSSM, ui32); AssertRCReturnVoid(rc);
     57
     58    /* Save DLM context state. Clean fields which will not be valid on restore (->dlm and ->currentListInfo).
     59     * We interested only in fields: currentListIdentifier, currentListMode and listBase. */
     60    crMemcpy(&dlmContextState, pExpandoContextState->dlmContext, sizeof(CRDLMContextState));
     61    dlmContextState.dlm             = NULL;
     62    dlmContextState.currentListInfo = NULL;
     63    rc = SSMR3PutMem(pSSM, &dlmContextState, sizeof(CRDLMContextState)); AssertRCReturnVoid(rc);
     64
     65    /* Delegate the rest of work to DLM module. */
     66    crDLMSaveState(pExpandoContextState->dlmContext->dlm, pSSM);
     67}
    2168
    2269static int
    2370expandoSPUSaveState(void *pData)
    2471{
     72    uint32_t    magic   = VBOX_EXPANDOSPU_SSM_MAGIC;
     73    uint32_t    version = VBOX_EXPANDOSPU_SSM_VERSION;
     74    PSSMHANDLE  pSSM    = (PSSMHANDLE)pData;
     75    int32_t     rc;
     76    uint32_t    cStates;
     77
    2578    crDebug("Saving state of Expando SPU.");
    26     crDLMSaveState();
     79
     80    AssertReturn(pSSM, 1);
     81
     82    /* Magic & version first. */
     83    rc = SSMR3PutU32(pSSM, magic);      AssertRCReturn(rc, rc);
     84    rc = SSMR3PutU32(pSSM, version);    AssertRCReturn(rc, rc);
     85
     86    /* Store number of Expando SPU contexts. */
     87    cStates = (uint32_t)crHashtableNumElements(expando_spu.contextTable);
     88    rc = SSMR3PutU32(pSSM, cStates);  AssertRCReturn(rc, rc);
     89
     90    /* Walk over context table and store required data. */
     91    crHashtableWalk(expando_spu.contextTable, expandoSPUSaveContextCb, pSSM);
     92
     93    /* Expando SPU and DLM data should end with magic (consistency check). */
     94    rc = SSMR3PutU32(pSSM, magic);      AssertRCReturn(rc, rc);
     95
    2796    return 0;
    2897}
    2998
     99static int
     100expandoSPULoadState(void *pData)
     101{
     102    uint32_t    magic   = 0;
     103    uint32_t    version = 0;
     104    PSSMHANDLE  pSSM    = (PSSMHANDLE)pData;
     105    int32_t     rc;
     106
     107    crDebug("Loading state of Expando SPU.");
     108
     109    AssertReturn(pSSM, 1);
     110
     111    /* Check magic and version. */
     112    rc = SSMR3GetU32(pSSM, &magic);
     113    AssertRCReturn(rc, rc);
     114
     115    if (magic == VBOX_EXPANDOSPU_SSM_MAGIC)
     116    {
     117        rc = SSMR3GetU32(pSSM, &version);
     118        AssertRCReturn(rc, rc);
     119
     120        if (version >= VBOX_EXPANDOSPU_SSM_VERSION_ONE)
     121        {
     122            uint32_t cStates = 0;
     123            uint32_t i;
     124            bool     fSuccess = false;
     125
     126            /* Restore number of Expando SPU contexts. */
     127            rc = SSMR3GetU32(pSSM, &cStates);
     128            AssertRCReturn(rc, rc);
     129
     130            /* Restore and update Expando SPU contexts one by one. */
     131            for (i = 0; i < cStates; i++)
     132            {
     133                uint32_t             idContext = 0;
     134                ExpandoContextState *pExpandoContextState;
     135
     136                rc = SSMR3GetU32(pSSM, &idContext);
     137                AssertRCReturn(rc, rc);
     138
     139                /* Find context which was previously created by CR Server. */
     140                pExpandoContextState = crHashtableSearch(expando_spu.contextTable, idContext);
     141                if (pExpandoContextState)
     142                {
     143                    CRDLMContextState dlmContextState;
     144
     145                    /* Restore and update DLM context state. */
     146                    rc = SSMR3GetMem(pSSM, &dlmContextState, sizeof(CRDLMContextState));
     147                    if (RT_SUCCESS(rc))
     148                    {
     149                        pExpandoContextState->dlmContext->currentListIdentifier = dlmContextState.currentListIdentifier;
     150                        pExpandoContextState->dlmContext->currentListMode       = dlmContextState.currentListMode;
     151                        pExpandoContextState->dlmContext->listBase              = dlmContextState.listBase;
     152
     153                        crDLMSetCurrentState(pExpandoContextState->dlmContext);
     154                        crStateMakeCurrent(pExpandoContextState->State);
     155
     156                        /* Delegate the rest of work to DLM module. */
     157                        fSuccess = crDLMLoadState(pExpandoContextState->dlmContext->dlm, pSSM, &expando_spu.server->dispatch);
     158                        if (fSuccess)
     159                        {
     160                            continue;
     161                        }
     162                        else
     163                        {
     164                            crError("Expando SPU: stop restoring Display Lists.");
     165                            break;
     166                        }
     167                    }
     168                    else
     169                    {
     170                        crError("Expando SPU: unable to load state: state file structure error (1).");
     171                        break;
     172                    }
     173                }
     174                else
     175                {
     176                    crError("Expando SPU: unable to load state: no context ID %u found.", idContext);
     177                    break;
     178                }
     179            }
     180
     181            if (fSuccess)
     182            {
     183                /* Expando SPU and DLM data should end with magic (consistency check). */
     184                magic = 0;
     185                rc = SSMR3GetU32(pSSM, &magic);
     186                if (RT_SUCCESS(rc))
     187                {
     188                    if (magic == VBOX_EXPANDOSPU_SSM_MAGIC)
     189                    {
     190                        crInfo("Expando SPU state loaded.");
     191                        return 0;
     192                    }
     193                    else
     194                        crError("Expando SPU: unable to load state: SSM data corrupted.");
     195                }
     196                else
     197                    crError("Expando SPU: unable to load state: state file structure error (2): no magic.");
     198            }
     199            else
     200                crError("Expando SPU: unable to load state: some list(s) could not be restored.");
     201        }
     202        else
     203            crError("Expando SPU: unable to load state: unexpected SSM version (0x%x).", version);
     204    }
     205    else
     206        crError("Expando SPU: unable to load state: SSM data possibly corrupted.");
     207
     208    return VERR_SSM_UNEXPECTED_DATA;
     209}
     210
    30211static SPUFunctions *
    31 expandoSPUInit( int id, SPU *child, SPU *self,
    32                                                                  unsigned int context_id,
    33                                                                  unsigned int num_contexts )
    34 {
    35 
    36         (void) self;
    37         (void) context_id;
    38         (void) num_contexts;
    39 
    40         expando_spu.id = id;
    41         expando_spu.has_child = 0;
    42         expando_spu.server = NULL;
    43         if (child)
    44         {
    45                 crSPUInitDispatchTable( &(expando_spu.child) );
    46                 crSPUCopyDispatchTable( &(expando_spu.child), &(child->dispatch_table) );
    47                 expando_spu.has_child = 1;
    48         }
    49         crSPUInitDispatchTable( &(expando_spu.super) );
    50         crSPUCopyDispatchTable( &(expando_spu.super), &(self->superSPU->dispatch_table) );
    51         expandospuGatherConfiguration();
    52 
    53         /* Expando-specific initialization */
    54         expando_spu.contextTable = crAllocHashtable();
    55 
    56         /* We'll be using the state tracker for each context */
    57         crStateInit();
     212expandoSPUInit(int id, SPU *child, SPU *self, unsigned int context_id, unsigned int num_contexts)
     213{
     214
     215    (void)self;
     216    (void)context_id;
     217    (void)num_contexts;
     218
     219    expando_spu.id = id;
     220    expando_spu.has_child = 0;
     221    expando_spu.server = NULL;
     222
     223    if (child)
     224    {
     225        crSPUInitDispatchTable(&(expando_spu.child));
     226        crSPUCopyDispatchTable(&(expando_spu.child), &(child->dispatch_table));
     227        expando_spu.has_child = 1;
     228    }
     229
     230    crSPUInitDispatchTable(&(expando_spu.super));
     231    crSPUCopyDispatchTable(&(expando_spu.super), &(self->superSPU->dispatch_table));
     232    expandospuGatherConfiguration();
     233
     234    /* Expando-specific initialization */
     235    expando_spu.contextTable = crAllocHashtable();
     236
     237    /* We'll be using the state tracker for each context */
     238    crStateInit();
    58239
    59240    /* Export optional interfaces for SPU save/restore. */
    60241    self->dispatch_table.spu_save_state = expandoSPUSaveState;
    61 
    62         return &expando_functions;
     242    self->dispatch_table.spu_load_state = expandoSPULoadState;
     243
     244    return &expando_functions;
    63245}
    64246
     
    66248expandoSPUSelfDispatch(SPUDispatchTable *self)
    67249{
    68         crSPUInitDispatchTable( &(expando_spu.self) );
    69         crSPUCopyDispatchTable( &(expando_spu.self), self );
    70 
    71         expando_spu.server = (CRServer *)(self->server);
     250    crSPUInitDispatchTable(&(expando_spu.self));
     251    crSPUCopyDispatchTable(&(expando_spu.self), self);
     252
     253    expando_spu.server = (CRServer *)(self->server);
    72254}
    73255
     
    82264
    83265int
    84 SPULoad( char **name, char **super, SPUInitFuncPtr *init,
    85                                  SPUSelfDispatchFuncPtr *self, SPUCleanupFuncPtr *cleanup,
    86                                  SPUOptionsPtr *options, int *flags )
    87 {
    88         *name = "expando";
    89         //*super = "passthrough";
    90         *super = "render";
    91         *init = expandoSPUInit;
    92         *self = expandoSPUSelfDispatch;
    93         *cleanup = expandoSPUCleanup;
    94         *options = expandoSPUOptions;
    95         *flags = (SPU_NO_PACKER|SPU_NOT_TERMINAL|SPU_MAX_SERVERS_ZERO);
    96        
    97         return 1;
    98 }
     266SPULoad(char **name, char **super, SPUInitFuncPtr *init, SPUSelfDispatchFuncPtr *self,
     267    SPUCleanupFuncPtr *cleanup, SPUOptionsPtr *options, int *flags)
     268{
     269    *name = "expando";
     270    *super = "render";
     271    *init = expandoSPUInit;
     272    *self = expandoSPUSelfDispatch;
     273    *cleanup = expandoSPUCleanup;
     274    *options = expandoSPUOptions;
     275    *flags = (SPU_NO_PACKER|SPU_NOT_TERMINAL|SPU_MAX_SERVERS_ZERO);
     276
     277    return 1;
     278}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette