2017-12-21 31 views
0

제가 그 튜토리얼 dx12 내용 : https://www.braynzarsoft.net/viewtutorial/q16390-directx-12-constant-buffers-root-descriptor-tables#c0여러 일정한 버퍼 - 등록 - dx12

는 I 2 상수 버퍼있어이 단계를 수정하려고 시도 (그래서 레지스터 B0 및 B1 내가 잘 이해 경우). 내 루트 기호에 말을 시작하는 것을 들어

2 개 매개 변수가 지금

// 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 = &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 = &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 

하지만 변수에 일정한 버퍼를 연결하는 데 실패, 나는 코드의이 부분에 수정하려고 :

// 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 < 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->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&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 < frameBufferCount; ++i) 
{ 
    hr = device->CreateCommittedResource(
     &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), // this heap will be used to upload the constant buffer data 
     D3D12_HEAP_FLAG_NONE, // no flags 
     &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(&constantBufferUploadHeap[i])); 
    constantBufferUploadHeap[i]->SetName(L"Constant Buffer Upload Resource Heap"); 

    D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {}; 
    cbvDesc.BufferLocation = constantBufferUploadHeap[i]->GetGPUVirtualAddress(); 
    cbvDesc.SizeInBytes = (sizeof(ConstantBuffer) + 255) & ~255; // CB size is required to be 256-byte aligned. 
    device->CreateConstantBufferView(&cbvDesc, mainDescriptorHeap[i]->GetCPUDescriptorHandleForHeapStart()); 

    ZeroMemory(&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]->Map(0, &readRange, reinterpret_cast<void**>(&cbColorMultiplierGPUAddress[i])); 
    memcpy(cbColorMultiplierGPUAddress[i], &cbColorMultiplierData, sizeof(cbColorMultiplierData)); 
} 

감사

답변

1

루트 서명이 잘못된 것입니다, 당신은 어떤 범위 디스크립터 테이블을 설정하기 위해 노력하고 있습니다.

당신은 루트 일정한 버퍼 및 디스크립터 테이블, 루트 상수, 루트 서명에 일정한 버퍼를 등록하는 3 가지 방법이있다. 첫 번째 두 개는 루트 매개 변수 당 하나의 상수 버퍼를 연결하는 반면 세 번째는 단일 테이블에 여러 개의 상수 버퍼를 설정할 수 있습니다. 귀하의 경우에는

2의 배열에 하나의 범위 다스 려와 형 디스크립터 테이블의 단일 루트 매개 변수는 당신이 일정한 버퍼를 바인딩 할 수 있도록 충분하다.

나는 root signatures 더 나은 개념을 이해하는 HLSL에 선언하는 방법을 읽어보실 것을 권장하고는 C++ 선언에 변환 방법에 대해 설명합니다. 일정한 버퍼를 조작하는 실행 부로서는

. d3d12의 수명 관리가 없거나 d3d11을 사용하는 드라이버는 매우 신중해야합니다. GPU가 이전 내용을 사용하여 이미 완료되었는지 확인하지 않고 버퍼 메모리를 일정 기간 업데이트 할 수 없습니다. 해결책은 링 버퍼를 사용하여 프레임 상수 버퍼를 할당하고 울타리를 사용하여 너무 빨리 덮어 쓰지 않도록하는 것입니다.

은 내가보기 엔 당신이 D3D11에 충실하는 것이 좋습니다. d3d12는 그 대체물이 아니며 매우 복잡한 렌더러에서만 찾아 볼 수있는이 성능 문제를 극복하기 위해 만들어졌으며 응용 프로그램이 아닌 경우에는 이미 d3d11과 GPU에 대한 전문 지식을 가진 사람들이 사용하게됩니다. GTA V의 복잡성 수준 (예를 들어)은 d3d12로 전환하여 발밑에서 슛하는 것입니다.

+0

감사합니다, 나는 actualy 그 작업, 그 문제를 지적하고 나에게 난 더 이상이 코드가없는 HLSL 루트 서명 : 에 대한 링크를 제공하기 : https://github.com/Zeldarck/TrainingDx12 그러나 나는 그래픽 프로그래밍을 시작 미래 이 문제에 백업합니다, 그래서 너무 DX11에서 아무것도 몰라. 경고를 주셔서 감사하지만 잠시 나 dx12를 계속하는 것을 더 좋아합니다. – Zeldarck

+1

@ Zeldarck @ Zeldarck 아주 나쁜 생각이지만, 그것에 충실하면 좋습니다. Microsoft 설명서를 읽고 또 배우고 자습서를 피하십시오. 설명서를 읽고 API에 대한 지식을 쌓으십시오. 위험 할 때는 CPU/GPU 동기화 및 메모리 관리에 특히주의하십시오. – galop1n