diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 7b558f5b7..3ebe8b4ee 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -1909,8 +1909,17 @@ namespace bgfx { namespace d3d11 m_deviceCtx->CopySubresourceRegion(texture.m_staging, subresource, 0, 0, 0, texture.m_ptr, subresource, NULL); - D3D11_MAPPED_SUBRESOURCE mapped; - DX_CHECK(m_deviceCtx->Map(texture.m_staging, subresource, D3D11_MAP_READ, 0, &mapped) ); + D3D11_MAPPED_SUBRESOURCE mapped = {}; + const HRESULT hr = m_deviceCtx->Map(texture.m_staging, subresource, D3D11_MAP_READ, 0, &mapped); + + if (FAILED(hr) ) + { + BX_TRACE("readTexture: Map failed 0x%08x, device removed reason 0x%08x." + , uint32_t(hr) + , uint32_t(m_device->GetDeviceRemovedReason() ) + ); + return; + } uint32_t srcWidth = bx::max(1, texture.m_width >>_mip); uint32_t srcHeight = bx::max(1, texture.m_height>>_mip); @@ -1979,10 +1988,21 @@ namespace bgfx { namespace d3d11 box.back = 1; m_deviceCtx->CopySubresourceRegion(staging, 0, _offset, 0, 0, buffer.m_ptr, 0, &box); - D3D11_MAPPED_SUBRESOURCE mapped; - DX_CHECK(m_deviceCtx->Map(staging, 0, D3D11_MAP_READ, 0, &mapped) ); - bx::memCopy(_data, (const uint8_t*)mapped.pData + _offset, _size); - m_deviceCtx->Unmap(staging, 0); + D3D11_MAPPED_SUBRESOURCE mapped = {}; + const HRESULT hr = m_deviceCtx->Map(staging, 0, D3D11_MAP_READ, 0, &mapped); + + if (FAILED(hr) ) + { + BX_TRACE("readBuffer: Map failed 0x%08x, device removed reason 0x%08x." + , uint32_t(hr) + , uint32_t(m_device->GetDeviceRemovedReason() ) + ); + } + else + { + bx::memCopy(_data, (const uint8_t*)mapped.pData + _offset, _size); + m_deviceCtx->Unmap(staging, 0); + } DX_RELEASE(staging, 0); } @@ -2159,21 +2179,31 @@ namespace bgfx { namespace d3d11 } } - D3D11_MAPPED_SUBRESOURCE mapped; - DX_CHECK(m_deviceCtx->Map(texture, 0, D3D11_MAP_READ, 0, &mapped) ); + D3D11_MAPPED_SUBRESOURCE mapped = {}; + hr = m_deviceCtx->Map(texture, 0, D3D11_MAP_READ, 0, &mapped); - g_callback->screenShot( - _filePath - , backBufferDesc.Width - , backBufferDesc.Height - , mapped.RowPitch - , colorFormat - , mapped.pData - , backBufferDesc.Height*mapped.RowPitch - , false - ); + if (FAILED(hr) ) + { + BX_TRACE("requestScreenShot: Map failed 0x%08x, device removed reason 0x%08x." + , uint32_t(hr) + , uint32_t(m_device->GetDeviceRemovedReason() ) + ); + } + else + { + g_callback->screenShot( + _filePath + , backBufferDesc.Width + , backBufferDesc.Height + , mapped.RowPitch + , colorFormat + , mapped.pData + , backBufferDesc.Height*mapped.RowPitch + , false + ); - m_deviceCtx->Unmap(texture, 0); + m_deviceCtx->Unmap(texture, 0); + } DX_RELEASE(texture, 0); } @@ -3622,21 +3652,31 @@ namespace bgfx { namespace d3d11 m_deviceCtx->CopyResource(m_captureTexture, m_captureResolve); } - D3D11_MAPPED_SUBRESOURCE mapped; - DX_CHECK(m_deviceCtx->Map(m_captureTexture, 0, D3D11_MAP_READ, 0, &mapped) ); + D3D11_MAPPED_SUBRESOURCE mapped = {}; + const HRESULT hr = m_deviceCtx->Map(m_captureTexture, 0, D3D11_MAP_READ, 0, &mapped); - bimg::imageSwizzleBgra8( - mapped.pData - , mapped.RowPitch - , m_scd.width - , m_scd.height - , mapped.pData - , mapped.RowPitch - ); + if (FAILED(hr) ) + { + BX_TRACE("capture: Map failed 0x%08x, device removed reason 0x%08x." + , uint32_t(hr) + , uint32_t(m_device->GetDeviceRemovedReason() ) + ); + } + else + { + bimg::imageSwizzleBgra8( + mapped.pData + , mapped.RowPitch + , m_scd.width + , m_scd.height + , mapped.pData + , mapped.RowPitch + ); - g_callback->captureFrame(mapped.pData, m_scd.height*mapped.RowPitch); + g_callback->captureFrame(mapped.pData, m_scd.height*mapped.RowPitch); - m_deviceCtx->Unmap(m_captureTexture, 0); + m_deviceCtx->Unmap(m_captureTexture, 0); + } DX_RELEASE(backBuffer, 0); } diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index 4702c5fb6..04f379312 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -693,11 +693,13 @@ namespace bgfx { namespace d3d12 #endif // BX_PLATFORM_WINDOWS } + static bool reportDeviceLost(HRESULT _hr); + ID3D12Resource* createCommittedResource(ID3D12Device* _device, HeapProperty::Enum _heapProperty, const D3D12_RESOURCE_DESC* _resourceDesc, const D3D12_CLEAR_VALUE* _clearValue, bool _memSet = false, D3D12_HEAP_FLAGS _heapFlags = D3D12_HEAP_FLAG_NONE) { const HeapProperty& heapProperty = s_heapProperties[_heapProperty]; ID3D12Resource* resource = NULL; - DX_CHECK(_device->CreateCommittedResource( + const HRESULT hr = _device->CreateCommittedResource( &heapProperty.m_properties , _heapFlags , _resourceDesc @@ -705,7 +707,14 @@ namespace bgfx { namespace d3d12 , _clearValue , IID_ID3D12Resource , (void**)&resource - ) ); + ); + + if (reportDeviceLost(hr) ) + { + return NULL; + } + + BX_ASSERT(SUCCEEDED(hr), "CreateCommittedResource FAILED 0x%08x.", uint32_t(hr) ); BX_WARN(NULL != resource, "CreateCommittedResource failed (size: %d). Out of memory?" , _resourceDesc->Width ); @@ -2322,7 +2331,7 @@ namespace bgfx { namespace d3d12 } } - DX_RELEASE(dred, 0); + DX_RELEASE_I(dred); } bool handleDeviceLost(HRESULT _hr) @@ -2532,6 +2541,14 @@ namespace bgfx { namespace d3d12 ID3D12Resource* readback = createCommittedResource(m_device, HeapProperty::ReadBack, total); + if (NULL == readback) + { + BX_TRACE("readTexture: failed to create readback buffer, device removed reason 0x%08x." + , uint32_t(m_device->GetDeviceRemovedReason() ) + ); + return; + } + const uint32_t srcWidth = bx::max(1u, texture.m_width >>_mip); const uint32_t srcHeight = bx::max(1u, texture.m_height>>_mip); @@ -2570,13 +2587,23 @@ namespace bgfx { namespace d3d12 uint32_t pitch = bx::min(srcPitch, dstPitch); - uint8_t* src; - readback->Map(0, NULL, (void**)&src); + uint8_t* src = NULL; + const HRESULT hr = readback->Map(0, NULL, (void**)&src); - bx::memCopy(dst, dstPitch, src, srcPitch, pitch, numBlockRows); + if (FAILED(hr) ) + { + BX_TRACE("readTexture: Map failed 0x%08x, device removed reason 0x%08x." + , uint32_t(hr) + , uint32_t(m_device->GetDeviceRemovedReason() ) + ); + } + else + { + bx::memCopy(dst, dstPitch, src, srcPitch, pitch, numBlockRows); - D3D12_RANGE writeRange = { 0, 0 }; - readback->Unmap(0, &writeRange); + D3D12_RANGE writeRange = { 0, 0 }; + readback->Unmap(0, &writeRange); + } DX_RELEASE(readback, 0); } @@ -2613,6 +2640,14 @@ namespace bgfx { namespace d3d12 ID3D12Resource* readback = createCommittedResource(m_device, HeapProperty::ReadBack, stencilOffset + total[1]); + if (NULL == readback) + { + BX_TRACE("readTexturePlanar: failed to create readback buffer, device removed reason 0x%08x." + , uint32_t(m_device->GetDeviceRemovedReason() ) + ); + return; + } + const uint32_t srcWidth = bx::max(1u, _texture.m_width >>_mip); const uint32_t srcHeight = bx::max(1u, _texture.m_height>>_mip); @@ -2639,47 +2674,57 @@ namespace bgfx { namespace d3d12 finish(); m_commandList = m_cmd.alloc(); - uint8_t* src; - readback->Map(0, NULL, (void**)&src); + uint8_t* src = NULL; + const HRESULT hr = readback->Map(0, NULL, (void**)&src); - const uint32_t texelSize = bimg::getBlockInfo(bimg::TextureFormat::Enum(_texture.m_textureFormat) ).blockSize; - const uint32_t dstPitch = srcWidth * texelSize; - - for (uint32_t yy = 0; yy < srcHeight; ++yy) + if (FAILED(hr) ) { - const uint8_t* depthRow = src + layout[0].Offset + yy*layout[0].Footprint.RowPitch; - const uint8_t* stencilRow = src + layout[1].Offset + yy*layout[1].Footprint.RowPitch; - uint8_t* dstRow = (uint8_t*)_data + yy*dstPitch; + BX_TRACE("readTexturePlanar: Map failed 0x%08x, device removed reason 0x%08x." + , uint32_t(hr) + , uint32_t(m_device->GetDeviceRemovedReason() ) + ); + } + else + { + const uint32_t texelSize = bimg::getBlockInfo(bimg::TextureFormat::Enum(_texture.m_textureFormat) ).blockSize; + const uint32_t dstPitch = srcWidth * texelSize; - for (uint32_t xx = 0; xx < srcWidth; ++xx) + for (uint32_t yy = 0; yy < srcHeight; ++yy) { - uint8_t* texel = dstRow + xx*texelSize; + const uint8_t* depthRow = src + layout[0].Offset + yy*layout[0].Footprint.RowPitch; + const uint8_t* stencilRow = src + layout[1].Offset + yy*layout[1].Footprint.RowPitch; + uint8_t* dstRow = (uint8_t*)_data + yy*dstPitch; - if (1 == texelSize) + for (uint32_t xx = 0; xx < srcWidth; ++xx) { - texel[0] = stencilRow[xx]; - } - else - { - bx::memCopy(texel, depthRow + xx*4, 4); + uint8_t* texel = dstRow + xx*texelSize; - if (4 == texelSize) + if (1 == texelSize) { - texel[3] = stencilRow[xx]; + texel[0] = stencilRow[xx]; } else { - texel[4] = stencilRow[xx]; - texel[5] = 0; - texel[6] = 0; - texel[7] = 0; + bx::memCopy(texel, depthRow + xx*4, 4); + + if (4 == texelSize) + { + texel[3] = stencilRow[xx]; + } + else + { + texel[4] = stencilRow[xx]; + texel[5] = 0; + texel[6] = 0; + texel[7] = 0; + } } } } - } - D3D12_RANGE writeRange = { 0, 0 }; - readback->Unmap(0, &writeRange); + D3D12_RANGE writeRange = { 0, 0 }; + readback->Unmap(0, &writeRange); + } DX_RELEASE(readback, 0); } @@ -2700,6 +2745,14 @@ namespace bgfx { namespace d3d12 ID3D12Resource* readback = createCommittedResource(m_device, HeapProperty::ReadBack, _size); + if (NULL == readback) + { + BX_TRACE("readBuffer: failed to create readback buffer, device removed reason 0x%08x." + , uint32_t(m_device->GetDeviceRemovedReason() ) + ); + return; + } + const D3D12_RESOURCE_STATES state = buffer.setState(m_commandList, D3D12_RESOURCE_STATE_COPY_SOURCE); m_commandList->CopyBufferRegion(readback, 0, buffer.m_ptr, _offset, _size); buffer.setState(m_commandList, state); @@ -2708,10 +2761,22 @@ namespace bgfx { namespace d3d12 m_commandList = m_cmd.alloc(); void* src = NULL; - readback->Map(0, NULL, (void**)&src); - bx::memCopy(_data, src, _size); - D3D12_RANGE readbackWriteRange = { 0, 0 }; - readback->Unmap(0, &readbackWriteRange); + const HRESULT hr = readback->Map(0, NULL, (void**)&src); + + if (FAILED(hr) ) + { + BX_TRACE("readBuffer: Map failed 0x%08x, device removed reason 0x%08x." + , uint32_t(hr) + , uint32_t(m_device->GetDeviceRemovedReason() ) + ); + } + else + { + bx::memCopy(_data, src, _size); + + D3D12_RANGE writeRange = { 0, 0 }; + readback->Unmap(0, &writeRange); + } DX_RELEASE(readback, 0); } @@ -2897,6 +2962,20 @@ namespace bgfx { namespace d3d12 ID3D12Resource* readback = createCommittedResource(m_device, HeapProperty::ReadBack, total); + if (NULL == readback) + { + BX_TRACE("requestScreenShot: failed to create readback buffer, device removed reason 0x%08x." + , uint32_t(m_device->GetDeviceRemovedReason() ) + ); + + if (NULL != swapFb) + { + DX_RELEASE(backBuffer, swapFb->getSwapChainDesc().bufferCount); + } + + return; + } + D3D12_BOX box; box.left = 0; box.top = 0; @@ -2917,21 +2996,31 @@ namespace bgfx { namespace d3d12 finish(); m_commandList = m_cmd.alloc(); - void* data; - readback->Map(0, NULL, (void**)&data); + void* data = NULL; + const HRESULT hr = readback->Map(0, NULL, (void**)&data); - g_callback->screenShot(_filePath - , width - , height - , layout.Footprint.RowPitch - , colorFormat - , data - , (uint32_t)total - , false - ); + if (FAILED(hr) ) + { + BX_TRACE("requestScreenShot: Map failed 0x%08x, device removed reason 0x%08x." + , uint32_t(hr) + , uint32_t(m_device->GetDeviceRemovedReason() ) + ); + } + else + { + g_callback->screenShot(_filePath + , width + , height + , layout.Footprint.RowPitch + , colorFormat + , data + , (uint32_t)total + , false + ); - D3D12_RANGE writeRange = { 0, 0 }; - readback->Unmap(0, &writeRange); + D3D12_RANGE writeRange = { 0, 0 }; + readback->Unmap(0, &writeRange); + } DX_RELEASE(readback, 0); @@ -4549,6 +4638,13 @@ namespace bgfx { namespace d3d12 static RendererContextD3D12* s_renderD3D12; + static bool reportDeviceLost(HRESULT _hr) + { + return NULL != s_renderD3D12 + && s_renderD3D12->handleDeviceLost(_hr) + ; + } + ID3D12PipelineState* videoGetPipelineState(RendererContextD3D12* _renderer, ProgramHandle _handle) { return _renderer->getPipelineState(_handle); @@ -10033,7 +10129,7 @@ namespace bgfx { namespace d3d12 ; const bool depthClamp = depthControl.m_depthClamp; - + ID3D12PipelineState* pso = getPipelineState( state diff --git a/src/renderer_webgpu.cpp b/src/renderer_webgpu.cpp index 26a4ea83b..453f7ce9a 100644 --- a/src/renderer_webgpu.cpp +++ b/src/renderer_webgpu.cpp @@ -1830,34 +1830,38 @@ WGPU_IMPORT static void readTextureCb(WGPUMapAsyncStatus _status, WGPUStringView _message, void* _userdata1, void* _userdata2) { - BX_ASSERT(WGPUMapAsyncStatus_Success == _status, "%d", _status); - - BX_UNUSED(_status, _message, _userdata2); - ReadTexture& readTexture = *(ReadTexture*)_userdata1; - const void* result = (const void*)WGPU_CHECK(wgpuBufferGetConstMappedRange( - readTexture.buffer - , 0 - , readTexture.size - ) ); - - if (0 != readTexture.stencilPitch) + if (WGPUMapAsyncStatus_Success != _status) { - interleaveDepthStencil(readTexture, result); + BX_TRACE("readTexture: map failed %d.", _status); + trace(_message); } else { - bx::gather( - readTexture.data - , result - , readTexture.pitch - , readTexture.dataPitch - , readTexture.height - ); - } + const void* result = (const void*)WGPU_CHECK(wgpuBufferGetConstMappedRange( + readTexture.buffer + , 0 + , readTexture.size + ) ); - WGPU_CHECK(wgpuBufferUnmap(readTexture.buffer) ); + if (0 != readTexture.stencilPitch) + { + interleaveDepthStencil(readTexture, result); + } + else + { + bx::gather( + readTexture.data + , result + , readTexture.pitch + , readTexture.dataPitch + , readTexture.height + ); + } + + WGPU_CHECK(wgpuBufferUnmap(readTexture.buffer) ); + } wgpuRelease(readTexture.buffer); @@ -1873,21 +1877,25 @@ WGPU_IMPORT static void readBufferCb(WGPUMapAsyncStatus _status, WGPUStringView _message, void* _userdata1, void* _userdata2) { - BX_ASSERT(WGPUMapAsyncStatus_Success == _status, "%d", _status); - - BX_UNUSED(_status, _message, _userdata2); - ReadBuffer& readBuffer = *(ReadBuffer*)_userdata1; - const void* result = (const void*)WGPU_CHECK(wgpuBufferGetConstMappedRange( - readBuffer.buffer - , 0 - , readBuffer.size - ) ); + if (WGPUMapAsyncStatus_Success != _status) + { + BX_TRACE("readBuffer: map failed %d.", _status); + trace(_message); + } + else + { + const void* result = (const void*)WGPU_CHECK(wgpuBufferGetConstMappedRange( + readBuffer.buffer + , 0 + , readBuffer.size + ) ); - bx::memCopy(readBuffer.data, result, readBuffer.size); + bx::memCopy(readBuffer.data, result, readBuffer.size); - WGPU_CHECK(wgpuBufferUnmap(readBuffer.buffer) ); + WGPU_CHECK(wgpuBufferUnmap(readBuffer.buffer) ); + } wgpuRelease(readBuffer.buffer);