diff options
Diffstat (limited to '3rdparty/bgfx/src/renderer_d3d9.cpp')
-rw-r--r-- | 3rdparty/bgfx/src/renderer_d3d9.cpp | 620 |
1 files changed, 399 insertions, 221 deletions
diff --git a/3rdparty/bgfx/src/renderer_d3d9.cpp b/3rdparty/bgfx/src/renderer_d3d9.cpp index 0406f33eb2f..d14956ab49d 100644 --- a/3rdparty/bgfx/src/renderer_d3d9.cpp +++ b/3rdparty/bgfx/src/renderer_d3d9.cpp @@ -148,31 +148,12 @@ namespace bgfx { namespace d3d9 D3DCULL_CCW, }; - static const D3DFORMAT s_checkColorFormats[] = - { - D3DFMT_UNKNOWN, - D3DFMT_A8R8G8B8, D3DFMT_UNKNOWN, - D3DFMT_R32F, D3DFMT_R16F, D3DFMT_G16R16, D3DFMT_A8R8G8B8, D3DFMT_UNKNOWN, - - D3DFMT_UNKNOWN, // terminator - }; - - static D3DFORMAT s_colorFormat[] = - { - D3DFMT_UNKNOWN, // ignored - D3DFMT_A8R8G8B8, - D3DFMT_A2B10G10R10, - D3DFMT_A16B16G16R16, - D3DFMT_A16B16G16R16F, - D3DFMT_R16F, - D3DFMT_R32F, - }; - static const D3DTEXTUREADDRESS s_textureAddress[] = { D3DTADDRESS_WRAP, D3DTADDRESS_MIRROR, D3DTADDRESS_CLAMP, + D3DTADDRESS_BORDER, }; static const D3DTEXTUREFILTERTYPE s_textureFilter[] = @@ -208,21 +189,44 @@ namespace bgfx { namespace d3d9 { D3DFMT_UNKNOWN }, // PTC24 { D3DFMT_UNKNOWN }, // Unknown { D3DFMT_A1 }, // R1 + { D3DFMT_A8 }, // A8 { D3DFMT_L8 }, // R8 - { D3DFMT_G16R16 }, // R16 + { D3DFMT_UNKNOWN }, // R8I + { D3DFMT_UNKNOWN }, // R8U + { D3DFMT_UNKNOWN }, // R8S + { D3DFMT_L16 }, // R16 + { D3DFMT_UNKNOWN }, // R16I + { D3DFMT_UNKNOWN }, // R16U { D3DFMT_R16F }, // R16F - { D3DFMT_UNKNOWN }, // R32 + { D3DFMT_UNKNOWN }, // R16S + { D3DFMT_UNKNOWN }, // R32I + { D3DFMT_UNKNOWN }, // R32U { D3DFMT_R32F }, // R32F { D3DFMT_A8L8 }, // RG8 + { D3DFMT_UNKNOWN }, // RG8I + { D3DFMT_UNKNOWN }, // RG8U + { D3DFMT_UNKNOWN }, // RG8S { D3DFMT_G16R16 }, // RG16 + { D3DFMT_UNKNOWN }, // RG16I + { D3DFMT_UNKNOWN }, // RG16U { D3DFMT_G16R16F }, // RG16F - { D3DFMT_UNKNOWN }, // RG32 + { D3DFMT_UNKNOWN }, // RG16S + { D3DFMT_UNKNOWN }, // RG32I + { D3DFMT_UNKNOWN }, // RG32U { D3DFMT_G32R32F }, // RG32F + { D3DFMT_UNKNOWN }, // RGB9E5F { D3DFMT_A8R8G8B8 }, // BGRA8 { D3DFMT_UNKNOWN }, // RGBA8 + { D3DFMT_UNKNOWN }, // RGBA8I + { D3DFMT_UNKNOWN }, // RGBA8U + { D3DFMT_UNKNOWN }, // RGBA8S { D3DFMT_A16B16G16R16 }, // RGBA16 + { D3DFMT_UNKNOWN }, // RGBA16I + { D3DFMT_UNKNOWN }, // RGBA16U { D3DFMT_A16B16G16R16F }, // RGBA16F - { D3DFMT_UNKNOWN }, // RGBA32 + { D3DFMT_UNKNOWN }, // RGBA16S + { D3DFMT_UNKNOWN }, // RGBA32I + { D3DFMT_UNKNOWN }, // RGBA32U { D3DFMT_A32B32G32R32F }, // RGBA32F { D3DFMT_R5G6B5 }, // R5G6B5 { D3DFMT_A4R4G4B4 }, // RGBA4 @@ -282,7 +286,8 @@ namespace bgfx { namespace d3d9 , m_initialized(false) , m_amd(false) , m_nvidia(false) - , m_instancing(false) + , m_instancingSupport(false) + , m_timerQuerySupport(false) , m_rtMsaa(false) { } @@ -291,8 +296,21 @@ namespace bgfx { namespace d3d9 { } - void init() + bool init() { + struct ErrorState + { + enum Enum + { + Default, + LoadedD3D9, + CreatedD3D9, + CreatedDevice, + }; + }; + + ErrorState::Enum errorState = ErrorState::Default; + m_fbh.idx = invalidHandle; memset(m_uniforms, 0, sizeof(m_uniforms) ); memset(&m_resolution, 0, sizeof(m_resolution) ); @@ -319,11 +337,18 @@ namespace bgfx { namespace d3d9 RECT rect; GetWindowRect( (HWND)g_platformData.nwh, &rect); - m_params.BackBufferWidth = rect.right-rect.left; + m_params.BackBufferWidth = rect.right-rect.left; m_params.BackBufferHeight = rect.bottom-rect.top; m_d3d9dll = bx::dlopen("d3d9.dll"); - BGFX_FATAL(NULL != m_d3d9dll, Fatal::UnableToInitialize, "Failed to load d3d9.dll."); + BX_WARN(NULL != m_d3d9dll, "Failed to load d3d9.dll."); + + if (NULL == m_d3d9dll) + { + goto error; + } + + errorState = ErrorState::LoadedD3D9; if (BX_ENABLED(BGFX_CONFIG_DEBUG_PIX) ) { @@ -351,79 +376,93 @@ namespace bgfx { namespace d3d9 #endif // BGFX_CONFIG_RENDERER_DIRECT3D9EX { Direct3DCreate9 = (Direct3DCreate9Fn)bx::dlsym(m_d3d9dll, "Direct3DCreate9"); - BGFX_FATAL(NULL != Direct3DCreate9, Fatal::UnableToInitialize, "Function Direct3DCreate9 not found."); + BX_WARN(NULL != Direct3DCreate9, "Function Direct3DCreate9 not found."); + + if (NULL == Direct3DCreate9) + { + goto error; + } + m_d3d9 = Direct3DCreate9(D3D_SDK_VERSION); m_pool = D3DPOOL_MANAGED; } - BGFX_FATAL(m_d3d9, Fatal::UnableToInitialize, "Unable to create Direct3D."); + BX_WARN(NULL != m_d3d9, "Unable to create Direct3D."); - m_adapter = D3DADAPTER_DEFAULT; - m_deviceType = BGFX_PCI_ID_SOFTWARE_RASTERIZER == g_caps.vendorId - ? D3DDEVTYPE_REF - : D3DDEVTYPE_HAL - ; - - uint8_t numGPUs = uint8_t(bx::uint32_min(BX_COUNTOF(g_caps.gpu), m_d3d9->GetAdapterCount() ) ); - for (uint32_t ii = 0; ii < numGPUs; ++ii) + if (NULL == m_d3d9) { - D3DADAPTER_IDENTIFIER9 desc; - HRESULT hr = m_d3d9->GetAdapterIdentifier(ii, 0, &desc); - if (SUCCEEDED(hr) ) - { - BX_TRACE("Adapter #%d", ii); - BX_TRACE("\tDriver: %s", desc.Driver); - BX_TRACE("\tDescription: %s", desc.Description); - BX_TRACE("\tDeviceName: %s", desc.DeviceName); - BX_TRACE("\tVendorId: 0x%08x, DeviceId: 0x%08x, SubSysId: 0x%08x, Revision: 0x%08x" - , desc.VendorId - , desc.DeviceId - , desc.SubSysId - , desc.Revision - ); + goto error; + } - g_caps.gpu[ii].vendorId = (uint16_t)desc.VendorId; - g_caps.gpu[ii].deviceId = (uint16_t)desc.DeviceId; + errorState = ErrorState::CreatedD3D9; - if (D3DADAPTER_DEFAULT == m_adapter) + { + m_adapter = D3DADAPTER_DEFAULT; + m_deviceType = BGFX_PCI_ID_SOFTWARE_RASTERIZER == g_caps.vendorId + ? D3DDEVTYPE_REF + : D3DDEVTYPE_HAL + ; + + uint8_t numGPUs = uint8_t(bx::uint32_min(BX_COUNTOF(g_caps.gpu), m_d3d9->GetAdapterCount() ) ); + for (uint32_t ii = 0; ii < numGPUs; ++ii) + { + D3DADAPTER_IDENTIFIER9 desc; + HRESULT hr = m_d3d9->GetAdapterIdentifier(ii, 0, &desc); + if (SUCCEEDED(hr) ) { - if ( (BGFX_PCI_ID_NONE != g_caps.vendorId || 0 != g_caps.deviceId) - && (BGFX_PCI_ID_NONE == g_caps.vendorId || desc.VendorId == g_caps.vendorId) - && ( 0 == g_caps.deviceId || desc.DeviceId == g_caps.deviceId) ) + BX_TRACE("Adapter #%d", ii); + BX_TRACE("\tDriver: %s", desc.Driver); + BX_TRACE("\tDescription: %s", desc.Description); + BX_TRACE("\tDeviceName: %s", desc.DeviceName); + BX_TRACE("\tVendorId: 0x%08x, DeviceId: 0x%08x, SubSysId: 0x%08x, Revision: 0x%08x" + , desc.VendorId + , desc.DeviceId + , desc.SubSysId + , desc.Revision + ); + + g_caps.gpu[ii].vendorId = (uint16_t)desc.VendorId; + g_caps.gpu[ii].deviceId = (uint16_t)desc.DeviceId; + + if (D3DADAPTER_DEFAULT == m_adapter) { - m_adapter = ii; - } + if ( (BGFX_PCI_ID_NONE != g_caps.vendorId || 0 != g_caps.deviceId) + && (BGFX_PCI_ID_NONE == g_caps.vendorId || desc.VendorId == g_caps.vendorId) + && ( 0 == g_caps.deviceId || desc.DeviceId == g_caps.deviceId) ) + { + m_adapter = ii; + } - if (BX_ENABLED(BGFX_CONFIG_DEBUG_PERFHUD) - && 0 != strstr(desc.Description, "PerfHUD")) - { - m_adapter = ii; - m_deviceType = D3DDEVTYPE_REF; + if (BX_ENABLED(BGFX_CONFIG_DEBUG_PERFHUD) + && 0 != strstr(desc.Description, "PerfHUD") ) + { + m_adapter = ii; + m_deviceType = D3DDEVTYPE_REF; + } } } } - } - DX_CHECK(m_d3d9->GetAdapterIdentifier(m_adapter, 0, &m_identifier) ); - m_amd = m_identifier.VendorId == BGFX_PCI_ID_AMD; - m_nvidia = m_identifier.VendorId == BGFX_PCI_ID_NVIDIA; - g_caps.vendorId = 0 == m_identifier.VendorId - ? BGFX_PCI_ID_SOFTWARE_RASTERIZER - : (uint16_t)m_identifier.VendorId - ; - g_caps.deviceId = (uint16_t)m_identifier.DeviceId; + DX_CHECK(m_d3d9->GetAdapterIdentifier(m_adapter, 0, &m_identifier) ); + m_amd = m_identifier.VendorId == BGFX_PCI_ID_AMD; + m_nvidia = m_identifier.VendorId == BGFX_PCI_ID_NVIDIA; + g_caps.vendorId = 0 == m_identifier.VendorId + ? BGFX_PCI_ID_SOFTWARE_RASTERIZER + : (uint16_t)m_identifier.VendorId + ; + g_caps.deviceId = (uint16_t)m_identifier.DeviceId; - uint32_t behaviorFlags[] = - { - D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE | D3DCREATE_PUREDEVICE, - D3DCREATE_MIXED_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, - D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, - }; + uint32_t behaviorFlags[] = + { + D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE | D3DCREATE_PUREDEVICE, + D3DCREATE_MIXED_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, + D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, + }; - for (uint32_t ii = 0; ii < BX_COUNTOF(behaviorFlags) && NULL == m_device; ++ii) - { + for (uint32_t ii = 0; ii < BX_COUNTOF(behaviorFlags) && NULL == m_device; ++ii) + { #if 0 // BGFX_CONFIG_RENDERER_DIRECT3D9EX - DX_CHECK(m_d3d9->CreateDeviceEx(m_adapter + DX_CHECK(m_d3d9->CreateDeviceEx(m_adapter , m_deviceType , g_platformHooks.nwh , behaviorFlags[ii] @@ -432,17 +471,25 @@ namespace bgfx { namespace d3d9 , &m_device ) ); #else - DX_CHECK(m_d3d9->CreateDevice(m_adapter - , m_deviceType - , (HWND)g_platformData.nwh - , behaviorFlags[ii] - , &m_params - , &m_device - ) ); + DX_CHECK(m_d3d9->CreateDevice(m_adapter + , m_deviceType + , (HWND)g_platformData.nwh + , behaviorFlags[ii] + , &m_params + , &m_device + )); #endif // BGFX_CONFIG_RENDERER_DIRECT3D9EX + } + } + + BX_WARN(NULL != m_device, "Unable to create Direct3D9 device."); + + if (NULL == m_device) + { + goto error; } - BGFX_FATAL(m_device, Fatal::UnableToInitialize, "Unable to create Direct3D9 device."); + errorState = ErrorState::CreatedDevice; m_numWindows = 1; @@ -456,15 +503,23 @@ namespace bgfx { namespace d3d9 DX_CHECK(m_device->GetDeviceCaps(&m_caps) ); // For shit GPUs that can create DX9 device but can't do simple stuff. GTFO! - BGFX_FATAL( (D3DPTEXTURECAPS_SQUAREONLY & m_caps.TextureCaps) == 0, Fatal::MinimumRequiredSpecs, "D3DPTEXTURECAPS_SQUAREONLY"); - BGFX_FATAL( (D3DPTEXTURECAPS_MIPMAP & m_caps.TextureCaps) == D3DPTEXTURECAPS_MIPMAP, Fatal::MinimumRequiredSpecs, "D3DPTEXTURECAPS_MIPMAP"); - BGFX_FATAL( (D3DPTEXTURECAPS_ALPHA & m_caps.TextureCaps) == D3DPTEXTURECAPS_ALPHA, Fatal::MinimumRequiredSpecs, "D3DPTEXTURECAPS_ALPHA"); - BGFX_FATAL(m_caps.VertexShaderVersion >= D3DVS_VERSION(2, 0) && m_caps.PixelShaderVersion >= D3DPS_VERSION(2, 1) - , Fatal::MinimumRequiredSpecs + BX_WARN( (D3DPTEXTURECAPS_SQUAREONLY & m_caps.TextureCaps) == 0, "D3DPTEXTURECAPS_SQUAREONLY"); + BX_WARN( (D3DPTEXTURECAPS_MIPMAP & m_caps.TextureCaps) == D3DPTEXTURECAPS_MIPMAP, "D3DPTEXTURECAPS_MIPMAP"); + BX_WARN( (D3DPTEXTURECAPS_ALPHA & m_caps.TextureCaps) == D3DPTEXTURECAPS_ALPHA, "D3DPTEXTURECAPS_ALPHA"); + BX_WARN(m_caps.VertexShaderVersion >= D3DVS_VERSION(2, 0) && m_caps.PixelShaderVersion >= D3DPS_VERSION(2, 1) , "Shader Model Version (vs: %x, ps: %x)." , m_caps.VertexShaderVersion , m_caps.PixelShaderVersion ); + + if ( (D3DPTEXTURECAPS_SQUAREONLY & m_caps.TextureCaps) != 0 + || (D3DPTEXTURECAPS_MIPMAP & m_caps.TextureCaps) != D3DPTEXTURECAPS_MIPMAP + || (D3DPTEXTURECAPS_ALPHA & m_caps.TextureCaps) != D3DPTEXTURECAPS_ALPHA + || !(m_caps.VertexShaderVersion >= D3DVS_VERSION(2, 0) && m_caps.PixelShaderVersion >= D3DPS_VERSION(2, 1) ) ) + { + goto error; + } + BX_TRACE("Max vertex shader 3.0 instr. slots: %d", m_caps.MaxVertexShader30InstructionSlots); BX_TRACE("Max vertex shader constants: %d", m_caps.MaxVertexShaderConst); BX_TRACE("Max fragment shader 2.0 instr. slots: %d", m_caps.PS20Caps.NumInstructionSlots); @@ -476,6 +531,7 @@ namespace bgfx { namespace d3d9 | BGFX_CAPS_TEXTURE_3D | BGFX_CAPS_TEXTURE_COMPARE_LEQUAL | BGFX_CAPS_VERTEX_ATTRIB_HALF + | BGFX_CAPS_VERTEX_ATTRIB_UINT10 | BGFX_CAPS_FRAGMENT_DEPTH | BGFX_CAPS_SWAP_CHAIN | ( (UINT16_MAX < m_caps.MaxVertexIndex) ? BGFX_CAPS_INDEX32 : 0) @@ -486,7 +542,7 @@ namespace bgfx { namespace d3d9 m_caps.NumSimultaneousRTs = uint8_t(bx::uint32_min(m_caps.NumSimultaneousRTs, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) ); g_caps.maxFBAttachments = uint8_t(m_caps.NumSimultaneousRTs); - m_caps.MaxAnisotropy = bx::uint32_min(m_caps.MaxAnisotropy, 1); + m_caps.MaxAnisotropy = bx::uint32_max(m_caps.MaxAnisotropy, 1); if (BX_ENABLED(BGFX_CONFIG_RENDERER_USE_EXTENSIONS) ) { @@ -500,7 +556,7 @@ namespace bgfx { namespace d3d9 BX_UNUSED(fourcc); } - m_instancing = false + m_instancingSupport = false || s_extendedFormats[ExtendedFormat::Inst].m_supported || (m_caps.VertexShaderVersion >= D3DVS_VERSION(3, 0) ) ; @@ -520,7 +576,7 @@ namespace bgfx { namespace d3d9 s_textureFormat[TextureFormat::BC4].m_fmt = s_extendedFormats[ExtendedFormat::Ati1].m_supported ? D3DFMT_ATI1 : D3DFMT_UNKNOWN; s_textureFormat[TextureFormat::BC5].m_fmt = s_extendedFormats[ExtendedFormat::Ati2].m_supported ? D3DFMT_ATI2 : D3DFMT_UNKNOWN; - g_caps.supported |= m_instancing ? BGFX_CAPS_INSTANCING : 0; + g_caps.supported |= m_instancingSupport ? BGFX_CAPS_INSTANCING : 0; for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii) { @@ -556,23 +612,16 @@ namespace bgfx { namespace d3d9 , s_textureFormat[ii].m_fmt ) ) ? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER : BGFX_CAPS_FORMAT_TEXTURE_NONE; - g_caps.formats[ii] = support; - } - } + support |= SUCCEEDED(m_d3d9->CheckDeviceMultiSampleType(m_adapter + , m_deviceType + , s_textureFormat[ii].m_fmt + , true + , D3DMULTISAMPLE_2_SAMPLES + , NULL + ) ) ? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA : BGFX_CAPS_FORMAT_TEXTURE_NONE; - uint32_t index = 1; - for (const D3DFORMAT* fmt = &s_checkColorFormats[index]; *fmt != D3DFMT_UNKNOWN; ++fmt, ++index) - { - for (; *fmt != D3DFMT_UNKNOWN; ++fmt) - { - if (SUCCEEDED(m_d3d9->CheckDeviceFormat(m_adapter, m_deviceType, adapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, *fmt) ) ) - { - s_colorFormat[index] = *fmt; - break; - } + g_caps.formats[ii] = support; } - - for (; *fmt != D3DFMT_UNKNOWN; ++fmt); } m_fmtDepth = D3DFMT_D24S8; @@ -609,6 +658,18 @@ namespace bgfx { namespace d3d9 #endif // BX_PLATFORM_WINDOWS { + IDirect3DQuery9* timerQueryTest[3] = {}; + m_timerQuerySupport = true + && SUCCEEDED(m_device->CreateQuery(D3DQUERYTYPE_TIMESTAMPDISJOINT, &timerQueryTest[0]) ) + && SUCCEEDED(m_device->CreateQuery(D3DQUERYTYPE_TIMESTAMP, &timerQueryTest[1]) ) + && SUCCEEDED(m_device->CreateQuery(D3DQUERYTYPE_TIMESTAMPFREQ, &timerQueryTest[2]) ) + ; + DX_RELEASE(timerQueryTest[0], 0); + DX_RELEASE(timerQueryTest[1], 0); + DX_RELEASE(timerQueryTest[2], 0); + } + + { IDirect3DSwapChain9* swapChain; DX_CHECK(m_device->GetSwapChain(0, &swapChain) ); @@ -632,6 +693,48 @@ namespace bgfx { namespace d3d9 postReset(); m_initialized = true; + + return true; + + error: + switch (errorState) + { + case ErrorState::CreatedDevice: +#if BGFX_CONFIG_RENDERER_DIRECT3D9EX + if (NULL != m_d3d9ex) + { + DX_RELEASE(m_deviceEx, 1); + DX_RELEASE(m_device, 0); + } + else +#endif // BGFX_CONFIG_RENDERER_DIRECT3D9EX + { + DX_RELEASE(m_device, 0); + } + + case ErrorState::CreatedD3D9: +#if BGFX_CONFIG_RENDERER_DIRECT3D9EX + if (NULL != m_d3d9ex) + { + DX_RELEASE(m_d3d9, 1); + DX_RELEASE(m_d3d9ex, 0); + } + else +#endif // BGFX_CONFIG_RENDERER_DIRECT3D9EX + { + DX_RELEASE(m_d3d9, 0); + } + +#if BX_PLATFORM_WINDOWS + case ErrorState::LoadedD3D9: + bx::dlclose(m_d3d9dll); +#endif // BX_PLATFORM_WINDOWS + + case ErrorState::Default: + break; + } + + return false; } void shutdown() @@ -981,7 +1084,7 @@ namespace bgfx { namespace d3d9 uint8_t flags = predefined.m_type; setShaderUniform(flags, predefined.m_loc, proj, 4); - m_textures[_blitter.m_texture.idx].commit(0); + m_textures[_blitter.m_texture.idx].commit(0, BGFX_SAMPLER_DEFAULT_FLAGS, NULL); } void blitRender(TextVideoMemBlitter& _blitter, uint32_t _numIndices) BX_OVERRIDE @@ -1095,7 +1198,7 @@ namespace bgfx { namespace d3d9 } DX_CHECK(m_device->SetDepthStencilSurface(m_backBufferDepthStencil) ); - DX_CHECK(m_device->SetRenderState(D3DRS_SRGBWRITEENABLE, 0 != (m_flags & BGFX_RESET_SRGB_BACKBUFFER) )); + DX_CHECK(m_device->SetRenderState(D3DRS_SRGBWRITEENABLE, 0 != (m_flags & BGFX_RESET_SRGB_BACKBUFFER) ) ); } else { @@ -1249,7 +1352,10 @@ namespace bgfx { namespace d3d9 capturePreReset(); DX_RELEASE(m_flushQuery, 0); - m_gpuTimer.preReset(); + if (m_timerQuerySupport) + { + m_gpuTimer.preReset(); + } for (uint32_t ii = 0; ii < BX_COUNTOF(m_indexBuffers); ++ii) { @@ -1279,7 +1385,10 @@ namespace bgfx { namespace d3d9 DX_CHECK(m_device->GetDepthStencilSurface(&m_backBufferDepthStencil) ); DX_CHECK(m_device->CreateQuery(D3DQUERYTYPE_EVENT, &m_flushQuery) ); - m_gpuTimer.postReset(); + if (m_timerQuerySupport) + { + m_gpuTimer.postReset(); + } capturePostReset(); @@ -1308,18 +1417,26 @@ namespace bgfx { namespace d3d9 { for (uint32_t stage = 0; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++stage) { - m_samplerFlags[stage][0] = UINT32_MAX; - m_samplerFlags[stage][1] = UINT32_MAX; + m_samplerFlags[stage] = UINT32_MAX; } } - void setSamplerState(uint8_t _stage, uint32_t _flags, bool _vertex = false) + static void setSamplerState(IDirect3DDevice9* _device, DWORD _stage, D3DSAMPLERSTATETYPE _type, DWORD _value) + { + DX_CHECK(_device->SetSamplerState(_stage, _type, _value) ); + if (4 > _stage) + { + DX_CHECK(_device->SetSamplerState(D3DVERTEXTEXTURESAMPLER0 + _stage, _type, _value) ); + } + } + + void setSamplerState(uint8_t _stage, uint32_t _flags, const float _rgba[4]) { const uint32_t flags = _flags&( (~BGFX_TEXTURE_RESERVED_MASK) | BGFX_TEXTURE_SAMPLER_BITS_MASK | BGFX_TEXTURE_SRGB); BX_CHECK(_stage < BX_COUNTOF(m_samplerFlags), ""); - if (m_samplerFlags[_stage][_vertex] != flags) + if (m_samplerFlags[_stage] != flags) { - m_samplerFlags[_stage][_vertex] = flags; + m_samplerFlags[_stage] = flags; IDirect3DDevice9* device = m_device; D3DTEXTUREADDRESS tau = s_textureAddress[(_flags&BGFX_TEXTURE_U_MASK)>>BGFX_TEXTURE_U_SHIFT]; D3DTEXTUREADDRESS tav = s_textureAddress[(_flags&BGFX_TEXTURE_V_MASK)>>BGFX_TEXTURE_V_SHIFT]; @@ -1328,16 +1445,26 @@ namespace bgfx { namespace d3d9 D3DTEXTUREFILTERTYPE magFilter = s_textureFilter[(_flags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT]; D3DTEXTUREFILTERTYPE mipFilter = s_textureFilter[(_flags&BGFX_TEXTURE_MIP_MASK)>>BGFX_TEXTURE_MIP_SHIFT]; - DWORD stage = (_vertex ? D3DVERTEXTEXTURESAMPLER0 : 0) + _stage; - - DX_CHECK(device->SetSamplerState(stage, D3DSAMP_ADDRESSU, tau) ); - DX_CHECK(device->SetSamplerState(stage, D3DSAMP_ADDRESSV, tav) ); - DX_CHECK(device->SetSamplerState(stage, D3DSAMP_ADDRESSW, taw) ); - DX_CHECK(device->SetSamplerState(stage, D3DSAMP_MINFILTER, minFilter) ); - DX_CHECK(device->SetSamplerState(stage, D3DSAMP_MAGFILTER, magFilter) ); - DX_CHECK(device->SetSamplerState(stage, D3DSAMP_MIPFILTER, mipFilter) ); - DX_CHECK(device->SetSamplerState(stage, D3DSAMP_MAXANISOTROPY, m_maxAnisotropy) ); - DX_CHECK(device->SetSamplerState(stage, D3DSAMP_SRGBTEXTURE, 0 != (flags & BGFX_TEXTURE_SRGB)) ); + setSamplerState(device, _stage, D3DSAMP_ADDRESSU, tau); + setSamplerState(device, _stage, D3DSAMP_ADDRESSV, tav); + setSamplerState(device, _stage, D3DSAMP_ADDRESSW, taw); + setSamplerState(device, _stage, D3DSAMP_MINFILTER, minFilter); + setSamplerState(device, _stage, D3DSAMP_MAGFILTER, magFilter); + setSamplerState(device, _stage, D3DSAMP_MIPFILTER, mipFilter); + setSamplerState(device, _stage, D3DSAMP_MAXANISOTROPY, m_maxAnisotropy); + setSamplerState(device, _stage, D3DSAMP_SRGBTEXTURE, 0 != (flags & BGFX_TEXTURE_SRGB) ); + if (NULL != _rgba) + { + if (needBorderColor(_flags) ) + { + DWORD bc = D3DCOLOR_COLORVALUE(_rgba[0], _rgba[1], _rgba[2], _rgba[3]); + setSamplerState(device + , _stage + , D3DSAMP_BORDERCOLOR + , bc + ); + } + } } } @@ -1424,15 +1551,15 @@ namespace bgfx { namespace d3d9 } } - void commit(ConstantBuffer& _constantBuffer) + void commit(UniformBuffer& _uniformBuffer) { - _constantBuffer.reset(); + _uniformBuffer.reset(); IDirect3DDevice9* device = m_device; for (;;) { - uint32_t opcode = _constantBuffer.read(); + uint32_t opcode = _uniformBuffer.read(); if (UniformType::End == opcode) { @@ -1443,17 +1570,17 @@ namespace bgfx { namespace d3d9 uint16_t loc; uint16_t num; uint16_t copy; - ConstantBuffer::decodeOpcode(opcode, type, loc, num, copy); + UniformBuffer::decodeOpcode(opcode, type, loc, num, copy); const char* data; if (copy) { - data = _constantBuffer.read(g_uniformTypeSize[type]*num); + data = _uniformBuffer.read(g_uniformTypeSize[type]*num); } else { UniformHandle handle; - memcpy(&handle, _constantBuffer.read(sizeof(UniformHandle) ), sizeof(UniformHandle) ); + memcpy(&handle, _uniformBuffer.read(sizeof(UniformHandle) ), sizeof(UniformHandle) ); data = (const char*)m_uniforms[handle.idx]; } @@ -1474,7 +1601,7 @@ namespace bgfx { namespace d3d9 switch ( (int32_t)type) { - case UniformType::Uniform3x3fv: + case UniformType::Mat3: { float* value = (float*)data; for (uint32_t ii = 0, count = num/3; ii < count; ++ii, loc += 3, value += 9) @@ -1497,7 +1624,7 @@ namespace bgfx { namespace d3d9 } break; - case UniformType::Uniform3x3fv|BGFX_UNIFORM_FRAGMENTBIT: + case UniformType::Mat3|BGFX_UNIFORM_FRAGMENTBIT: { float* value = (float*)data; for (uint32_t ii = 0, count = num/3; ii < count; ++ii, loc += 3, value += 9) @@ -1520,23 +1647,17 @@ namespace bgfx { namespace d3d9 } break; - CASE_IMPLEMENT_UNIFORM(Uniform1i, I, int); - CASE_IMPLEMENT_UNIFORM(Uniform1f, F, float); - CASE_IMPLEMENT_UNIFORM(Uniform1iv, I, int); - CASE_IMPLEMENT_UNIFORM(Uniform1fv, F, float); - CASE_IMPLEMENT_UNIFORM(Uniform2fv, F, float); - CASE_IMPLEMENT_UNIFORM(Uniform3fv, F, float); - CASE_IMPLEMENT_UNIFORM(Uniform4fv, F, float); - CASE_IMPLEMENT_UNIFORM(Uniform4x4fv, F, float); + CASE_IMPLEMENT_UNIFORM(Int1, I, int); + CASE_IMPLEMENT_UNIFORM(Vec4, F, float); + CASE_IMPLEMENT_UNIFORM(Mat4, F, float); case UniformType::End: break; default: - BX_TRACE("%4d: INVALID 0x%08x, t %d, l %d, n %d, c %d", _constantBuffer.getPos(), opcode, type, loc, num, copy); + BX_TRACE("%4d: INVALID 0x%08x, t %d, l %d, n %d, c %d", _uniformBuffer.getPos(), opcode, type, loc, num, copy); break; } - #undef CASE_IMPLEMENT_UNIFORM } } @@ -1562,7 +1683,7 @@ namespace bgfx { namespace d3d9 { if (BGFX_CLEAR_COLOR_USE_PALETTE & _clear.m_flags) { - uint8_t index = (uint8_t)bx::uint32_min(BGFX_CONFIG_MAX_CLEAR_COLOR_PALETTE-1, _clear.m_index[0]); + uint8_t index = (uint8_t)bx::uint32_min(BGFX_CONFIG_MAX_COLOR_PALETTE-1, _clear.m_index[0]); const float* rgba = _palette[index]; const float rr = rgba[0]; const float gg = rgba[1]; @@ -1701,7 +1822,7 @@ namespace bgfx { namespace d3d9 float mrtClear[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS][4]; for (uint32_t ii = 0; ii < numMrt; ++ii) { - uint8_t index = (uint8_t)bx::uint32_min(BGFX_CONFIG_MAX_CLEAR_COLOR_PALETTE-1, _clear.m_index[ii]); + uint8_t index = (uint8_t)bx::uint32_min(BGFX_CONFIG_MAX_COLOR_PALETTE-1, _clear.m_index[ii]); memcpy(mrtClear[ii], _palette[index], 16); } @@ -1772,7 +1893,8 @@ namespace bgfx { namespace d3d9 bool m_initialized; bool m_amd; bool m_nvidia; - bool m_instancing; + bool m_instancingSupport; + bool m_timerQuerySupport; D3DFORMAT m_fmtDepth; @@ -1786,7 +1908,7 @@ namespace bgfx { namespace d3d9 UniformRegistry m_uniformReg; void* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS]; - uint32_t m_samplerFlags[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS][2]; + uint32_t m_samplerFlags[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS]; TextureD3D9* m_updateTexture; uint8_t* m_updateTextureBits; @@ -1805,7 +1927,11 @@ namespace bgfx { namespace d3d9 RendererContextI* rendererCreate() { s_renderD3D9 = BX_NEW(g_allocator, RendererContextD3D9); - s_renderD3D9->init(); + if (!s_renderD3D9->init() ) + { + BX_DELETE(g_allocator, s_renderD3D9); + s_renderD3D9 = NULL; + } return s_renderD3D9; } @@ -1952,25 +2078,31 @@ namespace bgfx { namespace d3d9 static const uint8_t s_attribType[][4][2] = { - { + { // Uint8 { D3DDECLTYPE_UBYTE4, D3DDECLTYPE_UBYTE4N }, { D3DDECLTYPE_UBYTE4, D3DDECLTYPE_UBYTE4N }, { D3DDECLTYPE_UBYTE4, D3DDECLTYPE_UBYTE4N }, { D3DDECLTYPE_UBYTE4, D3DDECLTYPE_UBYTE4N }, }, - { + { // Uint10 + { D3DDECLTYPE_UDEC3, D3DDECLTYPE_DEC3N }, + { D3DDECLTYPE_UDEC3, D3DDECLTYPE_DEC3N }, + { D3DDECLTYPE_UDEC3, D3DDECLTYPE_DEC3N }, + { D3DDECLTYPE_UDEC3, D3DDECLTYPE_DEC3N }, + }, + { // Int16 { D3DDECLTYPE_SHORT2, D3DDECLTYPE_SHORT2N }, { D3DDECLTYPE_SHORT2, D3DDECLTYPE_SHORT2N }, { D3DDECLTYPE_SHORT4, D3DDECLTYPE_SHORT4N }, { D3DDECLTYPE_SHORT4, D3DDECLTYPE_SHORT4N }, }, - { + { // Half { D3DDECLTYPE_FLOAT16_2, D3DDECLTYPE_FLOAT16_2 }, { D3DDECLTYPE_FLOAT16_2, D3DDECLTYPE_FLOAT16_2 }, { D3DDECLTYPE_FLOAT16_4, D3DDECLTYPE_FLOAT16_4 }, { D3DDECLTYPE_FLOAT16_4, D3DDECLTYPE_FLOAT16_4 }, }, - { + { // Float { D3DDECLTYPE_FLOAT1, D3DDECLTYPE_FLOAT1 }, { D3DDECLTYPE_FLOAT2, D3DDECLTYPE_FLOAT2 }, { D3DDECLTYPE_FLOAT3, D3DDECLTYPE_FLOAT3 }, @@ -1985,7 +2117,7 @@ namespace bgfx { namespace d3d9 for (uint32_t attr = 0; attr < Attrib::Count; ++attr) { - if (0xff != _decl.m_attributes[attr]) + if (UINT16_MAX != _decl.m_attributes[attr]) { uint8_t num; AttribType::Enum type; @@ -2099,26 +2231,31 @@ namespace bgfx { namespace d3d9 m_predefined[m_numPredefined].m_type = uint8_t(predefined|fragmentBit); m_numPredefined++; } - else + else if (0 == (BGFX_UNIFORM_SAMPLERBIT & type) ) { const UniformInfo* info = s_renderD3D9->m_uniformReg.find(name); BX_CHECK(NULL != info, "User defined uniform '%s' is not found, it won't be set.", name); + if (NULL != info) { if (NULL == m_constantBuffer) { - m_constantBuffer = ConstantBuffer::create(1024); + m_constantBuffer = UniformBuffer::create(1024); } kind = "user"; m_constantBuffer->writeUniformHandle( (UniformType::Enum)(type|fragmentBit), regIndex, info->m_handle, regCount); } } + else + { + kind = "sampler"; + } - BX_TRACE("\t%s: %s, type %2d, num %2d, r.index %3d, r.count %2d" + BX_TRACE("\t%s: %s (%s), num %2d, r.index %3d, r.count %2d" , kind , name - , type + , getUniformTypeName(UniformType::Enum(type&~BGFX_UNIFORM_MASK) ) , num , regIndex , regCount @@ -2423,8 +2560,6 @@ namespace bgfx { namespace d3d9 void TextureD3D9::create(const Memory* _mem, uint32_t _flags, uint8_t _skip) { - m_flags = _flags; - ImageContainer imageContainer; if (imageParse(imageContainer, _mem->data, _mem->size) ) @@ -2436,6 +2571,7 @@ namespace bgfx { namespace d3d9 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); + m_flags = _flags; m_requestedFormat = imageContainer.m_format; m_textureFormat = imageContainer.m_format; @@ -2568,7 +2704,7 @@ namespace bgfx { namespace d3d9 { uint32_t slicePitch; s_renderD3D9->m_updateTextureSide = _side; - s_renderD3D9->m_updateTextureMip = _mip; + s_renderD3D9->m_updateTextureMip = _mip; s_renderD3D9->m_updateTextureBits = lock(_side, _mip, s_renderD3D9->m_updateTexturePitch, slicePitch); } @@ -2619,13 +2755,21 @@ namespace bgfx { namespace d3d9 unlock(s_renderD3D9->m_updateTextureSide, s_renderD3D9->m_updateTextureMip); } - void TextureD3D9::commit(uint8_t _stage, uint32_t _flags) + void TextureD3D9::commit(uint8_t _stage, uint32_t _flags, const float _palette[][4]) { - s_renderD3D9->setSamplerState(_stage, 0 == (BGFX_SAMPLER_DEFAULT_FLAGS & _flags) ? _flags : m_flags); - DX_CHECK(s_renderD3D9->m_device->SetTexture(_stage, m_ptr) ); + uint32_t flags = 0 == (BGFX_SAMPLER_DEFAULT_FLAGS & _flags) + ? _flags + : m_flags + ; + uint32_t index = (flags & BGFX_TEXTURE_BORDER_COLOR_MASK) >> BGFX_TEXTURE_BORDER_COLOR_SHIFT; + s_renderD3D9->setSamplerState(_stage, flags, _palette[index]); -// s_renderD3D9->setSamplerState(_stage, 0 == (BGFX_SAMPLER_DEFAULT_FLAGS & _flags) ? _flags : m_flags, true); -// DX_CHECK(s_renderD3D9->m_device->SetTexture(D3DVERTEXTEXTURESAMPLER0 + _stage, m_ptr) ); + IDirect3DDevice9* device = s_renderD3D9->m_device; + DX_CHECK(device->SetTexture(_stage, m_ptr) ); + if (4 > _stage) + { + DX_CHECK(device->SetTexture(D3DVERTEXTEXTURESAMPLER0 + _stage, m_ptr) ); + } } void TextureD3D9::resolve() const @@ -2727,10 +2871,13 @@ namespace bgfx { namespace d3d9 m_hwnd = (HWND)_nwh; + m_width = bx::uint32_max(_width, 16); + m_height = bx::uint32_max(_height, 16); + D3DPRESENT_PARAMETERS params; memcpy(¶ms, &s_renderD3D9->m_params, sizeof(D3DPRESENT_PARAMETERS) ); - params.BackBufferWidth = bx::uint32_max(_width, 16); - params.BackBufferHeight = bx::uint32_max(_height, 16); + params.BackBufferWidth = m_width; + params.BackBufferHeight = m_height; DX_CHECK(s_renderD3D9->m_device->CreateAdditionalSwapChain(¶ms, &m_swapChain) ); DX_CHECK(m_swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &m_color[0]) ); @@ -2828,7 +2975,8 @@ namespace bgfx { namespace d3d9 { if (NULL != m_hwnd) { - DX_RELEASE(m_color[0], 0); + DX_RELEASE(m_color[0], 0); + DX_RELEASE(m_depthStencil, 0); DX_RELEASE(m_swapChain, 0); } else @@ -2857,8 +3005,22 @@ namespace bgfx { namespace d3d9 { if (NULL != m_hwnd) { - DX_CHECK(s_renderD3D9->m_device->CreateAdditionalSwapChain(&s_renderD3D9->m_params, &m_swapChain) ); + D3DPRESENT_PARAMETERS params; + memcpy(¶ms, &s_renderD3D9->m_params, sizeof(D3DPRESENT_PARAMETERS) ); + params.BackBufferWidth = m_width; + params.BackBufferHeight = m_height; + + DX_CHECK(s_renderD3D9->m_device->CreateAdditionalSwapChain(¶ms, &m_swapChain) ); DX_CHECK(m_swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &m_color[0]) ); + DX_CHECK(s_renderD3D9->m_device->CreateDepthStencilSurface(params.BackBufferWidth + , params.BackBufferHeight + , params.AutoDepthStencilFormat + , params.MultiSampleType + , params.MultiSampleQuality + , FALSE + , &m_depthStencil + , NULL + ) ); } else { @@ -2961,6 +3123,7 @@ namespace bgfx { namespace d3d9 void TimerQueryD3D9::end() { Frame& frame = m_frame[m_control.m_current]; + frame.m_disjoint->Issue(D3DISSUE_END); frame.m_end->Issue(D3DISSUE_END); frame.m_freq->Issue(D3DISSUE_END); m_control.commit(1); @@ -2978,14 +3141,14 @@ namespace bgfx { namespace d3d9 { m_control.consume(1); - uint64_t start; - DX_CHECK(frame.m_start->GetData(&start, sizeof(start), 0) ); + uint64_t timeStart; + DX_CHECK(frame.m_start->GetData(&timeStart, sizeof(timeStart), 0) ); - uint64_t end; - DX_CHECK(frame.m_end->GetData(&end, sizeof(end), 0) ); + uint64_t timeEnd; + DX_CHECK(frame.m_end->GetData(&timeEnd, sizeof(timeEnd), 0) ); m_frequency = freq; - m_elapsed = end - start; + m_elapsed = timeEnd - timeStart; return true; } @@ -3006,8 +3169,7 @@ namespace bgfx { namespace d3d9 int64_t captureElapsed = 0; device->BeginScene(); - - if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) ) + if (m_timerQuerySupport) { m_gpuTimer.begin(); } @@ -3036,7 +3198,7 @@ namespace bgfx { namespace d3d9 DX_CHECK(device->SetRenderState(D3DRS_FILLMODE, _render->m_debug&BGFX_DEBUG_WIREFRAME ? D3DFILL_WIREFRAME : D3DFILL_SOLID) ); uint16_t programIdx = invalidHandle; SortKey key; - uint8_t view = 0xff; + uint16_t view = UINT16_MAX; FrameBufferHandle fbh = BGFX_INVALID_HANDLE; uint32_t blendFactor = 0; @@ -3121,7 +3283,7 @@ namespace bgfx { namespace d3d9 if (BGFX_CLEAR_NONE != (clear.m_flags & BGFX_CLEAR_MASK) ) { - clearQuad(_clearQuad, viewState.m_rect, clear, _render->m_clearColor); + clearQuad(_clearQuad, viewState.m_rect, clear, _render->m_colorPalette); prim = s_primInfo[BX_COUNTOF(s_primName)]; // Force primitive type update after clear quad. } @@ -3335,7 +3497,7 @@ namespace bgfx { namespace d3d9 bool programChanged = false; bool constantsChanged = draw.m_constBegin < draw.m_constEnd; - rendererUpdateUniforms(this, _render->m_constantBuffer, draw.m_constBegin, draw.m_constEnd); + rendererUpdateUniforms(this, _render->m_uniformBuffer, draw.m_constBegin, draw.m_constEnd); if (key.m_program != programIdx) { @@ -3363,13 +3525,13 @@ namespace bgfx { namespace d3d9 if (constantsChanged) { - ConstantBuffer* vcb = program.m_vsh->m_constantBuffer; + UniformBuffer* vcb = program.m_vsh->m_constantBuffer; if (NULL != vcb) { commit(*vcb); } - ConstantBuffer* fcb = program.m_fsh->m_constantBuffer; + UniformBuffer* fcb = program.m_fsh->m_constantBuffer; if (NULL != fcb) { commit(*fcb); @@ -3382,15 +3544,15 @@ namespace bgfx { namespace d3d9 { for (uint8_t stage = 0; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++stage) { - const Binding& sampler = draw.m_bind[stage]; + const Binding& bind = draw.m_bind[stage]; Binding& current = currentState.m_bind[stage]; - if (current.m_idx != sampler.m_idx - || current.m_un.m_draw.m_flags != sampler.m_un.m_draw.m_flags + if (current.m_idx != bind.m_idx + || current.m_un.m_draw.m_flags != bind.m_un.m_draw.m_flags || programChanged) { - if (invalidHandle != sampler.m_idx) + if (invalidHandle != bind.m_idx) { - m_textures[sampler.m_idx].commit(stage, sampler.m_un.m_draw.m_flags); + m_textures[bind.m_idx].commit(stage, bind.m_un.m_draw.m_flags, _render->m_colorPalette); } else { @@ -3398,7 +3560,7 @@ namespace bgfx { namespace d3d9 } } - current = sampler; + current = bind; } } @@ -3423,7 +3585,7 @@ namespace bgfx { namespace d3d9 DX_CHECK(device->SetStreamSource(0, vb.m_ptr, 0, vertexDecl.m_decl.m_stride) ); if (isValid(draw.m_instanceDataBuffer) - && m_instancing) + && m_instancingSupport) { const VertexBufferD3D9& inst = m_vertexBuffers[draw.m_instanceDataBuffer.idx]; DX_CHECK(device->SetStreamSourceFreq(0, D3DSTREAMSOURCE_INDEXEDDATA|draw.m_numInstances) ); @@ -3475,10 +3637,10 @@ namespace bgfx { namespace d3d9 numVertices = vb.m_size/vertexDecl.m_decl.m_stride; } - uint32_t numIndices = 0; + uint32_t numIndices = 0; uint32_t numPrimsSubmitted = 0; - uint32_t numInstances = 0; - uint32_t numPrimsRendered = 0; + uint32_t numInstances = 0; + uint32_t numPrimsRendered = 0; if (isValid(draw.m_indexBuffer) ) { @@ -3501,10 +3663,10 @@ namespace bgfx { namespace d3d9 } else if (prim.m_min <= draw.m_numIndices) { - numIndices = draw.m_numIndices; + numIndices = draw.m_numIndices; numPrimsSubmitted = numIndices/prim.m_div - prim.m_sub; - numInstances = draw.m_numInstances; - numPrimsRendered = numPrimsSubmitted*draw.m_numInstances; + numInstances = draw.m_numInstances; + numPrimsRendered = numPrimsSubmitted*draw.m_numInstances; DX_CHECK(device->DrawIndexedPrimitive(prim.m_type , draw.m_startVertex @@ -3518,8 +3680,8 @@ namespace bgfx { namespace d3d9 else { numPrimsSubmitted = numVertices/prim.m_div - prim.m_sub; - numInstances = draw.m_numInstances; - numPrimsRendered = numPrimsSubmitted*draw.m_numInstances; + numInstances = draw.m_numInstances; + numPrimsRendered = numPrimsSubmitted*draw.m_numInstances; DX_CHECK(device->DrawPrimitive(prim.m_type , draw.m_startVertex @@ -3562,14 +3724,12 @@ namespace bgfx { namespace d3d9 min = min > frameTime ? frameTime : min; max = max < frameTime ? frameTime : max; - if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) ) - { - PIX_BEGINEVENT(D3DCOLOR_RGBA(0x40, 0x40, 0x40, 0xff), L"debugstats"); - - static uint32_t maxGpuLatency = 0; - static double maxGpuElapsed = 0.0f; - double elapsedGpuMs = 0.0; + static uint32_t maxGpuLatency = 0; + static double maxGpuElapsed = 0.0f; + double elapsedGpuMs = 0.0; + if (m_timerQuerySupport) + { m_gpuTimer.end(); while (m_gpuTimer.get() ) @@ -3579,6 +3739,19 @@ namespace bgfx { namespace d3d9 maxGpuElapsed = elapsedGpuMs > maxGpuElapsed ? elapsedGpuMs : maxGpuElapsed; } maxGpuLatency = bx::uint32_imax(maxGpuLatency, m_gpuTimer.m_control.available()-1); + } + + const int64_t timerFreq = bx::getHPFrequency(); + + Stats& perfStats = _render->m_perfStats; + perfStats.cpuTime = frameTime; + perfStats.cpuTimerFreq = timerFreq; + perfStats.gpuTime = m_gpuTimer.m_elapsed; + perfStats.gpuTimerFreq = m_gpuTimer.m_frequency; + + if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) ) + { + PIX_BEGINEVENT(D3DCOLOR_RGBA(0x40, 0x40, 0x40, 0xff), L"debugstats"); TextVideoMem& tvm = m_textVideoMem; @@ -3586,9 +3759,9 @@ namespace bgfx { namespace d3d9 if (now >= next) { - next = now + bx::getHPFrequency(); + next = now + timerFreq; - double freq = double(bx::getHPFrequency() ); + double freq = double(timerFreq); double toMs = 1000.0/freq; tvm.clear(); @@ -3598,7 +3771,11 @@ namespace bgfx { namespace d3d9 ); const D3DADAPTER_IDENTIFIER9& identifier = m_identifier; - tvm.printf(0, pos++, 0x0f, " Device: %s (%s)", identifier.Description, identifier.Driver); + tvm.printf(0, pos++, 0x8f, " Device: %s (%s)", identifier.Description, identifier.Driver); + + char processMemoryUsed[16]; + bx::prettify(processMemoryUsed, BX_COUNTOF(processMemoryUsed), bx::getProcessMemoryUsed() ); + tvm.printf(0, pos++, 0x8f, " Memory: %s (process) ", processMemoryUsed); pos = 10; tvm.printf(10, pos++, 0x8e, " Frame: %7.3f, % 7.3f \x1f, % 7.3f \x1e [ms] / % 6.2f FPS " @@ -3617,7 +3794,7 @@ namespace bgfx { namespace d3d9 ); double elapsedCpuMs = double(elapsed)*toMs; - tvm.printf(10, pos++, 0x8e, " Submitted: %4d (draw %4d, compute %4d) / CPU %3.4f [ms] %c GPU %3.4f [ms] (latency %d)" + tvm.printf(10, pos++, 0x8e, " Submitted: %5d (draw %5d, compute %4d) / CPU %7.4f [ms] %c GPU %7.4f [ms] (latency %d)" , _render->m_num , statsKeyType[0] , statsKeyType[1] @@ -3639,18 +3816,19 @@ namespace bgfx { namespace d3d9 ); } - tvm.printf(10, pos++, 0x8e, " Indices: %7d", statsNumIndices); - tvm.printf(10, pos++, 0x8e, " DVB size: %7d", _render->m_vboffset); - tvm.printf(10, pos++, 0x8e, " DIB size: %7d", _render->m_iboffset); + 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, " DVB size: %7d ", _render->m_vboffset); + tvm.printf(10, pos++, 0x8e, " DIB size: %7d ", _render->m_iboffset); double captureMs = double(captureElapsed)*toMs; - tvm.printf(10, pos++, 0x8e, " Capture: %3.4f [ms]", captureMs); + tvm.printf(10, pos++, 0x8e, " Capture: %7.4f [ms]", captureMs); uint8_t attr[2] = { 0x89, 0x8a }; uint8_t attrIndex = _render->m_waitSubmit < _render->m_waitRender; - tvm.printf(10, pos++, attr[attrIndex&1], " Submit wait: %3.4f [ms]", _render->m_waitSubmit*toMs); - tvm.printf(10, pos++, attr[(attrIndex+1)&1], " Render wait: %3.4f [ms]", _render->m_waitRender*toMs); + tvm.printf(10, pos++, attr[attrIndex&1], " Submit wait: %7.4f [ms]", _render->m_waitSubmit*toMs); + tvm.printf(10, pos++, attr[(attrIndex+1)&1], " Render wait: %7.4f [ms]", _render->m_waitRender*toMs); min = frameTime; max = frameTime; |