diff options
Diffstat (limited to '3rdparty/bgfx/src/renderer_d3d12.cpp')
-rw-r--r-- | 3rdparty/bgfx/src/renderer_d3d12.cpp | 829 |
1 files changed, 533 insertions, 296 deletions
diff --git a/3rdparty/bgfx/src/renderer_d3d12.cpp b/3rdparty/bgfx/src/renderer_d3d12.cpp index cf001166b4c..c38ad43a7d0 100644 --- a/3rdparty/bgfx/src/renderer_d3d12.cpp +++ b/3rdparty/bgfx/src/renderer_d3d12.cpp @@ -10,7 +10,8 @@ namespace bgfx { namespace d3d12 { - static wchar_t s_viewNameW[BGFX_CONFIG_MAX_VIEWS][256]; + static wchar_t s_viewNameW[BGFX_CONFIG_MAX_VIEWS][BGFX_CONFIG_MAX_VIEW_NAME]; + static char s_viewName[BGFX_CONFIG_MAX_VIEWS][BGFX_CONFIG_MAX_VIEW_NAME]; struct PrimInfo { @@ -239,7 +240,7 @@ namespace bgfx { namespace d3d12 { DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RGBA4 { DXGI_FORMAT_B5G5R5A1_UNORM, DXGI_FORMAT_B5G5R5A1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RGB5A1 { DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RGB10A2 - { DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R11G11B10F + { DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG11B10F { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // UnknownDepth { DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_D16_UNORM, DXGI_FORMAT_UNKNOWN }, // D16 { DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN }, // D24 @@ -260,6 +261,8 @@ namespace bgfx { namespace d3d12 { "BITANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UINT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "COLOR", 1, DXGI_FORMAT_R8G8B8A8_UINT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "COLOR", 2, DXGI_FORMAT_R8G8B8A8_UINT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "COLOR", 3, DXGI_FORMAT_R8G8B8A8_UINT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "BLENDINDICES", 0, DXGI_FORMAT_R8G8B8A8_UINT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "BLENDWEIGHT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, @@ -432,6 +435,46 @@ namespace bgfx { namespace d3d12 return createCommittedResource(_device, _heapProperty, &resourceDesc, NULL); } + inline bool isLost(HRESULT _hr) + { + return false + || _hr == DXGI_ERROR_DEVICE_REMOVED + || _hr == DXGI_ERROR_DEVICE_HUNG + || _hr == DXGI_ERROR_DEVICE_RESET + || _hr == DXGI_ERROR_DRIVER_INTERNAL_ERROR + || _hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE + ; + } + + static const char* getLostReason(HRESULT _hr) + { + switch (_hr) + { + // The GPU device instance has been suspended. Use GetDeviceRemovedReason to determine the appropriate action. + case DXGI_ERROR_DEVICE_REMOVED: return "DXGI_ERROR_DEVICE_REMOVED"; + + // The GPU will not respond to more commands, most likely because of an invalid command passed by the calling application. + case DXGI_ERROR_DEVICE_HUNG: return "DXGI_ERROR_DEVICE_HUNG"; + + // The GPU will not respond to more commands, most likely because some other application submitted invalid commands. + // The calling application should re-create the device and continue. + case DXGI_ERROR_DEVICE_RESET: return "DXGI_ERROR_DEVICE_RESET"; + + // An internal issue prevented the driver from carrying out the specified operation. The driver's state is probably + // suspect, and the application should not continue. + case DXGI_ERROR_DRIVER_INTERNAL_ERROR: return "DXGI_ERROR_DRIVER_INTERNAL_ERROR"; + + // A resource is not available at the time of the call, but may become available later. + case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE: return "DXGI_ERROR_NOT_CURRENTLY_AVAILABLE"; + + case S_OK: return "S_OK"; + + default: break; + } + + return "Unknown HRESULT?"; + } + BX_NO_INLINE void setDebugObjectName(ID3D12Object* _object, const char* _format, ...) { if (BX_ENABLED(BGFX_CONFIG_DEBUG_OBJECT_NAME) ) @@ -459,6 +502,42 @@ namespace bgfx { namespace d3d12 static PFN_CREATE_EVENT_EX_A CreateEventExA; #endif // USE_D3D12_DYNAMIC_LIB + inline D3D12_CPU_DESCRIPTOR_HANDLE getCPUHandleHeapStart(ID3D12DescriptorHeap* _heap) + { +#if BX_COMPILER_MSVC + return _heap->GetCPUDescriptorHandleForHeapStart(); +#else + D3D12_CPU_DESCRIPTOR_HANDLE handle; + typedef void (WINAPI ID3D12DescriptorHeap::*PFN_GET_CPU_DESCRIPTOR_HANDLE_FOR_HEAP_START)(D3D12_CPU_DESCRIPTOR_HANDLE *); + (_heap->*(PFN_GET_CPU_DESCRIPTOR_HANDLE_FOR_HEAP_START)(&ID3D12DescriptorHeap::GetCPUDescriptorHandleForHeapStart) )(&handle); + return handle; +#endif // BX_COMPILER_MSVC + } + + inline D3D12_GPU_DESCRIPTOR_HANDLE getGPUHandleHeapStart(ID3D12DescriptorHeap* _heap) + { +#if BX_COMPILER_MSVC + return _heap->GetGPUDescriptorHandleForHeapStart(); +#else + D3D12_GPU_DESCRIPTOR_HANDLE handle; + typedef void (WINAPI ID3D12DescriptorHeap::*PFN_GET_GPU_DESCRIPTOR_HANDLE_FOR_HEAP_START)(D3D12_GPU_DESCRIPTOR_HANDLE *); + (_heap->*(PFN_GET_GPU_DESCRIPTOR_HANDLE_FOR_HEAP_START)(&ID3D12DescriptorHeap::GetGPUDescriptorHandleForHeapStart) )(&handle); + return handle; +#endif // BX_COMPILER_MSVC + } + + inline D3D12_RESOURCE_DESC getResourceDesc(ID3D12Resource* _resource) + { +#if BX_COMPILER_MSVC + return _resource->GetDesc(); +#else + typedef void (STDMETHODCALLTYPE ID3D12Resource::*PFN_GET_GET_DESC)(D3D12_RESOURCE_DESC*); + D3D12_RESOURCE_DESC desc; + (_resource->*(PFN_GET_GET_DESC)(&ID3D12Resource::GetDesc))(&desc); + return desc; +#endif // BX_COMPILER_MSVC + } + struct RendererContextD3D12 : public RendererContextI { RendererContextD3D12() @@ -467,6 +546,7 @@ namespace bgfx { namespace d3d12 , m_renderdocdll(NULL) , m_featureLevel(D3D_FEATURE_LEVEL(0) ) , m_wireframe(false) + , m_lost(false) , m_maxAnisotropy(1) , m_depthClamp(false) , m_fsChanges(0) @@ -499,32 +579,33 @@ namespace bgfx { namespace d3d12 LUID luid; m_renderdocdll = loadRenderDoc(); + setGraphicsDebuggerPresent(NULL != m_renderdocdll); - m_fbh.idx = invalidHandle; + m_fbh.idx = kInvalidHandle; bx::memSet(m_uniforms, 0, sizeof(m_uniforms) ); bx::memSet(&m_resolution, 0, sizeof(m_resolution) ); #if USE_D3D12_DYNAMIC_LIB m_kernel32dll = bx::dlopen("kernel32.dll"); - BX_WARN(NULL != m_kernel32dll, "Failed to load kernel32.dll."); if (NULL == m_kernel32dll) { + BX_TRACE("Init error: Failed to load kernel32.dll."); goto error; } CreateEventExA = (PFN_CREATE_EVENT_EX_A)bx::dlsym(m_kernel32dll, "CreateEventExA"); - BX_WARN(NULL != CreateEventExA, "Function CreateEventExA not found."); if (NULL == CreateEventExA) { + BX_TRACE("Init error: Function CreateEventExA not found."); goto error; } errorState = ErrorState::LoadedKernel32; m_d3d12dll = bx::dlopen("d3d12.dll"); - BX_WARN(NULL != m_d3d12dll, "Failed to load d3d12.dll."); if (NULL == m_d3d12dll) { + BX_TRACE("Init error: Failed to load d3d12.dll."); goto error; } @@ -543,22 +624,23 @@ namespace bgfx { namespace d3d12 || NULL == D3D12GetDebugInterface || NULL == D3D12SerializeRootSignature) { + BX_TRACE("Init error: Function not found."); goto error; } m_dxgidll = bx::dlopen("dxgi.dll"); - BX_WARN(NULL != m_dxgidll, "Failed to load dxgi.dll."); if (NULL == m_dxgidll) { + BX_TRACE("Init error: Failed to load dxgi.dll."); goto error; } CreateDXGIFactory1 = (PFN_CREATE_DXGI_FACTORY)bx::dlsym(m_dxgidll, "CreateDXGIFactory1"); - BX_WARN(NULL != CreateDXGIFactory1, "Function CreateDXGIFactory1 not found."); if (NULL == CreateDXGIFactory1) { + BX_TRACE("Init error: Function CreateDXGIFactory1 not found."); goto error; } #endif // USE_D3D12_DYNAMIC_LIB @@ -573,10 +655,10 @@ namespace bgfx { namespace d3d12 hr = S_OK; m_factory = NULL; #endif // BX_PLATFORM_* - BX_WARN(SUCCEEDED(hr), "Unable to create DXGI factory."); if (FAILED(hr) ) { + BX_TRACE("Init error: Unable to create DXGI factory."); goto error; } @@ -629,7 +711,7 @@ namespace bgfx { namespace d3d12 } if (BX_ENABLED(BGFX_CONFIG_DEBUG_PERFHUD) - && 0 != strstr(description, "PerfHUD") ) + && 0 != bx::strFind(description, "PerfHUD") ) { m_adapter = adapter; m_driverType = D3D_DRIVER_TYPE_REFERENCE; @@ -678,14 +760,19 @@ namespace bgfx { namespace d3d12 if (FAILED(hr) ) { - BX_TRACE("Unable to create Direct3D12 device."); + BX_TRACE("Init error: Unable to create Direct3D12 device."); goto error; } if (NULL != m_factory) { bx::memSet(&m_adapterDesc, 0, sizeof(m_adapterDesc) ); - luid = m_device->GetAdapterLuid(); +// NOTICE: +// LUID STDMETHODCALLTYPE ID3D12Device::GetAdapterLuid() has a different behaviour in gcc , +// because gcc64 returns small struct in RAX, but the microsoft implemention of ID3D12Device::GetAdapterLuid() in d3d12.dll +// pass the struct LUID's address as the second parameter. + typedef void (STDMETHODCALLTYPE ID3D12Device::*ID3D12Device_GetAdapterLuid_f)(LUID *); + (m_device->*(ID3D12Device_GetAdapterLuid_f)(&ID3D12Device::GetAdapterLuid))(&luid); #if BX_PLATFORM_WINDOWS IDXGIAdapter3* adapter; #else @@ -743,7 +830,7 @@ namespace bgfx { namespace d3d12 if (FAILED(hr) ) { - BX_TRACE("Unable to query IDXGIDevice1 interface 0x%08x.", hr); + BX_TRACE("Init error: Unable to query IDXGIDevice1 interface 0x%08x.", hr); goto error; } @@ -751,7 +838,7 @@ namespace bgfx { namespace d3d12 if (FAILED(hr) ) { - BX_TRACE("DXGIDevice1::GetAdapter failed 0x%08x.", hr); + BX_TRACE("Init error: DXGIDevice1::GetAdapter failed 0x%08x.", hr); goto error; } @@ -759,7 +846,7 @@ namespace bgfx { namespace d3d12 if (FAILED(hr) ) { - BX_TRACE("IDXGIAdapter::GetParent failed 0x%08x.", hr); + BX_TRACE("Init error: IDXGIAdapter::GetParent failed 0x%08x.", hr); goto error; } } @@ -784,7 +871,7 @@ namespace bgfx { namespace d3d12 DX_RELEASE(m_adapter, 1); if (FAILED(hr) ) { - BX_TRACE("Unable to create Direct3D11 device."); + BX_TRACE("Init error: Unable to create Direct3D11 device."); goto error; } @@ -864,7 +951,7 @@ namespace bgfx { namespace d3d12 #endif // BX_PLATFORM_* if (FAILED(hr) ) { - BX_TRACE("Failed to create swap chain."); + BX_TRACE("Init error: Failed to create swap chain."); goto error; } } @@ -1014,7 +1101,7 @@ namespace bgfx { namespace d3d12 { uint16_t support = BGFX_CAPS_FORMAT_TEXTURE_NONE; - const DXGI_FORMAT fmt = isDepth(TextureFormat::Enum(ii) ) + const DXGI_FORMAT fmt = bimg::isDepth(bimg::TextureFormat::Enum(ii) ) ? s_textureFormat[ii].m_fmtDsv : s_textureFormat[ii].m_fmt ; @@ -1154,6 +1241,13 @@ namespace bgfx { namespace d3d12 g_caps.formats[ii] = support; } + // Init reserved part of view name. + for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii) + { + bx::snprintf(s_viewName[ii], BGFX_CONFIG_MAX_VIEW_NAME_RESERVED + 1, "%3d ", ii); + mbstowcs(s_viewNameW[ii], s_viewName[ii], BGFX_CONFIG_MAX_VIEW_NAME_RESERVED); + } + postReset(); m_batch.create(4<<10); @@ -1250,29 +1344,25 @@ namespace bgfx { namespace d3d12 #endif // USE_D3D12_DYNAMIC_LIB } - RendererType::Enum getRendererType() const BX_OVERRIDE + RendererType::Enum getRendererType() const override { return RendererType::Direct3D12; } - const char* getRendererName() const BX_OVERRIDE + const char* getRendererName() const override { return BGFX_RENDERER_DIRECT3D12_NAME; } - static bool isLost(HRESULT _hr) + bool isDeviceRemoved() override { - return DXGI_ERROR_DEVICE_REMOVED == _hr - || DXGI_ERROR_DEVICE_HUNG == _hr - || DXGI_ERROR_DEVICE_RESET == _hr - || DXGI_ERROR_DRIVER_INTERNAL_ERROR == _hr - || DXGI_ERROR_NOT_CURRENTLY_AVAILABLE == _hr - ; + return m_lost; } - void flip(HMD& /*_hmd*/) BX_OVERRIDE + void flip(HMD& /*_hmd*/) override { - if (NULL != m_swapChain) + if (NULL != m_swapChain + && !m_lost) { int64_t start = bx::getHPCounter(); @@ -1293,124 +1383,122 @@ namespace bgfx { namespace d3d12 int64_t now = bx::getHPCounter(); m_presentElapsed = now - start; - if (FAILED(hr) - && isLost(hr) ) - { - ++m_lost; - BGFX_FATAL(10 > m_lost, bgfx::Fatal::DeviceLost, "Device is lost. FAILED 0x%08x", hr); - } - else - { - m_lost = 0; - } + m_lost = isLost(hr); + BGFX_FATAL(!m_lost + , bgfx::Fatal::DeviceLost + , "Device is lost. FAILED 0x%08x %s (%s)" + , hr + , getLostReason(hr) + , DXGI_ERROR_DEVICE_REMOVED == hr ? getLostReason(m_device->GetDeviceRemovedReason() ) : "no info" + ); } } - void createIndexBuffer(IndexBufferHandle _handle, Memory* _mem, uint16_t _flags) BX_OVERRIDE + void createIndexBuffer(IndexBufferHandle _handle, Memory* _mem, uint16_t _flags) override { m_indexBuffers[_handle.idx].create(_mem->size, _mem->data, _flags, false); } - void destroyIndexBuffer(IndexBufferHandle _handle) BX_OVERRIDE + void destroyIndexBuffer(IndexBufferHandle _handle) override { m_indexBuffers[_handle.idx].destroy(); } - void createVertexDecl(VertexDeclHandle _handle, const VertexDecl& _decl) BX_OVERRIDE + void createVertexDecl(VertexDeclHandle _handle, const VertexDecl& _decl) override { VertexDecl& decl = m_vertexDecls[_handle.idx]; bx::memCopy(&decl, &_decl, sizeof(VertexDecl) ); dump(decl); } - void destroyVertexDecl(VertexDeclHandle /*_handle*/) BX_OVERRIDE + void destroyVertexDecl(VertexDeclHandle /*_handle*/) override { } - void createVertexBuffer(VertexBufferHandle _handle, Memory* _mem, VertexDeclHandle _declHandle, uint16_t _flags) BX_OVERRIDE + void createVertexBuffer(VertexBufferHandle _handle, Memory* _mem, VertexDeclHandle _declHandle, uint16_t _flags) override { m_vertexBuffers[_handle.idx].create(_mem->size, _mem->data, _declHandle, _flags); } - void destroyVertexBuffer(VertexBufferHandle _handle) BX_OVERRIDE + void destroyVertexBuffer(VertexBufferHandle _handle) override { m_vertexBuffers[_handle.idx].destroy(); } - void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint16_t _flags) BX_OVERRIDE + void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint16_t _flags) override { m_indexBuffers[_handle.idx].create(_size, NULL, _flags, false); } - void updateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem) BX_OVERRIDE + void updateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem) override { m_indexBuffers[_handle.idx].update(m_commandList, _offset, bx::uint32_min(_size, _mem->size), _mem->data); } - void destroyDynamicIndexBuffer(IndexBufferHandle _handle) BX_OVERRIDE + void destroyDynamicIndexBuffer(IndexBufferHandle _handle) override { m_indexBuffers[_handle.idx].destroy(); } - void createDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size, uint16_t _flags) BX_OVERRIDE + void createDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size, uint16_t _flags) override { VertexDeclHandle decl = BGFX_INVALID_HANDLE; m_vertexBuffers[_handle.idx].create(_size, NULL, decl, _flags); } - void updateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem) BX_OVERRIDE + void updateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem) override { m_vertexBuffers[_handle.idx].update(m_commandList, _offset, bx::uint32_min(_size, _mem->size), _mem->data); } - void destroyDynamicVertexBuffer(VertexBufferHandle _handle) BX_OVERRIDE + void destroyDynamicVertexBuffer(VertexBufferHandle _handle) override { m_vertexBuffers[_handle.idx].destroy(); } - void createShader(ShaderHandle _handle, Memory* _mem) BX_OVERRIDE + void createShader(ShaderHandle _handle, Memory* _mem) override { m_shaders[_handle.idx].create(_mem); } - void destroyShader(ShaderHandle _handle) BX_OVERRIDE + void destroyShader(ShaderHandle _handle) override { m_shaders[_handle.idx].destroy(); } - void createProgram(ProgramHandle _handle, ShaderHandle _vsh, ShaderHandle _fsh) BX_OVERRIDE + void createProgram(ProgramHandle _handle, ShaderHandle _vsh, ShaderHandle _fsh) override { m_program[_handle.idx].create(&m_shaders[_vsh.idx], isValid(_fsh) ? &m_shaders[_fsh.idx] : NULL); } - void destroyProgram(ProgramHandle _handle) BX_OVERRIDE + void destroyProgram(ProgramHandle _handle) override { m_program[_handle.idx].destroy(); } - void createTexture(TextureHandle _handle, Memory* _mem, uint32_t _flags, uint8_t _skip) BX_OVERRIDE + void createTexture(TextureHandle _handle, Memory* _mem, uint32_t _flags, uint8_t _skip) override { m_textures[_handle.idx].create(_mem, _flags, _skip); } - void updateTextureBegin(TextureHandle /*_handle*/, uint8_t /*_side*/, uint8_t /*_mip*/) BX_OVERRIDE + void updateTextureBegin(TextureHandle /*_handle*/, uint8_t /*_side*/, uint8_t /*_mip*/) override { } - void updateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) BX_OVERRIDE + void updateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) override { m_textures[_handle.idx].update(m_commandList, _side, _mip, _rect, _z, _depth, _pitch, _mem); } - void updateTextureEnd() BX_OVERRIDE + void updateTextureEnd() override { } - void readTexture(TextureHandle _handle, void* _data, uint8_t _mip ) BX_OVERRIDE + void readTexture(TextureHandle _handle, void* _data, uint8_t _mip ) override { const TextureD3D12& texture = m_textures[_handle.idx]; - D3D12_RESOURCE_DESC desc = texture.m_ptr->GetDesc(); + D3D12_RESOURCE_DESC desc = getResourceDesc(texture.m_ptr); D3D12_PLACED_SUBRESOURCE_FOOTPRINT layout; uint32_t numRows; @@ -1448,7 +1536,7 @@ namespace bgfx { namespace d3d12 uint8_t* src; readback->Map(0, NULL, (void**)&src); - const uint8_t bpp = getBitsPerPixel(TextureFormat::Enum(texture.m_textureFormat) ); + const uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(texture.m_textureFormat) ); uint8_t* dst = (uint8_t*)_data; uint32_t dstPitch = srcWidth*bpp/8; @@ -1467,7 +1555,7 @@ namespace bgfx { namespace d3d12 DX_RELEASE(readback, 0); } - void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height, uint8_t _numMips) BX_OVERRIDE + void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height, uint8_t _numMips) override { TextureD3D12& texture = m_textures[_handle.idx]; @@ -1495,35 +1583,35 @@ namespace bgfx { namespace d3d12 release(mem); } - void overrideInternal(TextureHandle _handle, uintptr_t _ptr) BX_OVERRIDE + void overrideInternal(TextureHandle _handle, uintptr_t _ptr) override { BX_UNUSED(_handle, _ptr); } - uintptr_t getInternal(TextureHandle _handle) BX_OVERRIDE + uintptr_t getInternal(TextureHandle _handle) override { BX_UNUSED(_handle); return 0; } - void destroyTexture(TextureHandle _handle) BX_OVERRIDE + void destroyTexture(TextureHandle _handle) override { m_textures[_handle.idx].destroy(); } - void createFrameBuffer(FrameBufferHandle _handle, uint8_t _num, const Attachment* _attachment) BX_OVERRIDE + void createFrameBuffer(FrameBufferHandle _handle, uint8_t _num, const Attachment* _attachment) override { m_frameBuffers[_handle.idx].create(_num, _attachment); } - void createFrameBuffer(FrameBufferHandle _handle, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _depthFormat) BX_OVERRIDE + void createFrameBuffer(FrameBufferHandle _handle, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _depthFormat) override { uint16_t denseIdx = m_numWindows++; m_windows[denseIdx] = _handle; m_frameBuffers[_handle.idx].create(denseIdx, _nwh, _width, _height, _depthFormat); } - void destroyFrameBuffer(FrameBufferHandle _handle) BX_OVERRIDE + void destroyFrameBuffer(FrameBufferHandle _handle) override { uint16_t denseIdx = m_frameBuffers[_handle.idx].destroy(); if (UINT16_MAX != denseIdx) @@ -1538,7 +1626,7 @@ namespace bgfx { namespace d3d12 } } - void createUniform(UniformHandle _handle, UniformType::Enum _type, uint16_t _num, const char* _name) BX_OVERRIDE + void createUniform(UniformHandle _handle, UniformType::Enum _type, uint16_t _num, const char* _name) override { if (NULL != m_uniforms[_handle.idx]) { @@ -1552,14 +1640,14 @@ namespace bgfx { namespace d3d12 m_uniformReg.add(_handle, _name, data); } - void destroyUniform(UniformHandle _handle) BX_OVERRIDE + void destroyUniform(UniformHandle _handle) override { BX_FREE(g_allocator, m_uniforms[_handle.idx]); m_uniforms[_handle.idx] = NULL; m_uniformReg.remove(_handle); } - void requestScreenShot(FrameBufferHandle _handle, const char* _filePath) BX_OVERRIDE + void requestScreenShot(FrameBufferHandle _handle, const char* _filePath) override { BX_UNUSED(_handle); @@ -1567,7 +1655,7 @@ namespace bgfx { namespace d3d12 m_cmd.finish(m_backBufferColorFence[idx]); ID3D12Resource* backBuffer = m_backBufferColor[idx]; - D3D12_RESOURCE_DESC desc = backBuffer->GetDesc(); + D3D12_RESOURCE_DESC desc = getResourceDesc(backBuffer); const uint32_t width = (uint32_t)desc.Width; const uint32_t height = (uint32_t)desc.Height; @@ -1606,17 +1694,18 @@ namespace bgfx { namespace d3d12 void* data; readback->Map(0, NULL, (void**)&data); - imageSwizzleBgra8( + bimg::imageSwizzleBgra8( data + , layout.Footprint.RowPitch , width , height - , (uint32_t)pitch , data + , layout.Footprint.RowPitch ); g_callback->screenShot(_filePath , width , height - , (uint32_t)pitch + , layout.Footprint.RowPitch , data , (uint32_t)total , false @@ -1626,27 +1715,59 @@ namespace bgfx { namespace d3d12 DX_RELEASE(readback, 0); } - void updateViewName(uint8_t /*_id*/, const char* /*_name*/) BX_OVERRIDE + void updateViewName(ViewId _id, const char* _name) override { + if (BX_ENABLED(BGFX_CONFIG_DEBUG_PIX) ) + { + mbstowcs(&s_viewNameW[_id][BGFX_CONFIG_MAX_VIEW_NAME_RESERVED] + , _name + , BX_COUNTOF(s_viewNameW[0])-BGFX_CONFIG_MAX_VIEW_NAME_RESERVED + ); + } + + bx::strCopy(&s_viewName[_id][BGFX_CONFIG_MAX_VIEW_NAME_RESERVED] + , BX_COUNTOF(s_viewName[0]) - BGFX_CONFIG_MAX_VIEW_NAME_RESERVED + , _name + ); } - void updateUniform(uint16_t _loc, const void* _data, uint32_t _size) BX_OVERRIDE + void updateUniform(uint16_t _loc, const void* _data, uint32_t _size) override { bx::memCopy(m_uniforms[_loc], _data, _size); } - void setMarker(const char* /*_marker*/, uint32_t /*_size*/) BX_OVERRIDE + void setMarker(const char* /*_marker*/, uint32_t /*_size*/) override { } - void invalidateOcclusionQuery(OcclusionQueryHandle _handle) BX_OVERRIDE + void invalidateOcclusionQuery(OcclusionQueryHandle _handle) override { m_occlusionQuery.invalidate(_handle); } - void submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) BX_OVERRIDE; + virtual void setName(Handle _handle, const char* _name) override + { + switch (_handle.type) + { + case Handle::Shader: +// setDebugObjectName(m_shaders[_handle.idx].m_ptr, _name); + break; + + case Handle::Texture: + setDebugObjectName(m_textures[_handle.idx].m_ptr, _name); + break; + + default: + BX_CHECK(false, "Invalid handle type?! %d", _handle.type); + break; + } + } + + void submitBlit(BlitState& _bs, uint16_t _view); - void blitSetup(TextVideoMemBlitter& _blitter) BX_OVERRIDE + void submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) override; + + void blitSetup(TextVideoMemBlitter& _blitter) override { const uint32_t width = getBufferWidth(); const uint32_t height = getBufferHeight(); @@ -1686,7 +1807,7 @@ namespace bgfx { namespace d3d12 m_commandList->SetGraphicsRootSignature(m_rootSignature); float proj[16]; - bx::mtxOrtho(proj, 0.0f, (float)width, (float)height, 0.0f, 0.0f, 1000.0f); + bx::mtxOrtho(proj, 0.0f, (float)width, (float)height, 0.0f, 0.0f, 1000.0f, 0.0f, false); PredefinedUniform& predefined = m_program[_blitter.m_program.idx].m_predefined[0]; uint8_t flags = predefined.m_type; @@ -1730,7 +1851,7 @@ namespace bgfx { namespace d3d12 m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); } - void blitRender(TextVideoMemBlitter& _blitter, uint32_t _numIndices) BX_OVERRIDE + void blitRender(TextVideoMemBlitter& _blitter, uint32_t _numIndices) override { const uint32_t numVertices = _numIndices*4/6; if (0 < numVertices) @@ -1775,7 +1896,7 @@ namespace bgfx { namespace d3d12 for (uint32_t ii = 0, num = m_scd.BufferCount; ii < num; ++ii) { - D3D12_CPU_DESCRIPTOR_HANDLE handle = m_rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); + D3D12_CPU_DESCRIPTOR_HANDLE handle = getCPUHandleHeapStart(m_rtvDescriptorHeap); handle.ptr += ii * rtvDescriptorSize; DX_CHECK(m_swapChain->GetBuffer(ii , IID_ID3D12Resource @@ -1815,7 +1936,7 @@ namespace bgfx { namespace d3d12 m_device->CreateDepthStencilView(m_backBufferDepthStencil , &dsvDesc - , m_dsvDescriptorHeap->GetCPUDescriptorHandleForHeapStart() + , getCPUHandleHeapStart(m_dsvDescriptorHeap) ); for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii) @@ -1864,7 +1985,7 @@ data.NumQualityLevels = 0; } } - void updateResolution(const Resolution& _resolution) + bool updateResolution(const Resolution& _resolution) { if (!!(_resolution.m_flags & BGFX_RESET_MAXANISOTROPY) ) { @@ -1946,6 +2067,8 @@ data.NumQualityLevels = 0; postReset(); } + + return false; } void setShaderUniform(uint8_t _flags, uint32_t _regIndex, const void* _val, uint32_t _numRegs) @@ -2024,10 +2147,10 @@ data.NumQualityLevels = 0; if (!isValid(_fbh) ) { - m_rtvHandle = m_rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); + m_rtvHandle = getCPUHandleHeapStart(m_rtvDescriptorHeap); uint32_t rtvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); m_rtvHandle.ptr += m_backBufferColorIdx * rtvDescriptorSize; - m_dsvHandle = m_dsvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); + m_dsvHandle = getCPUHandleHeapStart(m_dsvDescriptorHeap); m_currentColor = &m_rtvHandle; m_currentDepthStencil = &m_dsvHandle; @@ -2039,7 +2162,7 @@ data.NumQualityLevels = 0; if (0 < frameBuffer.m_num) { - D3D12_CPU_DESCRIPTOR_HANDLE rtvDescriptor = m_rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); + D3D12_CPU_DESCRIPTOR_HANDLE rtvDescriptor = getCPUHandleHeapStart(m_rtvDescriptorHeap); uint32_t rtvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); m_rtvHandle.ptr = rtvDescriptor.ptr + (BX_COUNTOF(m_backBufferColor) + _fbh.idx * BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) * rtvDescriptorSize; m_currentColor = &m_rtvHandle; @@ -2051,7 +2174,7 @@ data.NumQualityLevels = 0; if (isValid(frameBuffer.m_depth) ) { - D3D12_CPU_DESCRIPTOR_HANDLE dsvDescriptor = m_dsvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); + D3D12_CPU_DESCRIPTOR_HANDLE dsvDescriptor = getCPUHandleHeapStart(m_dsvDescriptorHeap); uint32_t dsvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV); m_dsvHandle.ptr = dsvDescriptor.ptr + (1 + _fbh.idx) * dsvDescriptorSize; m_currentDepthStencil = &m_dsvHandle; @@ -2243,7 +2366,7 @@ data.NumQualityLevels = 0; for (jj = 0; jj < num; ++jj) { curr = &_vertexElements[jj]; - if (0 == bx::strncmp(curr->SemanticName, "TEXCOORD") + if (0 == bx::strCmp(curr->SemanticName, "TEXCOORD") && curr->SemanticIndex == index) { break; @@ -2831,7 +2954,6 @@ data.NumQualityLevels = 0; #endif // BX_PLATFORM_WINDOWS int64_t m_presentElapsed; - uint16_t m_lost; uint16_t m_numWindows; FrameBufferHandle m_windows[BGFX_CONFIG_MAX_FRAME_BUFFERS]; @@ -2860,6 +2982,7 @@ data.NumQualityLevels = 0; Resolution m_resolution; bool m_wireframe; + bool m_lost; #if BX_PLATFORM_WINDOWS DXGI_SWAP_CHAIN_DESC m_scd; @@ -2920,7 +3043,6 @@ data.NumQualityLevels = 0; m_size = _size; ID3D12Device* device = s_renderD3D12->m_device; - m_incrementSize = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); D3D12_DESCRIPTOR_HEAP_DESC desc; @@ -2951,8 +3073,8 @@ data.NumQualityLevels = 0; void ScratchBufferD3D12::reset(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle) { m_pos = 0; - m_cpuHandle = m_heap->GetCPUDescriptorHandleForHeapStart(); - m_gpuHandle = m_heap->GetGPUDescriptorHandleForHeapStart(); + m_cpuHandle = getCPUHandleHeapStart(m_heap); + m_gpuHandle = getGPUHandleHeapStart(m_heap); _gpuHandle = m_gpuHandle; } @@ -3108,8 +3230,8 @@ data.NumQualityLevels = 0; , (void**)&m_heap ) ); - m_cpuHandle = m_heap->GetCPUDescriptorHandleForHeapStart(); - m_gpuHandle = m_heap->GetGPUDescriptorHandleForHeapStart(); + m_cpuHandle = getCPUHandleHeapStart(m_heap); + m_gpuHandle = getGPUHandleHeapStart(m_heap); } void DescriptorAllocatorD3D12::destroy() @@ -3156,7 +3278,7 @@ data.NumQualityLevels = 0; sd.AddressU = s_textureAddress[(flags&BGFX_TEXTURE_U_MASK)>>BGFX_TEXTURE_U_SHIFT]; sd.AddressV = s_textureAddress[(flags&BGFX_TEXTURE_V_MASK)>>BGFX_TEXTURE_V_SHIFT]; sd.AddressW = s_textureAddress[(flags&BGFX_TEXTURE_W_MASK)>>BGFX_TEXTURE_W_SHIFT]; - sd.MipLODBias = 0.0f; + sd.MipLODBias = float(BGFX_CONFIG_MIP_LOD_BIAS); sd.MaxAnisotropy = maxAnisotropy; sd.ComparisonFunc = 0 == cmpFunc ? D3D12_COMPARISON_FUNC_NEVER : s_cmpFunc[cmpFunc]; @@ -3673,7 +3795,7 @@ data.NumQualityLevels = 0; }; static const UavFormat s_uavFormat[] = - { // BGFX_BUFFER_COMPUTE_TYPE_UINT, BGFX_BUFFER_COMPUTE_TYPE_INT, BGFX_BUFFER_COMPUTE_TYPE_FLOAT + { // BGFX_BUFFER_COMPUTE_TYPE_INT, BGFX_BUFFER_COMPUTE_TYPE_UINT, BGFX_BUFFER_COMPUTE_TYPE_FLOAT { { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, 0 }, // ignored { { DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_UNKNOWN }, 1 }, // BGFX_BUFFER_COMPUTE_FORMAT_8x1 { { DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_UNKNOWN }, 2 }, // BGFX_BUFFER_COMPUTE_FORMAT_8x2 @@ -3929,7 +4051,7 @@ data.NumQualityLevels = 0; } } - uint16_t shaderSize; + uint32_t shaderSize; bx::read(&reader, shaderSize); const void* code = reader.getDataPtr(); @@ -3968,14 +4090,14 @@ data.NumQualityLevels = 0; void TextureD3D12::create(const Memory* _mem, uint32_t _flags, uint8_t _skip) { - ImageContainer imageContainer; + bimg::ImageContainer imageContainer; - if (imageParse(imageContainer, _mem->data, _mem->size) ) + if (bimg::imageParse(imageContainer, _mem->data, _mem->size) ) { uint8_t numMips = imageContainer.m_numMips; const uint8_t startLod = uint8_t(bx::uint32_min(_skip, numMips-1) ); numMips -= startLod; - const ImageBlockInfo& blockInfo = getBlockInfo(TextureFormat::Enum(imageContainer.m_format) ); + const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(imageContainer.m_format); const uint32_t textureWidth = bx::uint32_max(blockInfo.blockWidth, imageContainer.m_width >>startLod); const uint32_t textureHeight = bx::uint32_max(blockInfo.blockHeight, imageContainer.m_height>>startLod); const uint16_t numLayers = imageContainer.m_numLayers; @@ -3987,7 +4109,7 @@ data.NumQualityLevels = 0; m_requestedFormat = uint8_t(imageContainer.m_format); m_textureFormat = uint8_t(getViableTextureFormat(imageContainer) ); const bool convert = m_textureFormat != m_requestedFormat; - const uint8_t bpp = getBitsPerPixel(TextureFormat::Enum(m_textureFormat) ); + const uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_textureFormat) ); if (imageContainer.m_cubeMap) { @@ -4009,7 +4131,7 @@ data.NumQualityLevels = 0; uint32_t kk = 0; - const bool compressed = isCompressed(TextureFormat::Enum(m_textureFormat) ); + const bool compressed = bimg::isCompressed(bimg::TextureFormat::Enum(m_textureFormat) ); const bool swizzle = TextureFormat::BGRA8 == m_textureFormat && 0 != (m_flags&BGFX_TEXTURE_COMPUTE_WRITE); uint32_t blockWidth = 1; uint32_t blockHeight = 1; @@ -4051,8 +4173,8 @@ data.NumQualityLevels = 0; height = bx::uint32_max(blockHeight, height); depth = bx::uint32_max(1, depth); - ImageMip mip; - if (imageGetRawData(imageContainer, side, lod+startLod, _mem->data, _mem->size, mip) ) + bimg::ImageMip mip; + if (bimg::imageGetRawData(imageContainer, side, lod+startLod, _mem->data, _mem->size, mip) ) { if (convert) { @@ -4060,7 +4182,7 @@ data.NumQualityLevels = 0; const uint32_t slice = bx::strideAlign(pitch * height, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT); uint8_t* temp = (uint8_t*)BX_ALLOC(g_allocator, slice); - imageDecodeToBgra8(temp + bimg::imageDecodeToBgra8(temp , mip.m_data , mip.m_width , mip.m_height @@ -4078,7 +4200,7 @@ data.NumQualityLevels = 0; uint32_t slice = bx::strideAlign( (mip.m_height/blockInfo.blockHeight)*pitch, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT); uint8_t* temp = (uint8_t*)BX_ALLOC(g_allocator, slice); - imageCopy(temp + bimg::imageCopy(temp , mip.m_height/blockInfo.blockHeight , (mip.m_width /blockInfo.blockWidth )*mip.m_blockSize , mip.m_data @@ -4096,7 +4218,7 @@ data.NumQualityLevels = 0; const uint32_t slice = bx::strideAlign(pitch * mip.m_height, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT); uint8_t* temp = (uint8_t*)BX_ALLOC(g_allocator, slice); - imageCopy(temp + bimg::imageCopy(temp , mip.m_height , mip.m_width*mip.m_bpp / 8 , mip.m_data @@ -4109,11 +4231,6 @@ data.NumQualityLevels = 0; totalSize += slice; } - if (swizzle) - { -// imageSwizzleBgra8(temp, width, height, mip.m_width*4, data); - } - srd[kk].SlicePitch = mip.m_height*srd[kk].RowPitch; ++kk; } @@ -4160,11 +4277,10 @@ data.NumQualityLevels = 0; resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; resourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE; resourceDesc.DepthOrArraySize = numSides; - D3D12_RESOURCE_STATES state = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; D3D12_CLEAR_VALUE* clearValue = NULL; - if (isDepth(TextureFormat::Enum(m_textureFormat) ) ) + if (bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) ) ) { resourceDesc.Format = s_textureFormat[m_textureFormat].m_fmt; resourceDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; @@ -4364,11 +4480,11 @@ data.NumQualityLevels = 0; setState(_commandList, D3D12_RESOURCE_STATE_COPY_DEST); const uint32_t subres = _mip + (_side * m_numMips); - const uint32_t bpp = getBitsPerPixel(TextureFormat::Enum(m_textureFormat) ); + const uint32_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_textureFormat) ); const uint32_t rectpitch = _rect.m_width*bpp/8; const uint32_t srcpitch = UINT16_MAX == _pitch ? rectpitch : _pitch; - D3D12_RESOURCE_DESC desc = m_ptr->GetDesc(); + D3D12_RESOURCE_DESC desc = getResourceDesc(m_ptr); desc.Height = _rect.m_height; @@ -4458,14 +4574,14 @@ data.NumQualityLevels = 0; { ID3D12Device* device = s_renderD3D12->m_device; - D3D12_CPU_DESCRIPTOR_HANDLE rtvDescriptor = s_renderD3D12->m_rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); + D3D12_CPU_DESCRIPTOR_HANDLE rtvDescriptor = getCPUHandleHeapStart(s_renderD3D12->m_rtvDescriptorHeap); uint32_t rtvDescriptorSize = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); uint32_t fbhIdx = (uint32_t)(this - s_renderD3D12->m_frameBuffers); rtvDescriptor.ptr += (BX_COUNTOF(s_renderD3D12->m_backBufferColor) + fbhIdx * BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) * rtvDescriptorSize; m_width = 0; m_height = 0; - m_depth.idx = bgfx::invalidHandle; + m_depth.idx = bgfx::kInvalidHandle; m_num = 0; for (uint32_t ii = 0; ii < m_numTh; ++ii) { @@ -4476,20 +4592,20 @@ data.NumQualityLevels = 0; if (0 == m_width) { - D3D12_RESOURCE_DESC desc = texture.m_ptr->GetDesc(); + D3D12_RESOURCE_DESC desc = getResourceDesc(texture.m_ptr); m_width = uint32_t(desc.Width); m_height = uint32_t(desc.Height); } - if (isDepth( (TextureFormat::Enum)texture.m_textureFormat) ) + if (bimg::isDepth(bimg::TextureFormat::Enum(texture.m_textureFormat) ) ) { BX_CHECK(!isValid(m_depth), ""); m_depth = handle; - D3D12_CPU_DESCRIPTOR_HANDLE dsvDescriptor = s_renderD3D12->m_dsvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); + D3D12_CPU_DESCRIPTOR_HANDLE dsvDescriptor = getCPUHandleHeapStart(s_renderD3D12->m_dsvDescriptorHeap); uint32_t dsvDescriptorSize = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV); dsvDescriptor.ptr += (1 + fbhIdx) * dsvDescriptorSize; - const ImageBlockInfo& blockInfo = getBlockInfo(TextureFormat::Enum(texture.m_textureFormat) ); + const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(texture.m_textureFormat) ); BX_UNUSED(blockInfo); D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc; @@ -4525,7 +4641,7 @@ data.NumQualityLevels = 0; { m_numTh = 0; - m_depth.idx = bgfx::invalidHandle; + m_depth.idx = bgfx::kInvalidHandle; uint16_t denseIdx = m_denseIdx; m_denseIdx = UINT16_MAX; @@ -4545,7 +4661,7 @@ data.NumQualityLevels = 0; if (BGFX_CLEAR_COLOR & _clear.m_flags && 0 != m_num) { - D3D12_CPU_DESCRIPTOR_HANDLE rtvDescriptor = s_renderD3D12->m_rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); + D3D12_CPU_DESCRIPTOR_HANDLE rtvDescriptor = getCPUHandleHeapStart(s_renderD3D12->m_rtvDescriptorHeap); uint32_t rtvDescriptorSize = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); rtvDescriptor.ptr += (BX_COUNTOF(s_renderD3D12->m_backBufferColor) + fbhIdx * BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) * rtvDescriptorSize; @@ -4589,7 +4705,7 @@ data.NumQualityLevels = 0; if (isValid(m_depth) && (BGFX_CLEAR_DEPTH|BGFX_CLEAR_STENCIL) & _clear.m_flags) { - D3D12_CPU_DESCRIPTOR_HANDLE dsvDescriptor = s_renderD3D12->m_dsvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); + D3D12_CPU_DESCRIPTOR_HANDLE dsvDescriptor = getCPUHandleHeapStart(s_renderD3D12->m_dsvDescriptorHeap); uint32_t dsvDescriptorSize = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV); dsvDescriptor.ptr += (1 + fbhIdx) * dsvDescriptorSize; @@ -4614,20 +4730,28 @@ data.NumQualityLevels = 0; queryHeapDesc.NodeMask = 1; queryHeapDesc.Type = D3D12_QUERY_HEAP_TYPE_TIMESTAMP; DX_CHECK(s_renderD3D12->m_device->CreateQueryHeap(&queryHeapDesc - , IID_ID3D12QueryHeap - , (void**)&m_queryHeap - ) ); + , IID_ID3D12QueryHeap + , (void**)&m_queryHeap + ) ); const uint32_t size = queryHeapDesc.Count*sizeof(uint64_t); m_readback = createCommittedResource(s_renderD3D12->m_device - , HeapProperty::ReadBack - , size - ); + , HeapProperty::ReadBack + , size + ); DX_CHECK(s_renderD3D12->m_cmd.m_commandQueue->GetTimestampFrequency(&m_frequency) ); D3D12_RANGE range = { 0, size }; - m_readback->Map(0, &range, (void**)&m_result); + m_readback->Map(0, &range, (void**)&m_queryResult); + + for (uint32_t ii = 0; ii < BX_COUNTOF(m_result); ++ii) + { + Result& result = m_result[ii]; + result.reset(); + } + + m_control.reset(); } void TimerQueryD3D12::shutdown() @@ -4639,50 +4763,86 @@ data.NumQualityLevels = 0; DX_RELEASE(m_readback, 0); } - void TimerQueryD3D12::begin(ID3D12GraphicsCommandList* _commandList) + uint32_t TimerQueryD3D12::begin(uint32_t _resultIdx) { - BX_UNUSED(_commandList); while (0 == m_control.reserve(1) ) { m_control.consume(1); } - uint32_t offset = m_control.m_current * 2 + 0; - _commandList->EndQuery(m_queryHeap + Result& result = m_result[_resultIdx]; + ++result.m_pending; + + const uint32_t idx = m_control.m_current; + Query& query = m_query[idx]; + query.m_resultIdx = _resultIdx; + query.m_ready = false; + + ID3D12GraphicsCommandList* commandList = s_renderD3D12->m_commandList; + + uint32_t offset = idx * 2 + 0; + commandList->EndQuery(m_queryHeap , D3D12_QUERY_TYPE_TIMESTAMP , offset ); + + m_control.commit(1); + + return idx; } - void TimerQueryD3D12::end(ID3D12GraphicsCommandList* _commandList) + void TimerQueryD3D12::end(uint32_t _idx) { - BX_UNUSED(_commandList); - uint32_t offset = m_control.m_current * 2; - _commandList->EndQuery(m_queryHeap + Query& query = m_query[_idx]; + query.m_ready = true; + query.m_fence = s_renderD3D12->m_cmd.m_currentFence - 1; + uint32_t offset = _idx * 2; + + ID3D12GraphicsCommandList* commandList = s_renderD3D12->m_commandList; + + commandList->EndQuery(m_queryHeap , D3D12_QUERY_TYPE_TIMESTAMP , offset + 1 ); - _commandList->ResolveQueryData(m_queryHeap + commandList->ResolveQueryData(m_queryHeap , D3D12_QUERY_TYPE_TIMESTAMP , offset , 2 , m_readback , offset * sizeof(uint64_t) ); - m_control.commit(1); + + while (update() ) + { + } } - bool TimerQueryD3D12::get() + bool TimerQueryD3D12::update() { if (0 != m_control.available() ) { - uint32_t offset = m_control.m_read * 2; - m_begin = m_result[offset+0]; - m_end = m_result[offset+1]; - m_elapsed = m_end - m_begin; + uint32_t idx = m_control.m_read; + Query& query = m_query[idx]; + + if (!query.m_ready) + { + return false; + } + + if (query.m_fence > s_renderD3D12->m_cmd.m_completedFence) + { + return false; + } m_control.consume(1); + Result& result = m_result[query.m_resultIdx]; + --result.m_pending; + + uint32_t offset = idx * 2; + result.m_begin = m_queryResult[offset+0]; + result.m_end = m_queryResult[offset+1]; + return true; } @@ -4764,7 +4924,7 @@ data.NumQualityLevels = 0; OcclusionQueryHandle& handle = m_handle[(m_control.m_read + ii) % size]; if (handle.idx == _handle.idx) { - handle.idx = bgfx::invalidHandle; + handle.idx = bgfx::kInvalidHandle; } } } @@ -4775,16 +4935,99 @@ data.NumQualityLevels = 0; uint16_t m_samplerStateIdx; }; + void RendererContextD3D12::submitBlit(BlitState& _bs, uint16_t _view) + { + while (_bs.hasItem(_view) ) + { + const BlitItem& blit = _bs.advance(); + + const TextureD3D12& src = m_textures[blit.m_src.idx]; + const TextureD3D12& dst = m_textures[blit.m_dst.idx]; + + uint32_t srcWidth = bx::uint32_min(src.m_width, blit.m_srcX + blit.m_width) - blit.m_srcX; + uint32_t srcHeight = bx::uint32_min(src.m_height, blit.m_srcY + blit.m_height) - blit.m_srcY; + uint32_t srcDepth = bx::uint32_min(src.m_depth, blit.m_srcZ + blit.m_depth) - blit.m_srcZ; + uint32_t dstWidth = bx::uint32_min(dst.m_width, blit.m_dstX + blit.m_width) - blit.m_dstX; + uint32_t dstHeight = bx::uint32_min(dst.m_height, blit.m_dstY + blit.m_height) - blit.m_dstY; + uint32_t dstDepth = bx::uint32_min(dst.m_depth, blit.m_dstZ + blit.m_depth) - blit.m_dstZ; + uint32_t width = bx::uint32_min(srcWidth, dstWidth); + uint32_t height = bx::uint32_min(srcHeight, dstHeight); + uint32_t depth = bx::uint32_min(srcDepth, dstDepth); + + if (TextureD3D12::Texture3D == src.m_type) + { + D3D12_BOX box; + box.left = blit.m_srcX; + box.top = blit.m_srcY; + box.front = blit.m_srcZ; + box.right = blit.m_srcX + width; + box.bottom = blit.m_srcY + height;; + box.back = blit.m_srcZ + bx::uint32_imax(1, depth); + + D3D12_TEXTURE_COPY_LOCATION dstLocation = { dst.m_ptr, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, {{}} }; + D3D12_TEXTURE_COPY_LOCATION srcLocation = { src.m_ptr, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, {{}} }; + m_commandList->CopyTextureRegion(&dstLocation + , blit.m_dstX + , blit.m_dstY + , blit.m_dstZ + , &srcLocation + , &box + ); + } + else + { + D3D12_BOX box; + box.left = blit.m_srcX; + box.top = blit.m_srcY; + box.front = 0; + box.right = blit.m_srcX + width; + box.bottom = blit.m_srcY + height;; + box.back = 1; + + const uint32_t srcZ = TextureD3D12::TextureCube == src.m_type + ? blit.m_srcZ + : 0 + ; + const uint32_t dstZ = TextureD3D12::TextureCube == dst.m_type + ? blit.m_dstZ + : 0 + ; + + D3D12_TEXTURE_COPY_LOCATION dstLocation; + dstLocation.pResource = dst.m_ptr; + dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + dstLocation.SubresourceIndex = dstZ*dst.m_numMips+blit.m_dstMip; + D3D12_TEXTURE_COPY_LOCATION srcLocation; + srcLocation.pResource = src.m_ptr; + srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + srcLocation.SubresourceIndex = srcZ*src.m_numMips+blit.m_srcMip; + + bool depthStencil = bimg::isDepth(bimg::TextureFormat::Enum(src.m_textureFormat) ); + m_commandList->CopyTextureRegion(&dstLocation + , blit.m_dstX + , blit.m_dstY + , 0 + , &srcLocation + , depthStencil ? NULL : &box + ); + } + } + } + void RendererContextD3D12::submit(Frame* _render, ClearQuad& /*_clearQuad*/, TextVideoMemBlitter& _textVideoMemBlitter) { // PIX_BEGINEVENT(D3DCOLOR_FRAME, L"rendererSubmit"); - updateResolution(_render->m_resolution); + if (m_lost + || updateResolution(_render->m_resolution) ) + { + return; + } - int64_t elapsed = -bx::getHPCounter(); + int64_t timeBegin = bx::getHPCounter(); int64_t captureElapsed = 0; - m_gpuTimer.begin(m_commandList); + uint32_t frameQueryIdx = m_gpuTimer.begin(BGFX_CONFIG_MAX_VIEWS); if (0 < _render->m_iboffset) { @@ -4805,6 +5048,9 @@ data.NumQualityLevels = 0; currentState.m_stateFlags = BGFX_STATE_NONE; currentState.m_stencil = packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE); + RenderBind currentBind; + currentBind.clear(); + _render->m_hmdInitialized = false; const bool hmdEnabled = false; @@ -4814,8 +5060,8 @@ data.NumQualityLevels = 0; // bool wireframe = !!(_render->m_debug&BGFX_DEBUG_WIREFRAME); // setDebugWireframe(wireframe); - uint16_t currentSamplerStateIdx = invalidHandle; - uint16_t currentProgramIdx = invalidHandle; + uint16_t currentSamplerStateIdx = kInvalidHandle; + uint16_t currentProgramIdx = kInvalidHandle; uint32_t currentBindHash = 0; bool hasPredefined = false; bool commandListChanged = false; @@ -4824,10 +5070,7 @@ data.NumQualityLevels = 0; uint16_t view = UINT16_MAX; FrameBufferHandle fbh = { BGFX_CONFIG_MAX_FRAME_BUFFERS }; - BlitKey blitKey; - blitKey.decode(_render->m_blitKeys[0]); - uint16_t numBlitItems = _render->m_numBlitItems; - uint16_t blitItem = 0; + BlitState bs(_render); uint32_t blendFactor = 0; @@ -4847,6 +5090,12 @@ data.NumQualityLevels = 0; uint32_t statsNumIndices = 0; uint32_t statsKeyType[2] = {}; + Profiler<TimerQueryD3D12> profiler( + _render + , m_gpuTimer + , s_viewName + ); + #if BX_PLATFORM_WINDOWS m_backBufferColorIdx = m_swapChain->GetCurrentBackBufferIndex(); #endif // BX_PLATFORM_WINDOWS @@ -4876,9 +5125,9 @@ data.NumQualityLevels = 0; // uint8_t eye = 0; // uint8_t restartState = 0; - viewState.m_rect = _render->m_rect[0]; + viewState.m_rect = _render->m_view[0].m_rect; - int32_t numItems = _render->m_num; + int32_t numItems = _render->m_numRenderItems; for (int32_t item = 0, restartItem = numItems; item < numItems || restartItem < numItems;) { const uint64_t encodedKey = _render->m_sortKeys[item]; @@ -4890,7 +5139,9 @@ data.NumQualityLevels = 0; || item == numItems ; - const RenderItem& renderItem = _render->m_renderItem[_render->m_sortValues[item] ]; + const uint32_t itemIdx = _render->m_sortValues[item]; + const RenderItem& renderItem = _render->m_renderItem[itemIdx]; + const RenderBind& renderBind = _render->m_renderItemBind[itemIdx]; ++item; if (viewChanged) @@ -4900,16 +5151,23 @@ data.NumQualityLevels = 0; view = key.m_view; currentPso = NULL; - currentSamplerStateIdx = invalidHandle; - currentProgramIdx = invalidHandle; + currentSamplerStateIdx = kInvalidHandle; + currentProgramIdx = kInvalidHandle; hasPredefined = false; - fbh = _render->m_fb[view]; + fbh = _render->m_view[view].m_fbh; setFrameBuffer(fbh); - viewState.m_rect = _render->m_rect[view]; - const Rect& rect = _render->m_rect[view]; - const Rect& scissorRect = _render->m_scissor[view]; + if (item > 1) + { + profiler.end(); + } + + profiler.begin(view); + + viewState.m_rect = _render->m_view[view].m_rect; + const Rect& rect = _render->m_view[view].m_rect; + const Rect& scissorRect = _render->m_view[view].m_scissor; viewHasScissor = !scissorRect.isZero(); viewScissorRect = viewHasScissor ? scissorRect : rect; @@ -4930,7 +5188,7 @@ data.NumQualityLevels = 0; m_commandList->RSSetScissorRects(1, &rc); restoreScissor = false; - Clear& clr = _render->m_clear[view]; + Clear& clr = _render->m_view[view].m_clear; if (BGFX_CLEAR_NONE != clr.m_flags) { Rect clearRect = rect; @@ -4940,83 +5198,7 @@ data.NumQualityLevels = 0; prim = s_primInfo[BX_COUNTOF(s_primName)]; // Force primitive type update. - const uint8_t blitView = SortKey::decodeView(encodedKey); - for (; blitItem < numBlitItems && blitKey.m_view <= blitView; blitItem++) - { - const BlitItem& blit = _render->m_blitItem[blitItem]; - blitKey.decode(_render->m_blitKeys[blitItem+1]); - - const TextureD3D12& src = m_textures[blit.m_src.idx]; - const TextureD3D12& dst = m_textures[blit.m_dst.idx]; - - uint32_t srcWidth = bx::uint32_min(src.m_width, blit.m_srcX + blit.m_width) - blit.m_srcX; - uint32_t srcHeight = bx::uint32_min(src.m_height, blit.m_srcY + blit.m_height) - blit.m_srcY; - uint32_t srcDepth = bx::uint32_min(src.m_depth, blit.m_srcZ + blit.m_depth) - blit.m_srcZ; - uint32_t dstWidth = bx::uint32_min(dst.m_width, blit.m_dstX + blit.m_width) - blit.m_dstX; - uint32_t dstHeight = bx::uint32_min(dst.m_height, blit.m_dstY + blit.m_height) - blit.m_dstY; - uint32_t dstDepth = bx::uint32_min(dst.m_depth, blit.m_dstZ + blit.m_depth) - blit.m_dstZ; - uint32_t width = bx::uint32_min(srcWidth, dstWidth); - uint32_t height = bx::uint32_min(srcHeight, dstHeight); - uint32_t depth = bx::uint32_min(srcDepth, dstDepth); - - if (TextureD3D12::Texture3D == src.m_type) - { - D3D12_BOX box; - box.left = blit.m_srcX; - box.top = blit.m_srcY; - box.front = blit.m_srcZ; - box.right = blit.m_srcX + width; - box.bottom = blit.m_srcY + height;; - box.back = blit.m_srcZ + bx::uint32_imax(1, depth); - - D3D12_TEXTURE_COPY_LOCATION dstLocation = { dst.m_ptr, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, {{}} }; - D3D12_TEXTURE_COPY_LOCATION srcLocation = { src.m_ptr, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, {{}} }; - m_commandList->CopyTextureRegion(&dstLocation - , blit.m_dstX - , blit.m_dstY - , blit.m_dstZ - , &srcLocation - , &box - ); - } - else - { - D3D12_BOX box; - box.left = blit.m_srcX; - box.top = blit.m_srcY; - box.front = 0; - box.right = blit.m_srcX + width; - box.bottom = blit.m_srcY + height;; - box.back = 1; - - const uint32_t srcZ = TextureD3D12::TextureCube == src.m_type - ? blit.m_srcZ - : 0 - ; - const uint32_t dstZ = TextureD3D12::TextureCube == dst.m_type - ? blit.m_dstZ - : 0 - ; - - D3D12_TEXTURE_COPY_LOCATION dstLocation; - dstLocation.pResource = dst.m_ptr; - dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - dstLocation.SubresourceIndex = dstZ*dst.m_numMips+blit.m_dstMip; - D3D12_TEXTURE_COPY_LOCATION srcLocation; - srcLocation.pResource = src.m_ptr; - srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - srcLocation.SubresourceIndex = srcZ*src.m_numMips+blit.m_srcMip; - - bool depthStencil = isDepth(TextureFormat::Enum(src.m_textureFormat) ); - m_commandList->CopyTextureRegion(&dstLocation - , blit.m_dstX - , blit.m_dstY - , 0 - , &srcLocation - , depthStencil ? NULL : &box - ); - } - } + submitBlit(bs, view); } if (isCompute) @@ -5043,7 +5225,7 @@ data.NumQualityLevels = 0; currentBindHash = 0; } - uint32_t bindHash = bx::hashMurmur2A(compute.m_bind, sizeof(compute.m_bind) ); + uint32_t bindHash = bx::hash<bx::HashMurmur2A>(renderBind.m_bind, sizeof(renderBind.m_bind) ); if (currentBindHash != bindHash) { currentBindHash = bindHash; @@ -5056,12 +5238,13 @@ data.NumQualityLevels = 0; for (uint32_t ii = 0; ii < BGFX_MAX_COMPUTE_BINDINGS; ++ii) { - const Binding& bind = compute.m_bind[ii]; - if (invalidHandle != bind.m_idx) + const Binding& bind = renderBind.m_bind[ii]; + if (kInvalidHandle != bind.m_idx) { switch (bind.m_type) { case Binding::Image: + case Binding::Texture: { TextureD3D12& texture = m_textures[bind.m_idx]; @@ -5132,10 +5315,10 @@ data.NumQualityLevels = 0; } bool constantsChanged = false; - if (compute.m_constBegin < compute.m_constEnd + if (compute.m_uniformBegin < compute.m_uniformEnd || currentProgramIdx != key.m_program) { - rendererUpdateUniforms(this, _render->m_uniformBuffer, compute.m_constBegin, compute.m_constEnd); + rendererUpdateUniforms(this, _render->m_uniformBuffer[compute.m_uniformIdx], compute.m_uniformBegin, compute.m_uniformEnd); currentProgramIdx = key.m_program; ProgramD3D12& program = m_program[currentProgramIdx]; @@ -5234,8 +5417,8 @@ data.NumQualityLevels = 0; currentPso = NULL; currentBindHash = 0; - currentSamplerStateIdx = invalidHandle; - currentProgramIdx = invalidHandle; + currentSamplerStateIdx = kInvalidHandle; + currentProgramIdx = kInvalidHandle; currentState.clear(); currentState.m_scissor = !draw.m_scissor; changedFlags = BGFX_STATE_MASK; @@ -5243,11 +5426,13 @@ data.NumQualityLevels = 0; currentState.m_stateFlags = newFlags; currentState.m_stencil = newStencil; + currentBind.clear(); + const uint64_t pt = newFlags&BGFX_STATE_PT_MASK; primIndex = uint8_t(pt>>BGFX_STATE_PT_SHIFT); } - rendererUpdateUniforms(this, _render->m_uniformBuffer, draw.m_constBegin, draw.m_constEnd); + rendererUpdateUniforms(this, _render->m_uniformBuffer[draw.m_uniformIdx], draw.m_uniformBegin, draw.m_uniformEnd); if (isValid(draw.m_stream[0].m_handle) ) { @@ -5271,7 +5456,7 @@ data.NumQualityLevels = 0; ); uint16_t scissor = draw.m_scissor; - uint32_t bindHash = bx::hashMurmur2A(draw.m_bind, sizeof(draw.m_bind) ); + uint32_t bindHash = bx::hash<bx::HashMurmur2A>(renderBind.m_bind, sizeof(renderBind.m_bind) ); if (currentBindHash != bindHash || 0 != changedStencil || (hasFactor && blendFactor != draw.m_rgba) @@ -5297,17 +5482,47 @@ data.NumQualityLevels = 0; srvHandle[0].ptr = 0; for (uint32_t stage = 0; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++stage) { - const Binding& bind = draw.m_bind[stage]; - if (invalidHandle != bind.m_idx) + const Binding& bind = renderBind.m_bind[stage]; + if (kInvalidHandle != bind.m_idx) { - TextureD3D12& texture = m_textures[bind.m_idx]; - texture.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); - scratchBuffer.allocSrv(srvHandle[stage], texture); - samplerFlags[stage] = (0 == (BGFX_TEXTURE_INTERNAL_DEFAULT_SAMPLER & bind.m_un.m_draw.m_textureFlags) - ? bind.m_un.m_draw.m_textureFlags - : texture.m_flags - ) & (BGFX_TEXTURE_SAMPLER_BITS_MASK|BGFX_TEXTURE_BORDER_COLOR_MASK) - ; + switch (bind.m_type) + { + case Binding::Texture: + { + TextureD3D12& texture = m_textures[bind.m_idx]; + texture.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); + scratchBuffer.allocSrv(srvHandle[stage], texture); + samplerFlags[stage] = (0 == (BGFX_TEXTURE_INTERNAL_DEFAULT_SAMPLER & bind.m_un.m_draw.m_textureFlags) + ? bind.m_un.m_draw.m_textureFlags + : texture.m_flags + ) & (BGFX_TEXTURE_SAMPLER_BITS_MASK | BGFX_TEXTURE_BORDER_COLOR_MASK) + ; + } + break; + + case Binding::IndexBuffer: + case Binding::VertexBuffer: + { + BufferD3D12& buffer = Binding::IndexBuffer == bind.m_type + ? m_indexBuffers[bind.m_idx] + : m_vertexBuffers[bind.m_idx] + ; + + if (Access::Read != bind.m_un.m_compute.m_access) + { + // The api functions prevent binding with Access::Write, + // but might as well allow it in here for future-proofing + buffer.setState(m_commandList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + scratchBuffer.allocUav(srvHandle[stage], buffer); + } + else + { + buffer.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); + scratchBuffer.allocSrv(srvHandle[stage], buffer); + } + } + break; + } } else { @@ -5397,7 +5612,7 @@ data.NumQualityLevels = 0; { restoreScissor = true; Rect scissorRect; - scissorRect.setIntersect(viewScissorRect,_render->m_rectCache.m_cache[scissor]); + scissorRect.setIntersect(viewScissorRect, _render->m_frameCache.m_rectCache.m_cache[scissor]); if (scissorRect.isZeroArea() ) { continue; @@ -5419,7 +5634,7 @@ data.NumQualityLevels = 0; } bool constantsChanged = false; - if (draw.m_constBegin < draw.m_constEnd + if (draw.m_uniformBegin < draw.m_uniformEnd || currentProgramIdx != key.m_program || BGFX_STATE_ALPHA_REF_MASK & changedFlags) { @@ -5471,18 +5686,27 @@ data.NumQualityLevels = 0; } m_batch.end(m_commandList); - } + kick(); - int64_t now = bx::getHPCounter(); - elapsed += now; + submitBlit(bs, BGFX_CONFIG_MAX_VIEWS); + + if (0 < _render->m_numRenderItems) + { + if (0 != (m_resolution.m_flags & BGFX_RESET_FLUSH_AFTER_RENDER) ) + { +// deviceCtx->Flush(); + } - static int64_t last = now; +// captureElapsed = -bx::getHPCounter(); +// capture(); +// captureElapsed += bx::getHPCounter(); - Stats& perfStats = _render->m_perfStats; - perfStats.cpuTimeBegin = last; + profiler.end(); + } + } - int64_t frameTime = now - last; - last = now; + int64_t timeEnd = bx::getHPCounter(); + int64_t frameTime = timeEnd - timeBegin; static int64_t min = frameTime; static int64_t max = frameTime; @@ -5498,28 +5722,44 @@ data.NumQualityLevels = 0; presentMin = bx::int64_min(presentMin, m_presentElapsed); presentMax = bx::int64_max(presentMax, m_presentElapsed); - m_gpuTimer.end(m_commandList); - - do + if (UINT32_MAX != frameQueryIdx) { + m_gpuTimer.end(frameQueryIdx); + + const TimerQueryD3D12::Result& result = m_gpuTimer.m_result[BGFX_CONFIG_MAX_VIEWS]; double toGpuMs = 1000.0 / double(m_gpuTimer.m_frequency); - elapsedGpuMs = m_gpuTimer.m_elapsed * toGpuMs; + elapsedGpuMs = (result.m_end - result.m_begin) * toGpuMs; maxGpuElapsed = elapsedGpuMs > maxGpuElapsed ? elapsedGpuMs : maxGpuElapsed; + + maxGpuLatency = bx::uint32_imax(maxGpuLatency, result.m_pending-1); } - while (m_gpuTimer.get() ); maxGpuLatency = bx::uint32_imax(maxGpuLatency, m_gpuTimer.m_control.available()-1); const int64_t timerFreq = bx::getHPFrequency(); - perfStats.cpuTimeEnd = now; + Stats& perfStats = _render->m_perfStats; + perfStats.cpuTimeBegin = timeBegin; + perfStats.cpuTimeEnd = timeEnd; perfStats.cpuTimerFreq = timerFreq; - perfStats.gpuTimeBegin = m_gpuTimer.m_begin; - perfStats.gpuTimeEnd = m_gpuTimer.m_end; + const TimerQueryD3D12::Result& result = m_gpuTimer.m_result[BGFX_CONFIG_MAX_VIEWS]; + perfStats.gpuTimeBegin = result.m_begin; + perfStats.gpuTimeEnd = result.m_end; perfStats.gpuTimerFreq = m_gpuTimer.m_frequency; perfStats.numDraw = statsKeyType[0]; perfStats.numCompute = statsKeyType[1]; perfStats.maxGpuLatency = maxGpuLatency; + perfStats.gpuMemoryMax = -INT64_MAX; + perfStats.gpuMemoryUsed = -INT64_MAX; + +#if BX_PLATFORM_WINDOWS + DXGI_QUERY_VIDEO_MEMORY_INFO vmi[2]; + DX_CHECK(m_adapter->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &vmi[0]) ); + DX_CHECK(m_adapter->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &vmi[1]) ); + + perfStats.gpuMemoryMax = int64_t(vmi[0].Budget); + perfStats.gpuMemoryUsed = int64_t(vmi[0].CurrentUsage); +#endif // BX_PLATFORM_WINDOWS if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) ) { @@ -5528,12 +5768,13 @@ data.NumQualityLevels = 0; // m_needPresent = true; TextVideoMem& tvm = m_textVideoMem; - static int64_t next = now; + static int64_t next = timeEnd; - if (now >= next) + if (timeEnd >= next) { - next = now + bx::getHPFrequency(); - double freq = double(bx::getHPFrequency() ); + next = timeEnd + timerFreq; + + double freq = double(timerFreq); double toMs = 1000.0 / freq; tvm.clear(); @@ -5570,10 +5811,6 @@ data.NumQualityLevels = 0; ); #if BX_PLATFORM_WINDOWS - DXGI_QUERY_VIDEO_MEMORY_INFO vmi[2]; - DX_CHECK(m_adapter->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &vmi[0]) ); - DX_CHECK(m_adapter->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &vmi[1]) ); - for (uint32_t ii = 0; ii < BX_COUNTOF(vmi); ++ii) { const DXGI_QUERY_VIDEO_MEMORY_INFO& memInfo = vmi[ii]; @@ -5625,9 +5862,9 @@ data.NumQualityLevels = 0; , !!(m_resolution.m_flags&BGFX_RESET_MAXANISOTROPY) ? '\xfe' : ' ' ); - double elapsedCpuMs = double(elapsed)*toMs; + double elapsedCpuMs = double(frameTime)*toMs; tvm.printf(10, pos++, 0x8e, " Submitted: %5d (draw %5d, compute %4d) / CPU %7.4f [ms] " - , _render->m_num + , _render->m_numRenderItems , statsKeyType[0] , statsKeyType[1] , elapsedCpuMs @@ -5661,7 +5898,7 @@ data.NumQualityLevels = 0; } tvm.printf(10, pos++, 0x8e, " Indices: %7d ", statsNumIndices); - tvm.printf(10, pos++, 0x8e, " Uniform size: %7d, Max: %7d ", _render->m_uniformEnd, _render->m_uniformMax); +// tvm.printf(10, pos++, 0x8e, " Uniform size: %7d, Max: %7d ", _render->m_uniformEnd, _render->m_uniformMax); tvm.printf(10, pos++, 0x8e, " DVB size: %7d ", _render->m_vboffset); tvm.printf(10, pos++, 0x8e, " DIB size: %7d ", _render->m_iboffset); |