1#include "RenderTargetsD3D12.h"
3#include "TexturesD3D12.h"
4#include "FormatsD3D12.h"
5#include "GraphicsDeviceD3D12.h"
9 D3D12_BLEND Blends[] = {
12 D3D12_BLEND_SRC_COLOR,
13 D3D12_BLEND_INV_SRC_COLOR,
14 D3D12_BLEND_SRC_ALPHA,
15 D3D12_BLEND_INV_SRC_ALPHA,
16 D3D12_BLEND_DEST_ALPHA,
17 D3D12_BLEND_INV_DEST_ALPHA,
18 D3D12_BLEND_DEST_COLOR,
19 D3D12_BLEND_INV_DEST_COLOR,
20 D3D12_BLEND_SRC_ALPHA_SAT,
21 D3D12_BLEND_BLEND_FACTOR,
22 D3D12_BLEND_INV_BLEND_FACTOR,
24 static_assert(
sizeof(Blends) ==
sizeof(Blends[0]) * size_t(Cogs::BlendState::Blend::Count));
26 D3D12_BLEND_OP BlendOperations[] = {
28 D3D12_BLEND_OP_SUBTRACT,
29 D3D12_BLEND_OP_REV_SUBTRACT,
33 static_assert(
sizeof(BlendOperations) ==
sizeof(BlendOperations[0]) * size_t(Cogs::BlendState::BlendOperation::Count));
36 D3D12_BLEND BlendOptions[] = {
39 D3D12_BLEND_SRC_COLOR,
40 D3D12_BLEND_INV_SRC_COLOR,
41 D3D12_BLEND_SRC_ALPHA,
42 D3D12_BLEND_INV_SRC_ALPHA,
43 D3D12_BLEND_DEST_ALPHA,
44 D3D12_BLEND_INV_DEST_ALPHA,
49HRESULT Cogs::RenderTargetsD3D12::initialize(
struct GraphicsDeviceD3D12 * graphicsDevice)
51 this->graphicsDevice = graphicsDevice;
52 device = graphicsDevice->device;
53 textures = &graphicsDevice->textures;
55 rtvPool.initialize(device, 256, D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
56 dsvPool.initialize(device, 256, D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
63 auto textureDesc = texture->GetDesc();
65 RenderTargetD3D12 renderTarget{};
66 renderTarget.descriptor[0] = rtvPool.allocate();
67 renderTarget.descriptorHandle[0] = renderTarget.descriptor[0]->
handle;
68 renderTarget.numViews = 1;
69 renderTarget.numSamples = textureDesc.SampleDesc.Count;
71 renderTarget.viewDesc[0].Format = textureDesc.Format;
72 renderTarget.viewDesc[0].ViewDimension = textureDesc.SampleDesc.Count > 1 ? D3D12_RTV_DIMENSION_TEXTURE2DMS : D3D12_RTV_DIMENSION_TEXTURE2D;
74 device->CreateRenderTargetView(texture, renderTarget.viewDesc, renderTarget.descriptorHandle[0]);
76 renderTarget.resource = texture;
78 return renderTargets.addResource(renderTarget);
84 renderTarget.numViews =
static_cast<uint8_t
>(numViews);
86 for (
size_t i = 0; i < numViews; ++i) {
87 renderTarget.descriptor[i] = rtvPool.allocate();
88 renderTarget.descriptorHandle[i] = renderTarget.descriptor[i]->handle;
90 const auto & texture = textures->textures[renderTargetViews[i].
texture];
92 renderTarget.textures[i] = renderTargetViews[i].
texture;
95 renderTarget.viewDesc[i].ViewDimension = texture.numSamples > 1 ? D3D12_RTV_DIMENSION_TEXTURE2DMS : D3D12_RTV_DIMENSION_TEXTURE2D;
97 if (texture.desc.layers == 1) {
98 renderTarget.viewDesc[i].ViewDimension = texture.numSamples > 1 ? D3D12_RTV_DIMENSION_TEXTURE2DMS : D3D12_RTV_DIMENSION_TEXTURE2D;
99 renderTarget.viewDesc[i].Texture2D.MipSlice = 0;
101 renderTarget.viewDesc[i].ViewDimension = texture.numSamples > 1 ? D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY : D3D12_RTV_DIMENSION_TEXTURE2DARRAY;
102 renderTarget.viewDesc[i].Texture2DArray.ArraySize = 1;
103 renderTarget.viewDesc[i].Texture2DArray.FirstArraySlice = renderTargetViews[i].
layerIndex;
104 renderTarget.viewDesc[i].Texture2DArray.MipSlice = renderTargetViews[i].
levelIndex;
107 device->CreateRenderTargetView(texture.resource, &renderTarget.viewDesc[i], renderTarget.descriptorHandle[i]);
110 return renderTargets.addResource(renderTarget);
115 auto & renderTarget = renderTargets[handle];
117 for (
size_t i = 0; i < renderTarget.numViews; ++i) {
118 graphicsDevice->context.currentFrameResources->orphanedRTVs.push_back(
OrphanRTVDescriptor{ renderTarget.descriptor[i] });
121 renderTargets.removeResource(handle);
126 auto & renderTarget = renderTargets[handle];
127 auto & renderTexture = textures->textures[renderTarget.textures[0]];
129 auto depthTextureHandle = textures->loadTexture(
nullptr, renderTexture.width, renderTexture.height, TextureFormat::R32_TYPELESS, renderTexture.numSamples,
TextureFlags::DepthBuffer);
131 return createDepthStencilTarget(handle, depthTextureHandle);
137 desc.texture = textureHandle;
140 return createDepthStencilTarget(handle, desc);
145 auto & texture = textures->textures[depthStencilView.
texture];
147 auto textureDesc = texture.resource->GetDesc();
150 dsTarget.descriptor = dsvPool.allocate();
151 dsTarget.descriptorHandle = dsTarget.descriptor->handle;
153 dsTarget.viewDesc.Format = textureDesc.Format == DXGI_FORMAT_R32_TYPELESS ? DXGI_FORMAT_D32_FLOAT : textureDesc.Format;
154 if (texture.desc.layers == 1) {
155 dsTarget.viewDesc.ViewDimension = textureDesc.SampleDesc.Count > 1 ? D3D12_DSV_DIMENSION_TEXTURE2DMS : D3D12_DSV_DIMENSION_TEXTURE2D;
156 dsTarget.viewDesc.Texture2D.MipSlice = 0;
158 dsTarget.viewDesc.ViewDimension = textureDesc.SampleDesc.Count > 1 ? D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY : D3D12_DSV_DIMENSION_TEXTURE2DARRAY;
159 dsTarget.viewDesc.Texture2DArray.ArraySize = 1;
160 dsTarget.viewDesc.Texture2DArray.FirstArraySlice = depthStencilView.
layerIndex;
161 dsTarget.viewDesc.Texture2DArray.MipSlice = depthStencilView.
levelIndex;
164 dsTarget.texture = depthStencilView.
texture;
166 device->CreateDepthStencilView(texture.resource, &dsTarget.viewDesc, dsTarget.descriptorHandle);
168 return depthStencilTargets.addResource(dsTarget);
173 dsvPool.deallocate(depthStencilTargets[handle].descriptor);
175 depthStencilTargets.removeResource(handle);
182 D3D12_COMPARISON_FUNC DepthFunctions[] = {
183 D3D12_COMPARISON_FUNC_NEVER,
184 D3D12_COMPARISON_FUNC_LESS,
185 D3D12_COMPARISON_FUNC_LESS_EQUAL,
186 D3D12_COMPARISON_FUNC_EQUAL,
187 D3D12_COMPARISON_FUNC_GREATER_EQUAL,
188 D3D12_COMPARISON_FUNC_GREATER,
189 D3D12_COMPARISON_FUNC_NOT_EQUAL,
190 D3D12_COMPARISON_FUNC_ALWAYS
200 depthStencilStateD3d12.depthStencilDesc.DepthEnable = depthStencilState.
depthEnabled;
201 depthStencilStateD3d12.depthStencilDesc.DepthWriteMask = depthStencilState.
writeEnabled ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO;
202 depthStencilStateD3d12.depthStencilDesc.DepthFunc = Direct3D12::DepthFunctions[depthStencilState.
depthFunction];
205 depthStencilStateD3d12.depthStencilDesc.StencilEnable =
false;
206 depthStencilStateD3d12.depthStencilDesc.StencilReadMask = 0xFF;
207 depthStencilStateD3d12.depthStencilDesc.StencilWriteMask = 0xFF;
210 depthStencilStateD3d12.depthStencilDesc.FrontFace.StencilFailOp = D3D12_STENCIL_OP_KEEP;
211 depthStencilStateD3d12.depthStencilDesc.FrontFace.StencilDepthFailOp = D3D12_STENCIL_OP_INCR;
212 depthStencilStateD3d12.depthStencilDesc.FrontFace.StencilPassOp = D3D12_STENCIL_OP_KEEP;
213 depthStencilStateD3d12.depthStencilDesc.FrontFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS;
216 depthStencilStateD3d12.depthStencilDesc.BackFace.StencilFailOp = D3D12_STENCIL_OP_KEEP;
217 depthStencilStateD3d12.depthStencilDesc.BackFace.StencilDepthFailOp = D3D12_STENCIL_OP_DECR;
218 depthStencilStateD3d12.depthStencilDesc.BackFace.StencilPassOp = D3D12_STENCIL_OP_KEEP;
219 depthStencilStateD3d12.depthStencilDesc.BackFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS;
221 return depthStencilStates.addResource(depthStencilStateD3d12);
226 depthStencilStates.removeResource(handle);
233 const D3D12_CULL_MODE CullModes[] = {
234 D3D12_CULL_MODE_FRONT,
235 D3D12_CULL_MODE_BACK,
244 rasterizerStateD3d12.rasterizerDesc = {};
246 rasterizerStateD3d12.rasterizerDesc.FillMode = rasterizerState.
wireFrame ? D3D12_FILL_MODE_WIREFRAME : D3D12_FILL_MODE_SOLID;
247 rasterizerStateD3d12.rasterizerDesc.CullMode = Direct3D11::CullModes[rasterizerState.
cullMode];
249 rasterizerStateD3d12.rasterizerDesc.AntialiasedLineEnable =
true;
251 rasterizerStateD3d12.rasterizerDesc.MultisampleEnable = rasterizerState.
multiSample;
252 rasterizerStateD3d12.rasterizerDesc.DepthClipEnable =
true;
254 rasterizerStateD3d12.rasterizerDesc.DepthBias =
static_cast<INT
>(rasterizerState.
depthBias);
255 rasterizerStateD3d12.rasterizerDesc.SlopeScaledDepthBias = rasterizerState.
slopeScaledDepthBias;
256 rasterizerStateD3d12.rasterizerDesc.DepthBiasClamp = rasterizerState.
depthBiasClamp;
258 return rasterizerStates.addResource(rasterizerStateD3d12);
263 rasterizerStates.removeResource(handle);
269 return loadBlendState(&blendState, &blendState, 1, BlendFlags::None);
274 return loadBlendState(&blendStateColor, &blendStateAlpha, 1, BlendFlags::None);
279 return loadBlendState(&blendStateColor, &blendStateAlpha, 1, flags);
286 BlendStateD3D12 blendStateD3d12 = {};
287 blendStateD3d12.blendDesc = {};
289 blendStateD3d12.blendDesc.AlphaToCoverageEnable = (flags & BlendFlags::AlphaToCoverage) != 0 ? TRUE : FALSE;
290 blendStateD3d12.blendDesc.IndependentBlendEnable = (flags & BlendFlags::IndependentBlend) != 0 ? TRUE : FALSE;
294 const uint32_t numStates = blendStateD3d12.blendDesc.IndependentBlendEnable ? 8 : 1;
295 for (uint32_t i = 0; i < numStates; ++i) {
296 const Cogs::BlendState& blendStateColor = i < numBlendStates ? blendStatesColor[i] : defaultBlendState;
297 const Cogs::BlendState& blendStateAlpha = blendStatesAlpha ? (i < numBlendStates ? blendStatesAlpha[i] : defaultBlendState) : defaultBlendState;
299 blendStateD3d12.blendDesc.RenderTarget[i].BlendEnable = blendStateColor.
enabled;
300 blendStateD3d12.blendDesc.RenderTarget[i].SrcBlend = Blends[size_t(blendStateColor.
sourceBlend)];
301 blendStateD3d12.blendDesc.RenderTarget[i].DestBlend = Blends[size_t(blendStateColor.
destinationBlend)];
302 blendStateD3d12.blendDesc.RenderTarget[i].BlendOp = BlendOperations[size_t(blendStateColor.
operation)];
303 blendStateD3d12.blendDesc.RenderTarget[i].SrcBlendAlpha = blendStateAlpha.
enabled ? Blends[size_t(blendStateAlpha.
sourceBlend)] : D3D12_BLEND_ZERO;
304 blendStateD3d12.blendDesc.RenderTarget[i].DestBlendAlpha = blendStateAlpha.
enabled ? Blends[size_t(blendStateAlpha.
destinationBlend)] : D3D12_BLEND_ONE;
305 blendStateD3d12.blendDesc.RenderTarget[i].BlendOpAlpha = blendStateAlpha.
enabled ? BlendOperations[size_t(blendStateAlpha.
operation)] : D3D12_BLEND_OP_ADD;
306 blendStateD3d12.blendDesc.RenderTarget[i].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
308 return blendStates.addResource(blendStateD3d12);
313 blendStates.removeResource(handle);
const DXGI_FORMAT Formats[]
Must match up to Format definition.
Contains all Cogs related functionality.
@ Direct3D12
Graphics device using the Direct3D 12 API.
@ Direct3D11
Graphics device using the Direct3D 11 API.
Encapsulates blend state for the graphics pipeline in a state object.
uint8_t enabled
If blending is enabled.
Blend destinationBlend
Blend option for the blend destination data.
static BlendState DefaultState()
Creates a blend state object initialized with the default settings.
BlendOperation operation
How the two blend values are combined.
Blend sourceBlend
Blend option for the blend source data.
Encapsulates state for depth buffer usage and stencil buffer usage in a state object.
bool depthEnabled
If depth testing is enabled/disabled. Default is true.
DepthFunction depthFunction
The depth function to use for depth testing.
bool writeEnabled
If writes to the depth buffer are enabled/disabled. Default is true.
Describes a single depth stencil view and which resources to use from the underlying texture.
TextureHandle texture
Texture handle.
uint8_t levelIndex
Index of the mipmap level to render to.
uint16_t layerIndex
Index of the first layer (if array) to write depth to.
handle_type handle
Internal resource handle.
static const Handle_t InvalidHandle
Represents an invalid handle.
Encapsulates state for primitive rasterization in a state object.
bool multiSample
If multisample rasterization should be enabled. Default is true.
bool frontCounterClockwise
If counter clockwise polygon winding is used to specify front facing polygons. Default is false.
CullMode cullMode
Which face culling mode to apply to primitives before rasterization.
float depthBias
Depth bias to apply to depth values after initial rasterization before depth values are written.
float depthBiasClamp
Value to clamp the depth bias to so that it may not go outside desired values even when applying slop...
float slopeScaledDepthBias
Slope scaled depth bias value controlling the depth bias value based on the area of the polygon on sc...
bool wireFrame
If only wire frames should be rasterized. Default is false.
Describes a single render target view and which resources to use from the underlying texture.
uint16_t layerIndex
Index of the first layer (if array) to render to.
TextureHandle texture
Texture handle.
uint8_t levelIndex
Index of the mipmap level to render to.
void releaseRenderTarget(RenderTargetHandle handle)
Release the render target with the given renderTargetHandle.
RasterizerStateHandle loadRasterizerState(const RasterizerState &rasterizerState)
Load a rasterizer state object.
BlendStateHandle loadBlendState(const BlendState &blendState)
Load a blend state object.
void releaseBlendState(BlendStateHandle handle)
Release the blend state with the given handle.
void releaseDepthStencilTarget(DepthStencilHandle handle)
Release the depth target with the given depthStencilHandle.
DepthStencilStateHandle loadDepthStencilState(const DepthStencilState &depthStencilState)
Load a depth stencil state object.
void releaseDepthStencilState(DepthStencilStateHandle handle)
Release the depth stencil state with the given handle.
void releaseRasterizerState(RasterizerStateHandle handle)
Release the rasterizer state with the given handle.
void releaseResources()
Release all allocated render target resources.
DepthStencilHandle createDepthStencilTarget(const RenderTargetHandle handle)
Creates a depth/stencil target to back the render target with the given handle.
@ DepthBuffer
The texture can be used as a depth target and have depth buffer values written into.