diff options
Diffstat (limited to '3rdparty/bgfx/src/renderer_d3d9.cpp')
-rw-r--r-- | 3rdparty/bgfx/src/renderer_d3d9.cpp | 974 |
1 files changed, 520 insertions, 454 deletions
diff --git a/3rdparty/bgfx/src/renderer_d3d9.cpp b/3rdparty/bgfx/src/renderer_d3d9.cpp index 4f4267be9ad..7dd76c2cc46 100644 --- a/3rdparty/bgfx/src/renderer_d3d9.cpp +++ b/3rdparty/bgfx/src/renderer_d3d9.cpp @@ -7,6 +7,7 @@ #if BGFX_CONFIG_RENDERER_DIRECT3D9 # include "renderer_d3d9.h" +# include <bx/pixelformat.h> namespace bgfx { namespace d3d9 { @@ -237,7 +238,7 @@ namespace bgfx { namespace d3d9 { D3DFMT_A4R4G4B4 }, // RGBA4 { D3DFMT_A1R5G5B5 }, // RGB5A1 { D3DFMT_A2B10G10R10 }, // RGB10A2 - { D3DFMT_UNKNOWN }, // R11G11B10F + { D3DFMT_UNKNOWN }, // RG11B10F { D3DFMT_UNKNOWN }, // UnknownDepth { D3DFMT_D16 }, // D16 { D3DFMT_D24X8 }, // D24 @@ -275,6 +276,91 @@ namespace bgfx { namespace d3d9 static PFN_D3DPERF_BEGIN_EVENT D3DPERF_BeginEvent; static PFN_D3DPERF_END_EVENT D3DPERF_EndEvent; + static const D3DVERTEXELEMENT9 s_attrib[] = + { + { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, + { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 }, + { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0 }, + { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0 }, + { 0, 0, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 }, + { 0, 0, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1 }, + { 0, 0, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 2 }, + { 0, 0, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 3 }, + { 0, 0, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0 }, + { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0 }, + { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, + { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 }, + { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2 }, + { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3 }, + { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4 }, + { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 5 }, + { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 6 }, + { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 7 }, + D3DDECL_END() + }; + BX_STATIC_ASSERT(Attrib::Count == BX_COUNTOF(s_attrib)-1); + + 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 }, + { D3DDECLTYPE_FLOAT4, D3DDECLTYPE_FLOAT4 }, + }, + }; + BX_STATIC_ASSERT(AttribType::Count == BX_COUNTOF(s_attribType) ); + + static D3DVERTEXELEMENT9* fillVertexDecl(uint8_t _stream, D3DVERTEXELEMENT9* _out, const VertexDecl& _decl) + { + D3DVERTEXELEMENT9* elem = _out; + + for (uint32_t attr = 0; attr < Attrib::Count; ++attr) + { + if (UINT16_MAX != _decl.m_attributes[attr]) + { + uint8_t num; + AttribType::Enum type; + bool normalized; + bool asInt; + _decl.decode(Attrib::Enum(attr), num, type, normalized, asInt); + + bx::memCopy(elem, &s_attrib[attr], sizeof(D3DVERTEXELEMENT9) ); + + elem->Stream = _stream; + elem->Type = s_attribType[type][num-1][normalized]; + elem->Offset = _decl.m_offset[attr]; + ++elem; + } + } + + return elem; + } + inline bool isLost(HRESULT _hr) { return false @@ -328,7 +414,7 @@ namespace bgfx { namespace d3d9 ErrorState::Enum errorState = ErrorState::Default; - m_fbh.idx = invalidHandle; + m_fbh.idx = kInvalidHandle; bx::memSet(m_uniforms, 0, sizeof(m_uniforms) ); bx::memSet(&m_resolution, 0, sizeof(m_resolution) ); @@ -345,7 +431,7 @@ namespace bgfx { namespace d3d9 m_params.EnableAutoDepthStencil = TRUE; m_params.AutoDepthStencilFormat = D3DFMT_D24S8; m_params.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL; -#if BX_PLATFORM_WINDOWS + m_params.FullScreen_RefreshRateInHz = 0; m_params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; m_params.SwapEffect = D3DSWAPEFFECT_DISCARD; @@ -361,12 +447,14 @@ namespace bgfx { namespace d3d9 if (NULL == m_d3d9dll) { - BX_TRACE("Failed to load d3d9.dll."); + BX_TRACE("Init error: Failed to load d3d9.dll."); goto error; } errorState = ErrorState::LoadedD3D9; + m_nvapi.init(); + if (BX_ENABLED(BGFX_CONFIG_DEBUG_PIX) ) { D3DPERF_SetMarker = (PFN_D3DPERF_SET_MARKER )bx::dlsym(m_d3d9dll, "D3DPERF_SetMarker"); @@ -409,7 +497,7 @@ namespace bgfx { namespace d3d9 if (NULL == Direct3DCreate9) { - BX_TRACE("Function Direct3DCreate9 not found."); + BX_TRACE("Init error: Function Direct3DCreate9 not found."); goto error; } @@ -419,7 +507,7 @@ namespace bgfx { namespace d3d9 if (NULL == m_d3d9) { - BX_TRACE("Unable to create Direct3D."); + BX_TRACE("Init error: Unable to create Direct3D."); goto error; } @@ -463,7 +551,7 @@ namespace bgfx { namespace d3d9 } if (BX_ENABLED(BGFX_CONFIG_DEBUG_PERFHUD) - && 0 != strstr(desc.Description, "PerfHUD") ) + && 0 != bx::strFind(desc.Description, "PerfHUD") ) { m_adapter = ii; m_deviceType = D3DDEVTYPE_REF; @@ -518,7 +606,7 @@ namespace bgfx { namespace d3d9 if (NULL == m_device) { - BX_TRACE("Unable to create Direct3D9 device."); + BX_TRACE("Init error: Unable to create Direct3D9 device."); goto error; } @@ -568,6 +656,7 @@ namespace bgfx { namespace d3d9 || (D3DPTEXTURECAPS_ALPHA & m_caps.TextureCaps) != D3DPTEXTURECAPS_ALPHA || !(m_caps.VertexShaderVersion >= D3DVS_VERSION(2, 0) && m_caps.PixelShaderVersion >= D3DPS_VERSION(2, 1) ) ) { + BX_TRACE("Init error: Min spec not satisfied."); goto error; } @@ -577,6 +666,7 @@ namespace bgfx { namespace d3d9 BX_TRACE("Max fragment shader 3.0 instr. slots: %d", m_caps.MaxPixelShader30InstructionSlots); BX_TRACE("Num simultaneous render targets: %d", m_caps.NumSimultaneousRTs); BX_TRACE("Max vertex index: %d", m_caps.MaxVertexIndex); + BX_TRACE("Max streams: %d", m_caps.MaxStreams); g_caps.supported |= ( 0 | BGFX_CAPS_TEXTURE_3D @@ -590,12 +680,14 @@ namespace bgfx { namespace d3d9 | BGFX_CAPS_TEXTURE_READ_BACK | (m_occlusionQuerySupport ? BGFX_CAPS_OCCLUSION_QUERY : 0) ); - g_caps.limits.maxTextureSize = uint16_t(bx::uint32_min(m_caps.MaxTextureWidth, m_caps.MaxTextureHeight) ); - m_caps.NumSimultaneousRTs = uint8_t(bx::uint32_min(m_caps.NumSimultaneousRTs, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) ); - g_caps.limits.maxFBAttachments = uint8_t(m_caps.NumSimultaneousRTs); + m_caps.NumSimultaneousRTs = bx::uint32_min(m_caps.NumSimultaneousRTs, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS); + m_caps.MaxStreams = bx::uint32_min(m_caps.MaxStreams, BGFX_CONFIG_MAX_VERTEX_STREAMS); + m_caps.MaxAnisotropy = bx::uint32_max(m_caps.MaxAnisotropy, 1); - m_caps.MaxAnisotropy = bx::uint32_max(m_caps.MaxAnisotropy, 1); + g_caps.limits.maxTextureSize = uint16_t(bx::uint32_min(m_caps.MaxTextureWidth, m_caps.MaxTextureHeight) ); + g_caps.limits.maxFBAttachments = uint8_t(m_caps.NumSimultaneousRTs); + g_caps.limits.maxVertexStreams = uint8_t(m_caps.MaxStreams); if (BX_ENABLED(BGFX_CONFIG_RENDERER_USE_EXTENSIONS) ) { @@ -700,7 +792,7 @@ namespace bgfx { namespace d3d9 support |= SUCCEEDED(m_d3d9->CheckDeviceFormat(m_adapter , m_deviceType , adapterFormat - , isDepth(TextureFormat::Enum(ii) ) ? D3DUSAGE_DEPTHSTENCIL : D3DUSAGE_RENDERTARGET + , bimg::isDepth(bimg::TextureFormat::Enum(ii) ) ? D3DUSAGE_DEPTHSTENCIL : D3DUSAGE_RENDERTARGET , D3DRTYPE_TEXTURE , s_textureFormat[ii].m_fmt ) ) ? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER : BGFX_CAPS_FORMAT_TEXTURE_NONE; @@ -716,7 +808,7 @@ namespace bgfx { namespace d3d9 support |= SUCCEEDED(m_d3d9->CheckDeviceFormat(m_adapter , m_deviceType , adapterFormat - , isDepth(TextureFormat::Enum(ii) ) ? D3DUSAGE_DEPTHSTENCIL : D3DUSAGE_RENDERTARGET + , bimg::isDepth(bimg::TextureFormat::Enum(ii) ) ? D3DUSAGE_DEPTHSTENCIL : D3DUSAGE_RENDERTARGET , D3DRTYPE_TEXTURE , s_textureFormat[ii].m_fmt ) ) ? BGFX_CAPS_FORMAT_TEXTURE_MIP_AUTOGEN : BGFX_CAPS_FORMAT_TEXTURE_NONE; @@ -726,37 +818,6 @@ namespace bgfx { namespace d3d9 m_fmtDepth = D3DFMT_D24S8; -#elif BX_PLATFORM_XBOX360 - m_params.PresentationInterval = D3DPRESENT_INTERVAL_ONE; - m_params.DisableAutoBackBuffer = FALSE; - m_params.DisableAutoFrontBuffer = FALSE; - m_params.FrontBufferFormat = D3DFMT_X8R8G8B8; - m_params.FrontBufferColorSpace = D3DCOLORSPACE_RGB; - - m_d3d9 = Direct3DCreate9(D3D_SDK_VERSION); - BX_TRACE("Creating D3D9 %p", m_d3d9); - - XVIDEO_MODE videoMode; - XGetVideoMode(&videoMode); - if (!videoMode.fIsWideScreen) - { - m_params.Flags |= D3DPRESENTFLAG_NO_LETTERBOX; - } - - BX_TRACE("Creating device"); - DX_CHECK(m_d3d9->CreateDevice(m_adapter - , m_deviceType - , NULL - , D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_BUFFER_2_FRAMES - , &m_params - , &m_device - ) ); - - BX_TRACE("Device %p", m_device); - - m_fmtDepth = D3DFMT_D24FS8; -#endif // BX_PLATFORM_WINDOWS - { IDirect3DSwapChain9* swapChain; DX_CHECK(m_device->GetSwapChain(0, &swapChain) ); @@ -820,10 +881,9 @@ namespace bgfx { namespace d3d9 DX_RELEASE(m_d3d9, 0); } -#if BX_PLATFORM_WINDOWS case ErrorState::LoadedD3D9: + m_nvapi.shutdown(); bx::dlclose(m_d3d9dll); -#endif // BX_PLATFORM_WINDOWS case ErrorState::Default: break; @@ -856,11 +916,6 @@ namespace bgfx { namespace d3d9 m_textures[ii].destroy(); } - for (uint32_t ii = 0; ii < BX_COUNTOF(m_vertexDecls); ++ii) - { - m_vertexDecls[ii].destroy(); - } - if (NULL != m_d3d9ex) { DX_RELEASE(m_deviceEx, 1); @@ -874,19 +929,18 @@ namespace bgfx { namespace d3d9 DX_RELEASE(m_d3d9, 0); } -#if BX_PLATFORM_WINDOWS + m_nvapi.shutdown(); bx::dlclose(m_d3d9dll); -#endif // BX_PLATFORM_WINDOWS m_initialized = false; } - RendererType::Enum getRendererType() const BX_OVERRIDE + RendererType::Enum getRendererType() const override { return RendererType::Direct3D9; } - const char* getRendererName() const BX_OVERRIDE + const char* getRendererName() const override { if (NULL != m_d3d9ex) { @@ -896,110 +950,111 @@ namespace bgfx { namespace d3d9 return BGFX_RENDERER_DIRECT3D9_NAME; } - 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); } - 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 { - m_vertexDecls[_handle.idx].create(_decl); + 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 { - m_vertexDecls[_handle.idx].destroy(); } - 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); } - 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); } - 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(_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); } - 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(_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], m_shaders[_fsh.idx]); } - 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 { m_updateTexture = &m_textures[_handle.idx]; m_updateTexture->updateBegin(_side, _mip); } - 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_updateTexture->update(_side, _mip, _rect, _z, _depth, _pitch, _mem); } - void updateTextureEnd() BX_OVERRIDE + void updateTextureEnd() override { m_updateTexture->updateEnd(); m_updateTexture = NULL; } - void readTexture(TextureHandle _handle, void* _data, uint8_t _mip) BX_OVERRIDE + void readTexture(TextureHandle _handle, void* _data, uint8_t _mip) override { TextureD3D9& texture = m_textures[_handle.idx]; @@ -1015,7 +1070,7 @@ namespace bgfx { namespace d3d9 uint32_t srcPitch = lockedRect.Pitch; uint8_t* src = (uint8_t*)lockedRect.pBits; - 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; @@ -1032,7 +1087,7 @@ namespace bgfx { namespace d3d9 DX_CHECK(texture.m_texture2d->UnlockRect(_mip) ); } - 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 { TextureD3D9& texture = m_textures[_handle.idx]; @@ -1060,7 +1115,7 @@ namespace bgfx { namespace d3d9 release(mem); } - void overrideInternal(TextureHandle _handle, uintptr_t _ptr) BX_OVERRIDE + void overrideInternal(TextureHandle _handle, uintptr_t _ptr) override { // Resource ref. counts might be messed up outside of bgfx. // Disabling ref. count check once texture is overridden. @@ -1068,7 +1123,7 @@ namespace bgfx { namespace d3d9 m_textures[_handle.idx].overrideInternal(_ptr); } - uintptr_t getInternal(TextureHandle _handle) BX_OVERRIDE + uintptr_t getInternal(TextureHandle _handle) override { // Resource ref. counts might be messed up outside of bgfx. // Disabling ref. count check once texture is overridden. @@ -1076,24 +1131,24 @@ namespace bgfx { namespace d3d9 return uintptr_t(m_textures[_handle.idx].m_ptr); } - 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) @@ -1108,7 +1163,7 @@ namespace bgfx { namespace d3d9 } } - 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]) { @@ -1122,16 +1177,15 @@ namespace bgfx { namespace d3d9 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 { -#if BX_PLATFORM_WINDOWS IDirect3DSwapChain9* swapChain = isValid(_handle) ? m_frameBuffers[_handle.idx].m_swapChain : m_swapChain @@ -1195,12 +1249,9 @@ namespace bgfx { namespace d3d9 DX_CHECK(surface->UnlockRect() ); DX_RELEASE(surface, 0); -#else - BX_UNUSED(_handle, _filePath); -#endif // BX_PLATFORM_WINDOWS } - 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) ) { @@ -1210,18 +1261,18 @@ namespace bgfx { namespace d3d9 ); } - bx::strlcpy(&s_viewName[_id][BGFX_CONFIG_MAX_VIEW_NAME_RESERVED] - , _name + 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 { #if BGFX_CONFIG_DEBUG_PIX uint32_t size = _size*sizeof(wchar_t); @@ -1232,14 +1283,21 @@ namespace bgfx { namespace d3d9 BX_UNUSED(_marker, _size); } - 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 + { + BX_UNUSED(_handle, _name) + } + + 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 { uint32_t width = m_params.BackBufferWidth; uint32_t height = m_params.BackBufferHeight; @@ -1271,15 +1329,15 @@ namespace bgfx { namespace d3d9 DX_CHECK(device->SetPixelShader(program.m_fsh->m_pixelShader) ); VertexBufferD3D9& vb = m_vertexBuffers[_blitter.m_vb->handle.idx]; - VertexDeclD3D9& vertexDecl = m_vertexDecls[_blitter.m_vb->decl.idx]; - DX_CHECK(device->SetStreamSource(0, vb.m_ptr, 0, vertexDecl.m_decl.m_stride) ); - DX_CHECK(device->SetVertexDeclaration(vertexDecl.m_ptr) ); + VertexDecl& vertexDecl = m_vertexDecls[_blitter.m_vb->decl.idx]; + DX_CHECK(device->SetStreamSource(0, vb.m_ptr, 0, vertexDecl.m_stride) ); + setInputLayout(vertexDecl, 0); IndexBufferD3D9& ib = m_indexBuffers[_blitter.m_ib->handle.idx]; DX_CHECK(device->SetIndices(ib.m_ptr) ); 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 = program.m_predefined[0]; uint8_t flags = predefined.m_type; @@ -1288,7 +1346,7 @@ namespace bgfx { namespace d3d9 m_textures[_blitter.m_texture.idx].commit(0, BGFX_TEXTURE_INTERNAL_DEFAULT_SAMPLER, NULL); } - 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) @@ -1359,7 +1417,6 @@ namespace bgfx { namespace d3d9 m_textVideoMem.resize(false, _resolution.m_width, _resolution.m_height); m_textVideoMem.clear(); -#if BX_PLATFORM_WINDOWS D3DDEVICE_CREATION_PARAMETERS dcp; DX_CHECK(m_device->GetCreationParameters(&dcp) ); @@ -1367,7 +1424,6 @@ namespace bgfx { namespace d3d9 DX_CHECK(m_d3d9->GetAdapterDisplayMode(dcp.AdapterOrdinal, &dm) ); m_params.BackBufferFormat = dm.Format; -#endif // BX_PLATFORM_WINDOWS m_params.BackBufferWidth = _resolution.m_width; m_params.BackBufferHeight = _resolution.m_height; @@ -1458,7 +1514,12 @@ namespace bgfx { namespace d3d9 m_flushQuery->GetData(NULL, 0, D3DGETDATA_FLUSH); } - void flip(HMD& /*_hmd*/) BX_OVERRIDE + bool isDeviceRemoved() override + { + return false; + } + + void flip(HMD& /*_hmd*/) override { if (NULL != m_swapChain) { @@ -1487,7 +1548,6 @@ namespace bgfx { namespace d3d9 hr = m_frameBuffers[m_windows[ii].idx].present(); } -#if BX_PLATFORM_WINDOWS if (isLost(hr) ) { do @@ -1509,7 +1569,6 @@ namespace bgfx { namespace d3d9 { BX_TRACE("Present failed with err 0x%08x.", hr); } -#endif // BX_PLATFORM_ } } } @@ -1519,6 +1578,7 @@ namespace bgfx { namespace d3d9 m_needPresent = false; invalidateSamplerState(); + m_inputLayoutCache.invalidate(); for (uint32_t stage = 0; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++stage) { @@ -1985,7 +2045,7 @@ namespace bgfx { namespace d3d9 } VertexBufferD3D9& vb = m_vertexBuffers[_clearQuad.m_vb->handle.idx]; - VertexDeclD3D9& vertexDecl = m_vertexDecls[_clearQuad.m_vb->decl.idx]; + VertexDecl& vertexDecl = m_vertexDecls[_clearQuad.m_vb->decl.idx]; uint32_t stride = _clearQuad.m_decl.m_stride; { @@ -2055,7 +2115,7 @@ namespace bgfx { namespace d3d9 DX_CHECK(device->SetStreamSource(0, vb.m_ptr, 0, stride) ); DX_CHECK(device->SetStreamSourceFreq(0, 1) ); DX_CHECK(device->SetStreamSource(1, NULL, 0, 0) ); - DX_CHECK(device->SetVertexDeclaration(vertexDecl.m_ptr) ); + setInputLayout(vertexDecl, 0); DX_CHECK(device->SetIndices(NULL) ); DX_CHECK(device->DrawPrimitive(D3DPT_TRIANGLESTRIP , 0 @@ -2064,9 +2124,55 @@ namespace bgfx { namespace d3d9 } } -#if BX_PLATFORM_WINDOWS + void setInputLayout(uint8_t _numStreams, const VertexDecl** _vertexDecls, uint16_t _numInstanceData) + { + bx::HashMurmur2A murmur; + murmur.begin(); + murmur.add(_numInstanceData); + for (uint8_t stream = 0; stream < _numStreams; ++stream) + { + murmur.add(_vertexDecls[stream]->m_hash); + } + uint64_t layoutHash = murmur.end(); + + IDirect3DVertexDeclaration9* layout = m_inputLayoutCache.find(layoutHash); + if (NULL == layout) + { + D3DVERTEXELEMENT9 vertexElements[Attrib::Count+1+BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT]; + D3DVERTEXELEMENT9* elem = vertexElements; + + for (uint8_t stream = 0; stream < _numStreams; ++stream) + { + elem = fillVertexDecl(stream, elem, *_vertexDecls[stream]); + } + + const D3DVERTEXELEMENT9 inst = { _numStreams, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }; + + for (uint8_t ii = 0; ii < _numInstanceData; ++ii) + { + bx::memCopy(elem, &inst, sizeof(D3DVERTEXELEMENT9) ); + elem->UsageIndex = uint8_t(7-ii); // TEXCOORD7 = i_data0, TEXCOORD6 = i_data1, etc. + elem->Offset = ii*16; + ++elem; + } + + bx::memCopy(elem, &s_attrib[Attrib::Count], sizeof(D3DVERTEXELEMENT9) ); + + DX_CHECK(m_device->CreateVertexDeclaration(vertexElements, &layout) ); + + m_inputLayoutCache.add(layoutHash, layout); + } + + DX_CHECK(m_device->SetVertexDeclaration(layout) ); + } + + void setInputLayout(const VertexDecl& _vertexDecl, uint16_t _numInstanceData) + { + const VertexDecl* decls[1] = { &_vertexDecl }; + setInputLayout(BX_COUNTOF(decls), decls, _numInstanceData); + } + D3DCAPS9 m_caps; -#endif // BX_PLATFORM_WINDOWS IDirect3D9Ex* m_d3d9ex; IDirect3DDevice9Ex* m_deviceEx; @@ -2094,6 +2200,7 @@ namespace bgfx { namespace d3d9 IDirect3DVertexDeclaration9* m_instanceDataDecls[BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT]; void* m_d3d9dll; + NvApi m_nvapi; uint32_t m_adapter; D3DDEVTYPE m_deviceType; D3DPRESENT_PARAMETERS m_params; @@ -2116,7 +2223,7 @@ namespace bgfx { namespace d3d9 ShaderD3D9 m_shaders[BGFX_CONFIG_MAX_SHADERS]; ProgramD3D9 m_program[BGFX_CONFIG_MAX_PROGRAMS]; TextureD3D9 m_textures[BGFX_CONFIG_MAX_TEXTURES]; - VertexDeclD3D9 m_vertexDecls[BGFX_CONFIG_MAX_VERTEX_DECLS]; + VertexDecl m_vertexDecls[BGFX_CONFIG_MAX_VERTEX_DECLS]; FrameBufferD3D9 m_frameBuffers[BGFX_CONFIG_MAX_FRAME_BUFFERS]; UniformRegistry m_uniformReg; void* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS]; @@ -2129,6 +2236,8 @@ namespace bgfx { namespace d3d9 uint8_t m_updateTextureSide; uint8_t m_updateTextureMip; + StateCacheT<IDirect3DVertexDeclaration9> m_inputLayoutCache; + TextVideoMem m_textVideoMem; FrameBufferHandle m_fbh; @@ -2159,15 +2268,15 @@ namespace bgfx { namespace d3d9 { m_size = _size; m_flags = _flags; - m_dynamic = NULL == _data; uint32_t usage = D3DUSAGE_WRITEONLY; D3DPOOL pool = s_renderD3D9->m_pool; - if (m_dynamic) + if (NULL == _data) { usage |= D3DUSAGE_DYNAMIC; pool = D3DPOOL_DEFAULT; + m_dynamic = (uint8_t*)BX_ALLOC(g_allocator, _size); } const D3DFORMAT format = 0 == (_flags & BGFX_BUFFER_INDEX32) @@ -2191,7 +2300,7 @@ namespace bgfx { namespace d3d9 void IndexBufferD3D9::preReset() { - if (m_dynamic) + if (NULL != m_dynamic) { DX_RELEASE(m_ptr, 0); } @@ -2199,7 +2308,7 @@ namespace bgfx { namespace d3d9 void IndexBufferD3D9::postReset() { - if (m_dynamic) + if (NULL != m_dynamic) { const D3DFORMAT format = 0 == (m_flags & BGFX_BUFFER_INDEX32) ? D3DFMT_INDEX16 @@ -2213,6 +2322,8 @@ namespace bgfx { namespace d3d9 , &m_ptr , NULL ) ); + + update(0, m_size, m_dynamic); } } @@ -2220,24 +2331,24 @@ namespace bgfx { namespace d3d9 { m_size = _size; m_decl = _declHandle; - m_dynamic = NULL == _data; uint32_t usage = D3DUSAGE_WRITEONLY; D3DPOOL pool = s_renderD3D9->m_pool; - if (m_dynamic) + if (NULL == _data) { usage |= D3DUSAGE_DYNAMIC; pool = D3DPOOL_DEFAULT; + m_dynamic = (uint8_t*)BX_ALLOC(g_allocator, _size); } DX_CHECK(s_renderD3D9->m_device->CreateVertexBuffer(m_size - , usage - , 0 - , pool - , &m_ptr - , NULL - ) ); + , usage + , 0 + , pool + , &m_ptr + , NULL + ) ); if (NULL != _data) { @@ -2247,7 +2358,7 @@ namespace bgfx { namespace d3d9 void VertexBufferD3D9::preReset() { - if (m_dynamic) + if (NULL != m_dynamic) { DX_RELEASE(m_ptr, 0); } @@ -2255,127 +2366,18 @@ namespace bgfx { namespace d3d9 void VertexBufferD3D9::postReset() { - if (m_dynamic) + if (NULL != m_dynamic) { DX_CHECK(s_renderD3D9->m_device->CreateVertexBuffer(m_size - , D3DUSAGE_WRITEONLY|D3DUSAGE_DYNAMIC - , 0 - , D3DPOOL_DEFAULT - , &m_ptr - , NULL - ) ); - } - } - - static const D3DVERTEXELEMENT9 s_attrib[] = - { - { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, - { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 }, - { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0 }, - { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0 }, - { 0, 0, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 }, - { 0, 0, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1 }, - { 0, 0, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0 }, - { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0 }, - { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, - { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 }, - { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2 }, - { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3 }, - { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4 }, - { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 5 }, - { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 6 }, - { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 7 }, - D3DDECL_END() - }; - BX_STATIC_ASSERT(Attrib::Count == BX_COUNTOF(s_attrib)-1); - - 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 }, - { D3DDECLTYPE_FLOAT4, D3DDECLTYPE_FLOAT4 }, - }, - }; - BX_STATIC_ASSERT(AttribType::Count == BX_COUNTOF(s_attribType) ); - - static D3DVERTEXELEMENT9* fillVertexDecl(D3DVERTEXELEMENT9* _out, const VertexDecl& _decl) - { - D3DVERTEXELEMENT9* elem = _out; - - for (uint32_t attr = 0; attr < Attrib::Count; ++attr) - { - if (UINT16_MAX != _decl.m_attributes[attr]) - { - uint8_t num; - AttribType::Enum type; - bool normalized; - bool asInt; - _decl.decode(Attrib::Enum(attr), num, type, normalized, asInt); - - bx::memCopy(elem, &s_attrib[attr], sizeof(D3DVERTEXELEMENT9) ); - - elem->Type = s_attribType[type][num-1][normalized]; - elem->Offset = _decl.m_offset[attr]; - ++elem; - } - } - - return elem; - } - - static IDirect3DVertexDeclaration9* createVertexDeclaration(const VertexDecl& _decl, uint16_t _numInstanceData) - { - D3DVERTEXELEMENT9 vertexElements[Attrib::Count+1+BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT]; - D3DVERTEXELEMENT9* elem = fillVertexDecl(vertexElements, _decl); - - const D3DVERTEXELEMENT9 inst = { 1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }; + , D3DUSAGE_WRITEONLY|D3DUSAGE_DYNAMIC + , 0 + , D3DPOOL_DEFAULT + , &m_ptr + , NULL + ) ); - for (uint8_t ii = 0; ii < _numInstanceData; ++ii) - { - bx::memCopy(elem, &inst, sizeof(D3DVERTEXELEMENT9) ); - elem->UsageIndex = uint8_t(7-ii); // TEXCOORD7 = i_data0, TEXCOORD6 = i_data1, etc. - elem->Offset = ii*16; - ++elem; + update(0, m_size, m_dynamic); } - - bx::memCopy(elem, &s_attrib[Attrib::Count], sizeof(D3DVERTEXELEMENT9) ); - - IDirect3DVertexDeclaration9* ptr; - DX_CHECK(s_renderD3D9->m_device->CreateVertexDeclaration(vertexElements, &ptr) ); - return ptr; - } - - void VertexDeclD3D9::create(const VertexDecl& _decl) - { - bx::memCopy(&m_decl, &_decl, sizeof(VertexDecl) ); - dump(m_decl); - m_ptr = createVertexDeclaration(_decl, 0); } void ShaderD3D9::create(const Memory* _mem) @@ -2482,7 +2484,7 @@ namespace bgfx { namespace d3d9 } } - uint16_t shaderSize; + uint32_t shaderSize; bx::read(&reader, shaderSize); const DWORD* code = (const DWORD*)reader.getDataPtr(); @@ -2504,7 +2506,7 @@ namespace bgfx { namespace d3d9 void TextureD3D9::createTexture(uint32_t _width, uint32_t _height, uint8_t _numMips) { m_type = Texture2D; - const TextureFormat::Enum fmt = (TextureFormat::Enum)m_textureFormat; + const bimg::TextureFormat::Enum fmt = (bimg::TextureFormat::Enum)m_textureFormat; DWORD usage = 0; D3DPOOL pool = D3DPOOL_DEFAULT; @@ -2512,7 +2514,7 @@ namespace bgfx { namespace d3d9 const bool renderTarget = 0 != (m_flags&BGFX_TEXTURE_RT_MASK); const bool blit = 0 != (m_flags&BGFX_TEXTURE_BLIT_DST); const bool readBack = 0 != (m_flags&BGFX_TEXTURE_READ_BACK); - if (isDepth(fmt) ) + if (bimg::isDepth(fmt) ) { usage = D3DUSAGE_DEPTHSTENCIL; } @@ -2543,7 +2545,7 @@ namespace bgfx { namespace d3d9 { const Msaa& msaa = s_msaa[msaaQuality]; - if (isDepth(fmt) ) + if (bimg::isDepth(fmt) ) { DX_CHECK(device->CreateDepthStencilSurface( m_width @@ -2615,7 +2617,7 @@ namespace bgfx { namespace d3d9 , _width , _height , _numMips - , getName(fmt) + , bimg::getName(fmt) ); } @@ -2667,13 +2669,13 @@ namespace bgfx { namespace d3d9 void TextureD3D9::createCubeTexture(uint32_t _width, uint8_t _numMips) { m_type = TextureCube; - const TextureFormat::Enum fmt = (TextureFormat::Enum)m_textureFormat; + const bimg::TextureFormat::Enum fmt = (bimg::TextureFormat::Enum)m_textureFormat; DWORD usage = 0; const bool renderTarget = 0 != (m_flags&BGFX_TEXTURE_RT_MASK); const bool blit = 0 != (m_flags&BGFX_TEXTURE_BLIT_DST); - if (isDepth(fmt) ) + if (bimg::isDepth(fmt) ) { usage = D3DUSAGE_DEPTHSTENCIL; } @@ -2891,14 +2893,14 @@ namespace bgfx { namespace d3d9 void TextureD3D9::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(bimg::TextureFormat::Enum(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); @@ -2911,7 +2913,7 @@ namespace bgfx { namespace d3d9 m_textureFormat = uint8_t(getViableTextureFormat(imageContainer) ); const bool convert = m_textureFormat != m_requestedFormat; - uint8_t bpp = getBitsPerPixel(TextureFormat::Enum(m_textureFormat) ); + uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_textureFormat) ); if (imageContainer.m_cubeMap) { @@ -2926,11 +2928,6 @@ namespace bgfx { namespace d3d9 createTexture(textureWidth, textureHeight, numMips); } - if (imageContainer.m_srgb) - { - m_flags |= BGFX_TEXTURE_SRGB; - } - BX_TRACE("Texture %3d: %s (requested: %s), %dx%d%s%s." , this - s_renderD3D9->m_textures , getName( (TextureFormat::Enum)m_textureFormat) @@ -2950,8 +2947,8 @@ namespace bgfx { namespace d3d9 // bytes. If actual mip size is used it causes memory corruption. // http://www.aras-p.info/texts/D3D9GPUHacks.html#3dc const bool useMipSize = true - && imageContainer.m_format != TextureFormat::BC4 - && imageContainer.m_format != TextureFormat::BC5 + && imageContainer.m_format != bimg::TextureFormat::BC4 + && imageContainer.m_format != bimg::TextureFormat::BC5 ; for (uint8_t side = 0, numSides = imageContainer.m_cubeMap ? 6 : 1; side < numSides; ++side) @@ -2971,8 +2968,8 @@ namespace bgfx { namespace d3d9 mipHeight = bx::uint32_max(blockInfo.blockHeight, mipHeight); uint32_t mipSize = width*height*depth*bpp/8; - 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) ) { uint32_t pitch; uint32_t slicePitch; @@ -2986,7 +2983,7 @@ namespace bgfx { namespace d3d9 uint32_t srcpitch = mipWidth*bpp/8; uint8_t* temp = (uint8_t*)BX_ALLOC(g_allocator, srcpitch*mipHeight); - imageDecodeToBgra8(temp + bimg::imageDecodeToBgra8(temp , mip.m_data , mip.m_width , mip.m_height @@ -3000,7 +2997,7 @@ namespace bgfx { namespace d3d9 } else { - imageDecodeToBgra8(bits, mip.m_data, mip.m_width, mip.m_height, pitch, mip.m_format); + bimg::imageDecodeToBgra8(bits, mip.m_data, mip.m_width, mip.m_height, pitch, mip.m_format); } } else @@ -3009,11 +3006,11 @@ namespace bgfx { namespace d3d9 switch (m_textureFormat) { case TextureFormat::RGB5A1: - imageConvert(bits, 16, bx::packBgr5a1, mip.m_data, bx::unpackRgb5a1, size); + bimg::imageConvert(bits, 16, bx::packBgr5a1, mip.m_data, bx::unpackRgb5a1, size); break; case TextureFormat::RGBA4: - imageConvert(bits, 16, bx::packBgra4, mip.m_data, bx::unpackRgba4, size); + bimg::imageConvert(bits, 16, bx::packBgra4, mip.m_data, bx::unpackRgba4, size); break; default: @@ -3045,7 +3042,7 @@ namespace bgfx { namespace d3d9 void TextureD3D9::update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) { - 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; const uint32_t dstpitch = s_renderD3D9->m_updateTexturePitch; @@ -3059,7 +3056,7 @@ namespace bgfx { namespace d3d9 if (convert) { temp = (uint8_t*)BX_ALLOC(g_allocator, rectpitch*_rect.m_height); - imageDecodeToBgra8(temp, data, _rect.m_width, _rect.m_height, srcpitch, TextureFormat::Enum(m_requestedFormat) ); + bimg::imageDecodeToBgra8(temp, data, _rect.m_width, _rect.m_height, srcpitch, bimg::TextureFormat::Enum(m_requestedFormat) ); data = temp; } @@ -3071,11 +3068,11 @@ namespace bgfx { namespace d3d9 switch (m_textureFormat) { case TextureFormat::RGB5A1: - imageConvert(dst, 16, bx::packBgr5a1, src, bx::unpackRgb5a1, rectpitch); + bimg::imageConvert(dst, 16, bx::packBgr5a1, src, bx::unpackRgb5a1, rectpitch); break; case TextureFormat::RGBA4: - imageConvert(dst, 16, bx::packBgra4, src, bx::unpackRgba4, rectpitch); + bimg::imageConvert(dst, 16, bx::packBgra4, src, bx::unpackRgba4, rectpitch); break; default: @@ -3211,7 +3208,7 @@ namespace bgfx { namespace d3d9 m_height = texture.m_height; } - if (isDepth( (TextureFormat::Enum)texture.m_textureFormat) ) + if (bimg::isDepth(bimg::TextureFormat::Enum(texture.m_textureFormat) ) ) { m_dsIdx = uint8_t(ii); } @@ -3450,25 +3447,29 @@ namespace bgfx { namespace d3d9 { IDirect3DDevice9* device = s_renderD3D9->m_device; - for (uint32_t ii = 0; ii < BX_COUNTOF(m_frame); ++ii) + for (uint32_t ii = 0; ii < BX_COUNTOF(m_query); ++ii) { - Frame& frame = m_frame[ii]; + Query& frame = m_query[ii]; DX_CHECK(device->CreateQuery(D3DQUERYTYPE_TIMESTAMPDISJOINT, &frame.m_disjoint) ); DX_CHECK(device->CreateQuery(D3DQUERYTYPE_TIMESTAMP, &frame.m_begin) ); DX_CHECK(device->CreateQuery(D3DQUERYTYPE_TIMESTAMP, &frame.m_end) ); DX_CHECK(device->CreateQuery(D3DQUERYTYPE_TIMESTAMPFREQ, &frame.m_freq) ); } - m_elapsed = 0; - m_frequency = 1; + for (uint32_t ii = 0; ii < BX_COUNTOF(m_result); ++ii) + { + Result& result = m_result[ii]; + result.reset(); + } + m_control.reset(); } void TimerQueryD3D9::preReset() { - for (uint32_t ii = 0; ii < BX_COUNTOF(m_frame); ++ii) + for (uint32_t ii = 0; ii < BX_COUNTOF(m_query); ++ii) { - Frame& frame = m_frame[ii]; + Query& frame = m_query[ii]; DX_RELEASE(frame.m_disjoint, 0); DX_RELEASE(frame.m_begin, 0); DX_RELEASE(frame.m_end, 0); @@ -3476,51 +3477,74 @@ namespace bgfx { namespace d3d9 } } - void TimerQueryD3D9::begin() + uint32_t TimerQueryD3D9::begin(uint32_t _resultIdx) { while (0 == m_control.reserve(1) ) { - get(); + update(); } - Frame& frame = m_frame[m_control.m_current]; - frame.m_disjoint->Issue(D3DISSUE_BEGIN); - frame.m_begin->Issue(D3DISSUE_END); + 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; + + query.m_disjoint->Issue(D3DISSUE_BEGIN); + query.m_begin->Issue(D3DISSUE_END); + + m_control.commit(1); + + return idx; } - void TimerQueryD3D9::end() + void TimerQueryD3D9::end(uint32_t _idx) { - Frame& frame = m_frame[m_control.m_current]; - frame.m_disjoint->Issue(D3DISSUE_END); - frame.m_freq->Issue(D3DISSUE_END); - frame.m_end->Issue(D3DISSUE_END); - m_control.commit(1); + Query& query = m_query[_idx]; + query.m_ready = true; + + query.m_disjoint->Issue(D3DISSUE_END); + query.m_freq->Issue(D3DISSUE_END); + query.m_end->Issue(D3DISSUE_END); + + while (update() ) + { + } } - bool TimerQueryD3D9::get() + bool TimerQueryD3D9::update() { if (0 != m_control.available() ) { - Frame& frame = m_frame[m_control.m_read]; + Query& query = m_query[m_control.m_read]; + + if (!query.m_ready) + { + return false; + } uint64_t timeEnd; - const bool flush = BX_COUNTOF(m_frame)-1 == m_control.available(); - HRESULT hr = frame.m_end->GetData(&timeEnd, sizeof(timeEnd), flush ? D3DGETDATA_FLUSH : 0); + const bool flush = BX_COUNTOF(m_query)-1 == m_control.available(); + HRESULT hr = query.m_end->GetData(&timeEnd, sizeof(timeEnd), flush ? D3DGETDATA_FLUSH : 0); if (S_OK == hr || isLost(hr) ) { m_control.consume(1); uint64_t timeBegin; - DX_CHECK(frame.m_begin->GetData(&timeBegin, sizeof(timeBegin), 0) ); + DX_CHECK(query.m_begin->GetData(&timeBegin, sizeof(timeBegin), 0) ); uint64_t freq; - DX_CHECK(frame.m_freq->GetData(&freq, sizeof(freq), 0) ); + DX_CHECK(query.m_freq->GetData(&freq, sizeof(freq), 0) ); - m_frequency = freq; - m_begin = timeBegin; - m_end = timeEnd; - m_elapsed = timeEnd - timeBegin; + Result& result = m_result[query.m_resultIdx]; + --result.m_pending; + + result.m_frequency = freq; + result.m_begin = timeBegin; + result.m_end = timeEnd; return true; } @@ -3599,8 +3623,62 @@ namespace bgfx { namespace d3d9 Query& query = m_query[(m_control.m_read + ii) % size]; if (query.m_handle.idx == _handle.idx) { - query.m_handle.idx = bgfx::invalidHandle; + query.m_handle.idx = bgfx::kInvalidHandle; + } + } + } + + void RendererContextD3D9::submitBlit(BlitState& _bs, uint16_t _view) + { + while (_bs.hasItem(_view) ) + { + const BlitItem& blit = _bs.advance(); + + const TextureD3D9& src = m_textures[blit.m_src.idx]; + const TextureD3D9& 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 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 width = bx::uint32_min(srcWidth, dstWidth); + uint32_t height = bx::uint32_min(srcHeight, dstHeight); + + RECT srcRect = { LONG(blit.m_srcX), LONG(blit.m_srcY), LONG(blit.m_srcX + width), LONG(blit.m_srcY + height) }; + RECT dstRect = { LONG(blit.m_dstX), LONG(blit.m_dstY), LONG(blit.m_dstX + width), LONG(blit.m_dstY + height) }; + + IDirect3DSurface9* srcSurface = src.getSurface(uint8_t(blit.m_srcZ), blit.m_srcMip); + IDirect3DSurface9* dstSurface = dst.getSurface(uint8_t(blit.m_dstZ), blit.m_dstMip); + + // UpdateSurface (pool src: SYSTEMMEM, dst: DEFAULT) + // s/d T RTT RT + // T y y y + // RTT - - - + // RT - - - + // + // StretchRect (pool src and dst must be DEFAULT) + // s/d T RTT RT + // T - y y + // RTT - y y + // RT - y y + // + // GetRenderTargetData (dst must be SYSTEMMEM) + + bool depth = bimg::isDepth(bimg::TextureFormat::Enum(src.m_textureFormat) ); + HRESULT hr = m_device->StretchRect(srcSurface + , depth ? NULL : &srcRect + , dstSurface + , depth ? NULL : &dstRect + , D3DTEXF_NONE + ); + if (FAILED(hr) ) + { + hr = m_device->GetRenderTargetData(srcSurface, dstSurface); + BX_WARN(SUCCEEDED(hr), "StretchRect and GetRenderTargetData failed %x.", hr); } + + srcSurface->Release(); + dstSurface->Release(); } } @@ -3612,13 +3690,15 @@ namespace bgfx { namespace d3d9 updateResolution(_render->m_resolution); - int64_t elapsed = -bx::getHPCounter(); + int64_t timeBegin = bx::getHPCounter(); int64_t captureElapsed = 0; + uint32_t frameQueryIdx = UINT32_MAX; + device->BeginScene(); if (m_timerQuerySupport) { - m_gpuTimer.begin(); + frameQueryIdx = m_gpuTimer.begin(BGFX_CONFIG_MAX_VIEWS); } if (0 < _render->m_iboffset) @@ -3640,19 +3720,19 @@ namespace bgfx { namespace d3d9 currentState.m_stateFlags = BGFX_STATE_NONE; currentState.m_stencil = packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE); + RenderBind currentBind; + currentBind.clear(); + ViewState viewState(_render, false); DX_CHECK(device->SetRenderState(D3DRS_FILLMODE, _render->m_debug&BGFX_DEBUG_WIREFRAME ? D3DFILL_WIREFRAME : D3DFILL_SOLID) ); - uint16_t programIdx = invalidHandle; + uint16_t programIdx = kInvalidHandle; SortKey key; uint16_t view = UINT16_MAX; FrameBufferHandle fbh = { BGFX_CONFIG_MAX_FRAME_BUFFERS }; uint32_t blendFactor = 0; - BlitKey blitKey; - blitKey.decode(_render->m_blitKeys[0]); - uint16_t numBlitItems = _render->m_numBlitItems; - uint16_t blitItem = 0; + BlitState bs(_render); uint8_t primIndex; { @@ -3673,6 +3753,13 @@ namespace bgfx { namespace d3d9 invalidateSamplerState(); + Profiler<TimerQueryD3D9> profiler( + _render + , m_gpuTimer + , s_viewName + , m_timerQuerySupport + ); + if (m_occlusionQuerySupport) { m_occlusionQuery.resolve(_render); @@ -3680,7 +3767,7 @@ namespace bgfx { namespace d3d9 if (0 == (_render->m_debug&BGFX_DEBUG_IFH) ) { - for (uint32_t item = 0, numItems = _render->m_num; item < numItems; ++item) + for (uint32_t item = 0, numItems = _render->m_numRenderItems; item < numItems; ++item) { const uint64_t encodedKey = _render->m_sortKeys[item]; const bool isCompute = key.decode(encodedKey, _render->m_viewRemap); @@ -3692,7 +3779,9 @@ namespace bgfx { namespace d3d9 continue; } - const RenderDraw& draw = _render->m_renderItem[_render->m_sortValues[item] ].draw; + const uint32_t itemIdx = _render->m_sortValues[item]; + const RenderDraw& draw = _render->m_renderItem[itemIdx].draw; + const RenderBind& renderBind = _render->m_renderItemBind[itemIdx]; const bool hasOcclusionQuery = 0 != (draw.m_stateFlags & BGFX_STATE_INTERNAL_OCCLUSION_QUERY); if (isValid(draw.m_occlusionQuery) @@ -3719,25 +3808,26 @@ namespace bgfx { namespace d3d9 currentState.m_stateFlags = newFlags; currentState.m_stencil = newStencil; - PIX_ENDEVENT(); - PIX_BEGINEVENT(D3DCOLOR_VIEW, s_viewNameW[key.m_view]); - if (item > 0) - { - BGFX_PROFILER_END(); - } - BGFX_PROFILER_BEGIN_DYNAMIC(s_viewName[key.m_view]); - view = key.m_view; - programIdx = invalidHandle; + programIdx = kInvalidHandle; - if (_render->m_fb[view].idx != fbh.idx) + if (_render->m_view[view].m_fbh.idx != fbh.idx) { - fbh = _render->m_fb[view]; + fbh = _render->m_view[view].m_fbh; setFrameBuffer(fbh); } - viewState.m_rect = _render->m_rect[view]; - const Rect& scissorRect = _render->m_scissor[view]; + PIX_ENDEVENT(); + if (item > 0) + { + profiler.end(); + } + + profiler.begin(view); + PIX_BEGINEVENT(D3DCOLOR_VIEW, s_viewNameW[view]); + + viewState.m_rect = _render->m_view[view].m_rect; + const Rect& scissorRect = _render->m_view[view].m_scissor; viewHasScissor = !scissorRect.isZero(); viewScissorRect = viewHasScissor ? scissorRect : viewState.m_rect; @@ -3750,12 +3840,11 @@ namespace bgfx { namespace d3d9 vp.MaxZ = 1.0f; DX_CHECK(device->SetViewport(&vp) ); - Clear& clear = _render->m_clear[view]; + Clear& clear = _render->m_view[view].m_clear; if (BGFX_CLEAR_NONE != (clear.m_flags & BGFX_CLEAR_MASK) ) { clearQuad(_clearQuad, viewState.m_rect, clear, _render->m_colorPalette); - prim = s_primInfo[BX_COUNTOF(s_primName)]; // Force primitive type update after clear quad. } DX_CHECK(device->SetRenderState(D3DRS_STENCILENABLE, FALSE) ); @@ -3765,58 +3854,7 @@ namespace bgfx { namespace d3d9 DX_CHECK(device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE) ); DX_CHECK(device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER) ); - 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 TextureD3D9& src = m_textures[blit.m_src.idx]; - const TextureD3D9& 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 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 width = bx::uint32_min(srcWidth, dstWidth); - uint32_t height = bx::uint32_min(srcHeight, dstHeight); - - RECT srcRect = { LONG(blit.m_srcX), LONG(blit.m_srcY), LONG(blit.m_srcX + width), LONG(blit.m_srcY + height) }; - RECT dstRect = { LONG(blit.m_dstX), LONG(blit.m_dstY), LONG(blit.m_dstX + width), LONG(blit.m_dstY + height) }; - - IDirect3DSurface9* srcSurface = src.getSurface(uint8_t(blit.m_srcZ), blit.m_srcMip); - IDirect3DSurface9* dstSurface = dst.getSurface(uint8_t(blit.m_dstZ), blit.m_dstMip); - - // UpdateSurface (pool src: SYSTEMMEM, dst: DEFAULT) - // s/d T RTT RT - // T y y y - // RTT - - - - // RT - - - - // - // StretchRect (pool src and dst must be DEFAULT) - // s/d T RTT RT - // T - y y - // RTT - y y - // RT - y y - // - // GetRenderTargetData (dst must be SYSTEMMEM) - - bool depth = isDepth(TextureFormat::Enum(src.m_textureFormat) ); - HRESULT hr = m_device->StretchRect(srcSurface - , depth ? NULL : &srcRect - , dstSurface - , depth ? NULL : &dstRect - , D3DTEXF_NONE - ); - if (FAILED(hr) ) - { - hr = m_device->GetRenderTargetData(srcSurface, dstSurface); - BX_WARN(SUCCEEDED(hr), "StretchRect and GetRenderTargetData failed %x.", hr); - } - - srcSurface->Release(); - dstSurface->Release(); - } + submitBlit(bs, view); } uint16_t scissor = draw.m_scissor; @@ -3840,7 +3878,7 @@ namespace bgfx { namespace d3d9 else { 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; @@ -4044,14 +4082,14 @@ namespace bgfx { namespace d3d9 } bool programChanged = false; - bool constantsChanged = draw.m_constBegin < draw.m_constEnd; - rendererUpdateUniforms(this, _render->m_uniformBuffer, draw.m_constBegin, draw.m_constEnd); + bool constantsChanged = draw.m_uniformBegin < draw.m_uniformEnd; + rendererUpdateUniforms(this, _render->m_uniformBuffer[draw.m_uniformIdx], draw.m_uniformBegin, draw.m_uniformEnd); if (key.m_program != programIdx) { programIdx = key.m_program; - if (invalidHandle == programIdx) + if (kInvalidHandle == programIdx) { device->SetVertexShader(NULL); device->SetPixelShader(NULL); @@ -4067,7 +4105,7 @@ namespace bgfx { namespace d3d9 constantsChanged = true; } - if (invalidHandle != programIdx) + if (kInvalidHandle != programIdx) { ProgramD3D9& program = m_program[programIdx]; @@ -4092,13 +4130,14 @@ namespace bgfx { namespace d3d9 { for (uint8_t stage = 0; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++stage) { - const Binding& bind = draw.m_bind[stage]; - Binding& current = currentState.m_bind[stage]; + const Binding& bind = renderBind.m_bind[stage]; + Binding& current = currentBind.m_bind[stage]; + if (current.m_idx != bind.m_idx || current.m_un.m_draw.m_textureFlags != bind.m_un.m_draw.m_textureFlags || programChanged) { - if (invalidHandle != bind.m_idx) + if (kInvalidHandle != bind.m_idx) { m_textures[bind.m_idx].commit(stage, bind.m_un.m_draw.m_textureFlags, _render->m_colorPalette); } @@ -4112,45 +4151,75 @@ namespace bgfx { namespace d3d9 } } + bool vertexStreamChanged = hasVertexStreamChanged(currentState, draw); + if (programChanged - || currentState.m_streamMask != draw.m_streamMask - || currentState.m_stream[0].m_handle.idx != draw.m_stream[0].m_handle.idx - || currentState.m_instanceDataBuffer.idx != draw.m_instanceDataBuffer.idx - || currentState.m_instanceDataOffset != draw.m_instanceDataOffset - || currentState.m_instanceDataStride != draw.m_instanceDataStride) + || vertexStreamChanged) { - currentState.m_streamMask = draw.m_streamMask; - currentState.m_stream[0].m_handle = draw.m_stream[0].m_handle; + currentState.m_streamMask = draw.m_streamMask; currentState.m_instanceDataBuffer.idx = draw.m_instanceDataBuffer.idx; currentState.m_instanceDataOffset = draw.m_instanceDataOffset; currentState.m_instanceDataStride = draw.m_instanceDataStride; - uint16_t handle = draw.m_stream[0].m_handle.idx; - if (invalidHandle != handle) + const VertexDecl* decls[BGFX_CONFIG_MAX_VERTEX_STREAMS]; + + const bool instanced = true + && isValid(draw.m_instanceDataBuffer) + && m_instancingSupport + ; + + const uint32_t freq = instanced + ? D3DSTREAMSOURCE_INDEXEDDATA|draw.m_numInstances + : 1 + ; + + uint32_t numVertices = draw.m_numVertices; + uint8_t numStreams = 0; + for (uint32_t idx = 0, streamMask = draw.m_streamMask, ntz = bx::uint32_cnttz(streamMask) + ; 0 != streamMask + ; streamMask >>= 1, idx += 1, ntz = bx::uint32_cnttz(streamMask), ++numStreams + ) { + streamMask >>= ntz; + idx += ntz; + + currentState.m_stream[idx].m_decl = draw.m_stream[idx].m_decl; + currentState.m_stream[idx].m_handle = draw.m_stream[idx].m_handle; + currentState.m_stream[idx].m_startVertex = draw.m_stream[idx].m_startVertex; + + const uint16_t handle = draw.m_stream[idx].m_handle.idx; const VertexBufferD3D9& vb = m_vertexBuffers[handle]; + const uint16_t decl = !isValid(vb.m_decl) ? draw.m_stream[idx].m_decl.idx : vb.m_decl.idx; + const VertexDecl& vertexDecl = m_vertexDecls[decl]; + const uint32_t stride = vertexDecl.m_stride; + + decls[numStreams] = &vertexDecl; - uint16_t decl = !isValid(vb.m_decl) ? draw.m_stream[0].m_decl.idx : vb.m_decl.idx; - const VertexDeclD3D9& vertexDecl = m_vertexDecls[decl]; - DX_CHECK(device->SetStreamSource(0, vb.m_ptr, 0, vertexDecl.m_decl.m_stride) ); + numVertices = bx::uint32_min(UINT32_MAX == draw.m_numVertices + ? vb.m_size/stride + : draw.m_numVertices + , numVertices + ); + + DX_CHECK(device->SetStreamSourceFreq(0, freq) ); + DX_CHECK(device->SetStreamSource(numStreams, vb.m_ptr, 0, stride) ); + } - if (isValid(draw.m_instanceDataBuffer) - && m_instancingSupport) + currentState.m_numVertices = numVertices; + + if (0 < numStreams) + { + if (instanced) { const VertexBufferD3D9& inst = m_vertexBuffers[draw.m_instanceDataBuffer.idx]; - DX_CHECK(device->SetStreamSourceFreq(0, D3DSTREAMSOURCE_INDEXEDDATA|draw.m_numInstances) ); - DX_CHECK(device->SetStreamSourceFreq(1, UINT(D3DSTREAMSOURCE_INSTANCEDATA|1) ) ); - DX_CHECK(device->SetStreamSource(1, inst.m_ptr, draw.m_instanceDataOffset, draw.m_instanceDataStride) ); - - IDirect3DVertexDeclaration9* ptr = createVertexDeclaration(vertexDecl.m_decl, draw.m_instanceDataStride/16); - DX_CHECK(device->SetVertexDeclaration(ptr) ); - DX_RELEASE(ptr, 0); + DX_CHECK(device->SetStreamSourceFreq(numStreams, UINT(D3DSTREAMSOURCE_INSTANCEDATA|1) ) ); + DX_CHECK(device->SetStreamSource(numStreams, inst.m_ptr, draw.m_instanceDataOffset, draw.m_instanceDataStride) ); + setInputLayout(numStreams, decls, draw.m_instanceDataStride/16); } else { - DX_CHECK(device->SetStreamSourceFreq(0, 1) ); - DX_CHECK(device->SetStreamSource(1, NULL, 0, 0) ); - DX_CHECK(device->SetVertexDeclaration(vertexDecl.m_ptr) ); + DX_CHECK(device->SetStreamSource(numStreams, NULL, 0, 0) ); + setInputLayout(numStreams, decls, 0); } } else @@ -4165,7 +4234,7 @@ namespace bgfx { namespace d3d9 currentState.m_indexBuffer = draw.m_indexBuffer; uint16_t handle = draw.m_indexBuffer.idx; - if (invalidHandle != handle) + if (kInvalidHandle != handle) { const IndexBufferD3D9& ib = m_indexBuffers[handle]; DX_CHECK(device->SetIndices(ib.m_ptr) ); @@ -4178,15 +4247,7 @@ namespace bgfx { namespace d3d9 if (0 != currentState.m_streamMask) { - uint32_t numVertices = draw.m_numVertices; - if (UINT32_MAX == numVertices) - { - const VertexBufferD3D9& vb = m_vertexBuffers[currentState.m_stream[0].m_handle.idx]; - uint16_t decl = !isValid(vb.m_decl) ? draw.m_stream[0].m_decl.idx : vb.m_decl.idx; - const VertexDeclD3D9& vertexDecl = m_vertexDecls[decl]; - numVertices = vb.m_size/vertexDecl.m_decl.m_stride; - } - + uint32_t numVertices = draw.m_numVertices; uint32_t numIndices = 0; uint32_t numPrimsSubmitted = 0; uint32_t numInstances = 0; @@ -4256,7 +4317,9 @@ namespace bgfx { namespace d3d9 } } - if (0 < _render->m_num) + submitBlit(bs, BGFX_CONFIG_MAX_VIEWS); + + if (0 < _render->m_numRenderItems) { if (0 != (m_resolution.m_flags & BGFX_RESET_FLUSH_AFTER_RENDER) ) { @@ -4267,22 +4330,14 @@ namespace bgfx { namespace d3d9 capture(); captureElapsed += bx::getHPCounter(); - BGFX_PROFILER_END(); + profiler.end(); } } PIX_ENDEVENT(); - int64_t now = bx::getHPCounter(); - elapsed += now; - - static int64_t last = now; - - Stats& perfStats = _render->m_perfStats; - perfStats.cpuTimeBegin = last; - - 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; @@ -4293,31 +4348,32 @@ namespace bgfx { namespace d3d9 static double maxGpuElapsed = 0.0f; double elapsedGpuMs = 0.0; - if (m_timerQuerySupport) + if (UINT32_MAX != frameQueryIdx) { - m_gpuTimer.end(); + m_gpuTimer.end(frameQueryIdx); - do - { - double toGpuMs = 1000.0 / double(m_gpuTimer.m_frequency); - elapsedGpuMs = m_gpuTimer.m_elapsed * toGpuMs; - maxGpuElapsed = elapsedGpuMs > maxGpuElapsed ? elapsedGpuMs : maxGpuElapsed; - } - while (m_gpuTimer.get() ); + const TimerQueryD3D9::Result& result = m_gpuTimer.m_result[BGFX_CONFIG_MAX_VIEWS]; + double toGpuMs = 1000.0 / double(result.m_frequency); + elapsedGpuMs = (result.m_end - result.m_begin) * toGpuMs; + maxGpuElapsed = elapsedGpuMs > maxGpuElapsed ? elapsedGpuMs : maxGpuElapsed; - maxGpuLatency = bx::uint32_imax(maxGpuLatency, m_gpuTimer.m_control.available()-1); + maxGpuLatency = bx::uint32_imax(maxGpuLatency, result.m_pending-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; - perfStats.gpuTimerFreq = m_gpuTimer.m_frequency; + const TimerQueryD3D9::Result& result = m_gpuTimer.m_result[BGFX_CONFIG_MAX_VIEWS]; + perfStats.gpuTimeBegin = result.m_begin; + perfStats.gpuTimeEnd = result.m_end; + perfStats.gpuTimerFreq = result.m_frequency; perfStats.numDraw = statsKeyType[0]; perfStats.numCompute = statsKeyType[1]; perfStats.maxGpuLatency = maxGpuLatency; + m_nvapi.getMemoryInfo(perfStats.gpuMemoryUsed, perfStats.gpuMemoryMax); if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) ) { @@ -4326,11 +4382,11 @@ namespace bgfx { namespace d3d9 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 + timerFreq; + next = timeEnd + timerFreq; double freq = double(timerFreq); double toMs = 1000.0/freq; @@ -4364,9 +4420,9 @@ namespace bgfx { namespace d3d9 , !!(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] %c GPU %7.4f [ms] (latency %d)" - , _render->m_num + , _render->m_numRenderItems , statsKeyType[0] , statsKeyType[1] , elapsedCpuMs @@ -4388,11 +4444,21 @@ namespace bgfx { namespace d3d9 } 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); pos++; + tvm.printf(10, pos++, 0x8e, " Occlusion queries: %3d ", m_occlusionQuery.m_control.available() ); + + pos++; + tvm.printf(10, pos++, 0x8e, " State cache: "); + tvm.printf(10, pos++, 0x8e, " Input "); + tvm.printf(10, pos++, 0x8e, " %6d " + , m_inputLayoutCache.getCount() + ); + pos++; + double captureMs = double(captureElapsed)*toMs; tvm.printf(10, pos++, 0x8e, " Capture: %7.4f [ms]", captureMs); |