Introduction to a Resource in Direct3D 11
Resources are the building blocks of your scene. They contain most of the data that Direct3D uses to interpret and render your scene. Resources are areas in memory that can be accessed by the Direct3D pipeline. Resources contain the following types of data: geometry, textures, shader data. This topic introduces Direct3D resources such as buffers and textures.
You can create resources that are strongly typed or typeless; you can control whether resources have both read and write access; you can make resources accessible to only the CPU, GPU, or both. Up to 128 resources can be active for each pipeline stage.
Direct3D guarantees to return zero for any resource that is accessed out of bounds.
The lifecycle of a Direct3D resource is:
- Create a resource using one of the create methods of the ID3D11Device interface.
- Bind a resource to the pipeline using a context and one of the set methods of the ID3D11DeviceContext interface.
- Deallocate a resource by calling the Release method of the resource interface.
This section contains the following topics:
Strong vs Weak Typing
There are two ways to fully specify the layout (or memory footprint) of a resource:
- Typed - fully specify the type when the resource is created.
- Typeless - fully specify the type when the resource is bound to the pipeline.
Creating a fully-typed resource restricts the resource to the format it was created with. This enables the runtime to optimize access, especially if the resource is created with flags indicating that it cannot be mapped by the application. Resources created with a specific type cannot be reinterpreted using the view mechanism unless the resource was created with the D3D10_DDI_BIND_PRESENT flag. If D3D10_DDI_BIND_PRESENT is set render-target or shader resource views can be created on these resources using any of the fully typed members of the appropriate family, even if the original resource was created as fully typed.
In a type less resource, the data type is unknown when the resource is first created. The application must choose from the available type less formats (see DXGI_FORMAT). You must specify the size of the memory to allocate and whether the runtime will need to generate the subtextures in a mipmap. However, the exact data format (whether the memory will be interpreted as integers, floating point values, unsigned integers etc.) is not determined until the resource is bound to the pipeline with a resource view. As the texture format remains flexible until the texture is bound to the pipeline, the resource is referred to as weakly typed storage. Weakly typed storage has the advantage that it can be reused or reinterpreted in another format as long as the number of components and the bit count of each component are the same in both formats.
A single resource can be bound to multiple pipeline stages as long as each has a unique view, which fully qualifies the formats at each location. For example, a resource created with the format DXGI_FORMAT_R32G32B32A32_TYPELESS could be used as a DXGI_FORMAT_R32G32B32A32_FLOAT and a DXGI_FORMAT_R32G32B32A32_UINT at different locations in the pipeline simultaneously.
Resources can be stored in general purpose memory formats so that they can be shared by multiple pipeline stages. A pipeline stage interprets resource data using a view. A resource view is conceptually similar to casting the resource data so that it can be used in a particular context.
A view can be used with a typeless resource. That is, you can create a resource at compile time and declare the data type when the resource is bound to the pipeline. A view created for a typeless resource always has the same number of bits per component; the way the data is interpreted is dependent on the format specified. The format specified must be from the same family as the typeless format used when creating the resource. For example, a resource created with the R8G8B8A8_TYPELESS format cannot be viewed as a R32_FLOAT resource even though both formats may be the same size in memory.
A view also exposes other capabilities such as the ability to read back depth/stencil surfaces in a shader, generating a dynamic cubemap in a single pass, and rendering simultaneously to multiple slices of a volume.
|ID3D11DepthStencilView||Access a texture resource during depth-stencil testing.|
|ID3D11RenderTargetView||Access a texture resource that is used as a render-target.|
|ID3D11ShaderResourceView||Access a shader resource such as a constant buffer, a texture buffer, a texture or a sampler.|
|ID3D11UnorderedAccessView||Access an unordered resource using a pixel shader or a compute shader.|
Raw Views of Buffers
You can think of a raw buffer, which can also be called a byte address buffer, as a bag of bits to which you want raw access, that is, a buffer that you can conveniently access through chunks of one to four 32-bit typeless address values. You indicate that you want raw access to a buffer (or, a raw view of a buffer) when you call one of the following methods to create a view to the buffer:
- To create a shader resource view (SRV) to the buffer, call ID3D11Device::CreateShaderResourceView with the flag D3D11_BUFFEREX_SRV_FLAG_RAW. You specify this flag in the Flags member of the D3D11_BUFFEREX_SRV structure. You set D3D11_BUFFEREX_SRV in the BufferEx member of the D3D11_SHADER_RESOURCE_VIEW_DESC structure to which the pDesc parameter of ID3D11Device::CreateShaderResourceView points. You also set the D3D11_SRV_DIMENSION_BUFFEREX value in the ViewDimension member of D3D11_SHADER_RESOURCE_VIEW_DESC to indicate that the SRV is a raw view.
- To create an unordered access view (UAV) to the buffer, call ID3D11Device::CreateUnorderedAccessView with the flag D3D11_BUFFER_UAV_FLAG_RAW. You specify this flag in the Flags member of the D3D11_BUFFER_UAV structure. You set D3D11_BUFFER_UAV in the Buffer member of the D3D11_UNORDERED_ACCESS_VIEW_DESC structure to which the pDesc parameter of ID3D11Device::CreateUnorderedAccessView points. You also set the D3D11_UAV_DIMENSION_BUFFER value in the ViewDimension member of D3D11_UNORDERED_ACCESS_VIEW_DESC to indicate that the UAV is a raw view.
To create a raw view to a buffer, you must first call ID3D11Device::CreateBuffer with the D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS flag to create the underlying buffer resource. You specify this flag in the MiscFlags member of the D3D11_BUFFER_DESC structure to which the pDesc parameter of ID3D11Device::CreateBuffer points. You can't combine the D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS flag with D3D11_RESOURCE_MISC_BUFFER_STRUCTURED. Also, if you specify D3D11_BIND_CONSTANT_BUFFER in BindFlags of D3D11_BUFFER_DESC, you can't also specify D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS in MiscFlags. This is not a limitation of just raw views because constant buffers already have a constraint that they can't be combined with any other view.
Other than the preceding invalid cases, when you create a buffer with D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS, you aren't limited in functionality versus not setting D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS. That is, you can use such a buffer for non-raw access in any number of ways that are possible with Direct3D. If you specify the D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS flag, you only increase the available functionality.