Información general sobre los descriptores

Las llamadas API crean descriptores e identifican los recursos.

Datos del descriptor

Un descriptor es un bloque relativamente pequeño de datos que describe completamente un objeto a la GPU, en un formato opaco específico de la GPU. Hay varios tipos diferentes de descriptores: vistas de destino de representación (RTV), vistas de galería de símbolos de profundidad (DSV), vistas de recursos del sombreador (SRV), vistas de acceso no ordenadas (UAV), vistas de búfer de constantes (CBV) y muestreadores.

Los descriptores varían en tamaño, en función del hardware de GPU. Puede consultar el tamaño de un SRV, UAV o CBV llamando a ID3D12Device::GetDescriptorHandleIncrementSize. Los descriptores se muestran en esta documentación como unidades indivisibles; este es un ejemplo.

srv, cbv, uav, and sampler

Los descriptores se crean mediante llamadas API e incluirán información como el recurso y los mapas mip que desea que contenga el descriptor.

El controlador no realiza un seguimiento ni mantiene referencias a descriptores, es hasta la aplicación para asegurarse de que el tipo de descriptor correcto está en uso y que la información está actualizada. Hay una pequeña excepción a esto; el controlador inspecciona los enlaces de destino de representación para asegurarse de que las cadenas de intercambio funcionan correctamente.

Los descriptores de objeto no necesitan liberarse. Los controladores no adjuntan ninguna asignación a la creación de un descriptor. Sin embargo, un descriptor puede codificar referencias a otras asignaciones para las que la aplicación posee la duración. Por ejemplo, un descriptor para un SRV debe contener la dirección virtual del recurso D3D (por ejemplo, una textura) a la que hace referencia el SRV. Es responsabilidad de la aplicación asegurarse de que no se usa un descriptor SRV cuando el recurso D3D subyacente depende de que se haya destruido o se esté modificando (por ejemplo, que se declare como no residente).

La forma principal de usar descriptores es colocarlos en montones de descriptores, que son memoria de respaldo para descriptores.

Identificadores de descriptores

Un identificador de descriptor es la dirección única del descriptor. Es similar a un puntero, pero es opaco, ya que su implementación es específica del hardware. El identificador es único entre montones de descriptores, por lo que, por ejemplo, una matriz de identificadores puede hacer referencia a descriptores en varios montones.

Los identificadores de CPU son para su uso inmediato, como copiar donde se deben identificar tanto el origen como el destino. Inmediatamente después del uso (por ejemplo, una llamada a ID3D12GraphicsCommandList::OMSetRenderTargets), se pueden reutilizar o se puede eliminar su montón subyacente.

Los identificadores de GPU no son para su uso inmediato: identifican ubicaciones de una lista de comandos para su uso en tiempo de ejecución de GPU. Deben conservarse hasta que las listas de comandos que hagan referencia a ellas se hayan ejecutado completamente.

Para crear un identificador de descriptor para el inicio de un montón, después de crear el propio montón del descriptor, llame a uno de los métodos siguientes:

Estos métodos devuelven las estructuras siguientes:

A medida que el tamaño de los descriptores varía según el hardware, para obtener el incremento entre cada descriptor en un montón de uso:

Es seguro desplazar una ubicación inicial con un número de incrementos, copiar identificadores y pasar identificadores a llamadas API. No es seguro desreferenciar un identificador como si fuera un puntero de CPU válido, ni analizar los bits dentro de un identificador.

Se han agregado algunas estructuras auxiliares, con miembros de inicialización, para facilitar la administración de identificadores.

Descriptores null

Al crear descriptores mediante llamadas API, las aplicaciones pasan un valor null para el puntero de recursos en la definición del descriptor para lograr el efecto de nada enlazado cuando un sombreador accede a él.

El resto del descriptor debe rellenarse tanto como sea posible. Por ejemplo, en el caso de las vistas de recursos del sombreador (SRV), el descriptor se puede usar para distinguir el tipo de vista que es (Texture1D, Texture2D, etc.). Los parámetros numéricos del descriptor de vista, como el número de mapas mip, deben establecerse en valores válidos para un recurso.

En muchos casos, hay un comportamiento definido para acceder a un recurso sin enlazar, como SRV que devuelven valores predeterminados. Se respetarán al acceder a un descriptor null siempre que el tipo de acceso al sombreador sea compatible con el tipo de descriptor. Por ejemplo, si un sombreador espera un SRV Texture2D y accede a un SRV null definido como Texture1D, el comportamiento no está definido y podría dar lugar a un restablecimiento del dispositivo.

En resumen, para crear un descriptor null, pase null para el parámetro pResource al crear la vista con métodos como CreateShaderResourceView. Para el parámetro de descripción de vista pDesc, establezca una configuración que funcione si el recurso no fuera null (de lo contrario, puede producirse un bloqueo en algún hardware).

Sin embargo, los descriptores raíz no deben establecerse en null.

En el hardware de nivel 1 (consulte Niveles de hardware, todos los descriptores enlazados mediante tablas de descriptores) deben inicializarse, ya sea como descriptores reales o descriptores nulls, aunque el hardware no tenga acceso a él; de lo contrario, el comportamiento no está definido.

En el hardware de nivel 2, esto se aplica a los descriptores CBV y UAV enlazados, pero no a los descriptores SRV.

En el hardware de nivel 3, no hay ninguna restricción en esto, siempre que nunca se acceda a los descriptores sin inicializar.

Descriptores predeterminados

Para crear un descriptor predeterminado para una vista particular, pase un parámetro pResource válido al método de creación de vista (como CreateShaderResourceView), pero pase NULL para el parámetro pDesc. Por ejemplo, si el recurso contenía 14 mips, la vista contendrá 14 mips. El caso predeterminado cubre la asignación más obvia de un recurso a una vista. Esto requiere que el recurso se asigne con un nombre de formato completo (por ejemplo, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB en lugar de DXGI_FORMAT_R8G8B8A8_TYPELESS).

Los descriptores predeterminados no se pueden usar con una vista de estructura de aceleración de seguimiento de rayos, ya que el parámetro pResource proporcionado debe ser NULL y la ubicación debe pasarse mediante un D3D12_RAYTRACING_ACCELERATION_STRUCTURE_SRV.

Descriptores de