title: Multiple constant buffer - register - dx12
body: <p>I learn dx12 with that tutorial : 
  <a href="https://www.braynzarsoft.net/viewtutorial/q16390-directx-12-constant-buffers-root-descriptor-tables#c0" rel="nofollow noreferrer">https://www.braynzarsoft.net/viewtutorial/q16390-directx-12-constant-buffers-root-descriptor-tables#c0</a></p>
  
  <p>I tried to modify this step to got 2 constant buffer (so a register b0 and a b1, if i  understood well).</p>
  
  <p>For that I begin to say in my root sign there is 2 parameters:</p>
  
  <pre><code>// create root signature
  
  // create a descriptor range (descriptor table) and fill it out
  // this is a range of descriptors inside a descriptor heap
  D3D12_DESCRIPTOR_RANGE  descriptorTableRanges[1]; // only one range right now
  descriptorTableRanges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV; // this is a range of constant buffer views (descriptors)
  descriptorTableRanges[0].NumDescriptors = 2; // we only have one constant buffer, so the range is only 1
  descriptorTableRanges[0].BaseShaderRegister = 0; // start index of the shader registers in the range
  descriptorTableRanges[0].RegisterSpace = 0; // space 0. can usually be zero
  descriptorTableRanges[0].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; // this appends the range to the end of the root signature descriptor tables
  
  // create a descriptor table
  D3D12_ROOT_DESCRIPTOR_TABLE descriptorTable;
  descriptorTable.NumDescriptorRanges = 0;// _countof(descriptorTableRanges); // we only have one range
  descriptorTable.pDescriptorRanges = &amp;descriptorTableRanges[0]; // the pointer to the beginning of our ranges array
  D3D12_ROOT_DESCRIPTOR_TABLE descriptorTable2;
  descriptorTable2.NumDescriptorRanges = 1;// _countof(descriptorTableRanges); // we only have one range
  descriptorTable2.pDescriptorRanges = &amp;descriptorTableRanges[0]; // the pointer to the beginning of our ranges array
  
  
  // create a root parameter and fill it out
  D3D12_ROOT_PARAMETER  rootParameters[2]; // only one parameter right now
  rootParameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; // this is a descriptor table
  rootParameters[0].DescriptorTable = descriptorTable; // this is our descriptor table for this root parameter
  rootParameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX; // our pixel shader will be the only shader accessing this parameter for now
  rootParameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; // this is a descriptor table
  rootParameters[1].DescriptorTable = descriptorTable2; // this is our descriptor table for this root parameter
  rootParameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX; // our pixel shader will be the only shader accessing this parameter for now
  </code></pre>
  
  <p>But now I failed to link constant buffer to a variable, I try to modify in this part of the code:</p>
  
  <pre><code> // Create a constant buffer descriptor heap for each frame
  // this is the descriptor heap that will store our constant buffer descriptor
  for (int i = 0; i &lt; frameBufferCount; ++i)
  {
      D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {};
      heapDesc.NumDescriptors = 1;
      heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
      heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
      hr = device-&gt;CreateDescriptorHeap(&amp;heapDesc, IID_PPV_ARGS(&amp;mainDescriptorHeap[i]));
      if (FAILED(hr))
      {
          Running = false;
      }
  }
  
  // create the constant buffer resource heap
  // We will update the constant buffer one or more times per frame, so we will use only an upload heap
  // unlike previously we used an upload heap to upload the vertex and index data, and then copied over
  // to a default heap. If you plan to use a resource for more than a couple frames, it is usually more
  // efficient to copy to a default heap where it stays on the gpu. In this case, our constant buffer
  // will be modified and uploaded at least once per frame, so we only use an upload heap
  
  // create a resource heap, descriptor heap, and pointer to cbv for each frame
  for (int i = 0; i &lt; frameBufferCount; ++i)
  {
      hr = device-&gt;CreateCommittedResource(
          &amp;CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), // this heap will be used to upload the constant buffer data
          D3D12_HEAP_FLAG_NONE, // no flags
          &amp;CD3DX12_RESOURCE_DESC::Buffer(1024 * 64), // size of the resource heap. Must be a multiple of 64KB for single-textures and constant buffers
          D3D12_RESOURCE_STATE_GENERIC_READ, // will be data that is read from so we keep it in the generic read state
          nullptr, // we do not have use an optimized clear value for constant buffers
          IID_PPV_ARGS(&amp;constantBufferUploadHeap[i]));
      constantBufferUploadHeap[i]-&gt;SetName(L"Constant Buffer Upload Resource Heap");
  
      D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {};
      cbvDesc.BufferLocation = constantBufferUploadHeap[i]-&gt;GetGPUVirtualAddress();
      cbvDesc.SizeInBytes = (sizeof(ConstantBuffer) + 255) &amp; ~255;    // CB size is required to be 256-byte aligned.
      device-&gt;CreateConstantBufferView(&amp;cbvDesc, mainDescriptorHeap[i]-&gt;GetCPUDescriptorHandleForHeapStart());
  
      ZeroMemory(&amp;cbColorMultiplierData, sizeof(cbColorMultiplierData));
  
      CD3DX12_RANGE readRange(0, 0);    // We do not intend to read from this resource on the CPU. (End is less than or equal to begin)
      hr = constantBufferUploadHeap[i]-&gt;Map(0, &amp;readRange, reinterpret_cast&lt;void**&gt;(&amp;cbColorMultiplierGPUAddress[i]));
      memcpy(cbColorMultiplierGPUAddress[i], &amp;cbColorMultiplierData, sizeof(cbColorMultiplierData));
  }
  </code></pre>
  
  <p>Thank</p>