Compartir a través de


Listas de comandos compatibles

Esta sección solo se aplica a Windows 7 y versiones posteriores, y Windows Server 2008 R2 y versiones posteriores de Windows.

El entorno de ejecución de Direct3D usa la siguiente DDI de Direct3D 11 para las listas de comandos:

La semántica de las funciones CommandListExecute, CalcPrivateCommandListSize, CreateCommandList y DestroyCommandList del controlador se explican por sí mismas, basándose en otras funciones de DDI similares y en la documentación de la API de la DDI correspondiente.

Cuando el entorno de ejecución de Direct3D llama correctamente a la función CreateCommandList o RecycleCreateCommandList del controlador en el contexto diferido especificado en el miembro hDeferredContext de la estructura D3D11DDIARG_CREATECOMMANDLIST a la que apunta el parámetro pCreateCommandList, el entorno de ejecución de Direct3D realiza la siguiente secuencia de destrucción en el contexto diferido:

  1. El entorno de ejecución de Direct3D "cierra" todos los identificadores de objeto diferidos abiertos. Tenga en cuenta que estos identificadores pueden seguir apareciendo enlazados al contexto diferido.

  2. El entorno de ejecución destruye el contexto diferido.

Durante la llamada a CreateCommandList o RecycleCreateCommandList, las llamadas que realiza el controlador a las funciones de devolución de llamada de DDI state-refresh continúan divulgando el estado actual del contexto diferido. Sin embargo, durante el "cierre" y la destrucción del contexto diferido, las llamadas a la DDI de state-refresh reflejan que nada está enlazado (es decir, inmediatamente después de la llamada a CreateCommandList o RecycleCreateCommandList, todo está implícitamente sin enlazar).

La aplicación también puede abandonar un contexto diferido de forma explícita o debido a una condición de error por la API o el controlador. En estos casos, el entorno de ejecución de Direct3D realiza la siguiente secuencia:

  1. El entorno de ejecución de Direct3D llama a la función AbandonCommandList del controlador.

  2. El entorno de ejecución desenlaza los identificadores del contexto diferido uno por uno.

  3. El entorno de ejecución "cierra" todos los identificadores de objeto diferidos abiertos.

  4. El entorno de ejecución recicla o destruye el contexto diferido.

La secuencia anterior es similar a la secuencia de destrucción de un contexto inmediato. La llamada a la función AbandonCommandList del controlador permite que el controlador aplique el estado en lo que prefiera el controlador.

Durante la llamada a la función CommandListExecute del controlador, el controlador debe realizar la transición del estado del contexto diferido para que sea equivalente al estado que tenía cuando se creó el dispositivo. Esta operación también se conoce como una operación clear-state. Sin embargo, durante la llamada a la función CommandListExecute del controlador, las llamadas que realiza el controlador a las funciones de devolución de llamada de DDI state-refresh siguen reflejando el estado de lo que estaba enlazado durante la última llamada de DDI a una función de controlador. Durante la siguiente llamada de DDI a una función de controlador, las llamadas que realiza el controlador a las funciones de devolución de llamada de DDI state-refresh muestran el estado actual como completamente vacío, lo que refleja la transición de estado implícita desde CommandListExecute. Este hecho difiere ligeramente de la semántica típica y el comportamiento de las funciones de devolución de llamada DDI de state-refresh. Si el controlador hubiera llamado a una función de devolución de llamada de DDI state-refresh durante una llamada a una de las funciones SetShader del controlador, la función de devolución de llamada de DDI state-refresh se mostraría como ya enlazada al nuevo sombreador que se está enlazando. Esta divergencia del comportamiento de devolución de llamada de DDI state-refresh proporciona más flexibilidad al controlador para reflejar el estado anterior durante CommandListExecute.

La API de Direct3D versión 11 garantiza que ninguna consulta haya sido manipulada (es decir, que se haya llamado a QueryBegin o QueryEnd) por la lista de comandos y que solo haya sido "iniciada" por el contexto que intenta ejecutar la lista de comandos. La API también garantiza que ninguna lista de comandos que registre el mapa de un recurso dinámico se ejecute en un contexto que tenga el mismo recurso actualmente asignado. Antes de que una aplicación llame a la función FinishCommandList, el entorno de ejecución de Direct3D llama a la función de DDI QueryEnd y ResourceUnmap del controlador en cualquier consulta o recurso dinámico que siga incluyendo una consulta iniciada o un recurso asignado abierto porque FinishCommandList finaliza implícitamente los intervalos de consulta y desasigna cualquier recurso asignado.

Optimización para listas de comandos pequeñas

