1#include "ContextD3D12.h"
3#include "GraphicsDeviceD3D12.h"
5#include "Foundation/Logging/LogManager.h"
7#include "Foundation/HashFunctions.h"
20 RenderStats renderStats;
27 const D3D_PRIMITIVE_TOPOLOGY Topologies[] = {
28 D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
29 D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
30 D3D_PRIMITIVE_TOPOLOGY_LINELIST,
31 D3D_PRIMITIVE_TOPOLOGY_LINESTRIP,
32 D3D_PRIMITIVE_TOPOLOGY_POINTLIST,
33 D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ,
34 D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ,
35 D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ,
36 D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ,
37 D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST,
38 D3D11_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST,
39 D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST,
40 D3D11_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST,
43 const D3D12_PRIMITIVE_TOPOLOGY_TYPE TopologyTypes[] = {
44 D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE,
45 D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE,
46 D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE,
47 D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE,
48 D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT,
49 D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE,
50 D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE,
51 D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE,
52 D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE,
53 D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH,
54 D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH,
55 D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH,
56 D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH,
61Cogs::ContextD3D12::ContextD3D12() :
62 defaultBlendState(BlendStateHandle::InvalidHandle),
63 defaultDepthStencilState(DepthStencilStateHandle::InvalidHandle),
64 defaultRasterizerState(RasterizerStateHandle::InvalidHandle),
65 defaultRenderTarget(RenderTargetHandle::InvalidHandle),
66 defaultDepthStencil(DepthStencilHandle::InvalidHandle),
67 currentFrameResources(frameResources.data())
72Cogs::ContextD3D12::~ContextD3D12()
76 CloseHandle(eventHandle);
79void Cogs::ContextD3D12::destroy()
81 auto fenceValue = currentFenceValue;
82 auto completedFenceValue = fence->GetCompletedValue();
84 graphicsDevice->commandQueue->Signal(fence, fenceValue);
86 if (fenceValue > completedFenceValue) {
87 fence->SetEventOnCompletion(fenceValue, eventHandle);
88 WaitForSingleObject(eventHandle, INFINITE);
92void Cogs::ContextD3D12::initialize(GraphicsDeviceD3D12 * graphicsDevice)
94 this->device = graphicsDevice->device;
95 this->graphicsDevice = graphicsDevice;
99 for (
auto & frameResource : frameResources) {
100 hr = device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(frameResource.commandAllocator.internalPointer()));
103 LOG_ERROR(logger,
"Could not create command allocator.");
107 hr = device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, frameResource.commandAllocator,
nullptr, IID_PPV_ARGS(frameResource.commandList.internalPointer()));
110 LOG_ERROR(logger,
"Could not create command list.");
114 frameResource.commandList->Close();
117 eventHandle = CreateEventEx(NULL, FALSE, FALSE, EVENT_ALL_ACCESS);
118 assert(eventHandle != NULL);
122 D3D12_DESCRIPTOR_HEAP_DESC descHeapCbv = {};
123 descHeapCbv.NumDescriptors = 96000;
124 descHeapCbv.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
125 descHeapCbv.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
127 hr = device->CreateDescriptorHeap(&descHeapCbv, IID_PPV_ARGS(descriptorHeap.internalPointer()));
129 descHeapCbv.NumDescriptors = 256;
130 descHeapCbv.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
131 descHeapCbv.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
133 hr = device->CreateDescriptorHeap(&descHeapCbv, IID_PPV_ARGS(descriptorHeapCPU.internalPointer()));
135 D3D12_DESCRIPTOR_HEAP_DESC descHeapSampler = {};
136 descHeapSampler.NumDescriptors = 2048;
137 descHeapSampler.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER;
138 descHeapSampler.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
140 hr = device->CreateDescriptorHeap(&descHeapSampler, IID_PPV_ARGS(samplerDescriptorHeap.internalPointer()));
142 hr = device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(fence.internalPointer()));
144 constantBuffersUpdated =
false;
146 buffers = &graphicsDevice->buffers;
147 textures = &graphicsDevice->textures;
148 effects = &graphicsDevice->effects;
149 renderTargets = &graphicsDevice->renderTargets;
154 renderTargets->rasterizerStates.pin(defaultRasterizerState);
157 renderTargets->blendStates.pin(defaultBlendState);
160 renderTargets->depthStencilStates.pin(defaultDepthStencilState);
163 textures->samplerStates.pin(defaultSamplerState);
168 if (HandleIsValid(fenceHandle)) {
169 FenceD3D12& fence = graphicsDevice->syncObjects.fences[fenceHandle];
170 graphicsDevice->commandQueue->Signal(fence.fence, ++fence.value);
174void Cogs::ContextD3D12::beginFrame()
176 ID3D12DescriptorHeap * heaps[2] = {
178 samplerDescriptorHeap,
181 commandList->SetDescriptorHeaps(2, heaps);
183 constantBuffersUpdated =
false;
185 state.currentStateHash = 0;
188 ContextCommon::setCurrentEffect(
nullptr);
190 setBlendState(defaultBlendState,
nullptr);
191 setRasterizerState(defaultRasterizerState);
192 setDepthStencilState(defaultDepthStencilState);
194 setRenderTarget(defaultRenderTarget, defaultDepthStencil);
196 constantBuffersUpdated =
false;
202void Cogs::ContextD3D12::updateFrameResources()
204 if (frameResourceIndex == frameResources.size()) frameResourceIndex = 0;
206 if (frameResourceIndex == 0) {
207 descriptorSize = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
209 cbvCurrentCpuHandleCPU = descriptorHeapCPU->GetCPUDescriptorHandleForHeapStart();
211 cbvCurrentCpuHandle = descriptorHeap->GetCPUDescriptorHandleForHeapStart();
212 cbvCurrentGpuHandle = descriptorHeap->GetGPUDescriptorHandleForHeapStart();
214 srvCurrentCpuHandle.InitOffsetted(cbvCurrentCpuHandle, 32000, descriptorSize);
215 srvCurrentGpuHandle.InitOffsetted(cbvCurrentGpuHandle, 32000, descriptorSize);
217 uavCurrentCpuHandle.InitOffsetted(srvCurrentCpuHandle, 32000, descriptorSize);
218 uavCurrentGpuHandle.InitOffsetted(srvCurrentGpuHandle, 32000, descriptorSize);
220 samplerHandleIncrement = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
221 samplerCurrentCpuHandle = samplerDescriptorHeap->GetCPUDescriptorHandleForHeapStart();
222 samplerCurrentGpuHandle = samplerDescriptorHeap->GetGPUDescriptorHandleForHeapStart();
225 currentFrameResources = &frameResources[frameResourceIndex++];
227 currentFrameResources->closed =
false;
229 if (currentFrameResources->fenceValue > fence->GetCompletedValue()) {
230 fence->SetEventOnCompletion(currentFrameResources->fenceValue, eventHandle);
231 WaitForSingleObject(eventHandle, INFINITE);
234 for (
auto & orphan : currentFrameResources->orphanedBuffers) {
235 orphan.pool->deallocate(orphan.poolHandle);
238 for (
auto & orphan : currentFrameResources->orphanedRTVs) {
239 renderTargets->rtvPool.deallocate(orphan.poolHandle);
242 currentFrameResources->orphanedRTVs.clear();
243 currentFrameResources->orphanedResources.clear();
244 currentFrameResources->orphanedBuffers.clear();
246 commandAllocator = currentFrameResources->commandAllocator;
247 commandList = currentFrameResources->commandList;
249 commandAllocator->Reset();
252 commandList->Reset(commandAllocator,
nullptr);
255void Cogs::ContextD3D12::endFrame()
257 executeCommandList();
259 currentFrameResources->closed =
true;
264void Cogs::ContextD3D12::executeCommandList()
266 commandList->Close();
268 ID3D12CommandList * ppCommandLists[] = { commandList };
269 graphicsDevice->commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);
271 currentFrameResources->fenceValue = currentFenceValue;
273 graphicsDevice->commandQueue->Signal(fence, currentFenceValue);
278void Cogs::ContextD3D12::flush()
280 if (!currentFrameResources->closed) {
281 executeCommandList();
284 if (currentFrameResources->fenceValue > fence->GetCompletedValue()) {
285 fence->SetEventOnCompletion(currentFrameResources->fenceValue, eventHandle);
286 WaitForSingleObject(eventHandle, INFINITE);
289 if (!currentFrameResources->closed) {
290 commandList->Reset(commandAllocator, PSOs[state.currentStateHash]);
292 ID3D12DescriptorHeap * heaps[2] = {
294 samplerDescriptorHeap,
297 commandList->SetDescriptorHeaps(2, heaps);
303 return graphicsDevice->getEffects();
308 uint32_t strides[kMaxVertexInputSlots];
309 uint32_t offsets[kMaxVertexInputSlots];
311 for (
size_t i = 0; i < count; i++) {
312 auto & buffer = buffers->buffers[
BufferHandle(handles[i].handle)];
314 assert(buffer.vertexFormat &&
"Vertex buffer must have been created with format information attached.");
316 strides[i] = getSize(*buffer.vertexFormat);
320 setVertexBuffers(handles, count, strides, offsets);
325 iaState.numVertexBuffers = count;
327 for (
size_t i = 0; i < count; i++) {
328 auto & buffer = buffers->buffers[
BufferHandle(handles[i].handle)];
332 iaState.currentVertexBuffers[i] = &buffer;
333 iaState.formats[i] = buffer.vertexFormat;
334 iaState.strides[i] = strides[i];
335 iaState.offsets[i] = offsets ? offsets[i] : 0;
343 iaState.currentIndexBuffer = &buffers->buffers[indexBufferHandle];
345 commandList->IASetIndexBuffer(&iaState.currentIndexBuffer->indexBufferView);
350 void decode(int64_t handle, uint32_t & vsSlot, uint32_t & gsSlot, uint32_t & psSlot)
352 const uint64_t value =
static_cast<uint64_t
>(handle);
354 vsSlot = (value >> 32) & 0xFFFF;
355 gsSlot = (value >> 48);
356 psSlot = value & 0xFFFF;
362 assert(offset == 0 && size == ~0u &&
"Offset into constant buffers is not implemented");
363 uint32_t slots[ShaderType::NumShaderTypes];
364 decode(bufferBinding.
handle, slots);
366 auto & buffer = buffers->buffers[bufferHandle];
368 for (
size_t i = 0; i < ShaderType::NumShaderTypes; ++i) {
369 if (slots[i] != NoBinding) {
370 shaderState.CBVs[i].setChanged(slots[i], &buffer,
false);
374 constantBuffersUpdated =
true;
377void Cogs::ContextD3D12::setupDrawBuffers()
379 D3D12_VERTEX_BUFFER_VIEW views[32];
381 for (
size_t i = 0; i < iaState.numVertexBuffers; ++i) {
382 views[i] = iaState.currentVertexBuffers[i]->vertexBufferView;
383 views[i].StrideInBytes = iaState.strides[i];
386 commandList->IASetVertexBuffers(0,
static_cast<UINT
>(iaState.numVertexBuffers), views);
391 checkState(topology);
393 setupConstantBuffers();
396 D3D12_CONSTANT_BUFFER_VIEW_DESC nullCbvDesc = {};
399 for (UINT j = 0; j < ShaderType::NumShaderTypes; ++j) {
400 const UINT slots = shaderState.effectSignature.slots[SlotType::CBV].values[j];
402 if (slots && shaderState.CBVs[j].hasChanged()) {
403 for (UINT i = 0; i < slots; ++i) {
404 const auto & bindings = shaderState.CBVs[j];
406 if (bindings.getChanged(i)) {
408 device->CreateConstantBufferView(&bindings[i]->cbvDesc, CD3DX12_CPU_DESCRIPTOR_HANDLE(cbvCurrentCpuHandleCPU, offset + i, descriptorSize));
410 device->CreateConstantBufferView(&nullCbvDesc, CD3DX12_CPU_DESCRIPTOR_HANDLE(cbvCurrentCpuHandleCPU, offset + i, descriptorSize));
415 device->CopyDescriptorsSimple(slots, cbvCurrentCpuHandle, CD3DX12_CPU_DESCRIPTOR_HANDLE(cbvCurrentCpuHandleCPU, offset, descriptorSize), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
417 commandList->SetGraphicsRootDescriptorTable(shaderState.effectSignature.slots[SlotType::CBV].rangeIndex[j], cbvCurrentGpuHandle);
421 shaderState.CBVs[j].setUnchanged();
423 cbvCurrentCpuHandle.Offset(slots, descriptorSize);
424 cbvCurrentGpuHandle.Offset(slots, descriptorSize);
430 D3D12_UNORDERED_ACCESS_VIEW_DESC nullUavDesc{};
431 nullUavDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
432 nullUavDesc.Format = DXGI_FORMAT_R32_FLOAT;
434 for (UINT j = 0; j < ShaderType::NumShaderTypes; ++j) {
435 const UINT slots = shaderState.effectSignature.slots[SlotType::UAV].values[j];
437 if (slots && shaderState.UAVs[j].hasChanged()) {
438 for (UINT i = 0; i < slots; ++i) {
439 const auto & bindings = shaderState.UAVs[j];
441 if (bindings.getChanged(i)) {
443 auto buffer = bindings[i];
444 device->CreateUnorderedAccessView(buffer->resource, buffer->counterResource, &buffer->uavDesc, CD3DX12_CPU_DESCRIPTOR_HANDLE(uavCurrentCpuHandle, i, descriptorSize));
446 device->CreateUnorderedAccessView(
nullptr,
nullptr, &nullUavDesc, CD3DX12_CPU_DESCRIPTOR_HANDLE(uavCurrentCpuHandle, i, descriptorSize));
451 commandList->SetGraphicsRootDescriptorTable(shaderState.effectSignature.slots[SlotType::UAV].rangeIndex[j], uavCurrentGpuHandle);
453 shaderState.UAVs[j].setUnchanged();
455 uavCurrentCpuHandle.Offset(slots, descriptorSize);
456 uavCurrentGpuHandle.Offset(slots, descriptorSize);
462 D3D12_SHADER_RESOURCE_VIEW_DESC nullShaderResourceViewDesc = {};
463 nullShaderResourceViewDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
464 nullShaderResourceViewDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
465 nullShaderResourceViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
466 nullShaderResourceViewDesc.Texture2D.MipLevels = 1;
467 nullShaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
468 nullShaderResourceViewDesc.Texture2D.ResourceMinLODClamp = 0.0f;
470 for (UINT j = 0; j < ShaderType::NumShaderTypes; ++j) {
471 const UINT slots = shaderState.effectSignature.slots[SlotType::SRV].values[j];
473 if (slots && shaderState.SRVs[j].hasChanged()) {
474 for (UINT i = 0; i < slots; ++i) {
475 const auto & bindings = shaderState.SRVs[j];
478 auto & resource = bindings[i];
479 device->CreateShaderResourceView(resource->resource, &resource->srvDesc, CD3DX12_CPU_DESCRIPTOR_HANDLE(srvCurrentCpuHandle, i, descriptorSize));
481 device->CreateShaderResourceView(
nullptr, &nullShaderResourceViewDesc, CD3DX12_CPU_DESCRIPTOR_HANDLE(srvCurrentCpuHandle, i, descriptorSize));
485 commandList->SetGraphicsRootDescriptorTable(shaderState.effectSignature.slots[SlotType::SRV].rangeIndex[j], srvCurrentGpuHandle);
487 shaderState.SRVs[j].setUnchanged();
489 srvCurrentCpuHandle.Offset(slots, descriptorSize);
490 srvCurrentGpuHandle.Offset(slots, descriptorSize);
496 D3D12_SAMPLER_DESC nullSamplerDesc = {};
497 nullSamplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
498 nullSamplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
499 nullSamplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
500 nullSamplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
501 nullSamplerDesc.Filter = D3D12_FILTER_ANISOTROPIC;
502 nullSamplerDesc.MaxAnisotropy = 0;
503 nullSamplerDesc.MaxLOD = 16;
505 for (UINT j = 0; j < ShaderType::NumShaderTypes; ++j) {
506 const UINT slots = shaderState.effectSignature.slots[SlotType::Sampler].values[j];
508 if (slots && shaderState.Samplers[j].hasChanged()) {
509 for (UINT i = 0; i < slots; ++i) {
510 const auto & bindings = shaderState.Samplers[j];
511 const auto sampler = bindings[i];
514 device->CreateSampler(sampler, CD3DX12_CPU_DESCRIPTOR_HANDLE(samplerCurrentCpuHandle, i, samplerHandleIncrement));
516 device->CreateSampler(&nullSamplerDesc, CD3DX12_CPU_DESCRIPTOR_HANDLE(samplerCurrentCpuHandle, i, samplerHandleIncrement));
520 commandList->SetGraphicsRootDescriptorTable(shaderState.effectSignature.slots[SlotType::Sampler].rangeIndex[j], samplerCurrentGpuHandle);
522 shaderState.Samplers[j].setUnchanged();
524 samplerCurrentCpuHandle.Offset(slots, samplerHandleIncrement);
525 samplerCurrentGpuHandle.Offset(slots, samplerHandleIncrement);
533 setupPipelineState(primitiveType);
535 commandList->IASetPrimitiveTopology(Direct3D12::Topologies[primitiveType]);
537 commandList->DrawInstanced(
static_cast<UINT
>(numVertexes), 1,
static_cast<UINT
>(startVertex), 0);
542 setupPipelineState(primitiveType);
544 commandList->IASetPrimitiveTopology(Direct3D12::Topologies[primitiveType]);
546 const size_t indexCount = numIndexes ? numIndexes : iaState.currentIndexBuffer->count;
548 commandList->DrawIndexedInstanced(
static_cast<UINT
>(indexCount), 1,
static_cast<UINT
>(startIndex),
static_cast<UINT
>(startVertex), 0);
553 state.currentRasterizerState = &renderTargets->rasterizerStates[handle];
559 state.currentBlendState = &renderTargets->blendStates[handle];
562 const float white[4] = { 1.f, 1.f, 1.f, 1.f };
563 commandList->OMSetBlendFactor(constant ? constant : white);
570 state.currentDepthStencilState = &renderTargets->depthStencilStates[HandleIsValid(handle) ? handle : defaultDepthStencilState];
583 if (state.currentRenderTarget && !state.currentRenderTarget->resource) {
584 auto & renderTarget = *state.currentRenderTarget;
586 for (
int i = 0; i < renderTarget.numViews; ++i) {
587 if (HandleIsValid(renderTarget.textures[i])) {
588 auto & renderTexture = textures->textures[renderTarget.textures[i]];
589 setResourceState(commandList, renderTexture, D3D12_RESOURCE_STATE_RENDER_TARGET);
594 if (state.currentDepthStencil && HandleIsValid(state.currentDepthStencil->texture)) {
595 auto & depthTexture = textures->textures[state.currentDepthStencil->texture];
596 setResourceState(commandList, depthTexture, D3D12_RESOURCE_STATE_DEPTH_WRITE);
599 if (state.currentRenderTarget) {
600 auto & renderTarget = *state.currentRenderTarget;
602 commandList->OMSetRenderTargets(renderTarget.numViews, renderTarget.descriptorHandle, renderTarget.numViews == 1, state.currentDepthStencil ? &state.currentDepthStencil->descriptorHandle :
nullptr);
604 commandList->OMSetRenderTargets(0,
nullptr,
false, state.currentDepthStencil ? &state.currentDepthStencil->descriptorHandle :
nullptr);
610 D3D12_VIEWPORT viewPort = {
613 static_cast<float>(width),
614 static_cast<float>(height),
619 D3D12_RECT mRectScissor = { 0, 0,
static_cast<LONG
>(width),
static_cast<LONG
>(height) };
621 commandList->RSSetViewports(1, &viewPort);
622 commandList->RSSetScissorRects(1, &mRectScissor);
627 D3D12_RECT mRectScissor = {
static_cast<LONG
>(x),
static_cast<LONG
>(y),
static_cast<LONG
>(width),
static_cast<LONG
>(height) };
628 commandList->RSSetScissorRects(1, &mRectScissor);
633 auto renderTarget = state.currentRenderTarget;
635 for (
size_t i = 0; i < renderTarget->numViews; ++i) {
636 commandList->ClearRenderTargetView(renderTarget->descriptorHandle[i], color, 0,
nullptr);
642 auto renderTarget = state.currentRenderTarget;
644 for (
size_t i = 0; i < count; ++i) {
645 commandList->ClearRenderTargetView(renderTarget->descriptorHandle[i], colors[i], 0,
nullptr);
651 auto depthTarget = state.currentDepthStencil;
654 commandList->ClearDepthStencilView(depthTarget->descriptorHandle, D3D12_CLEAR_FLAG_DEPTH, depth, 0, 0,
nullptr);
660 currentEffect = effectHandle;
662 state.currentEffect = &effects->effects[effectHandle];
665 ContextCommon::setCurrentEffect(state.currentEffect);
667 assert(state.currentEffect->rootSignature &&
"Effect signature not valid.");
669 shaderState.effectSignature = state.currentEffect->signature;
672 shaderState.rootSignature = state.currentEffect->rootSignature;
674 commandList->SetGraphicsRootSignature(state.currentEffect->rootSignature);
676 for (uint32_t i = 0; i < ShaderType::NumShaderTypes; ++i) {
677 for (uint32_t j = 0; j < shaderState.effectSignature.slots[SlotType::CBV].values[i]; ++j) {
678 shaderState.CBVs[i].setChanged();
681 for (uint32_t j = 0; j < shaderState.effectSignature.slots[SlotType::Sampler].values[i]; ++j) {
682 shaderState.Samplers[i].setChanged();
685 for (uint32_t j = 0; j < shaderState.effectSignature.slots[SlotType::SRV].values[i]; ++j) {
686 shaderState.SRVs[i].setChanged();
689 for (uint32_t j = 0; j < shaderState.effectSignature.slots[SlotType::UAV].values[i]; ++j) {
690 shaderState.UAVs[i].setChanged();
698 state.currentInputLayout = &buffers->inputLayouts[inputLayoutHandle];
704 if (!state.dirty)
return;
706 const auto topologyType = Direct3D12::TopologyTypes[topology];
709 if (hashCode != state.currentStateHash) {
710 auto it = PSOs.find(hashCode);
712 if (it == PSOs.end()) {
713 auto & inputLayout = *state.currentInputLayout;
714 auto & effect = *state.currentEffect;
716 D3D12_GRAPHICS_PIPELINE_STATE_DESC descPso = {};
717 descPso.InputLayout = { inputLayout.inputElements, inputLayout.inputElementCount };
718 descPso.pRootSignature = state.currentEffect->rootSignature;
720 descPso.VS = {
reinterpret_cast<BYTE *
>(effect.vertexShader.byteCode->GetBufferPointer()), effect.vertexShader.byteCode->GetBufferSize() };
722 if (effect.hullShader.byteCode) {
723 descPso.HS = {
reinterpret_cast<BYTE *
>(effect.hullShader.byteCode->GetBufferPointer()), effect.hullShader.byteCode->GetBufferSize() };
726 if (effect.domainShader.byteCode) {
727 descPso.DS = {
reinterpret_cast<BYTE *
>(effect.domainShader.byteCode->GetBufferPointer()), effect.domainShader.byteCode->GetBufferSize() };
730 if (effect.geometryShader.byteCode) {
731 descPso.GS = {
reinterpret_cast<BYTE *
>(effect.geometryShader.byteCode->GetBufferPointer()), effect.geometryShader.byteCode->GetBufferSize() };
734 if (effect.pixelShader.byteCode) {
735 descPso.PS = {
reinterpret_cast<BYTE *
>(effect.pixelShader.byteCode->GetBufferPointer()), effect.pixelShader.byteCode->GetBufferSize() };
738 descPso.RasterizerState = state.currentRasterizerState->rasterizerDesc;
739 descPso.BlendState = state.currentBlendState->blendDesc;
740 descPso.DepthStencilState = state.currentDepthStencilState->depthStencilDesc;
742 descPso.SampleMask = UINT_MAX;
743 descPso.PrimitiveTopologyType = Direct3D12::TopologyTypes[topology];
745 if (state.currentRenderTarget) {
746 descPso.NumRenderTargets = state.currentRenderTarget->numViews;
750 descPso.SampleDesc.Count = textures->textures[state.currentRenderTarget->textures[0]].numSamples;
752 descPso.SampleDesc.Count = state.currentRenderTarget->numSamples;
755 for (
size_t i = 0; i < state.currentRenderTarget->numViews; ++i) {
756 descPso.RTVFormats[i] = state.currentRenderTarget->viewDesc[i].Format;
760 if (state.currentDepthStencil) {
761 if (!state.currentRenderTarget) {
762 auto & texture = textures->textures[state.currentDepthStencil->texture];
763 descPso.SampleDesc.Count = texture.numSamples;
765 descPso.DSVFormat = state.currentDepthStencil->viewDesc.Format;
768 device->CreateGraphicsPipelineState(&descPso, IID_PPV_ARGS(PSOs[hashCode].internalPointer()));
770 commandList->SetPipelineState(PSOs[hashCode]);
772 commandList->SetPipelineState(it->second);
775 state.currentStateHash = hashCode;
781 auto & sourceTexture = textures->textures[source];
782 auto & destination = textures->textures[destinationTexture];
784 setResourceState(commandList, sourceTexture, D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
785 setResourceState(commandList, destination, D3D12_RESOURCE_STATE_RESOLVE_DEST);
787 commandList->ResolveSubresource(destination.resource, 0, sourceTexture.resource, 0, sourceTexture.srvDesc.Format);
792 setupPipelineState(primitiveType);
794 commandList->IASetPrimitiveTopology(Direct3D12::Topologies[primitiveType]);
796 commandList->DrawInstanced(
static_cast<UINT
>(numVertexes),
static_cast<UINT
>(numInstances),
static_cast<UINT
>(startVertex),
static_cast<UINT
>(startInstance));
801 setupPipelineState(primitiveType);
803 commandList->IASetPrimitiveTopology(Direct3D12::Topologies[primitiveType]);
805 const size_t indexCount = numIndexes ? numIndexes : iaState.currentIndexBuffer->count;
807 commandList->DrawIndexedInstanced(
static_cast<UINT
>(indexCount),
static_cast<UINT
>(numInstances),
static_cast<UINT
>(startIndex), 0,
static_cast<UINT
>(startInstance));
812 auto & buffer = buffers->buffers[bufferHandle];
814 auto & texture = textures->textures[state.currentDepthStencil->texture];
815 setResourceState(commandList, texture, D3D12_RESOURCE_STATE_COPY_SOURCE);
816 auto resource = texture.resource;
818 auto desc = resource->GetDesc();
820 if (desc.Format == DXGI_FORMAT_D32_FLOAT || desc.Format == DXGI_FORMAT_D24_UNORM_S8_UINT) {
821 D3D12_RESOURCE_DESC textureDesc;
822 textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
823 textureDesc.DepthOrArraySize = 1;
824 textureDesc.Alignment = 0;
825 textureDesc.Width = desc.Width;
826 textureDesc.Height = desc.Height;
827 textureDesc.Format = DXGI_FORMAT_R32_FLOAT;
828 textureDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
829 textureDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
830 textureDesc.MipLevels =
static_cast<UINT16
>(1);
831 textureDesc.SampleDesc.Count = desc.SampleDesc.Count;
832 textureDesc.SampleDesc.Quality = 0;
835 if (FAILED(device->CreateCommittedResource(
836 &defaultHeapProperties,
837 D3D12_HEAP_FLAG_NONE,
839 D3D12_RESOURCE_STATE_COMMON,
841 IID_PPV_ARGS(copyTexture.internalPointer())))) {
846 currentFrameResources->orphanedResources.push_back(copyTexture);
848 setResourceState(commandList, texture, D3D12_RESOURCE_STATE_COPY_SOURCE);
849 setResourceBarrier(commandList, copyTexture, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_COPY_DEST);
851 commandList->CopyResource(copyTexture, resource);
853 setResourceBarrier(commandList, copyTexture, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COMMON);
855 resource = copyTexture;
856 desc = resource->GetDesc();
859 if (desc.SampleDesc.Count > 1) {
860 D3D12_RESOURCE_DESC textureDesc;
861 textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
862 textureDesc.DepthOrArraySize = 1;
863 textureDesc.Alignment = 0;
864 textureDesc.Width = desc.Width;
865 textureDesc.Height = desc.Height;
866 textureDesc.Format = DXGI_FORMAT_R32_FLOAT;
867 textureDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
868 textureDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
869 textureDesc.MipLevels =
static_cast<UINT16
>(1);
870 textureDesc.SampleDesc.Count = 1;
871 textureDesc.SampleDesc.Quality = 0;
874 if (FAILED(device->CreateCommittedResource(
875 &defaultHeapProperties,
876 D3D12_HEAP_FLAG_NONE,
878 D3D12_RESOURCE_STATE_COMMON,
880 IID_PPV_ARGS(resolveTexture.internalPointer())))) {
885 currentFrameResources->orphanedResources.push_back(resolveTexture);
887 if (resource == texture.resource) {
888 setResourceState(commandList, texture, D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
890 setResourceBarrier(commandList, resource, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
893 setResourceBarrier(commandList, resolveTexture, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_RESOLVE_DEST);
895 commandList->ResolveSubresource(resolveTexture, 0, resource, 0, textureDesc.Format);
897 setResourceBarrier(commandList, resolveTexture, D3D12_RESOURCE_STATE_RESOLVE_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
899 resource = resolveTexture;
900 desc = resource->GetDesc();
903 const int maxSubresources = 16;
904 UINT firstSubresource = 0;
905 UINT64 requiredSize = 0;
906 D3D12_PLACED_SUBRESOURCE_FOOTPRINT layouts[maxSubresources];
907 UINT numRows[maxSubresources];
908 UINT64 rowSizesInBytes[maxSubresources];
910 device->GetCopyableFootprints(&desc, 0, 1, 0, layouts, numRows, rowSizesInBytes, &requiredSize);
912 CD3DX12_RESOURCE_DESC bufferDesc = CD3DX12_RESOURCE_DESC::Buffer(requiredSize);
915 device->CreateCommittedResource(
916 &defaultHeapProperties,
917 D3D12_HEAP_FLAG_NONE,
919 D3D12_RESOURCE_STATE_GENERIC_READ,
921 IID_PPV_ARGS(temp.internalPointer()));
923 currentFrameResources->orphanedResources.push_back(temp);
925 setResourceBarrier(commandList, temp, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_COPY_DEST);
927 CD3DX12_TEXTURE_COPY_LOCATION src(resource, firstSubresource);
928 CD3DX12_TEXTURE_COPY_LOCATION dst(temp, layouts[0]);
932 box.right = x + width;
934 box.bottom = y + height;
938 commandList->CopyTextureRegion(&dst, x, y, 0, &src, &box);
940 setResourceState(commandList, texture, D3D12_RESOURCE_STATE_DEPTH_WRITE);
942 setResourceState(commandList, buffer, D3D12_RESOURCE_STATE_COPY_DEST);
943 setResourceBarrier(commandList, temp, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
945 for (
int i = 0; i < height; ++i) {
946 auto sourceOffset = layouts[0].Footprint.RowPitch * (y + i) + 4 * x;
948 commandList->CopyBufferRegion(buffer.resource, i * width * 4, temp, sourceOffset, width * 4);
954 auto & buffer = buffers->buffers[bufferHandle];
957 if (state.currentRenderTarget->resource) {
958 resource = state.currentRenderTarget->resource;
959 setResourceBarrier(commandList, resource, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
961 auto & texture = textures->textures[state.currentRenderTarget->textures[0]];
962 setResourceState(commandList, texture, D3D12_RESOURCE_STATE_COPY_SOURCE);
963 resource = texture.resource;
966 auto desc = resource->GetDesc();
967 if (desc.SampleDesc.Count > 1) {
968 D3D12_RESOURCE_DESC textureDesc;
969 textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
970 textureDesc.DepthOrArraySize =
static_cast<UINT16
>(1);
971 textureDesc.Alignment = 0;
972 textureDesc.Width = desc.Width;
973 textureDesc.Height = desc.Height;
974 textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
975 textureDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
976 textureDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
977 textureDesc.MipLevels =
static_cast<UINT16
>(1);
978 textureDesc.SampleDesc.Count = 1;
979 textureDesc.SampleDesc.Quality = 0;
982 if (FAILED(device->CreateCommittedResource(
983 &defaultHeapProperties,
984 D3D12_HEAP_FLAG_NONE,
986 D3D12_RESOURCE_STATE_COMMON,
988 IID_PPV_ARGS(resolveTexture.internalPointer())))) {
993 currentFrameResources->orphanedResources.push_back(resolveTexture);
995 setResourceBarrier(commandList, resource, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
996 setResourceBarrier(commandList, resolveTexture, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_RESOLVE_DEST);
998 commandList->ResolveSubresource(resolveTexture, 0, resource, 0, textureDesc.Format);
1000 setResourceBarrier(commandList, resource, D3D12_RESOURCE_STATE_RESOLVE_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
1001 setResourceBarrier(commandList, resolveTexture, D3D12_RESOURCE_STATE_RESOLVE_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
1003 resource = resolveTexture;
1004 desc = resource->GetDesc();
1007 const int maxSubresources = 16;
1008 UINT firstSubresource = 0;
1009 UINT64 requiredSize = 0;
1010 D3D12_PLACED_SUBRESOURCE_FOOTPRINT layouts[maxSubresources];
1011 UINT numRows[maxSubresources];
1012 UINT64 rowSizesInBytes[maxSubresources];
1014 device->GetCopyableFootprints(&desc, 0, 1, 0, layouts, numRows, rowSizesInBytes, &requiredSize);
1016 CD3DX12_RESOURCE_DESC bufferDesc = CD3DX12_RESOURCE_DESC::Buffer(requiredSize);
1019 device->CreateCommittedResource(
1020 &defaultHeapProperties,
1021 D3D12_HEAP_FLAG_NONE,
1023 D3D12_RESOURCE_STATE_GENERIC_READ,
1025 IID_PPV_ARGS(temp.internalPointer()));
1027 currentFrameResources->orphanedResources.push_back(temp);
1029 setResourceBarrier(commandList, temp, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_COPY_DEST);
1031 CD3DX12_TEXTURE_COPY_LOCATION src(resource, firstSubresource);
1032 CD3DX12_TEXTURE_COPY_LOCATION dst(temp, layouts[0]);
1036 box.right = x + width;
1038 box.bottom = y + height;
1042 commandList->CopyTextureRegion(&dst, x, y, 0, &src, &box);
1044 if (state.currentRenderTarget->resource && state.currentRenderTarget->numSamples == 1) {
1045 resource = state.currentRenderTarget->resource;
1046 setResourceBarrier(commandList, resource, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
1049 setResourceState(commandList, buffer, D3D12_RESOURCE_STATE_COPY_DEST);
1050 setResourceBarrier(commandList, temp, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
1052 for (
int i = 0; i < height; ++i) {
1053 auto sourceOffset = layouts[0].Footprint.RowPitch * (y + i) + 4 * x;
1055 commandList->CopyBufferRegion(buffer.resource, i * width * 4, temp, sourceOffset, width * 4);
1061 auto & buffer = buffers->buffers[bufferHandle];
1064 if (buffer.resource) {
1065 UINT8 * resourceData;
1066 buffer.resource->Map(0,
nullptr,
reinterpret_cast<void **
>(&resourceData));
1067 return resourceData;
1069 currentFrameResources->orphanedBuffers.push_back(
OrphanBufferD3D12{ buffer.pooledResource, &buffers->getBufferPool(buffer.size) });
1071 buffer.pooledResource = buffers->getBufferPool(buffer.size).allocate();
1072 buffer.cbvDesc.BufferLocation = buffer.pooledResource->mappedGpuRegion;
1074 for (
auto & cbv : shaderState.CBVs) {
1075 cbv.setAnyChanged(&buffer);
1078 return buffer.pooledResource->mappedRegion;
1081 if (buffer.resource) {
1082 UINT8 * resourcePointer;
1084 buffer.resource->Map(0,
nullptr,
reinterpret_cast<void **
>(&resourcePointer));
1086 return resourcePointer;
1088 return buffer.pooledResource->mappedRegion;
1093 if (buffer.resource) {
1094 UINT8 * resourcePointer;
1096 D3D12_RANGE range{};
1098 range.End = buffer.size;
1100 buffer.resource->Map(0, &range,
reinterpret_cast<void **
>(&resourcePointer));
1102 return resourcePointer;
1111 auto & buffer = buffers->buffers[bufferHandle];
1113 if (buffer.resource) {
1114 buffer.resource->Unmap(0,
nullptr);
1120 assert(HandleIsValid(textureHandle) &&
"Texture handle must be a valid texture.");
1122 auto & texture = this->textures->textures[textureHandle];
1124 const uint32_t width = std::max(1u, texture.width /
static_cast<uint32_t
>(std::pow(2, level)));
1125 const uint32_t height = std::max(1u, texture.height /
static_cast<uint32_t
>(std::pow(2, level)));
1127 D3D12_BOX rectangle;
1129 rectangle.right = width;
1131 rectangle.bottom = height;
1132 rectangle.front = 0;
1135 D3D12_SUBRESOURCE_DATA d{};
1137 d.RowPitch = width *
static_cast<uint32_t
>(getBlockSize(texture.format));
1139 if (!texture.uploadResource) {
1141 buffers->allocateBuffer(buffer, height * width * getBlockSize(texture.format),
nullptr);
1142 texture.uploadResource = buffer.resource;
1145 setResourceState(commandList, texture, D3D12_RESOURCE_STATE_COPY_DEST);
1147 UpdateSubresources(commandList, texture.resource, texture.uploadResource, 0, 0, 1, &d);
1152 auto & buffer = buffers->buffers[bufferHandle];
1155 auto & tempBuffer = buffers->buffers[tempBufferHandle];
1157 setResourceState(commandList, buffer, D3D12_RESOURCE_STATE_COPY_DEST);
1158 commandList->CopyBufferRegion(buffer.resource, offset, tempBuffer.resource, 0, size);
1160 buffers->releaseBuffer(tempBufferHandle);
1165 auto & destination = buffers->buffers[destinationHandle];
1166 auto & source = buffers->buffers[sourceHandle];
1168 setResourceState(commandList, destination, D3D12_RESOURCE_STATE_COPY_DEST);
1169 commandList->CopyResource(destination.resource, source.resource);
1172void Cogs::ContextD3D12::copyResource(TextureHandle destinationHandle, TextureHandle sourceHandle)
1178 uint32_t slots[ShaderType::NumShaderTypes];
1179 decode(textureBindingHandle.
handle, slots);
1181 if (!HandleIsValid(textureHandle))
return;
1183 auto & texture = textures->textures[textureHandle];
1185 checkTextureState(texture);
1187 for (
size_t i = 0; i < ShaderType::NumShaderTypes; ++i) {
1188 if (slots[i] != NoBinding) {
1189 shaderState.SRVs[i].setChanged(slots[i], &texture,
true);
1196 uint32_t slots[ShaderType::NumShaderTypes];
1197 decode(textureBindingHandle.
handle, slots);
1199 if (!HandleIsValid(textureViewHandle))
return;
1201 auto & textureView = textures->textureViews[textureViewHandle];
1202 auto & texture = textures->textures[textureView.texture];
1204 checkTextureState(texture);
1206 for (
size_t i = 0; i < ShaderType::NumShaderTypes; ++i) {
1207 if (slots[i] != NoBinding) {
1208 shaderState.SRVs[i].setChanged(slots[i], &texture,
true);
1213void Cogs::ContextD3D12::checkTextureState(TextureD3D12 & texture)
1215 if (texture.needsUpload) {
1216 setResourceState(commandList, texture, D3D12_RESOURCE_STATE_COPY_DEST);
1218 const int maxSubresources = 16;
1219 UINT numSubresources = texture.numSubResources;
1220 UINT firstSubresource = 0;
1221 UINT64 requiredSize = 0;
1222 D3D12_PLACED_SUBRESOURCE_FOOTPRINT layouts[maxSubresources];
1223 UINT numRows[maxSubresources];
1224 UINT64 rowSizesInBytes[maxSubresources];
1226 auto desc = texture.resource->GetDesc();
1227 device->GetCopyableFootprints(&desc, 0, texture.numSubResources, 0, layouts, numRows, rowSizesInBytes, &requiredSize);
1229 for (UINT i = 0; i < numSubresources; ++i)
1231 CD3DX12_TEXTURE_COPY_LOCATION dst(texture.resource, i + firstSubresource);
1232 CD3DX12_TEXTURE_COPY_LOCATION src(texture.uploadResource, layouts[i]);
1234 commandList->CopyTextureRegion(&dst, 0, 0, 0, &src,
nullptr);
1237 texture.needsUpload =
false;
1240 if (texture.usage != D3D12_RESOURCE_STATE_GENERIC_READ) {
1241 setResourceState(commandList, texture, D3D12_RESOURCE_STATE_GENERIC_READ);
1249 setBufferCounter(bufferHandle, sourceBufferHandle);
1257 auto & buffer = buffers->buffers[bufferHandle];
1258 auto & sourceBuffer = buffers->buffers[sourceBufferHandle];
1262 setResourceBarrier(commandList, buffer.counterResource, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
1264 if (sourceBuffer.pooledResource) {
1265 commandList->CopyBufferRegion(buffer.counterResource, 0, sourceBuffer.pooledResource->resource, sourceBuffer.pooledResource->offset, 4);
1267 commandList->CopyResource(buffer.counterResource, sourceBuffer.resource);
1270 setResourceBarrier(commandList, buffer.counterResource, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
1287 auto & binding = effects->bufferBindings[bufferBindingHandle];
1288 auto & buffer = buffers->buffers[bufferHandle];
1290 if (buffer.uploadResource.resource) {
1291 setResourceState(commandList, buffer, D3D12_RESOURCE_STATE_COPY_DEST);
1292 commandList->CopyResource(buffer.resource, buffer.uploadResource.resource);
1293 setResourceState(commandList, buffer, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
1295 currentFrameResources->orphanedResources.push_back(buffer.uploadResource.resource);
1296 buffer.uploadResource.resource =
nullptr;
1303 uint32_t slots[ShaderType::NumShaderTypes];
1304 decode(binding.uavBindings, slots);
1306 for (
size_t i = 0; i < ShaderType::NumShaderTypes; ++i) {
1307 if (slots[i] != NoBinding) {
1308 shaderState.UAVs[i].setChanged(slots[i], &buffer,
false);
1314 uint32_t slots[ShaderType::NumShaderTypes];
1315 decode(binding.srvBindings, slots);
1317 for (
size_t i = 0; i < ShaderType::NumShaderTypes; ++i) {
1318 if (slots[i] != NoBinding) {
1319 shaderState.SRVs[i].setChanged(slots[i], &buffer,
false);
1324 if (buffer.usage != D3D12_RESOURCE_STATE_UNORDERED_ACCESS) {
1325 setResourceState(commandList, buffer, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
1332 auto handle = HandleIsValid(samplerStateHandle) ? samplerStateHandle : defaultSamplerState;
1334 uint32_t slots[ShaderType::NumShaderTypes];
1335 decode(samplerStateBindingHandle.
handle, slots);
1337 auto & sampler = textures->samplerStates[handle];
1339 for (
size_t i = 0; i < ShaderType::NumShaderTypes; ++i) {
1340 if (slots[i] != NoBinding) {
1341 shaderState.Samplers[i].setChanged(slots[i], &sampler.samplerDesc,
false);
1346void Cogs::ContextD3D12::setupConstantBuffers()
1348 if (constantBuffersUpdated)
return;
1350 ContextCommon::updateConstantBuffers();
1352 auto & effect = this->effects->effects[this->currentEffect];
1355 if (!constantBuffer.dirty)
return;
1359 std::memcpy(mappedBuffer, constantBuffer.memoryBuffer.data(), constantBuffer.memoryBuffer.size());
1361 constantBuffer.dirty =
false;
1364 for (
auto & shader : effect.shaders) {
1365 for (
auto & constantBuffer : shader.reflection.constantBuffers) {
1366 if (HandleIsValid(constantBuffer.buffer)) {
1367 updateConstantBuffer(constantBuffer);
1372 for (
size_t i = 0; i < ShaderType::NumShaderTypes; ++i) {
1373 for (
auto & cb : effect.shaders[i].reflection.constantBuffers) {
1374 shaderState.CBVs[i].setChanged(cb.slot, &buffers->buffers[cb.buffer]);
Log implementation class.
bool HandleIsValid(const ResourceHandle_t< T > &handle)
Check if the given resource is valid, that is not equal to NoHandle or InvalidHandle.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Contains all Cogs related functionality.
@ Direct3D12
Graphics device using the Direct3D 12 API.
constexpr size_t fnv1a(uint8_t data, size_t hashValue) noexcept
Hashes a single byte using the fnv1a algorithm.
@ Read
The buffer can be mapped and read from by the CPU after creation.
@ Write
The buffer can be mapped and written to by the CPU after creation.
@ StructuredBufferWithCounter
The buffer can be bound as a structured buffer and read or written from shaders, with an additional a...
@ VertexBuffer
The buffer can be bound as input to the vertex shader stage as a vertex buffer.
@ None
The buffer will not be bound to the graphics pipeline. Suitable for staging resources.
static BlendState DefaultState()
Creates a blend state object initialized with the default settings.
void setRasterizerState(const RasterizerStateHandle handle) override
Set the current rasterizer state.
void dispatchCompute(const unsigned int threadGroupsX, const unsigned int threadGroupsY, const unsigned int threadGroupsZ) override
Dispatch computing work on the graphics device using the desired thread group count.
void updateSubBuffer(BufferHandle bufferHandle, const size_t offset, const size_t size, const void *data) override
Update a region of data in a buffer.
void clearDepth(const float depth=1.0f) override
Clear the currently set depth/stencil target to the given depth.
void clearRenderTarget(const float *color) override
Clear the currently set render target to the given value (4 component floating point RGBA).
void setBufferCounter(BufferHandle bufferHandle, uint32_t value)
Set the associated counter of a buffer.
void draw(PrimitiveType::EPrimitiveType primitiveType, const size_t startVertex, const size_t numVertexes) override
Draws non-indexed, non-instanced primitives.
void resolveResource(TextureHandle source, TextureHandle destination) override
Resolves the given source resource target into the given destination texture.
void setSamplerState(const SamplerStateBindingHandle samplerStateBindingHandle, const SamplerStateHandle samplerStateHandle) override
Sets the sampler state binding given to the given sampler state.
void setDepthStencilState(const DepthStencilStateHandle handle) override
Set the current depth stencil state.
void drawInstanced(PrimitiveType::EPrimitiveType primitiveType, const size_t startVertex, const size_t numVertexes, const size_t startInstance, const size_t numInstances) override
Draws non-indexed, instanced primitives.
void readColorBuffer(BufferHandle bufferHandle, int x, int y, int width, int height, Framebuffer::EFrameBuffer framebuffer) override
Reads data from the current render target into the given bufferHandle.
void setEffect(EffectHandle handle) override
Set the current effect.
void drawInstancedIndexed(PrimitiveType::EPrimitiveType primitiveType, const size_t startInstance, const size_t numInstances, const size_t startIndex, const size_t numIndexes) override
Draws indexed, instanced primitives.
void setBlendState(const BlendStateHandle handle, const float *constant) override
Set the current blend state.
void setConstantBuffer(const ConstantBufferBindingHandle bufferBinding, const BufferHandle bufferHandle, const uint32_t offset, const uint32_t size) override
Sets a constant buffer to the given constant buffer binding.
void setTexture(const TextureBindingHandle textureBindingHandle, const TextureHandle textureHandle) override
Sets the texture given to the binding given by textureBindingHandle.
uint32_t getBufferCounter(BufferHandle bufferHandle)
Get the associated counter of a buffer.
void signal(FenceHandle fenceHandle) override
Insert a fence in the command stream that will signal when all commands before the fence are complete...
void drawIndexed(PrimitiveType::EPrimitiveType primitiveType, const size_t startIndex, const size_t numIndexes, const size_t startVertex) override
Draws indexed, non-instanced primitives.
void setVertexBuffers(const VertexBufferHandle *vertexBufferHandles, const size_t count) override
Overload provided to support transitioning.
void setRenderTarget(const RenderTargetHandle handle, const DepthStencilHandle depthStencilHandle) override
Sets the current render target and an associated depth stencil target.
void unmap(BufferHandle bufferHandle) override
Unmaps the given buffer, applying any synchronization necessary to reflect changes in the mapped memo...
void setIndexBuffer(IndexBufferHandle indexBufferHandle, uint32_t stride, uint32_t offset) override
Sets the current index buffer.
void setScissor(const int x, const int y, const int width, const int height) override
Sets the current scissor rectangle.
void setViewport(const float x, const float y, const float width, const float height) override
Sets the current viewport to the given location and dimensions.
void readDepthBuffer(BufferHandle bufferHandle, int x, int y, int width, int height, Framebuffer::EFrameBuffer framebuffer) override
Reads data from the current depth target into the given bufferHandle.
void setInputLayout(const InputLayoutHandle inputLayoutHandle) override
Sets the current input layout.
void * map(BufferHandle bufferHandle, MapMode::EMapMode accessMode, uint32_t *stride=0) override
Maps the given buffer so it can be accessed.
void setBuffer(const BufferBindingHandle bufferBindingHandle, BufferHandle bufferHandle) override
Sets a buffer to bind to the given binding.
void updateSubTexture(TextureHandle textureHandle, const size_t level, const void *data) override
Update the data of a level in the given texture.
static DepthStencilState DefaultState()
Constructs a depth stencil state object initialized with the default values.
Handle template class used to provide opaque, non-converting handles.
static const Handle_t NoHandle
Represents a handle to nothing.
handle_type handle
Internal resource handle.
static const Handle_t InvalidHandle
Represents an invalid handle.
Provides effects and shader management functionality.
EMapMode
Mapping mode enumeration.
@ WriteDiscard
Write access. When unmapping the graphics system will discard the old contents of the resource.
Provides RAII style mapping of a buffer resource.
EPrimitiveType
Primitive type enumeration.
static RasterizerState DefaultState()
Constructs a rasterizer state initialized with the default values.
static SamplerState & DefaultState()
Constructs a sampler state initialized with the default values.