(reprint please indicate the source)
A little time has not been updated, the reason is that after one weeks of the bug results found to be less than an addition operation ....
But no one is going to see the effect anyway. _ (: 3"∠) _
The purpose of this time is to make a rotating color cube:
This is an example of what you did when you were learning d3d11, and now move on to D3d12, this time with the addition of: constant cache depth Caching
Vertex/Index Cache constant cache, the constant cache can put some GPU-only read data, here is the transformation matrix, in D3d12, the constant cache is 256-byte aligned (d3d12_constant_buffer_data_placement _alignment), so please note.
This allows you to create a constant cache and create CBV bindings to a descriptor
//create constant cache if (SUCCEEDED (HR)) {hr = M_pd3ddevice->createcommittedresource ( &cd3d12_heap_properties (D3d12_heap_type_upload), D3d12_heap_misc_none, &cd3d12_re
Source_desc::buffer (d3d12_constant_buffer_data_placement_alignment), D3d12_resource_usage_generic_read,
Nullptr, Iid_id3d12resource, reinterpret_cast<void**> (&m_pcbuffermatrix)
);
//bind to the constant cache view if (SUCCEEDED (HR)) {D3d12_constant_buffer_view_desc cbvdesc = {};
Cbvdesc.bufferlocation = M_pcbuffermatrix->getgpuvirtualaddress ();
Cbvdesc.sizeinbytes = d3d12_constant_buffer_data_placement_alignment;
M_pd3ddevice->createconstantbufferview (&cbvdesc, M_acpuhandlecsu[csu_matrixcbuffer]
); }
This part of the code, the use of d3d12_heap_type_upload is because we have to rewrite each frame, which is more convenient, corresponding, the efficiency may be lost points. The
also has been mentioned to put all the same descriptor together, so write a simple framework that is stored using a m_acpuhandlexxx array.
We store 3 matrices here: The world, the perspective, the pivot transformation matrix
2. Deep Cache , the effect of deep caching is needless to say, flexible use can get a good effect, create DSV binding to descriptor. The template is not used here, only the depth:
Create a depth cache if (SUCCEEDED (HR)) {D3d12_resource_desc Resourcedesc = cd3d12_resource_desc::tex2d ( Dxgi_format_r32_typeless, M_ubufferwidth, M_ubufferheight, 1, 1, 1, 0, D3d12_resource_misc_allow
_depth_stencil, D3d12_texture_layout_unknown, 0);
D3d12_clear_value Dsvclearvalue;
Dsvclearvalue.format = dxgi_format_d32_float;
DsvClearValue.DepthStencil.Depth = 1.0f;
DsvClearValue.DepthStencil.Stencil = 0;
hr = M_pd3ddevice->createcommittedresource (&cd3d12_heap_properties (D3d12_heap_type_default), D3d12_heap_misc_none, &resourcedesc, D3d12_resource_usage_depth, &dsvclearv
Alue, Iid_id3d12resource, reinterpret_cast<void**> (&m_pdepthbuffer));
}//binding depth cache to DSV if (SUCCEEDED (HR)) {D3d12_depth_stencil_view_desc dsvdesc = {}; Dsvdesc.vieWdimension = d3d12_dsv_dimension_texture2d;
Dsvdesc.format = dxgi_format_d32_float;
DsvDesc.Texture2D.MipSlice = 0;
Dsvdesc.flags = D3d12_dsv_none; /*no Return*/m_pd3ddevice->createdepthstencilview (M_pdepthbuffer, &dsvdesc, M_aCpuHandleDS
V[DSV_MAINDSV]); }
It feels like nothing to say, the helper provided by D3d12 is convenient, the default is on line, and the official document is available in detail.
3. Vertex/Index cache , render what a cube needs, at present we need: Vertex color and vertex coordinates, index is triangle index
Create a colored square auto Scenerenderer::createcoloredcube (id3d12resource*& vibuffer, d3d12_vertex_buffer_view& v
Buffer_view, d3d12_index_buffer_view& Ibuffer_view) noexcept-> HRESULT {HRESULT hr = S_OK;
id3d12resource* pvibuffer = nullptr; 8 vertices of the cube with the corresponding color Vertexcolor vertices[] = {{DIRECTX::XMFLOAT3 ( -1.f, -1.F, -1.f), Directx::xmfloat4 (0.F,
0.F, 0.F, 1.F)}, {DIRECTX::XMFLOAT3 ( -1.f, 1.F, -1.f), Directx::xmfloat4 (1.f, 0.F, 0.F, 1.F)}, {DIRECTX::XMFLOAT3 (1.f, 1.F, -1.f), Directx::xmfloat4 (0.F, 1.f, 0.F, 1.F)}, {DIRECTX::XMFLOAT3 (1.f, -1.F, -1.F), Directx::xmfloat4 (0.F, 0.F, 1.F, 1.F)}, {DIRECTX::XMFLOAT3 ( -1.f, -1.F, 1.f), Directx::xmfloat4 (0.F,
1.F, 1.F, 1.F)}, {DIRECTX::XMFLOAT3 ( -1.f, 1.F, 1.f), Directx::xmfloat4 (1.f, 1.f, 0.F, 1.F)}, {DIRECTX::XMFLOAT3 (1.f, 1.F, 1.f), Directx::xmfloat4 (1.f, 0.F, 1.F, 1.F)}, {DIRECTX::XMFLOAT3 (1.f, -1.F, 1.F), Directx::xmfloat4 (1.f, 1.f, 1.F, 1.F)}; Cube 6 faces 12 triangles 36 vertices uint16_t indices[] = {0, 1, 2, 0, 2, 3, 4, 5, 1, 4, 1, 0, 7, 6, 5, 7,
5, 4, 3, 2, 6, 3, 6, 7, 1, 5, 6, 1, 6, 2, 4, 0, 3, 4, 3, 7}; Create vertex Cache-Index cache shared buffer if (SUCCEEDED (HR)) {hr = M_pd3ddevice->createcommittedresource (&cd3d1 2_heap_properties (D3d12_heap_type_upload), D3d12_heap_misc_none, &cd3d12_resource_desc::buffer (sizeof (vertices) +sizeof (indices)), D3d12_resource_usage_generic_read, nullptr, iid_id
3d12resource, Reinterpret_cast<void**> (&pvibuffer));
}//Map void* buffer = nullptr;
if (SUCCEEDED (HR)) {hr = Pvibuffer->map (0, nullptr, &buffer);
}//copy-Cancel mapping-set if (SUCCEEDED (HR)) {:: memcpy (buffer, vertices, sizeof (vertices)); :: memcpy (Reinterpret_cast<uint8_t*> (buffer) + sizeof (vertices), indices, sizeof (indices));
Pvibuffer->unmap (0, nullptr); Set Vbuffer_view.
Bufferlocation = Pvibuffer->getgpuvirtualaddress (); Vbuffer_view.
strideinbytes = sizeof (Vertexcolor); Vbuffer_view.
sizeInBytes = sizeof (vertices); Ibuffer_view. Bufferlocation = Vbuffer_view.
Bufferlocation + sizeof (vertices); Ibuffer_view.
Format = Dxgi_format_r16_uint; Ibuffer_view.
sizeInBytes = sizeof (indices);
Vibuffer =:: Safeacquire (Pvibuffer);
}:: Saferelease (Pvibuffer);
return HR; }
Thanks to D3d12/win10 's virtual GPU address, we can apply the vertex cache cache with the index cache to increase efficiency. The corresponding input layout:
Input layout
D3d12_input_element_desc inputlayout[] = {
"POSITION", 0, dxgi_format_r32g32b32_float, 0, 0, d3d12_ Input_per_vertex_data, 0},
{"COLOR", 0, dxgi_format_r32g32b32a32_float, 0, sizeof (DIRECTX::XMFLOAT3), d3d12_ Input_per_vertex_data, 0},
};
In fact, the color can also use 3 floating-point number on the line, so that each node can save 1 floating point. The corresponding shader is:
C Buffer 0: Storage conversion matrix
Cbuffer Matrixbuffer:register (b0) {
matrix Worldmatrix;
Matrix Viewmatrix;
Matrix ProjectionMatrix;
};
VS input
struct Vertexinputtype {
float4 position : position;
FLOAT4 color : color;
VS output
struct Pixelinputtype {
float4 position : sv_position;
FLOAT4 color : color;
Processing
pixelinputtype colorvertexshader (Vertexinputtype input) {
pixelinputtype output;
Coordinate conversion
output.position = Mul (Float4 (input.position.xyz, 1), Worldmatrix);
Output.position = Mul (output.position, Viewmatrix);
Output.position = Mul (output.position, ProjectionMatrix);
Direct output
Output.color = Input.color;
return output;
}
Pixel shader processing
float4 colorpixelshader (pixelinputtype input): sv_target {return
input.color;
}
Note that because they are all "fixed pipelines," everything we use in the shader is explained:
Here the Cbuffer is used on the B0 register.
After all, the input is small, the pipeline takes up less resources, the parameters provided when serializing the Rootsignature d3d12_root_signature indicate this:
D3d12_root_signature Rootsigdesc = D3d12_root_signature ();
D3d12_root_parameter params[1];
D3d12_descriptor_range descrange[1];
Descrange[0]. Init (D3D12_DESCRIPTOR_RANGE_CBV, 1, 0);
Params[0]. Initasdescriptortable (Lengthof (Descrange), descrange);
Initialize
rootsigdesc.numparameters = Lengthof (params);
Rootsigdesc.pparameters = params;
Rootsigdesc.flags = D3d12_root_signature_allow_input_assembler_input_layout;
Only one descriptor table is currently available, and there is only one constant cache view (CBV), so it is descrange[0]. Init (D3D12_DESCRIPTOR_RANGE_CBV, 1, 0);
This empty command has a more empty depth cache:
//Execute Empty command
if (SUCCEEDED (HR)) {
this->setresourcebarrier (m_pcmdclear, M_ptargetbuffer, d3d12_ Resource_usage_present, d3d12_resource_usage_render_target);
M_pcmdclear->rssetviewports (1, &view);
Float Clearcolor[4] = {0.4f, 0.8f, 1.0f, 1.0f};
M_pcmdclear->clearrendertargetview (
M_acpuhandlertv[rtv_mainrtv],
clearcolor, nullptr, 0
);
M_pcmdclear->cleardepthstencilview (
M_ACPUHANDLEDSV[DSV_MAINDSV], d3d12_clear_depth, 1.0f,
0, nullptr, 0
);
This->setresourcebarrier (M_pcmdclear, M_ptargetbuffer, D3d12_resource_usage_render_target, D3D12_RESOURCE_ usage_present);
hr = M_pcmdclear->close ();
}
There are many more descriptions: Set up descriptor tables (corresponding pipelines), descriptor heap (provide resources), and set up vertex caching and Index caching:
Execute command if (SUCCEEDED (HR) {id3d12descriptorheap* heaps[] = {m_pcsudescriptors};
D3d12_rect scissor = {};
Scissor.right = M_ubufferwidth;
Scissor.bottom = M_ubufferheight; This->setresourcebarrier (M_pcmddraw, M_ptargetbuffer, D3d12_resource_usage_present, D3D12_RESOURCE_USAGE_REN
Der_target);
M_pcmddraw->rssetviewports (1, &view);
M_pcmddraw->rssetscissorrects (1, &scissor);
M_pcmddraw->setrendertargets (M_acpuhandlertv + Rtv_mainrtv, True, 1, M_ACPUHANDLEDSV + DSV_MAINDSV);
M_pcmddraw->setgraphicsrootsignature (M_prspipeline);
M_pcmddraw->setdescriptorheaps (Heaps, Lengthof (heaps));
M_pcmddraw->setgraphicsrootdescriptortable (0, M_pcsudescriptors->getgpudescriptorhandleforheapstart ());
M_pcmddraw->setpipelinestate (m_ppipelinestate);
M_pcmddraw->iasetprimitivetopology (D3d_primitive_topology_trianglestrip); M_pcmddraw->setvertexbuffers (0, &M_CUBEVBV, 1);
M_pcmddraw->setindexbuffer (&M_CUBEIBV);
M_pcmddraw->drawindexedinstanced (36, 1, 0, 0, 0); This->setresourcebarrier (M_pcmddraw, M_ptargetbuffer, D3d12_resource_usage_render_target, D3D12_RESOURCE_USAGE
_present);
hr = M_pcmddraw->close (); }
Update the constant cache direct modification can be automatically uploaded:
Code Download address: Click here