Una optimización del reciclaje de memoria para listas de comandos de pequeña cantidad de memoria puede ser importante para reducir la contención entre las llamadas a funciones DDI de lista de comandos y reducir la sobrecarga del procesamiento de llamadas que se requiere para las listas de comandos. La sobrecarga de procesamiento inherente a cada lista de comandos es significativa. Esta optimización está pensada para listas de comandos en las que la sobrecarga de procesamiento necesaria para las listas de comandos domina el tiempo de CPU y el espacio de memoria necesario para las listas de comandos. Una lista de comandos small-memory-amount es, por ejemplo, un único comando de gráficos, como CopyResource. La cantidad de memoria necesaria para CopyResource es de dos punteros. Sin embargo, CopyResource sigue necesitando la misma cantidad de procesamiento de llamadas de lista de comandos que una lista de comandos de gran cantidad de memoria. Cuando las listas de comandos small-memory-amount se generan con alta frecuencia, la sobrecarga de procesamiento necesaria para que el entorno de ejecución llame a las funciones CreateCommandList, DestroyCommandList, CreateDeferredContext y DestroyDevice(D3D10) del controlador (para el contexto diferido) es cada vez más importante. La memoria a la que se hace referencia aquí es la memoria del sistema que contiene estructuras de datos del controlador, que incluye la memoria para los identificadores DDI.

La función RecycleCommandList del controlador debe notificar al controlador cuándo los controladores salen del uso (pero aún no se eliminan) y cuándo se vuelven a usar los identificadores de controlador no usados previamente. Esta notificación se aplica a los identificadores command-list y deferred-context La única memoria a la que debe reciclarse el controlador es la memoria a la que apunta el controlador DDI. Aunque el objetivo de RecycleCommandList es reciclar la memoria que está asociada con el controlador, para mayor eficacia, el controlador tiene flexibilidad completa para elegir qué memoria se va a reciclar. El controlador no puede cambiar el tamaño de la región de memoria a la que apunta el indicador de la lista de comandos immediate-context. Este tamaño es el valor devuelto de CalcPrivateCommandListSize. El controlador tampoco puede cambiar el tamaño de la región de memoria a la que apunta el identificador local de la lista de comandos de contexto. Este tamaño es el valor devuelto de CalcDeferredContextHandleSize.

Las funciones de DDI RecycleCreateCommandList y RecycleCreateDeferredContext del controlador deben devolver códigos de error out-of-memory como valores E_OUTOFMEMORY HRESULT. Estas funciones no proporcionan estos códigos de error a través de llamadas a la función pfnSetErrorCb. Este requisito de controlador impide que el entorno de ejecución tenga que usar la sincronización de todo el dispositivo para ver si hay errores de contexto inmediatos de estas funciones de controlador de tipo de creación. Observar estos errores sería una fuente de contención grave para las listas de comandos small-memory-amount.

Las distinciones entre las funciones RecycleDestroyCommandList, RecycleCommandList y RecycleCreateCommandList del controlador son importantes. Entre sus características figuran las siguientes.

RecycleDestroyCommandList

El entorno de ejecución llama a la función RecycleDestroyCommandList del controlador para notificar al controlador que se requiere destrucción ligera. Es decir, el controlador aún no debe desasignar la memoria para el identificador de lista de comandos DDI. La función RecycleDestroyCommandList del controlador es de subprocesamiento libre como la función DestroyCommandList del controlador.

RecycleCommandList

La función RecycleCommandList del controlador informa al controlador de que el entorno de ejecución ha integrado un identificador de lista de comandos en la caché de contexto diferido. A continuación, la función permite al controlador integrar la memoria asociada a la lista de comandos en la caché de contexto diferido. El entorno de ejecución llama a la función RecycleCommandList del controlador desde el subproceso de contexto diferido. La función de DDI RecycleCommandList reduce la necesidad de que el controlador realice la sincronización propia.

RecycleCreateCommandList

El entorno de ejecución llama a la función RecycleCreateCommandList del controlador para que un identificador DDI sin usar previamente vuelva a ser válido.

Estas funciones de DDI de reciclaje proporcionan oportunidades de optimización para ayudar a reciclar recursos para listas de comandos small-memory-amount. El pseudocódigo siguiente muestra la implementación del entorno de ejecución a través del flujo de llamadas de función desde la API a DDI :

::FinishCommandList()
{
  // Empty InterlockedSList, integrating into the cache
  Loop { DC::pfnRecycleCommandList }

  If (Previously Destroyed CommandList Available)
 { IC::pfnRecycleCreateCommandList }
 else
  {
    IC::pfnCalcPrivateCommandListSize
    IC::pfnCreateCommandList
    IC::pfnCalcDeferredContextHandleSize(D3D11DDI_HT_COMMANDLIST)
  }

  Loop { DC::pfnDestroy* (context-local handle destroy) }

  IC::pfnRecycleCreateDeferredContext
}
...
Sporadic: DC::pfnCreate* (context-local open during first-bind per CommandList)

CommandList::Destroy()
{
  // If DC still alive, almost always recycle:
  If (DC still alive)
 { IC::pfnRecycleDestroyCommandList }
  Else
 { IC::pfnDestroyCommandList }
  // Add to InterlockedSList
}

En el diagrama de estado siguiente se muestra la validez de un identificador de lista de comandos DDI de contexto inmediato. El estado verde representa un identificador que se puede usar con CommandListExecute.

Diagrama que ilustra los estados de validez de un identificador de lista de comandos DDI immediate-context.