void TextureManager::ProcessGeneration(GenerateTextureInfo &generationInfo, RenderPassDescriptorHeap *srvHeap)
{
    ComputeContext *computeContext = mDirect3DManager->GetContextManager()->GetComputeContext();
    computeContext->SetDescriptorHeap(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, srvHeap->GetHeap());

    computeContext->SetPipelineState(generationInfo.GenerationShader);
    computeContext->SetRootSignature(generationInfo.GenerationShader->GetRootSignature());

    DescriptorHeapHandle generateTargetHandle = srvHeap->GetHeapHandleBlock(1);
    mDirect3DManager->GetDevice()->CopyDescriptorsSimple(1, generateTargetHandle.GetCPUHandle(), generationInfo.GenerateTarget->GetUnorderedAccessViewHandle().GetCPUHandle(), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);

    computeContext->SetDescriptorTable(0, generateTargetHandle.GetGPUHandle());
    computeContext->Dispatch(generationInfo.GenerateTarget->GetWidth() / 8, generationInfo.GenerateTarget->GetHeight() / 8, 1);

    generationInfo.GenerationFence = computeContext->Flush(mDirect3DManager->GetContextManager()->GetQueueManager());
}
void TextureManager::ProcessCubeMapFiltering(CubeMapFilterInfo &cubeMapFilterInfo, RenderPassDescriptorHeap *srvHeap, RenderPassDescriptorHeap *samplerHeap)
{
    Application::Assert(cubeMapFilterInfo.CubeMapToFilter->GetIsReady());

    Vector4 targets[6] =
    {
        Vector4(1.0f,  0.0f,  0.0f, 0.0f),  // +X
        Vector4(-1.0f, 0.0f,  0.0f, 0.0f),  // -X
        Vector4(0.0f,  1.0f,  0.0f, 0.0f),  // +Y
        Vector4(0.0f, -1.0f,  0.0f, 0.0f),  // -Y
        Vector4(0.0f,  0.0f,  1.0f, 0.0f),  // +Z
        Vector4(0.0f,  0.0f, -1.0f, 0.0f)   // -Z
    };

    Vector4 ups[6] =
    {
        Vector4(0.0f, 1.0f,  0.0f, 0.0f),  // +X
        Vector4(0.0f, 1.0f,  0.0f, 0.0f),  // -X
        Vector4(0.0f, 0.0f, -1.0f, 0.0f),  // +Y
        Vector4(0.0f, 0.0f,  1.0f, 0.0f),  // -Y
        Vector4(0.0f, 1.0f,  0.0f, 0.0f),  // +Z
        Vector4(0.0f, 1.0f,  0.0f, 0.0f)   // -Z
    };
    
    ComputeContext *computeContext = mDirect3DManager->GetContextManager()->GetComputeContext();
    computeContext->SetDescriptorHeap(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, srvHeap->GetHeap());
    computeContext->SetDescriptorHeap(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, samplerHeap->GetHeap());

    computeContext->SetPipelineState(cubeMapFilterInfo.EnvironmentFilterShader);
    computeContext->SetRootSignature(cubeMapFilterInfo.EnvironmentFilterShader->GetRootSignature());

    DescriptorHeapHandle envMapHandle = srvHeap->GetHeapHandleBlock(1);
    DescriptorHeapHandle envMapSamplerHandle = samplerHeap->GetHeapHandleBlock(1);
    mDirect3DManager->GetDevice()->CopyDescriptorsSimple(1, envMapHandle.GetCPUHandle(), cubeMapFilterInfo.CubeMapToFilter->GetTextureResource()->GetShaderResourceViewHandle().GetCPUHandle(), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
    mDirect3DManager->GetDevice()->CopyDescriptorsSimple(1, envMapSamplerHandle.GetCPUHandle(), cubeMapFilterInfo.EnvironmentSampler->GetSamplerHandle().GetCPUHandle(), D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);

    computeContext->SetDescriptorTable(0, envMapHandle.GetGPUHandle());
    computeContext->SetDescriptorTable(1, envMapSamplerHandle.GetGPUHandle());

    EnvironmentMapFilterTextureBuffer filterInfo;
    filterInfo.mipCount = (float)cubeMapFilterInfo.NumMips;

    for (uint32 cubeSideIndex = 0; cubeSideIndex < 6; cubeSideIndex++)
    {
        filterInfo.forwardDir = targets[cubeSideIndex];
        filterInfo.upDir = ups[cubeSideIndex];
        filterInfo.sourceDimensions = Vector2((float)cubeMapFilterInfo.DimensionSize, (float)cubeMapFilterInfo.DimensionSize);

        for (uint32 mipIndex = 0; mipIndex < cubeMapFilterInfo.NumMips; mipIndex++)
        {
            filterInfo.mipLevel = (float)(cubeMapFilterInfo.NumMips - mipIndex);
            DescriptorHeapHandle filterTargetHandle = srvHeap->GetHeapHandleBlock(1);
            mDirect3DManager->GetDevice()->CopyDescriptorsSimple(1, filterTargetHandle.GetCPUHandle(), cubeMapFilterInfo.FilterTarget->GetUnorderedAccessViewHandle(mipIndex, cubeSideIndex).GetCPUHandle(), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);

            computeContext->SetDescriptorTable(2, filterTargetHandle.GetGPUHandle());
            computeContext->SetConstants(3, 12, &filterInfo);
            computeContext->Dispatch((uint32)filterInfo.sourceDimensions.X / 8, (uint32)filterInfo.sourceDimensions.Y / 8, 1);

            filterInfo.sourceDimensions = Vector2(filterInfo.sourceDimensions.X / 2, filterInfo.sourceDimensions.Y / 2);
        }
    }

    cubeMapFilterInfo.FilterTarget->SetComputeFence(computeContext->Flush(mDirect3DManager->GetContextManager()->GetQueueManager()));
}