1#include "TexturesD3D12.h"
3#include "Foundation/Logging/Logger.h"
7#include "FormatsD3D12.h"
16 textures.removeResource(textureHandle);
22 sampler.samplerDesc.AddressU = Direct3D12::AddressModes[state.
addressModeS];
23 sampler.samplerDesc.AddressV = Direct3D12::AddressModes[state.
addressModeT];
24 sampler.samplerDesc.AddressW = Direct3D12::AddressModes[state.
addressModeW];
25 sampler.samplerDesc.Filter = Direct3D12::FilterModes[state.
filter];
27 sampler.samplerDesc.ComparisonFunc = Direct3D12::ComparisonFunctions[state.
comparisonFunction];
28 sampler.samplerDesc.MinLOD = 0;
29 sampler.samplerDesc.MaxLOD = 16;
30 sampler.samplerDesc.BorderColor[0] = state.
borderColor[0];
31 sampler.samplerDesc.BorderColor[1] = state.
borderColor[1];
32 sampler.samplerDesc.BorderColor[2] = state.
borderColor[2];
33 sampler.samplerDesc.BorderColor[3] = state.
borderColor[3];
35 return samplerStates.addResource(sampler);
40 samplerStates.removeResource(handle);
50 samplerStates.clear();
59 view.texture = viewDescription.
texture;
61 createShaderResourceView(view.srvDesc, textures[view.texture], viewDescription, textures[view.texture].desc.flags);
63 return textureViews.addResource(view);
68 textureViews.removeResource(handle);
73 auto & texture = textures[textureHandle];
75 return &*texture.resource;
82 texture.dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
83 texture.width = desc.width;
84 texture.height = desc.height;
85 texture.format = desc.format;
86 texture.numSamples = desc.samples;
88 D3D12_RESOURCE_FLAGS resourceFlags = D3D12_RESOURCE_FLAG_NONE;
90 resourceFlags |= (desc.flags &
TextureFlags::DepthBuffer) != 0 ? D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL : D3D12_RESOURCE_FLAG_NONE;
91 resourceFlags |= (desc.flags &
TextureFlags::RenderTarget) != 0 ? D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET : D3D12_RESOURCE_FLAG_NONE;
93 D3D12_RESOURCE_DESC textureDesc;
94 textureDesc.Dimension = texture.dimension;
95 textureDesc.DepthOrArraySize =
static_cast<UINT16
>(desc.layers * desc.faces);
96 textureDesc.Alignment = 0;
97 textureDesc.Width = desc.width;
98 textureDesc.Height = desc.height;
100 textureDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
101 textureDesc.Flags = resourceFlags;
102 textureDesc.MipLevels =
static_cast<UINT16
>(desc.levels);
103 textureDesc.SampleDesc.Count = desc.samples;
104 textureDesc.SampleDesc.Quality = 0;
106 D3D12_CLEAR_VALUE clearValue;
110 clearValue.Format = textureDesc.Format == DXGI_FORMAT_R32_TYPELESS ? DXGI_FORMAT_D32_FLOAT : textureDesc.Format;
111 clearValue.DepthStencil.Depth = 1.0f;
112 clearValue.DepthStencil.Stencil = 0;
114 hr = device->CreateCommittedResource(
115 &defaultHeapProperties,
116 D3D12_HEAP_FLAG_NONE,
118 D3D12_RESOURCE_STATE_COMMON,
120 IID_PPV_ARGS(texture.resource.internalPointer()));
126 createShaderResourceView(texture.srvDesc, texture, viewDesc, desc.flags);
129 clearValue.Format = textureDesc.Format;
130 clearValue.Color[0] = 1;
131 clearValue.Color[1] = 1;
132 clearValue.Color[2] = 1;
133 clearValue.Color[3] = 1;
135 hr = device->CreateCommittedResource(
136 &defaultHeapProperties,
137 D3D12_HEAP_FLAG_NONE,
139 D3D12_RESOURCE_STATE_COMMON,
141 IID_PPV_ARGS(texture.resource.internalPointer()));
143 texture.numSubResources = textureDesc.DepthOrArraySize * textureDesc.MipLevels;
146 const int maxSubresources = 16;
147 UINT64 uploadBufferSize = 0;
148 D3D12_PLACED_SUBRESOURCE_FOOTPRINT layouts[maxSubresources];
149 UINT numRows[maxSubresources];
150 UINT64 rowSizesInBytes[maxSubresources];
152 auto resourceDesc = texture.resource->GetDesc();
153 device->GetCopyableFootprints(&resourceDesc, 0, texture.numSubResources, 0, layouts, numRows, rowSizesInBytes, &uploadBufferSize);
155 CD3DX12_RESOURCE_DESC uploadBufferDesc = CD3DX12_RESOURCE_DESC::Buffer(uploadBufferSize);
157 device->CreateCommittedResource(
158 &uploadHeapProperties,
159 D3D12_HEAP_FLAG_NONE,
161 D3D12_RESOURCE_STATE_GENERIC_READ,
163 IID_PPV_ARGS(texture.uploadResource.internalPointer()));
165 UINT8 * resourceData;
166 texture.uploadResource->Map(0,
nullptr,
reinterpret_cast<void**
>(&resourceData));
168 size_t subResourceIndex = 0;
169 for (
size_t i = 0; i < desc.layers; ++i) {
170 for (
size_t j = 0; j < desc.faces; ++j) {
171 for (
size_t k = 0; k < desc.levels; ++k) {
172 D3D12_SUBRESOURCE_DATA srcData;
174 srcData.pData = data->getData(i, j, k);
175 srcData.RowPitch =
static_cast<uint32_t
>(data->getPitch(k));
176 srcData.SlicePitch = data->getLayerSize(0, desc.faces - 1, 0, desc.levels - 1);
178 auto & layout = layouts[subResourceIndex];
179 auto & rows = numRows[subResourceIndex];
181 D3D12_MEMCPY_DEST destData = { resourceData + layout.Offset, layout.Footprint.RowPitch, layout.Footprint.RowPitch * rows };
182 MemcpySubresource(&destData, &srcData, rowSizesInBytes[subResourceIndex], rows, layout.Footprint.Depth);
189 texture.uploadResource->Unmap(0,
nullptr);
190 texture.needsUpload =
true;
196 createShaderResourceView(texture.srvDesc, texture, viewDesc, desc.flags);
200 LOG_ERROR(logger,
"Error creating committed resource for texture.");
204 return textures.addResource(texture);
211 if (cubeMap && texture.desc.faces != 6) {
212 LOG_ERROR(logger,
"Cannot create cube map with %d faces.", texture.desc.faces);
217 srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
220 if (srvDesc.Format == DXGI_FORMAT_R32_TYPELESS) {
221 srvDesc.Format = DXGI_FORMAT_R32_FLOAT;
222 }
else if (srvDesc.Format == DXGI_FORMAT_R16_TYPELESS) {
223 srvDesc.Format = DXGI_FORMAT_R16_FLOAT;
224 }
else if (srvDesc.Format == DXGI_FORMAT_R8G8B8A8_TYPELESS) {
225 srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
228 const uint32_t mostDetailedMip = std::min(viewDesc.
levelIndex, std::max(1u, texture.desc.levels) - 1u);
230 if (texture.desc.layers == 1) {
232 srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE;
233 srvDesc.TextureCube.MipLevels = texture.desc.levels;
234 srvDesc.TextureCube.MostDetailedMip = mostDetailedMip;
236 srvDesc.ViewDimension = texture.desc.samples > 1 ? D3D12_SRV_DIMENSION_TEXTURE2DMS : D3D12_SRV_DIMENSION_TEXTURE2D;
237 srvDesc.Texture2D.MipLevels = texture.desc.levels;
238 srvDesc.Texture2D.MostDetailedMip = mostDetailedMip;
242 srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBEARRAY;
243 srvDesc.TextureCubeArray.MipLevels = texture.desc.levels;
244 srvDesc.TextureCubeArray.NumCubes = texture.desc.layers;
245 srvDesc.TextureCubeArray.MostDetailedMip = mostDetailedMip;
247 srvDesc.ViewDimension = texture.desc.samples > 1 ? D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY : D3D12_SRV_DIMENSION_TEXTURE2DARRAY;
248 srvDesc.Texture2DArray.MipLevels = texture.desc.levels;
249 srvDesc.Texture2DArray.ArraySize =
static_cast<uint32_t
>(texture.desc.layers);
250 srvDesc.Texture2DArray.MostDetailedMip = mostDetailedMip;
Log implementation class.
const DXGI_FORMAT Formats[]
Must match up to Format definition.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
static const Handle_t InvalidHandle
Represents an invalid handle.
Encapsulates state for texture sampling in a state object.
ComparisonFunction comparisonFunction
Specifies the comparison function to use when applying a comparison sampler.
unsigned int maxAnisotropy
Specifies the maximum number of anisotropic samples to use when sampling a texture.
AddressMode addressModeW
Specifies the addressing mode along the W axis in texture coordinate space.
AddressMode addressModeS
Specifies the addressing mode along the S axis in texture coordinate space.
FilterMode filter
Specifies the filter to use for texture sampling.
AddressMode addressModeT
Specifies the addressing mode along the T axis in texture coordinate space.
ETextureFlags
Texture flags enumeration.
@ DepthBuffer
The texture can be used as a depth target and have depth buffer values written into.
@ RenderTarget
The texture can be used as a render target and drawn into.
@ Texture
Texture usage, see Default.
@ CubeMap
The texture can be used as a cube map.
Describes how to fetch data from a texture in shaders.
uint32_t numLayers
Number of array layers available.
uint32_t numLevels
Number of mipmap levels available.
uint32_t levelIndex
First mipmap level to fetch data from.
TextureHandle texture
Texture.
void * getNativeHandle(TextureHandle textureHandle) override
Get the device-specific handle (D3D texture pointer, OpenGL texture ID etc) associated with the given...
void releaseSamplerState(SamplerStateHandle handle) override
Release the sampler state with the given handle.
TextureViewHandle createTextureView(TextureViewDescription &viewDescription) override
Create a texture view used to bind a limited view of the texture data to the rendering pipeline.
SamplerStateHandle loadSamplerState(const SamplerState &state) override
Load a sampler state object.
void releaseResources() override
Release all allocated texture resources.
void releaseTexture(TextureHandle textureHandle) override
Release the texture with the given textureHandle.
void releaseTextureView(const TextureViewHandle &handle) override
Release the given texture view.
TextureHandle loadTexture(const TextureDescription &desc, const TextureData *data) override
Load a texture from the given description.
void generateMipmaps(TextureHandle texureHandle) override
Use the graphics device to generate mipmaps for the texture with the given texture handle.