D3D12遇到的报错记录

E_INVALIDARG One or more arguments are invalid.

这个报错是最常见的报错了,一般是调用D3D的函数时的参数设置不对,或者参数设置无效,或者是当前系统环境不支持你所设置的参数,使用Visual studio进行学习开发的话,多注意Output窗口,一般会在报错提示的前后有更详细的提示

Invalid resource barrier type. [ RESOURCE_MANIPULATION ERROR #519: RESOURCE_BARRIER_INVALID_TYPE]

这个报错提示还是很清楚的,我出错的原因是

D3D12_RESOURCE_BARRIER resourceBarrier;
resourceBarrier.Transition.pResource = mRenderTargets[mFrameIndex].Get();
resourceBarrier.Transition.StateBefore = D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_PRESENT;
resourceBarrier.Transition.StateAfter = D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_RENDER_TARGET;
resourceBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
resourceBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAGS::D3D12_RESOURCE_BARRIER_FLAG_NONE;
//这一句没有写的话就会报这个错误,加上就好了,当然,这个Type可以选择合法的其他Type
resourceBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE::D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; 
mCommandList->ResourceBarrier(1, &resourceBarrier); 

编译报错: Severity Code Description Project File Line Suppression State Error X3501 ‘main’: entrypoint not found D3D12Guide E:\D3D12Guide\D3D12Guide\FXC 1

这个报错是因为写的shader文件没有main函数,有几种做法:

  • 若你使用的是D3DCompileFromFile编译,首先检查你传递的路径对不对
  • 若你的shader文件中可以添加main函数,加上就好了
  • 或你使用的是D3DCompileFromFile进行shader编译的话有下面两种做法可以选择
    • 在build的时候不编译该shader文件, 在Visual studio的 solution Explorer中找到你的shader文件,右键,在这里插入图片描述
      将属性中的配置改为图中所示即可
    • 告诉Visual studio你是用的是自己的编译器(也就是在运行时编译),还是在shader文件上鼠标右键在这里插入图片描述
      改为如图所示即可
      部分内容参考自stackoverflow
在DirectX 12渲染超大纹理需要采用纹理切割的技术,将大纹理切分成多个小纹理进行渲染。具体步骤如下: 1. 创建一个用于渲染的纹理对象,可以使用如下代码: ``` D3D12_HEAP_PROPERTIES heapProps = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT); D3D12_RESOURCE_DESC resDesc = CD3DX12_RESOURCE_DESC::Tex2D(format, width, height, 1, mipLevels); resDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; resDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; ThrowIfFailed(device->CreateCommittedResource( &heapProps, D3D12_HEAP_FLAG_NONE, &resDesc, D3D12_RESOURCE_STATE_RENDER_TARGET, nullptr, IID_PPV_ARGS(&m_RenderTarget))); ``` 其,format为纹理格式,width和height为纹理大小,mipLevels为mipmap级数。 2. 创建一个渲染目标视图和一个无序访问视图,用于后续的渲染和数据拷贝操作。可以使用如下代码: ``` D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = {}; rtvDesc.Format = format; rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_RTVDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), m_frameIndex, m_RTVDescriptorSize); device->CreateRenderTargetView(m_RenderTarget.Get(), &rtvDesc, rtvHandle); D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {}; uavDesc.Format = format; uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D; uavDesc.Texture2D.MipSlice = 0; CD3DX12_CPU_DESCRIPTOR_HANDLE uavHandle(m_UAVDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), m_frameIndex, m_UAVDescriptorSize); device->CreateUnorderedAccessView(m_RenderTarget.Get(), nullptr, &uavDesc, uavHandle); ``` 其,m_RTVDescriptorHeap和m_UAVDescriptorHeap为渲染目标视图和无序访问视图的描述符堆。 3. 将大纹理切割成多个小纹理,每个小纹理大小为256x256,循环遍历每个小纹理进行渲染。可以使用如下代码: ``` const int nTilesX = (width + 255) / 256; const int nTilesY = (height + 255) / 256; for (int y = 0; y < nTilesY; ++y) { for (int x = 0; x < nTilesX; ++x) { // Set viewport and scissor rect for current tile D3D12_VIEWPORT viewport = { x * 256.0f, y * 256.0f, 256.0f, 256.0f, 0.0f, 1.0f }; D3D12_RECT scissorRect = { x * 256, y * 256, (x + 1) * 256, (y + 1) * 256 }; // Set render target and clear color D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_RTVDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), m_frameIndex, m_RTVDescriptorSize); device->OMSetRenderTargets(1, &rtvHandle, FALSE, nullptr); float clearColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; commandList->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr); // Draw using current viewport and scissor rect commandList->RSSetViewports(1, &viewport); commandList->RSSetScissorRects(1, &scissorRect); // Draw code goes here } } ``` 其,m_frameIndex为当前帧的索引,commandList为渲染命令列表,需要在每个小纹理的渲染之前将渲染目标视图和清除颜色设置为当前纹理对应的视图和颜色。 4. 将渲染目标内容拷贝到CPU可访问的纹理,可以使用如下代码: ``` D3D12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(m_RenderTarget.Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); commandList->ResourceBarrier(1, &barrier); CD3DX12_TEXTURE_COPY_LOCATION src(m_RenderTarget.Get(), 0); CD3DX12_TEXTURE_COPY_LOCATION dst(m_StagingTexture.Get(), D3D12CalcSubresource(0, 0, 1)); commandList->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr); barrier = CD3DX12_RESOURCE_BARRIER::Transition(m_RenderTarget.Get(), D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET); commandList->ResourceBarrier(1, &barrier); ``` 其,m_StagingTexture为CPU可访问的纹理,需要将渲染目标从渲染状态转换为拷贝状态,然后使用CopyTextureRegion函数将渲染目标内容拷贝到CPU可访问的纹理,最后再将渲染目标从拷贝状态转换为渲染状态。 通过以上步骤,就可以在DirectX 12渲染超大纹理了。需要注意的是,纹理切割的大小和数量需要根据实际场景进行调整,以确保渲染效果和性能的平衡。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值