internal/graphicsdriver/directx: fix GetCPU/GPUDescriptorHandleForHeapStart for Xbox

Updates #2084
This commit is contained in:
Hajime Hoshi 2022-06-10 21:35:15 +09:00
parent b9373c498b
commit 07aa906753
3 changed files with 84 additions and 17 deletions

View File

@ -1250,19 +1250,51 @@ type _ID3D12DescriptrHeap_Vtbl struct {
GetGPUDescriptorHandleForHeapStart uintptr
}
func (i *_ID3D12DescriptorHeap) GetCPUDescriptorHandleForHeapStart() _D3D12_CPU_DESCRIPTOR_HANDLE {
func (i *_ID3D12DescriptorHeap) GetCPUDescriptorHandleForHeapStart() (_D3D12_CPU_DESCRIPTOR_HANDLE, error) {
if microsoftgdk.IsXbox() {
r, _, e := syscall.Syscall(i.vtbl.GetCPUDescriptorHandleForHeapStart, 1, uintptr(unsafe.Pointer(i)), 0, 0)
if r == 0 {
return _D3D12_CPU_DESCRIPTOR_HANDLE{}, fmt.Errorf("directx: ID3D12DescriptorHeap::GetCPUDescriptorHandleForHeapStart failed: %w", e)
}
return _D3D12_CPU_DESCRIPTOR_HANDLE{
ptr: r,
}, nil
}
// There is a bug in the header file:
// https://stackoverflow.com/questions/34118929/getcpudescriptorhandleforheapstart-stack-corruption
var handle _D3D12_CPU_DESCRIPTOR_HANDLE
syscall.Syscall(i.vtbl.GetCPUDescriptorHandleForHeapStart, 2, uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(&handle)), 0)
return handle
_, _, e := syscall.Syscall(i.vtbl.GetCPUDescriptorHandleForHeapStart, 2, uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(&handle)), 0)
if handle.ptr == 0 {
return _D3D12_CPU_DESCRIPTOR_HANDLE{}, fmt.Errorf("directx: ID3D12DescriptorHeap::GetCPUDescriptorHandleForHeapStart failed: %w", e)
}
return handle, nil
}
func (i *_ID3D12DescriptorHeap) GetGPUDescriptorHandleForHeapStart() _D3D12_GPU_DESCRIPTOR_HANDLE {
func (i *_ID3D12DescriptorHeap) GetGPUDescriptorHandleForHeapStart() (_D3D12_GPU_DESCRIPTOR_HANDLE, error) {
if microsoftgdk.IsXbox() {
r1, r2, e := syscall.Syscall(i.vtbl.GetGPUDescriptorHandleForHeapStart, 1, uintptr(unsafe.Pointer(i)), 0, 0)
var ptr uint64
if unsafe.Sizeof(uintptr(0)) == 4 {
ptr = uint64(r1) | uint64(r2)<<32
} else {
ptr = uint64(r1)
}
if ptr == 0 {
return _D3D12_GPU_DESCRIPTOR_HANDLE{}, fmt.Errorf("directx: ID3D12DescriptorHeap::GetGPUDescriptorHandleForHeapStart failed: %w", e)
}
return _D3D12_GPU_DESCRIPTOR_HANDLE{
ptr: ptr,
}, nil
}
// This has the same issue as GetCPUDescriptorHandleForHeapStart.
var handle _D3D12_GPU_DESCRIPTOR_HANDLE
syscall.Syscall(i.vtbl.GetGPUDescriptorHandleForHeapStart, 2, uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(&handle)), 0)
return handle
_, _, e := syscall.Syscall(i.vtbl.GetGPUDescriptorHandleForHeapStart, 2, uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(&handle)), 0)
if handle.ptr == 0 {
return _D3D12_GPU_DESCRIPTOR_HANDLE{}, fmt.Errorf("directx: ID3D12DescriptorHeap::GetGPUDescriptorHandleForHeapStart failed: %w", e)
}
return handle, nil
}
func (i *_ID3D12DescriptorHeap) Release() {

View File

@ -571,7 +571,10 @@ func (g *Graphics) resizeSwapChain(width, height int) error {
func (g *Graphics) createRenderTargetViews() (ferr error) {
// Create frame resources.
h := g.rtvDescriptorHeap.GetCPUDescriptorHandleForHeapStart()
h, err := g.rtvDescriptorHeap.GetCPUDescriptorHandleForHeapStart()
if err != nil {
return err
}
for i := 0; i < frameCount; i++ {
r, err := g.swapChain.GetBuffer(uint32(i))
if err != nil {
@ -1474,19 +1477,28 @@ func (i *Image) setAsRenderTarget(device *_ID3D12Device, useStencil bool) error
}
if i.screen {
rtv := i.graphics.rtvDescriptorHeap.GetCPUDescriptorHandleForHeapStart()
rtv, err := i.graphics.rtvDescriptorHeap.GetCPUDescriptorHandleForHeapStart()
if err != nil {
return err
}
rtv.Offset(int32(i.graphics.frameIndex), i.graphics.rtvDescriptorSize)
i.graphics.drawCommandList.OMSetRenderTargets(1, &rtv, false, nil)
return nil
}
rtv := i.rtvDescriptorHeap.GetCPUDescriptorHandleForHeapStart()
rtv, err := i.rtvDescriptorHeap.GetCPUDescriptorHandleForHeapStart()
if err != nil {
return err
}
var dsv *_D3D12_CPU_DESCRIPTOR_HANDLE
if useStencil {
if err := i.ensureDepthStencilView(device); err != nil {
return err
}
v := i.dsvDescriptorHeap.GetCPUDescriptorHandleForHeapStart()
v, err := i.dsvDescriptorHeap.GetCPUDescriptorHandleForHeapStart()
if err != nil {
return err
}
dsv = &v
i.graphics.drawCommandList.ClearDepthStencilView(v, _D3D12_CLEAR_FLAG_STENCIL, 0, 0, 0, nil)
@ -1517,7 +1529,10 @@ func (i *Image) ensureRenderTargetView(device *_ID3D12Device) error {
}
i.rtvDescriptorHeap = h
rtv := i.rtvDescriptorHeap.GetCPUDescriptorHandleForHeapStart()
rtv, err := i.rtvDescriptorHeap.GetCPUDescriptorHandleForHeapStart()
if err != nil {
return err
}
device.CreateRenderTargetView(i.texture, nil, rtv)
return nil
@ -1543,7 +1558,10 @@ func (i *Image) ensureDepthStencilView(device *_ID3D12Device) error {
}
i.dsvDescriptorHeap = h
dsv := i.dsvDescriptorHeap.GetCPUDescriptorHandleForHeapStart()
dsv, err := i.dsvDescriptorHeap.GetCPUDescriptorHandleForHeapStart()
if err != nil {
return err
}
if i.stencil == nil {
s, err := device.CreateCommittedResource(&_D3D12_HEAP_PROPERTIES{
Type: _D3D12_HEAP_TYPE_DEFAULT,

View File

@ -312,6 +312,10 @@ func (p *pipelineStates) initialize(device *_ID3D12Device) (ferr error) {
}
p.samplerDescriptorHeap = samplerH
h, err := p.samplerDescriptorHeap.GetCPUDescriptorHandleForHeapStart()
if err != nil {
return err
}
device.CreateSampler(&_D3D12_SAMPLER_DESC{
Filter: _D3D12_FILTER_MIN_MAG_MIP_POINT,
AddressU: _D3D12_TEXTURE_ADDRESS_MODE_WRAP,
@ -320,7 +324,7 @@ func (p *pipelineStates) initialize(device *_ID3D12Device) (ferr error) {
ComparisonFunc: _D3D12_COMPARISON_FUNC_NEVER,
MinLOD: -math.MaxFloat32,
MaxLOD: math.MaxFloat32,
}, p.samplerDescriptorHeap.GetCPUDescriptorHandleForHeapStart())
}, h)
return nil
}
@ -388,7 +392,10 @@ func (p *pipelineStates) useGraphicsPipelineState(device *_ID3D12Device, command
}
p.constantBuffers[frameIndex][idx] = cb
h := p.shaderDescriptorHeap.GetCPUDescriptorHandleForHeapStart()
h, err := p.shaderDescriptorHeap.GetCPUDescriptorHandleForHeapStart()
if err != nil {
return err
}
h.Offset(int32(frameIndex*numDescriptorsPerFrame+numConstantBufferAndSourceTextures*idx), p.shaderDescriptorSize)
device.CreateConstantBufferView(&_D3D12_CONSTANT_BUFFER_VIEW_DESC{
BufferLocation: cb.GetGPUVirtualAddress(),
@ -396,7 +403,10 @@ func (p *pipelineStates) useGraphicsPipelineState(device *_ID3D12Device, command
}, h)
}
h := p.shaderDescriptorHeap.GetCPUDescriptorHandleForHeapStart()
h, err := p.shaderDescriptorHeap.GetCPUDescriptorHandleForHeapStart()
if err != nil {
return err
}
h.Offset(int32(frameIndex*numDescriptorsPerFrame+numConstantBufferAndSourceTextures*idx), p.shaderDescriptorSize)
for _, src := range srcs {
h.Offset(1, p.shaderDescriptorSize)
@ -436,12 +446,19 @@ func (p *pipelineStates) useGraphicsPipelineState(device *_ID3D12Device, command
})
// Match the indices with rootParams in graphicsPipelineState.
gh := p.shaderDescriptorHeap.GetGPUDescriptorHandleForHeapStart()
gh, err := p.shaderDescriptorHeap.GetGPUDescriptorHandleForHeapStart()
if err != nil {
return err
}
gh.Offset(int32(frameIndex*numDescriptorsPerFrame+numConstantBufferAndSourceTextures*idx), p.shaderDescriptorSize)
commandList.SetGraphicsRootDescriptorTable(0, gh)
gh.Offset(1, p.shaderDescriptorSize)
commandList.SetGraphicsRootDescriptorTable(1, gh)
commandList.SetGraphicsRootDescriptorTable(2, p.samplerDescriptorHeap.GetGPUDescriptorHandleForHeapStart())
sh, err := p.samplerDescriptorHeap.GetGPUDescriptorHandleForHeapStart()
if err != nil {
return err
}
commandList.SetGraphicsRootDescriptorTable(2, sh)
return nil
}