From 12e5a9a316b4a10f175e0e2d304feb150f514603 Mon Sep 17 00:00:00 2001 From: Balazs Torok Date: Sun, 25 Sep 2016 21:42:17 +0200 Subject: [PATCH] basic implementation for Direct3D9 and Direct3DDevice9 --- renderdoc/common/timing.h | 51 + renderdoc/driver/d3d11/d3d11_device.cpp | 40 +- renderdoc/driver/d3d11/d3d11_device.h | 4 +- renderdoc/driver/d3d12/d3d12_device.cpp | 40 +- renderdoc/driver/d3d12/d3d12_device.h | 4 +- renderdoc/driver/d3d9/d3d9_debug.cpp | 314 ++++++ renderdoc/driver/d3d9/d3d9_debug.h | 76 ++ renderdoc/driver/d3d9/d3d9_device.cpp | 965 ++++++++++++++++++ renderdoc/driver/d3d9/d3d9_device.h | 287 ++++++ renderdoc/driver/d3d9/d3d9_hooks.cpp | 7 +- renderdoc/driver/d3d9/renderdoc_d3d9.vcxproj | 4 + .../d3d9/renderdoc_d3d9.vcxproj.filters | 18 + renderdoc/driver/gl/gl_driver.cpp | 39 +- renderdoc/driver/gl/gl_driver.h | 6 +- renderdoc/driver/vulkan/vk_core.cpp | 4 +- renderdoc/driver/vulkan/vk_core.h | 6 +- .../driver/vulkan/wrappers/vk_wsi_funcs.cpp | 33 +- 17 files changed, 1753 insertions(+), 145 deletions(-) create mode 100644 renderdoc/driver/d3d9/d3d9_debug.cpp create mode 100644 renderdoc/driver/d3d9/d3d9_debug.h create mode 100644 renderdoc/driver/d3d9/d3d9_device.cpp create mode 100644 renderdoc/driver/d3d9/d3d9_device.h diff --git a/renderdoc/common/timing.h b/renderdoc/common/timing.h index ccbc93ba3..dd7329f33 100644 --- a/renderdoc/common/timing.h +++ b/renderdoc/common/timing.h @@ -48,6 +48,57 @@ private: uint64_t m_Start; }; +class FrameTimer +{ +public: + void InitTimers() + { + m_HighPrecisionTimer.Restart(); + m_TotalTime = m_AvgFrametime = m_MinFrametime = m_MaxFrametime = 0.0; + } + + void UpdateTimers() + { + m_FrameTimes.push_back(m_HighPrecisionTimer.GetMilliseconds()); + m_TotalTime += m_FrameTimes.back(); + m_HighPrecisionTimer.Restart(); + + // update every second + if(m_TotalTime > 1000.0) + { + m_MinFrametime = 10000.0; + m_MaxFrametime = 0.0; + m_AvgFrametime = 0.0; + + m_TotalTime = 0.0; + + for(size_t i = 0; i < m_FrameTimes.size(); i++) + { + m_AvgFrametime += m_FrameTimes[i]; + if(m_FrameTimes[i] < m_MinFrametime) + m_MinFrametime = m_FrameTimes[i]; + if(m_FrameTimes[i] > m_MaxFrametime) + m_MaxFrametime = m_FrameTimes[i]; + } + + m_AvgFrametime /= double(m_FrameTimes.size()); + + m_FrameTimes.clear(); + } + } + + double GetAvgFrameTime() const { return m_AvgFrametime; } + double GetMinFrameTime() const { return m_MinFrametime; } + double GetMaxFrameTime() const { return m_MaxFrametime; } +private: + PerformanceTimer m_HighPrecisionTimer; + vector m_FrameTimes; + double m_TotalTime; + double m_AvgFrametime; + double m_MinFrametime; + double m_MaxFrametime; +}; + class ScopedTimer { public: diff --git a/renderdoc/driver/d3d11/d3d11_device.cpp b/renderdoc/driver/d3d11/d3d11_device.cpp index ceb4ef660..d337f1713 100644 --- a/renderdoc/driver/d3d11/d3d11_device.cpp +++ b/renderdoc/driver/d3d11/d3d11_device.cpp @@ -346,11 +346,9 @@ WrappedID3D11Device::WrappedID3D11Device(ID3D11Device *realDevice, D3D11InitPara m_ChunkAtomic = 0; - m_FrameTimer.Restart(); - m_AppControlledCapture = false; - m_TotalTime = m_AvgFrametime = m_MinFrametime = m_MaxFrametime = 0.0; + m_FrameTimer.InitTimers(); #if defined(RELEASE) const bool debugSerialiser = false; @@ -3239,32 +3237,7 @@ HRESULT WrappedID3D11Device::Present(WrappedIDXGISwapChain3 *swap, UINT SyncInte { D3D11RenderState old = *m_pImmediateContext->GetCurrentPipelineState(); - m_FrameTimes.push_back(m_FrameTimer.GetMilliseconds()); - m_TotalTime += m_FrameTimes.back(); - m_FrameTimer.Restart(); - - // update every second - if(m_TotalTime > 1000.0) - { - m_MinFrametime = 10000.0; - m_MaxFrametime = 0.0; - m_AvgFrametime = 0.0; - - m_TotalTime = 0.0; - - for(size_t i = 0; i < m_FrameTimes.size(); i++) - { - m_AvgFrametime += m_FrameTimes[i]; - if(m_FrameTimes[i] < m_MinFrametime) - m_MinFrametime = m_FrameTimes[i]; - if(m_FrameTimes[i] > m_MaxFrametime) - m_MaxFrametime = m_FrameTimes[i]; - } - - m_AvgFrametime /= double(m_FrameTimes.size()); - - m_FrameTimes.clear(); - } + m_FrameTimer.UpdateTimers(); uint32_t overlay = RenderDoc::Inst().GetOverlayBits(); @@ -3312,10 +3285,11 @@ HRESULT WrappedID3D11Device::Present(WrappedIDXGISwapChain3 *swap, UINT SyncInte } if(overlay & eRENDERDOC_Overlay_FrameRate) { - overlayText += StringFormat::Fmt(" %.2lf ms (%.2lf .. %.2lf) (%.0lf FPS)", m_AvgFrametime, - m_MinFrametime, m_MaxFrametime, - // max with 0.01ms so that we don't divide by zero - 1000.0f / RDCMAX(0.01, m_AvgFrametime)); + overlayText += StringFormat::Fmt( + " %.2lf ms (%.2lf .. %.2lf) (%.0lf FPS)", m_FrameTimer.GetAvgFrameTime(), + m_FrameTimer.GetMinFrameTime(), m_FrameTimer.GetMaxFrameTime(), + // max with 0.01ms so that we don't divide by zero + 1000.0f / RDCMAX(0.01, m_FrameTimer.GetAvgFrameTime())); } float y = 0.0f; diff --git a/renderdoc/driver/d3d11/d3d11_device.h b/renderdoc/driver/d3d11/d3d11_device.h index 4aa1db1f6..962ce140a 100644 --- a/renderdoc/driver/d3d11/d3d11_device.h +++ b/renderdoc/driver/d3d11/d3d11_device.h @@ -347,9 +347,7 @@ private: CaptureFailReason m_FailedReason; uint32_t m_Failures; - PerformanceTimer m_FrameTimer; - vector m_FrameTimes; - double m_TotalTime, m_AvgFrametime, m_MinFrametime, m_MaxFrametime; + FrameTimer m_FrameTimer; vector m_DebugMessages; diff --git a/renderdoc/driver/d3d12/d3d12_device.cpp b/renderdoc/driver/d3d12/d3d12_device.cpp index 111b96c92..9fee77497 100644 --- a/renderdoc/driver/d3d12/d3d12_device.cpp +++ b/renderdoc/driver/d3d12/d3d12_device.cpp @@ -183,9 +183,7 @@ WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitPara m_FrameCounter = 0; - m_FrameTimer.Restart(); - - m_TotalTime = m_AvgFrametime = m_MinFrametime = m_MaxFrametime = 0.0; + m_FrameTimer.InitTimers(); m_HeaderChunk = NULL; @@ -704,32 +702,7 @@ HRESULT WrappedID3D12Device::Present(WrappedIDXGISwapChain3 *swap, UINT SyncInte if(m_State == WRITING_IDLE) { - m_FrameTimes.push_back(m_FrameTimer.GetMilliseconds()); - m_TotalTime += m_FrameTimes.back(); - m_FrameTimer.Restart(); - - // update every second - if(m_TotalTime > 1000.0) - { - m_MinFrametime = 10000.0; - m_MaxFrametime = 0.0; - m_AvgFrametime = 0.0; - - m_TotalTime = 0.0; - - for(size_t i = 0; i < m_FrameTimes.size(); i++) - { - m_AvgFrametime += m_FrameTimes[i]; - if(m_FrameTimes[i] < m_MinFrametime) - m_MinFrametime = m_FrameTimes[i]; - if(m_FrameTimes[i] > m_MaxFrametime) - m_MaxFrametime = m_FrameTimes[i]; - } - - m_AvgFrametime /= double(m_FrameTimes.size()); - - m_FrameTimes.clear(); - } + m_FrameTimer.UpdateTimers(); uint32_t overlay = RenderDoc::Inst().GetOverlayBits(); @@ -788,10 +761,11 @@ HRESULT WrappedID3D12Device::Present(WrappedIDXGISwapChain3 *swap, UINT SyncInte } if(overlay & eRENDERDOC_Overlay_FrameRate) { - overlayText += StringFormat::Fmt(" %.2lf ms (%.2lf .. %.2lf) (%.0lf FPS)", m_AvgFrametime, - m_MinFrametime, m_MaxFrametime, - // max with 0.01ms so that we don't divide by zero - 1000.0f / RDCMAX(0.01, m_AvgFrametime)); + overlayText += StringFormat::Fmt( + " %.2lf ms (%.2lf .. %.2lf) (%.0lf FPS)", m_FrameTimer.GetAvgFrameTime(), + m_FrameTimer.GetMinFrameTime(), m_FrameTimer.GetMaxFrameTime(), + // max with 0.01ms so that we don't divide by zero + 1000.0f / RDCMAX(0.01, m_FrameTimer.GetAvgFrameTime())); } float y = 0.0f; diff --git a/renderdoc/driver/d3d12/d3d12_device.h b/renderdoc/driver/d3d12/d3d12_device.h index 1d9902d1b..6e20494a1 100644 --- a/renderdoc/driver/d3d12/d3d12_device.h +++ b/renderdoc/driver/d3d12/d3d12_device.h @@ -250,9 +250,7 @@ private: FetchFrameRecord m_FrameRecord; vector m_Drawcalls; - PerformanceTimer m_FrameTimer; - vector m_FrameTimes; - double m_TotalTime, m_AvgFrametime, m_MinFrametime, m_MaxFrametime; + FrameTimer m_FrameTimer; Serialiser *m_pSerialiser; bool m_AppControlledCapture; diff --git a/renderdoc/driver/d3d9/d3d9_debug.cpp b/renderdoc/driver/d3d9/d3d9_debug.cpp new file mode 100644 index 000000000..e0e2dff8a --- /dev/null +++ b/renderdoc/driver/d3d9/d3d9_debug.cpp @@ -0,0 +1,314 @@ +/****************************************************************************** +* The MIT License (MIT) +* +* Copyright (c) 2015-2016 Baldur Karlsson +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +******************************************************************************/ + +#include "d3d9_debug.h" +#include "os/os_specific.h" +#include "stb/stb_truetype.h" + +D3D9DebugManager::D3D9DebugManager(WrappedD3DDevice9 *wrapper) + : m_WrappedDevice(wrapper), m_fvf(D3DFVF_XYZ | D3DFVF_TEX1) +{ + InitFontRendering(); +} + +D3D9DebugManager::~D3D9DebugManager() +{ + ShutdownFontRendering(); +} + +bool D3D9DebugManager::InitFontRendering() +{ + HRESULT hr = S_OK; + + int width = FONT_TEX_WIDTH; + int height = FONT_TEX_HEIGHT; + + string font = GetEmbeddedResource(sourcecodepro_ttf); + byte *ttfdata = (byte *)font.c_str(); + + const int firstChar = int(' ') + 1; + const int lastChar = 127; + const int numChars = lastChar - firstChar; + + byte *buf = new byte[width * height]; + + const float pixelHeight = 20.0f; + + stbtt_BakeFontBitmap(ttfdata, 0, pixelHeight, buf, width, height, firstChar, numChars, + m_Font.charData); + + stbtt_fontinfo f = {0}; + stbtt_InitFont(&f, ttfdata, 0); + + int ascent = 0; + stbtt_GetFontVMetrics(&f, &ascent, NULL, NULL); + + m_Font.maxHeight = float(ascent) * stbtt_ScaleForPixelHeight(&f, pixelHeight); + + IDirect3DTexture9 *fontTex = NULL; + + hr = m_WrappedDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, + D3DPOOL_DEFAULT, &fontTex, NULL); + + if(FAILED(hr)) + { + RDCERR("Failed to create font texture %08x", hr); + } + + D3DLOCKED_RECT lockedRegion; + hr = fontTex->LockRect(0, &lockedRegion, NULL, D3DLOCK_DISCARD); + + if(FAILED(hr)) + { + RDCERR("Failed to lock font texture %08x", hr); + } + else + { + BYTE *texBase = (BYTE *)lockedRegion.pBits; + + for(int y = 0; y < height; y++) + { + byte *curRow = (texBase + (y * lockedRegion.Pitch)); + + for(int x = 0; x < width; x++) + { + curRow[x * 4 + 0] = buf[(y * width) + x]; + curRow[x * 4 + 1] = buf[(y * width) + x]; + curRow[x * 4 + 2] = buf[(y * width) + x]; + curRow[x * 4 + 3] = buf[(y * width) + x]; + } + } + + hr = fontTex->UnlockRect(0); + if(hr != S_OK) + { + RDCERR("Failed to unlock font texture %08x", hr); + } + } + + m_Font.Tex = fontTex; + + delete[] buf; + + return true; +} + +void D3D9DebugManager::ShutdownFontRendering() +{ + SAFE_RELEASE(m_Font.Tex); +} + +void D3D9DebugManager::SetOutputWindow(HWND w) +{ + // RECT rect; + // GetClientRect(w, &rect); + // m_supersamplingX = float(m_width) / float(rect.right - rect.left); + // m_supersamplingY = float(m_height) / float(rect.bottom - rect.top); +} + +void D3D9DebugManager::RenderText(float x, float y, const char *textfmt, ...) +{ + static char tmpBuf[4096]; + + va_list args; + va_start(args, textfmt); + StringFormat::vsnprintf(tmpBuf, 4095, textfmt, args); + tmpBuf[4095] = '\0'; + va_end(args); + + RenderTextInternal(x, y, tmpBuf); +} + +void D3D9DebugManager::RenderTextInternal(float x, float y, const char *text) +{ + if(char *t = strchr((char *)text, '\n')) + { + *t = 0; + RenderTextInternal(x, y, text); + RenderTextInternal(x, y + 1.0f, t + 1); + *t = '\n'; + return; + } + + if(strlen(text) == 0) + return; + + RDCASSERT(strlen(text) < FONT_MAX_CHARS); + + // transforms + float width = (float)m_width; + float height = (float)m_height; + float nearPlane = 0.001f; + float farPlane = 1.f; + D3DMATRIX identity = {1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f}; + D3DMATRIX ortho = {2.f / width, + 0.f, + 0.f, + 0.f, + 0.f, + -(2.f / height), + 0.f, + 0.f, + 0.f, + 0.f, + 1.f / (farPlane - nearPlane), + 0.f, + 0.f, + 0.f, + nearPlane / (nearPlane - farPlane), + 1.f}; + + HRESULT res = S_OK; + res |= m_WrappedDevice->SetTransform(D3DTS_PROJECTION, &ortho); + res |= m_WrappedDevice->SetTransform(D3DTS_WORLD, &identity); + res |= m_WrappedDevice->SetTransform(D3DTS_VIEW, &identity); + + // enable fixed function pipeline + res |= m_WrappedDevice->SetVertexShader(nullptr); + res |= m_WrappedDevice->SetPixelShader(nullptr); + + // default render states + res |= m_WrappedDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); + res |= m_WrappedDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + res |= m_WrappedDevice->SetRenderState(D3DRS_LIGHTING, FALSE); + res |= m_WrappedDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); + res |= m_WrappedDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, FALSE); + res |= m_WrappedDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + res |= m_WrappedDevice->SetRenderState(D3DRS_CLIPPING, FALSE); + res |= m_WrappedDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); + res |= m_WrappedDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); + res |= m_WrappedDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE); + res |= m_WrappedDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0x0000000F); + res |= m_WrappedDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + res |= m_WrappedDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); + res |= m_WrappedDevice->SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_DISABLE); + res |= m_WrappedDevice->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE); + res |= m_WrappedDevice->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE); + + // overlay render states + res |= m_WrappedDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + res |= m_WrappedDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + res |= m_WrappedDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + + // sampler states + res |= m_WrappedDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); + res |= m_WrappedDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); + res |= m_WrappedDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR /*D3DTEXF_POINT*/); + res |= m_WrappedDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR /*D3DTEXF_POINT*/); + res |= m_WrappedDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR /*D3DTEXF_POINT*/); + res |= m_WrappedDevice->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, 0); + + // texture stage states + res |= m_WrappedDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + res |= m_WrappedDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + res |= m_WrappedDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); + res |= m_WrappedDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + res |= m_WrappedDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + res |= m_WrappedDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT); + res |= m_WrappedDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0); + res |= m_WrappedDevice->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); + res |= m_WrappedDevice->SetTextureStageState(0, D3DTSS_COLORARG0, D3DTA_CURRENT); + res |= m_WrappedDevice->SetTextureStageState(0, D3DTSS_ALPHAARG0, D3DTA_CURRENT); + res |= m_WrappedDevice->SetTextureStageState(0, D3DTSS_RESULTARG, D3DTA_CURRENT); + res |= m_WrappedDevice->SetTextureStageState(0, D3DTSS_CONSTANT, 0xffffffff); + + res |= m_WrappedDevice->SetFVF(m_fvf); + res |= m_WrappedDevice->SetTexture(0, m_Font.Tex); + for(uint32_t stage = 1; stage < 8; stage++) + { + res |= m_WrappedDevice->SetTexture(stage, NULL); + } + + struct Vertex + { + float pos[3]; + float uv[2]; + + Vertex() {} + Vertex(float posx, float posy, float posz, float texu, float texv) + { + pos[0] = posx; + pos[1] = posy; + pos[2] = posz; + uv[0] = texu; + uv[1] = texv; + } + }; + + struct Quad + { + Vertex vertices[6]; + + Quad() {} + Quad(float x0, float y0, float z, float s0, float t0, float x1, float y1, float s1, float t1) + { + vertices[0] = Vertex(x0, y0, z, s0, t0); + vertices[1] = Vertex(x1, y0, z, s1, t0); + vertices[2] = Vertex(x0, y1, z, s0, t1); + vertices[3] = Vertex(x1, y0, z, s1, t0); + vertices[4] = Vertex(x1, y1, z, s1, t1); + vertices[5] = Vertex(x0, y1, z, s0, t1); + } + }; + + Quad *quads = NULL; + UINT triangleCount = 0; + { + UINT quadCount = (UINT)strlen(text); // calculate string length + + triangleCount = quadCount * 2; + // create text VB + quads = new Quad[quadCount]; + + float textPositionX = (-width / 2.f); + float textPositionY = (-height / 2.f) + ((y + 1.f) * m_Font.maxHeight); + + for(UINT i = 0; i < quadCount; ++i) + { + char glyphIndex = text[i] - (' ' + 1); + if(glyphIndex < 0) + { + float currentX = textPositionX; + textPositionX += m_Font.charData->xadvance; + quads[i] = Quad(currentX, textPositionY, 0.5f, 0.f, 0.f, textPositionX, + textPositionY + m_Font.maxHeight, 0.f, 0.f); + } + else + { + stbtt_aligned_quad quad; + stbtt_GetBakedQuad(m_Font.charData, 256, 128, glyphIndex, &textPositionX, &textPositionY, + &quad, 0); + quads[i] = Quad(quad.x0, quad.y0, 0.5f, quad.s0, quad.t0, quad.x1, quad.y1, quad.s1, quad.t1); + } + } + } + + if(quads != NULL) + { + res |= m_WrappedDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, triangleCount, &quads[0], + sizeof(Vertex)); + delete[] quads; + } +} \ No newline at end of file diff --git a/renderdoc/driver/d3d9/d3d9_debug.h b/renderdoc/driver/d3d9/d3d9_debug.h new file mode 100644 index 000000000..98fcdcd1e --- /dev/null +++ b/renderdoc/driver/d3d9/d3d9_debug.h @@ -0,0 +1,76 @@ +/****************************************************************************** +* The MIT License (MIT) +* +* Copyright (c) 2016 Baldur Karlsson +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +******************************************************************************/ + +#pragma once + +#include +#include +#include +#include "common/common.h" +#include "driver/dx/official/d3d9.h" +#include "stb/stb_truetype.h" +#include "d3d9_device.h" + +class D3D9DebugManager +{ +public: + D3D9DebugManager(WrappedD3DDevice9 *wrapper); + ~D3D9DebugManager(); + + void RenderText(float x, float y, const char *textfmt, ...); + + void SetOutputDimensions(int w, int h) + { + m_width = w; + m_height = h; + } + void SetOutputWindow(HWND w); + + // font/text rendering + bool InitFontRendering(); + void ShutdownFontRendering(); + + void RenderTextInternal(float x, float y, const char *text); + + static const int FONT_TEX_WIDTH = 256; + static const int FONT_TEX_HEIGHT = 128; + static const int FONT_MAX_CHARS = 256; + + static const uint32_t STAGE_BUFFER_BYTE_SIZE = 4 * 1024 * 1024; + + struct FontData + { + FontData() { RDCEraseMem(this, sizeof(FontData)); } + ~FontData() { SAFE_RELEASE(Tex); } + IDirect3DTexture9 *Tex; + stbtt_bakedchar charData[FONT_MAX_CHARS]; + float maxHeight; + } m_Font; + + DWORD m_fvf; + + int m_width; + int m_height; + WrappedD3DDevice9 *m_WrappedDevice; +}; diff --git a/renderdoc/driver/d3d9/d3d9_device.cpp b/renderdoc/driver/d3d9/d3d9_device.cpp new file mode 100644 index 000000000..20d23103c --- /dev/null +++ b/renderdoc/driver/d3d9/d3d9_device.cpp @@ -0,0 +1,965 @@ +/****************************************************************************** +* The MIT License (MIT) +* +* Copyright (c) 2016 Baldur Karlsson +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +******************************************************************************/ + +#include "d3d9_device.h" +#include "core/core.h" +#include "d3d9_debug.h" +#include "windows.h" // TODO investigate how else this can be solved + +WrappedD3DDevice9::WrappedD3DDevice9(IDirect3DDevice9 *device) + : m_device(device), m_DebugManager(nullptr) +{ + m_FrameTimer.InitTimers(); + m_FrameCounter = 0; +} + +WrappedD3DDevice9::~WrappedD3DDevice9() +{ + SAFE_DELETE(m_DebugManager); +} + +void WrappedD3DDevice9::LazyInit() +{ + m_DebugManager = new D3D9DebugManager(this); +} + +HRESULT __stdcall WrappedD3DDevice9::QueryInterface(REFIID riid, void **ppvObj) +{ + return m_device->QueryInterface(riid, ppvObj); +} + +ULONG __stdcall WrappedD3DDevice9::AddRef() +{ + ULONG refCount; + refCount = m_device->AddRef(); + return refCount; +} + +ULONG __stdcall WrappedD3DDevice9::Release() +{ + ULONG refCount; + refCount = m_device->Release(); + if(refCount == 0) + { + delete this; + } + return refCount; +} + +HRESULT __stdcall WrappedD3DDevice9::TestCooperativeLevel() +{ + return m_device->TestCooperativeLevel(); +} + +UINT __stdcall WrappedD3DDevice9::GetAvailableTextureMem() +{ + return m_device->GetAvailableTextureMem(); +} + +HRESULT __stdcall WrappedD3DDevice9::EvictManagedResources() +{ + return m_device->EvictManagedResources(); +} + +HRESULT __stdcall WrappedD3DDevice9::GetDirect3D(IDirect3D9 **ppD3D9) +{ + return m_device->GetDirect3D(ppD3D9); +} + +HRESULT __stdcall WrappedD3DDevice9::GetDeviceCaps(D3DCAPS9 *pCaps) +{ + return m_device->GetDeviceCaps(pCaps); +} + +HRESULT __stdcall WrappedD3DDevice9::GetDisplayMode(UINT iSwapChain, D3DDISPLAYMODE *pMode) +{ + return m_device->GetDisplayMode(iSwapChain, pMode); +} + +HRESULT __stdcall WrappedD3DDevice9::GetCreationParameters(D3DDEVICE_CREATION_PARAMETERS *pParameters) +{ + return m_device->GetCreationParameters(pParameters); +} + +HRESULT __stdcall WrappedD3DDevice9::SetCursorProperties(UINT XHotSpot, UINT YHotSpot, + IDirect3DSurface9 *pCursorBitmap) +{ + return m_device->SetCursorProperties(XHotSpot, YHotSpot, pCursorBitmap); +} + +void __stdcall WrappedD3DDevice9::SetCursorPosition(int X, int Y, DWORD Flags) +{ + m_device->SetCursorPosition(X, Y, Flags); +} + +BOOL __stdcall WrappedD3DDevice9::ShowCursor(BOOL bShow) +{ + return m_device->ShowCursor(bShow); +} + +HRESULT __stdcall WrappedD3DDevice9::CreateAdditionalSwapChain( + D3DPRESENT_PARAMETERS *pPresentationParameters, IDirect3DSwapChain9 **pSwapChain) +{ + return m_device->CreateAdditionalSwapChain(pPresentationParameters, pSwapChain); +} + +HRESULT __stdcall WrappedD3DDevice9::GetSwapChain(UINT iSwapChain, IDirect3DSwapChain9 **pSwapChain) +{ + return m_device->GetSwapChain(iSwapChain, pSwapChain); +} + +UINT __stdcall WrappedD3DDevice9::GetNumberOfSwapChains() +{ + return m_device->GetNumberOfSwapChains(); +} + +HRESULT __stdcall WrappedD3DDevice9::Reset(D3DPRESENT_PARAMETERS *pPresentationParameters) +{ + return m_device->Reset(pPresentationParameters); +} + +HRESULT __stdcall WrappedD3DDevice9::Present(CONST RECT *pSourceRect, CONST RECT *pDestRect, + HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion) +{ + m_FrameCounter++; + + // if (m_State == WRITING_IDLE) + { + m_FrameTimer.UpdateTimers(); + + uint32_t overlay = RenderDoc::Inst().GetOverlayBits(); + + static bool debugRenderOverlay = true; + + if(overlay & eRENDERDOC_Overlay_Enabled && debugRenderOverlay) + { + HRESULT res = S_OK; + res = m_device->BeginScene(); + IDirect3DStateBlock9 *stateBlock; + HRESULT stateBlockRes = m_device->CreateStateBlock(D3DSBT_ALL, &stateBlock); + + IDirect3DSurface9 *backBuffer; + res |= m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer); + res |= m_device->SetRenderTarget(0, backBuffer); + + D3DSURFACE_DESC bbDesc; + backBuffer->GetDesc(&bbDesc); + + IDirect3DSwapChain9 *swapChain; + m_device->GetSwapChain(0, &swapChain); + D3DPRESENT_PARAMETERS presentParams; + swapChain->GetPresentParameters(&presentParams); + + // + D3DVIEWPORT9 viewport = {0, 0, bbDesc.Width, bbDesc.Height, 0.f, 1.f}; + res |= m_device->SetViewport(&viewport); + + GetDebugManager()->SetOutputDimensions(bbDesc.Width, bbDesc.Height); + GetDebugManager()->SetOutputWindow(presentParams.hDeviceWindow); + + // if (activeWindow) + { + vector keys = RenderDoc::Inst().GetCaptureKeys(); + + string overlayText = "D3D9. "; + + if(overlay & eRENDERDOC_Overlay_FrameNumber) + { + overlayText += StringFormat::Fmt(" Frame: %d.", m_FrameCounter); + } + if(overlay & eRENDERDOC_Overlay_FrameRate) + { + overlayText += StringFormat::Fmt( + " %.2lf ms (%.2lf .. %.2lf) (%.0lf FPS)", m_FrameTimer.GetAvgFrameTime(), + m_FrameTimer.GetMinFrameTime(), m_FrameTimer.GetMaxFrameTime(), + // max with 0.01ms so that we don't divide by zero + 1000.0f / RDCMAX(0.01, m_FrameTimer.GetAvgFrameTime())); + } + + float y = 0.0f; + + if(!overlayText.empty()) + { + GetDebugManager()->RenderText(0.0f, y, overlayText.c_str()); + y += 1.0f; + } + + if(overlay & eRENDERDOC_Overlay_CaptureList) + { + // GetDebugManager()->RenderText(0.0f, y, "%d Captures saved.\n", + // (uint32_t)m_CapturedFrames.size()); + // y += 1.0f; + + // uint64_t now = Timing::GetUnixTimestamp(); + // for (size_t i = 0; i < m_CapturedFrames.size(); i++) + //{ + // if (now - m_CapturedFrames[i].captureTime < 20) + // { + // GetDebugManager()->RenderText(0.0f, y, "Captured frame %d.\n", + // m_CapturedFrames[i].frameNumber); + // y += 1.0f; + // } + //} + + GetDebugManager()->RenderText(0.0f, y, "Captures not supported with DX9"); + } + } + + stateBlockRes = stateBlock->Apply(); + res |= m_device->EndScene(); + } + } + + return m_device->Present(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); +} + +HRESULT __stdcall WrappedD3DDevice9::GetBackBuffer(UINT iSwapChain, UINT iBackBuffer, + D3DBACKBUFFER_TYPE Type, + IDirect3DSurface9 **ppBackBuffer) +{ + return m_device->GetBackBuffer(iSwapChain, iBackBuffer, Type, ppBackBuffer); +} + +HRESULT __stdcall WrappedD3DDevice9::GetRasterStatus(UINT iSwapChain, D3DRASTER_STATUS *pRasterStatus) +{ + return m_device->GetRasterStatus(iSwapChain, pRasterStatus); +} + +HRESULT __stdcall WrappedD3DDevice9::SetDialogBoxMode(BOOL bEnableDialogs) +{ + return m_device->SetDialogBoxMode(bEnableDialogs); +} + +void __stdcall WrappedD3DDevice9::SetGammaRamp(UINT iSwapChain, DWORD Flags, CONST D3DGAMMARAMP *pRamp) +{ + m_device->SetGammaRamp(iSwapChain, Flags, pRamp); +} + +void __stdcall WrappedD3DDevice9::GetGammaRamp(UINT iSwapChain, D3DGAMMARAMP *pRamp) +{ + m_device->GetGammaRamp(iSwapChain, pRamp); +} + +HRESULT __stdcall WrappedD3DDevice9::CreateTexture(UINT Width, UINT Height, UINT Levels, + DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, + IDirect3DTexture9 **ppTexture, + HANDLE *pSharedHandle) +{ + return m_device->CreateTexture(Width, Height, Levels, Usage, Format, Pool, ppTexture, + pSharedHandle); +} + +HRESULT __stdcall WrappedD3DDevice9::CreateVolumeTexture(UINT Width, UINT Height, UINT Depth, + UINT Levels, DWORD Usage, D3DFORMAT Format, + D3DPOOL Pool, + IDirect3DVolumeTexture9 **ppVolumeTexture, + HANDLE *pSharedHandle) +{ + return m_device->CreateVolumeTexture(Width, Height, Depth, Levels, Usage, Format, Pool, + ppVolumeTexture, pSharedHandle); +} + +HRESULT __stdcall WrappedD3DDevice9::CreateCubeTexture(UINT EdgeLength, UINT Levels, DWORD Usage, + D3DFORMAT Format, D3DPOOL Pool, + IDirect3DCubeTexture9 **ppCubeTexture, + HANDLE *pSharedHandle) +{ + return m_device->CreateCubeTexture(EdgeLength, Levels, Usage, Format, Pool, ppCubeTexture, + pSharedHandle); +} + +HRESULT __stdcall WrappedD3DDevice9::CreateVertexBuffer(UINT Length, DWORD Usage, DWORD FVF, + D3DPOOL Pool, + IDirect3DVertexBuffer9 **ppVertexBuffer, + HANDLE *pSharedHandle) +{ + return m_device->CreateVertexBuffer(Length, Usage, FVF, Pool, ppVertexBuffer, pSharedHandle); +} + +HRESULT __stdcall WrappedD3DDevice9::CreateIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, + D3DPOOL Pool, + IDirect3DIndexBuffer9 **ppIndexBuffer, + HANDLE *pSharedHandle) +{ + return m_device->CreateIndexBuffer(Length, Usage, Format, Pool, ppIndexBuffer, pSharedHandle); +} + +HRESULT __stdcall WrappedD3DDevice9::CreateRenderTarget(UINT Width, UINT Height, D3DFORMAT Format, + D3DMULTISAMPLE_TYPE MultiSample, + DWORD MultisampleQuality, BOOL Lockable, + IDirect3DSurface9 **ppSurface, + HANDLE *pSharedHandle) +{ + return m_device->CreateRenderTarget(Width, Height, Format, MultiSample, MultisampleQuality, + Lockable, ppSurface, pSharedHandle); +} + +HRESULT __stdcall WrappedD3DDevice9::CreateDepthStencilSurface( + UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, + DWORD MultisampleQuality, BOOL Discard, IDirect3DSurface9 **ppSurface, HANDLE *pSharedHandle) +{ + return m_device->CreateDepthStencilSurface(Width, Height, Format, MultiSample, MultisampleQuality, + Discard, ppSurface, pSharedHandle); +} + +HRESULT __stdcall WrappedD3DDevice9::UpdateSurface(IDirect3DSurface9 *pSourceSurface, + CONST RECT *pSourceRect, + IDirect3DSurface9 *pDestinationSurface, + CONST POINT *pDestPoint) +{ + return m_device->UpdateSurface(pSourceSurface, pSourceRect, pDestinationSurface, pDestPoint); +} + +HRESULT __stdcall WrappedD3DDevice9::UpdateTexture(IDirect3DBaseTexture9 *pSourceTexture, + IDirect3DBaseTexture9 *pDestinationTexture) +{ + return m_device->UpdateTexture(pSourceTexture, pDestinationTexture); +} + +HRESULT __stdcall WrappedD3DDevice9::GetRenderTargetData(IDirect3DSurface9 *pRenderTarget, + IDirect3DSurface9 *pDestSurface) +{ + return m_device->GetRenderTargetData(pRenderTarget, pDestSurface); +} + +HRESULT __stdcall WrappedD3DDevice9::GetFrontBufferData(UINT iSwapChain, + IDirect3DSurface9 *pDestSurface) +{ + return m_device->GetFrontBufferData(iSwapChain, pDestSurface); +} + +HRESULT __stdcall WrappedD3DDevice9::StretchRect(IDirect3DSurface9 *pSourceSurface, + CONST RECT *pSourceRect, + IDirect3DSurface9 *pDestSurface, + CONST RECT *pDestRect, D3DTEXTUREFILTERTYPE Filter) +{ + return m_device->StretchRect(pSourceSurface, pSourceRect, pDestSurface, pDestRect, Filter); +} + +HRESULT __stdcall WrappedD3DDevice9::ColorFill(IDirect3DSurface9 *pSurface, CONST RECT *pRect, + D3DCOLOR color) +{ + return m_device->ColorFill(pSurface, pRect, color); +} + +HRESULT __stdcall WrappedD3DDevice9::CreateOffscreenPlainSurface(UINT Width, UINT Height, + D3DFORMAT Format, D3DPOOL Pool, + IDirect3DSurface9 **ppSurface, + HANDLE *pSharedHandle) +{ + return m_device->CreateOffscreenPlainSurface(Width, Height, Format, Pool, ppSurface, pSharedHandle); +} + +HRESULT __stdcall WrappedD3DDevice9::SetRenderTarget(DWORD RenderTargetIndex, + IDirect3DSurface9 *pRenderTarget) +{ + return m_device->SetRenderTarget(RenderTargetIndex, pRenderTarget); +} + +HRESULT __stdcall WrappedD3DDevice9::GetRenderTarget(DWORD RenderTargetIndex, + IDirect3DSurface9 **ppRenderTarget) +{ + return m_device->GetRenderTarget(RenderTargetIndex, ppRenderTarget); +} + +HRESULT __stdcall WrappedD3DDevice9::SetDepthStencilSurface(IDirect3DSurface9 *pNewZStencil) +{ + return m_device->SetDepthStencilSurface(pNewZStencil); +} + +HRESULT __stdcall WrappedD3DDevice9::GetDepthStencilSurface(IDirect3DSurface9 **ppZStencilSurface) +{ + return m_device->GetDepthStencilSurface(ppZStencilSurface); +} + +HRESULT __stdcall WrappedD3DDevice9::BeginScene() +{ + return m_device->BeginScene(); +} + +HRESULT __stdcall WrappedD3DDevice9::EndScene() +{ + return m_device->EndScene(); +} + +HRESULT __stdcall WrappedD3DDevice9::Clear(DWORD Count, CONST D3DRECT *pRects, DWORD Flags, + D3DCOLOR Color, float Z, DWORD Stencil) +{ + return m_device->Clear(Count, pRects, Flags, Color, Z, Stencil); +} + +HRESULT __stdcall WrappedD3DDevice9::SetTransform(D3DTRANSFORMSTATETYPE State, + CONST D3DMATRIX *pMatrix) +{ + return m_device->SetTransform(State, pMatrix); +} + +HRESULT __stdcall WrappedD3DDevice9::GetTransform(D3DTRANSFORMSTATETYPE State, D3DMATRIX *pMatrix) +{ + return m_device->GetTransform(State, pMatrix); +} + +HRESULT __stdcall WrappedD3DDevice9::MultiplyTransform(D3DTRANSFORMSTATETYPE _arg1, + CONST D3DMATRIX *_arg2) +{ + return m_device->MultiplyTransform(_arg1, _arg2); +} + +HRESULT __stdcall WrappedD3DDevice9::SetViewport(CONST D3DVIEWPORT9 *pViewport) +{ + return m_device->SetViewport(pViewport); +} + +HRESULT __stdcall WrappedD3DDevice9::GetViewport(D3DVIEWPORT9 *pViewport) +{ + return m_device->GetViewport(pViewport); +} + +HRESULT __stdcall WrappedD3DDevice9::SetMaterial(CONST D3DMATERIAL9 *pMaterial) +{ + return m_device->SetMaterial(pMaterial); +} + +HRESULT __stdcall WrappedD3DDevice9::GetMaterial(D3DMATERIAL9 *pMaterial) +{ + return m_device->GetMaterial(pMaterial); +} + +HRESULT __stdcall WrappedD3DDevice9::SetLight(DWORD Index, CONST D3DLIGHT9 *_arg2) +{ + return m_device->SetLight(Index, _arg2); +} + +HRESULT __stdcall WrappedD3DDevice9::GetLight(DWORD Index, D3DLIGHT9 *_arg2) +{ + return m_device->GetLight(Index, _arg2); +} + +HRESULT __stdcall WrappedD3DDevice9::LightEnable(DWORD Index, BOOL Enable) +{ + return m_device->LightEnable(Index, Enable); +} + +HRESULT __stdcall WrappedD3DDevice9::GetLightEnable(DWORD Index, BOOL *pEnable) +{ + return m_device->GetLightEnable(Index, pEnable); +} + +HRESULT __stdcall WrappedD3DDevice9::SetClipPlane(DWORD Index, CONST float *pPlane) +{ + return m_device->SetClipPlane(Index, pPlane); +} + +HRESULT __stdcall WrappedD3DDevice9::GetClipPlane(DWORD Index, float *pPlane) +{ + return m_device->GetClipPlane(Index, pPlane); +} + +HRESULT __stdcall WrappedD3DDevice9::SetRenderState(D3DRENDERSTATETYPE State, DWORD Value) +{ + return m_device->SetRenderState(State, Value); +} + +HRESULT __stdcall WrappedD3DDevice9::GetRenderState(D3DRENDERSTATETYPE State, DWORD *pValue) +{ + return m_device->GetRenderState(State, pValue); +} + +HRESULT __stdcall WrappedD3DDevice9::CreateStateBlock(D3DSTATEBLOCKTYPE Type, + IDirect3DStateBlock9 **ppSB) +{ + return m_device->CreateStateBlock(Type, ppSB); +} + +HRESULT __stdcall WrappedD3DDevice9::BeginStateBlock() +{ + return m_device->BeginStateBlock(); +} + +HRESULT __stdcall WrappedD3DDevice9::EndStateBlock(IDirect3DStateBlock9 **ppSB) +{ + return m_device->EndStateBlock(ppSB); +} + +HRESULT __stdcall WrappedD3DDevice9::SetClipStatus(CONST D3DCLIPSTATUS9 *pClipStatus) +{ + return m_device->SetClipStatus(pClipStatus); +} + +HRESULT __stdcall WrappedD3DDevice9::GetClipStatus(D3DCLIPSTATUS9 *pClipStatus) +{ + return m_device->GetClipStatus(pClipStatus); +} + +HRESULT __stdcall WrappedD3DDevice9::GetTexture(DWORD Stage, IDirect3DBaseTexture9 **ppTexture) +{ + return m_device->GetTexture(Stage, ppTexture); +} + +HRESULT __stdcall WrappedD3DDevice9::SetTexture(DWORD Stage, IDirect3DBaseTexture9 *pTexture) +{ + return m_device->SetTexture(Stage, pTexture); +} + +HRESULT __stdcall WrappedD3DDevice9::GetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, + DWORD *pValue) +{ + return m_device->GetTextureStageState(Stage, Type, pValue); +} + +HRESULT __stdcall WrappedD3DDevice9::SetTextureStageState(DWORD Stage, + D3DTEXTURESTAGESTATETYPE Type, DWORD Value) +{ + return m_device->SetTextureStageState(Stage, Type, Value); +} + +HRESULT __stdcall WrappedD3DDevice9::GetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, + DWORD *pValue) +{ + return m_device->GetSamplerState(Sampler, Type, pValue); +} + +HRESULT __stdcall WrappedD3DDevice9::SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, + DWORD Value) +{ + return m_device->SetSamplerState(Sampler, Type, Value); +} + +HRESULT __stdcall WrappedD3DDevice9::ValidateDevice(DWORD *pNumPasses) +{ + return m_device->ValidateDevice(pNumPasses); +} + +HRESULT __stdcall WrappedD3DDevice9::SetPaletteEntries(UINT PaletteNumber, + CONST PALETTEENTRY *pEntries) +{ + return m_device->SetPaletteEntries(PaletteNumber, pEntries); +} + +HRESULT __stdcall WrappedD3DDevice9::GetPaletteEntries(UINT PaletteNumber, PALETTEENTRY *pEntries) +{ + return m_device->GetPaletteEntries(PaletteNumber, pEntries); +} + +HRESULT __stdcall WrappedD3DDevice9::SetCurrentTexturePalette(UINT PaletteNumber) +{ + return m_device->SetCurrentTexturePalette(PaletteNumber); +} + +HRESULT __stdcall WrappedD3DDevice9::GetCurrentTexturePalette(UINT *PaletteNumber) +{ + return m_device->GetCurrentTexturePalette(PaletteNumber); +} + +HRESULT __stdcall WrappedD3DDevice9::SetScissorRect(CONST RECT *pRect) +{ + return m_device->SetScissorRect(pRect); +} + +HRESULT __stdcall WrappedD3DDevice9::GetScissorRect(RECT *pRect) +{ + return m_device->GetScissorRect(pRect); +} + +HRESULT __stdcall WrappedD3DDevice9::SetSoftwareVertexProcessing(BOOL bSoftware) +{ + return m_device->SetSoftwareVertexProcessing(bSoftware); +} + +BOOL __stdcall WrappedD3DDevice9::GetSoftwareVertexProcessing() +{ + return m_device->GetSoftwareVertexProcessing(); +} + +HRESULT __stdcall WrappedD3DDevice9::SetNPatchMode(float nSegments) +{ + return m_device->SetNPatchMode(nSegments); +} + +float __stdcall WrappedD3DDevice9::GetNPatchMode() +{ + return m_device->GetNPatchMode(); +} + +HRESULT __stdcall WrappedD3DDevice9::DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, + UINT PrimitiveCount) +{ + return m_device->DrawPrimitive(PrimitiveType, StartVertex, PrimitiveCount); +} + +HRESULT __stdcall WrappedD3DDevice9::DrawIndexedPrimitive(D3DPRIMITIVETYPE _arg1, INT BaseVertexIndex, + UINT MinVertexIndex, UINT NumVertices, + UINT startIndex, UINT primCount) +{ + return m_device->DrawIndexedPrimitive(_arg1, BaseVertexIndex, MinVertexIndex, NumVertices, + startIndex, primCount); +} + +HRESULT __stdcall WrappedD3DDevice9::DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, + UINT PrimitiveCount, + CONST void *pVertexStreamZeroData, + UINT VertexStreamZeroStride) +{ + return m_device->DrawPrimitiveUP(PrimitiveType, PrimitiveCount, pVertexStreamZeroData, + VertexStreamZeroStride); +} + +HRESULT __stdcall WrappedD3DDevice9::DrawIndexedPrimitiveUP( + D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertices, UINT PrimitiveCount, + CONST void *pIndexData, D3DFORMAT IndexDataFormat, CONST void *pVertexStreamZeroData, + UINT VertexStreamZeroStride) +{ + return m_device->DrawIndexedPrimitiveUP(PrimitiveType, MinVertexIndex, NumVertices, + PrimitiveCount, pIndexData, IndexDataFormat, + pVertexStreamZeroData, VertexStreamZeroStride); +} + +HRESULT __stdcall WrappedD3DDevice9::ProcessVertices(UINT SrcStartIndex, UINT DestIndex, + UINT VertexCount, + IDirect3DVertexBuffer9 *pDestBuffer, + IDirect3DVertexDeclaration9 *pVertexDecl, + DWORD Flags) +{ + return m_device->ProcessVertices(SrcStartIndex, DestIndex, VertexCount, pDestBuffer, pVertexDecl, + Flags); +} + +HRESULT __stdcall WrappedD3DDevice9::CreateVertexDeclaration(CONST D3DVERTEXELEMENT9 *pVertexElements, + IDirect3DVertexDeclaration9 **ppDecl) +{ + return m_device->CreateVertexDeclaration(pVertexElements, ppDecl); +} + +HRESULT __stdcall WrappedD3DDevice9::SetVertexDeclaration(IDirect3DVertexDeclaration9 *pDecl) +{ + return m_device->SetVertexDeclaration(pDecl); +} + +HRESULT __stdcall WrappedD3DDevice9::GetVertexDeclaration(IDirect3DVertexDeclaration9 **ppDecl) +{ + return m_device->GetVertexDeclaration(ppDecl); +} + +HRESULT __stdcall WrappedD3DDevice9::SetFVF(DWORD FVF) +{ + return m_device->SetFVF(FVF); +} + +HRESULT __stdcall WrappedD3DDevice9::GetFVF(DWORD *pFVF) +{ + return m_device->GetFVF(pFVF); +} + +HRESULT __stdcall WrappedD3DDevice9::CreateVertexShader(CONST DWORD *pFunction, + IDirect3DVertexShader9 **ppShader) +{ + return m_device->CreateVertexShader(pFunction, ppShader); +} + +HRESULT __stdcall WrappedD3DDevice9::SetVertexShader(IDirect3DVertexShader9 *pShader) +{ + return m_device->SetVertexShader(pShader); +} + +HRESULT __stdcall WrappedD3DDevice9::GetVertexShader(IDirect3DVertexShader9 **ppShader) +{ + return m_device->GetVertexShader(ppShader); +} + +HRESULT __stdcall WrappedD3DDevice9::SetVertexShaderConstantF(UINT StartRegister, + CONST float *pConstantData, + UINT Vector4fCount) +{ + return m_device->SetVertexShaderConstantF(StartRegister, pConstantData, Vector4fCount); +} + +HRESULT __stdcall WrappedD3DDevice9::GetVertexShaderConstantF(UINT StartRegister, + float *pConstantData, + UINT Vector4fCount) +{ + return m_device->GetVertexShaderConstantF(StartRegister, pConstantData, Vector4fCount); +} + +HRESULT __stdcall WrappedD3DDevice9::SetVertexShaderConstantI(UINT StartRegister, + CONST int *pConstantData, + UINT Vector4iCount) +{ + return m_device->SetVertexShaderConstantI(StartRegister, pConstantData, Vector4iCount); +} + +HRESULT __stdcall WrappedD3DDevice9::GetVertexShaderConstantI(UINT StartRegister, + int *pConstantData, UINT Vector4iCount) +{ + return m_device->GetVertexShaderConstantI(StartRegister, pConstantData, Vector4iCount); +} + +HRESULT __stdcall WrappedD3DDevice9::SetVertexShaderConstantB(UINT StartRegister, + CONST BOOL *pConstantData, + UINT BoolCount) +{ + return m_device->SetVertexShaderConstantB(StartRegister, pConstantData, BoolCount); +} + +HRESULT __stdcall WrappedD3DDevice9::GetVertexShaderConstantB(UINT StartRegister, + BOOL *pConstantData, UINT BoolCount) +{ + return m_device->GetVertexShaderConstantB(StartRegister, pConstantData, BoolCount); +} + +HRESULT __stdcall WrappedD3DDevice9::SetStreamSource(UINT StreamNumber, + IDirect3DVertexBuffer9 *pStreamData, + UINT OffsetInBytes, UINT Stride) +{ + return m_device->SetStreamSource(StreamNumber, pStreamData, OffsetInBytes, Stride); +} + +HRESULT __stdcall WrappedD3DDevice9::GetStreamSource(UINT StreamNumber, + IDirect3DVertexBuffer9 **ppStreamData, + UINT *pOffsetInBytes, UINT *pStride) +{ + return m_device->GetStreamSource(StreamNumber, ppStreamData, pOffsetInBytes, pStride); +} + +HRESULT __stdcall WrappedD3DDevice9::SetStreamSourceFreq(UINT StreamNumber, UINT Setting) +{ + return m_device->SetStreamSourceFreq(StreamNumber, Setting); +} + +HRESULT __stdcall WrappedD3DDevice9::GetStreamSourceFreq(UINT StreamNumber, UINT *pSetting) +{ + return m_device->GetStreamSourceFreq(StreamNumber, pSetting); +} + +HRESULT __stdcall WrappedD3DDevice9::SetIndices(IDirect3DIndexBuffer9 *pIndexData) +{ + return m_device->SetIndices(pIndexData); +} + +HRESULT __stdcall WrappedD3DDevice9::GetIndices(IDirect3DIndexBuffer9 **ppIndexData) +{ + return m_device->GetIndices(ppIndexData); +} + +HRESULT __stdcall WrappedD3DDevice9::CreatePixelShader(CONST DWORD *pFunction, + IDirect3DPixelShader9 **ppShader) +{ + return m_device->CreatePixelShader(pFunction, ppShader); +} + +HRESULT __stdcall WrappedD3DDevice9::SetPixelShader(IDirect3DPixelShader9 *pShader) +{ + return m_device->SetPixelShader(pShader); +} + +HRESULT __stdcall WrappedD3DDevice9::GetPixelShader(IDirect3DPixelShader9 **ppShader) +{ + return m_device->GetPixelShader(ppShader); +} + +HRESULT __stdcall WrappedD3DDevice9::SetPixelShaderConstantF(UINT StartRegister, + CONST float *pConstantData, + UINT Vector4fCount) +{ + return m_device->SetPixelShaderConstantF(StartRegister, pConstantData, Vector4fCount); +} + +HRESULT __stdcall WrappedD3DDevice9::GetPixelShaderConstantF(UINT StartRegister, + float *pConstantData, UINT Vector4fCount) +{ + return m_device->GetPixelShaderConstantF(StartRegister, pConstantData, Vector4fCount); +} + +HRESULT __stdcall WrappedD3DDevice9::SetPixelShaderConstantI(UINT StartRegister, + CONST int *pConstantData, + UINT Vector4iCount) +{ + return m_device->SetPixelShaderConstantI(StartRegister, pConstantData, Vector4iCount); +} + +HRESULT __stdcall WrappedD3DDevice9::GetPixelShaderConstantI(UINT StartRegister, int *pConstantData, + UINT Vector4iCount) +{ + return m_device->GetPixelShaderConstantI(StartRegister, pConstantData, Vector4iCount); +} + +HRESULT __stdcall WrappedD3DDevice9::SetPixelShaderConstantB(UINT StartRegister, + CONST BOOL *pConstantData, + UINT BoolCount) +{ + return m_device->SetPixelShaderConstantB(StartRegister, pConstantData, BoolCount); +} + +HRESULT __stdcall WrappedD3DDevice9::GetPixelShaderConstantB(UINT StartRegister, + BOOL *pConstantData, UINT BoolCount) +{ + return m_device->GetPixelShaderConstantB(StartRegister, pConstantData, BoolCount); +} + +HRESULT __stdcall WrappedD3DDevice9::DrawRectPatch(UINT Handle, CONST float *pNumSegs, + CONST D3DRECTPATCH_INFO *pRectPatchInfo) +{ + return m_device->DrawRectPatch(Handle, pNumSegs, pRectPatchInfo); +} + +HRESULT __stdcall WrappedD3DDevice9::DrawTriPatch(UINT Handle, CONST float *pNumSegs, + CONST D3DTRIPATCH_INFO *pTriPatchInfo) +{ + return m_device->DrawTriPatch(Handle, pNumSegs, pTriPatchInfo); +} + +HRESULT __stdcall WrappedD3DDevice9::DeletePatch(UINT Handle) +{ + return m_device->DeletePatch(Handle); +} + +HRESULT __stdcall WrappedD3DDevice9::CreateQuery(D3DQUERYTYPE Type, IDirect3DQuery9 **ppQuery) +{ + return m_device->CreateQuery(Type, ppQuery); +} + +HRESULT __stdcall WrappedD3D9::QueryInterface(REFIID riid, void **ppvObj) +{ + return m_direct3D->QueryInterface(riid, ppvObj); +} + +ULONG __stdcall WrappedD3D9::AddRef() +{ + ULONG refCount; + refCount = m_direct3D->AddRef(); + return refCount; +} + +ULONG __stdcall WrappedD3D9::Release() +{ + ULONG refCount = m_direct3D->Release(); + if(refCount == 0) + { + delete this; + } + return refCount; +} + +HRESULT __stdcall WrappedD3D9::RegisterSoftwareDevice(void *pInitializeFunction) +{ + return m_direct3D->RegisterSoftwareDevice(pInitializeFunction); +} + +UINT __stdcall WrappedD3D9::GetAdapterCount() +{ + return m_direct3D->GetAdapterCount(); +} + +HRESULT __stdcall WrappedD3D9::GetAdapterIdentifier(UINT Adapter, DWORD Flags, + D3DADAPTER_IDENTIFIER9 *pIdentifier) +{ + return m_direct3D->GetAdapterIdentifier(Adapter, Flags, pIdentifier); +} + +UINT __stdcall WrappedD3D9::GetAdapterModeCount(UINT Adapter, D3DFORMAT Format) +{ + return m_direct3D->GetAdapterModeCount(Adapter, Format); +} + +HRESULT __stdcall WrappedD3D9::EnumAdapterModes(UINT Adapter, D3DFORMAT Format, UINT Mode, + D3DDISPLAYMODE *pMode) +{ + return m_direct3D->EnumAdapterModes(Adapter, Format, Mode, pMode); +} + +HRESULT __stdcall WrappedD3D9::GetAdapterDisplayMode(UINT Adapter, D3DDISPLAYMODE *pMode) +{ + return m_direct3D->GetAdapterDisplayMode(Adapter, pMode); +} + +HRESULT __stdcall WrappedD3D9::CheckDeviceType(UINT Adapter, D3DDEVTYPE DevType, + D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, + BOOL bWindowed) +{ + return m_direct3D->CheckDeviceType(Adapter, DevType, AdapterFormat, BackBufferFormat, bWindowed); +} + +HRESULT __stdcall WrappedD3D9::CheckDeviceFormat(UINT Adapter, D3DDEVTYPE DeviceType, + D3DFORMAT AdapterFormat, DWORD Usage, + D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) +{ + return m_direct3D->CheckDeviceFormat(Adapter, DeviceType, AdapterFormat, Usage, RType, CheckFormat); +} + +HRESULT __stdcall WrappedD3D9::CheckDeviceMultiSampleType(UINT Adapter, D3DDEVTYPE DeviceType, + D3DFORMAT SurfaceFormat, BOOL Windowed, + D3DMULTISAMPLE_TYPE MultiSampleType, + DWORD *pQualityLevels) +{ + return m_direct3D->CheckDeviceMultiSampleType(Adapter, DeviceType, SurfaceFormat, Windowed, + MultiSampleType, pQualityLevels); +} + +HRESULT __stdcall WrappedD3D9::CheckDepthStencilMatch(UINT Adapter, D3DDEVTYPE DeviceType, + D3DFORMAT AdapterFormat, + D3DFORMAT RenderTargetFormat, + D3DFORMAT DepthStencilFormat) +{ + return m_direct3D->CheckDepthStencilMatch(Adapter, DeviceType, AdapterFormat, RenderTargetFormat, + DepthStencilFormat); +} + +HRESULT __stdcall WrappedD3D9::CheckDeviceFormatConversion(UINT Adapter, D3DDEVTYPE DeviceType, + D3DFORMAT SourceFormat, + D3DFORMAT TargetFormat) +{ + return m_direct3D->CheckDeviceFormatConversion(Adapter, DeviceType, SourceFormat, TargetFormat); +} + +HRESULT __stdcall WrappedD3D9::GetDeviceCaps(UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9 *pCaps) +{ + return m_direct3D->GetDeviceCaps(Adapter, DeviceType, pCaps); +} + +HMONITOR __stdcall WrappedD3D9::GetAdapterMonitor(UINT Adapter) +{ + return m_direct3D->GetAdapterMonitor(Adapter); +} + +HRESULT __stdcall WrappedD3D9::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, + DWORD BehaviorFlags, + D3DPRESENT_PARAMETERS *pPresentationParameters, + IDirect3DDevice9 **ppReturnedDeviceInterface) +{ + IDirect3DDevice9 *device = NULL; + HRESULT res = m_direct3D->CreateDevice(Adapter, DeviceType, hFocusWindow, BehaviorFlags, + pPresentationParameters, &device); + if(res == S_OK) + { + RDCLOG("App creating d3d9 device"); + + WrappedD3DDevice9 *wrappedDevice = new WrappedD3DDevice9(device); + wrappedDevice->LazyInit(); // TODO this can be moved later probably + *ppReturnedDeviceInterface = wrappedDevice; + } + else + { + *ppReturnedDeviceInterface = NULL; + } + return res; +} diff --git a/renderdoc/driver/d3d9/d3d9_device.h b/renderdoc/driver/d3d9/d3d9_device.h new file mode 100644 index 000000000..39dea1769 --- /dev/null +++ b/renderdoc/driver/d3d9/d3d9_device.h @@ -0,0 +1,287 @@ +/****************************************************************************** +* The MIT License (MIT) +* +* Copyright (c) 2016 Baldur Karlsson +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +******************************************************************************/ + +#pragma once +#include "common/common.h" +#include "common/timing.h" +#include "driver/dx/official/d3d9.h" + +class D3D9DebugManager; + +class WrappedD3DDevice9 : public IDirect3DDevice9 +{ +public: + WrappedD3DDevice9(IDirect3DDevice9 *device); + ~WrappedD3DDevice9(); + + void LazyInit(); + + D3D9DebugManager *GetDebugManager() { return m_DebugManager; } + /*** IUnknown methods ***/ + virtual HRESULT __stdcall QueryInterface(REFIID riid, void **ppvObj); + virtual ULONG __stdcall AddRef(); + virtual ULONG __stdcall Release(); + + /*** IDirect3DDevice9 methods ***/ + virtual HRESULT __stdcall TestCooperativeLevel(); + virtual UINT __stdcall GetAvailableTextureMem(); + virtual HRESULT __stdcall EvictManagedResources(); + virtual HRESULT __stdcall GetDirect3D(IDirect3D9 **ppD3D9); + virtual HRESULT __stdcall GetDeviceCaps(D3DCAPS9 *pCaps); + virtual HRESULT __stdcall GetDisplayMode(UINT iSwapChain, D3DDISPLAYMODE *pMode); + virtual HRESULT __stdcall GetCreationParameters(D3DDEVICE_CREATION_PARAMETERS *pParameters); + virtual HRESULT __stdcall SetCursorProperties(UINT XHotSpot, UINT YHotSpot, + IDirect3DSurface9 *pCursorBitmap); + virtual void __stdcall SetCursorPosition(int X, int Y, DWORD Flags); + virtual BOOL __stdcall ShowCursor(BOOL bShow); + virtual HRESULT __stdcall CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS *pPresentationParameters, + IDirect3DSwapChain9 **pSwapChain); + virtual HRESULT __stdcall GetSwapChain(UINT iSwapChain, IDirect3DSwapChain9 **pSwapChain); + virtual UINT __stdcall GetNumberOfSwapChains(); + virtual HRESULT __stdcall Reset(D3DPRESENT_PARAMETERS *pPresentationParameters); + virtual HRESULT __stdcall Present(CONST RECT *pSourceRect, CONST RECT *pDestRect, + HWND hDestWindow, CONST RGNDATA *pDirtyRegion); + virtual HRESULT __stdcall GetBackBuffer(UINT iSwapChain, UINT iBackBuffer, + D3DBACKBUFFER_TYPE Type, IDirect3DSurface9 **ppBackBuffer); + virtual HRESULT __stdcall GetRasterStatus(UINT iSwapChain, D3DRASTER_STATUS *pRasterStatus); + virtual HRESULT __stdcall SetDialogBoxMode(BOOL bEnableDialogs); + virtual void __stdcall SetGammaRamp(UINT iSwapChain, DWORD Flags, CONST D3DGAMMARAMP *pRamp); + virtual void __stdcall GetGammaRamp(UINT iSwapChain, D3DGAMMARAMP *pRamp); + virtual HRESULT __stdcall CreateTexture(UINT Width, UINT Height, UINT Levels, DWORD Usage, + D3DFORMAT Format, D3DPOOL Pool, + IDirect3DTexture9 **ppTexture, HANDLE *pSharedHandle); + virtual HRESULT __stdcall CreateVolumeTexture(UINT Width, UINT Height, UINT Depth, UINT Levels, + DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, + IDirect3DVolumeTexture9 **ppVolumeTexture, + HANDLE *pSharedHandle); + virtual HRESULT __stdcall CreateCubeTexture(UINT EdgeLength, UINT Levels, DWORD Usage, + D3DFORMAT Format, D3DPOOL Pool, + IDirect3DCubeTexture9 **ppCubeTexture, + HANDLE *pSharedHandle); + virtual HRESULT __stdcall CreateVertexBuffer(UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, + IDirect3DVertexBuffer9 **ppVertexBuffer, + HANDLE *pSharedHandle); + virtual HRESULT __stdcall CreateIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, + D3DPOOL Pool, IDirect3DIndexBuffer9 **ppIndexBuffer, + HANDLE *pSharedHandle); + virtual HRESULT __stdcall CreateRenderTarget(UINT Width, UINT Height, D3DFORMAT Format, + D3DMULTISAMPLE_TYPE MultiSample, + DWORD MultisampleQuality, BOOL Lockable, + IDirect3DSurface9 **ppSurface, HANDLE *pSharedHandle); + virtual HRESULT __stdcall CreateDepthStencilSurface(UINT Width, UINT Height, D3DFORMAT Format, + D3DMULTISAMPLE_TYPE MultiSample, + DWORD MultisampleQuality, BOOL Discard, + IDirect3DSurface9 **ppSurface, + HANDLE *pSharedHandle); + virtual HRESULT __stdcall UpdateSurface(IDirect3DSurface9 *pSourceSurface, CONST RECT *pSourceRect, + IDirect3DSurface9 *pDestinationSurface, + CONST POINT *pDestPoint); + virtual HRESULT __stdcall UpdateTexture(IDirect3DBaseTexture9 *pSourceTexture, + IDirect3DBaseTexture9 *pDestinationTexture); + virtual HRESULT __stdcall GetRenderTargetData(IDirect3DSurface9 *pRenderTarget, + IDirect3DSurface9 *pDestSurface); + virtual HRESULT __stdcall GetFrontBufferData(UINT iSwapChain, IDirect3DSurface9 *pDestSurface); + virtual HRESULT __stdcall StretchRect(IDirect3DSurface9 *pSourceSurface, CONST RECT *pSourceRect, + IDirect3DSurface9 *pDestSurface, CONST RECT *pDestRect, + D3DTEXTUREFILTERTYPE Filter); + virtual HRESULT __stdcall ColorFill(IDirect3DSurface9 *pSurface, CONST RECT *pRect, D3DCOLOR color); + virtual HRESULT __stdcall CreateOffscreenPlainSurface(UINT Width, UINT Height, D3DFORMAT Format, + D3DPOOL Pool, IDirect3DSurface9 **ppSurface, + HANDLE *pSharedHandle); + virtual HRESULT __stdcall SetRenderTarget(DWORD RenderTargetIndex, + IDirect3DSurface9 *pRenderTarget); + virtual HRESULT __stdcall GetRenderTarget(DWORD RenderTargetIndex, + IDirect3DSurface9 **ppRenderTarget); + virtual HRESULT __stdcall SetDepthStencilSurface(IDirect3DSurface9 *pNewZStencil); + virtual HRESULT __stdcall GetDepthStencilSurface(IDirect3DSurface9 **ppZStencilSurface); + virtual HRESULT __stdcall BeginScene(); + virtual HRESULT __stdcall EndScene(); + virtual HRESULT __stdcall Clear(DWORD Count, CONST D3DRECT *pRects, DWORD Flags, D3DCOLOR Color, + float Z, DWORD Stencil); + virtual HRESULT __stdcall SetTransform(D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX *pMatrix); + virtual HRESULT __stdcall GetTransform(D3DTRANSFORMSTATETYPE State, D3DMATRIX *pMatrix); + virtual HRESULT __stdcall MultiplyTransform(D3DTRANSFORMSTATETYPE, CONST D3DMATRIX *); + virtual HRESULT __stdcall SetViewport(CONST D3DVIEWPORT9 *pViewport); + virtual HRESULT __stdcall GetViewport(D3DVIEWPORT9 *pViewport); + virtual HRESULT __stdcall SetMaterial(CONST D3DMATERIAL9 *pMaterial); + virtual HRESULT __stdcall GetMaterial(D3DMATERIAL9 *pMaterial); + virtual HRESULT __stdcall SetLight(DWORD Index, CONST D3DLIGHT9 *); + virtual HRESULT __stdcall GetLight(DWORD Index, D3DLIGHT9 *); + virtual HRESULT __stdcall LightEnable(DWORD Index, BOOL Enable); + virtual HRESULT __stdcall GetLightEnable(DWORD Index, BOOL *pEnable); + virtual HRESULT __stdcall SetClipPlane(DWORD Index, CONST float *pPlane); + virtual HRESULT __stdcall GetClipPlane(DWORD Index, float *pPlane); + virtual HRESULT __stdcall SetRenderState(D3DRENDERSTATETYPE State, DWORD Value); + virtual HRESULT __stdcall GetRenderState(D3DRENDERSTATETYPE State, DWORD *pValue); + virtual HRESULT __stdcall CreateStateBlock(D3DSTATEBLOCKTYPE Type, IDirect3DStateBlock9 **ppSB); + virtual HRESULT __stdcall BeginStateBlock(); + virtual HRESULT __stdcall EndStateBlock(IDirect3DStateBlock9 **ppSB); + virtual HRESULT __stdcall SetClipStatus(CONST D3DCLIPSTATUS9 *pClipStatus); + virtual HRESULT __stdcall GetClipStatus(D3DCLIPSTATUS9 *pClipStatus); + virtual HRESULT __stdcall GetTexture(DWORD Stage, IDirect3DBaseTexture9 **ppTexture); + virtual HRESULT __stdcall SetTexture(DWORD Stage, IDirect3DBaseTexture9 *pTexture); + virtual HRESULT __stdcall GetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, + DWORD *pValue); + virtual HRESULT __stdcall SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, + DWORD Value); + virtual HRESULT __stdcall GetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD *pValue); + virtual HRESULT __stdcall SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value); + virtual HRESULT __stdcall ValidateDevice(DWORD *pNumPasses); + virtual HRESULT __stdcall SetPaletteEntries(UINT PaletteNumber, CONST PALETTEENTRY *pEntries); + virtual HRESULT __stdcall GetPaletteEntries(UINT PaletteNumber, PALETTEENTRY *pEntries); + virtual HRESULT __stdcall SetCurrentTexturePalette(UINT PaletteNumber); + virtual HRESULT __stdcall GetCurrentTexturePalette(UINT *PaletteNumber); + virtual HRESULT __stdcall SetScissorRect(CONST RECT *pRect); + virtual HRESULT __stdcall GetScissorRect(RECT *pRect); + virtual HRESULT __stdcall SetSoftwareVertexProcessing(BOOL bSoftware); + virtual BOOL __stdcall GetSoftwareVertexProcessing(); + virtual HRESULT __stdcall SetNPatchMode(float nSegments); + virtual float __stdcall GetNPatchMode(); + virtual HRESULT __stdcall DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, + UINT PrimitiveCount); + virtual HRESULT __stdcall DrawIndexedPrimitive(D3DPRIMITIVETYPE, INT BaseVertexIndex, + UINT MinVertexIndex, UINT NumVertices, + UINT startIndex, UINT primCount); + virtual HRESULT __stdcall DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, + CONST void *pVertexStreamZeroData, + UINT VertexStreamZeroStride); + virtual HRESULT __stdcall DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, + UINT MinVertexIndex, UINT NumVertices, + UINT PrimitiveCount, CONST void *pIndexData, + D3DFORMAT IndexDataFormat, + CONST void *pVertexStreamZeroData, + UINT VertexStreamZeroStride); + virtual HRESULT __stdcall ProcessVertices(UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, + IDirect3DVertexBuffer9 *pDestBuffer, + IDirect3DVertexDeclaration9 *pVertexDecl, DWORD Flags); + virtual HRESULT __stdcall CreateVertexDeclaration(CONST D3DVERTEXELEMENT9 *pVertexElements, + IDirect3DVertexDeclaration9 **ppDecl); + virtual HRESULT __stdcall SetVertexDeclaration(IDirect3DVertexDeclaration9 *pDecl); + virtual HRESULT __stdcall GetVertexDeclaration(IDirect3DVertexDeclaration9 **ppDecl); + virtual HRESULT __stdcall SetFVF(DWORD FVF); + virtual HRESULT __stdcall GetFVF(DWORD *pFVF); + virtual HRESULT __stdcall CreateVertexShader(CONST DWORD *pFunction, + IDirect3DVertexShader9 **ppShader); + virtual HRESULT __stdcall SetVertexShader(IDirect3DVertexShader9 *pShader); + virtual HRESULT __stdcall GetVertexShader(IDirect3DVertexShader9 **ppShader); + virtual HRESULT __stdcall SetVertexShaderConstantF(UINT StartRegister, CONST float *pConstantData, + UINT Vector4fCount); + virtual HRESULT __stdcall GetVertexShaderConstantF(UINT StartRegister, float *pConstantData, + UINT Vector4fCount); + virtual HRESULT __stdcall SetVertexShaderConstantI(UINT StartRegister, CONST int *pConstantData, + UINT Vector4iCount); + virtual HRESULT __stdcall GetVertexShaderConstantI(UINT StartRegister, int *pConstantData, + UINT Vector4iCount); + virtual HRESULT __stdcall SetVertexShaderConstantB(UINT StartRegister, CONST BOOL *pConstantData, + UINT BoolCount); + virtual HRESULT __stdcall GetVertexShaderConstantB(UINT StartRegister, BOOL *pConstantData, + UINT BoolCount); + virtual HRESULT __stdcall SetStreamSource(UINT StreamNumber, IDirect3DVertexBuffer9 *pStreamData, + UINT OffsetInBytes, UINT Stride); + virtual HRESULT __stdcall GetStreamSource(UINT StreamNumber, IDirect3DVertexBuffer9 **ppStreamData, + UINT *pOffsetInBytes, UINT *pStride); + virtual HRESULT __stdcall SetStreamSourceFreq(UINT StreamNumber, UINT Setting); + virtual HRESULT __stdcall GetStreamSourceFreq(UINT StreamNumber, UINT *pSetting); + virtual HRESULT __stdcall SetIndices(IDirect3DIndexBuffer9 *pIndexData); + virtual HRESULT __stdcall GetIndices(IDirect3DIndexBuffer9 **ppIndexData); + virtual HRESULT __stdcall CreatePixelShader(CONST DWORD *pFunction, + IDirect3DPixelShader9 **ppShader); + virtual HRESULT __stdcall SetPixelShader(IDirect3DPixelShader9 *pShader); + virtual HRESULT __stdcall GetPixelShader(IDirect3DPixelShader9 **ppShader); + virtual HRESULT __stdcall SetPixelShaderConstantF(UINT StartRegister, CONST float *pConstantData, + UINT Vector4fCount); + virtual HRESULT __stdcall GetPixelShaderConstantF(UINT StartRegister, float *pConstantData, + UINT Vector4fCount); + virtual HRESULT __stdcall SetPixelShaderConstantI(UINT StartRegister, CONST int *pConstantData, + UINT Vector4iCount); + virtual HRESULT __stdcall GetPixelShaderConstantI(UINT StartRegister, int *pConstantData, + UINT Vector4iCount); + virtual HRESULT __stdcall SetPixelShaderConstantB(UINT StartRegister, CONST BOOL *pConstantData, + UINT BoolCount); + virtual HRESULT __stdcall GetPixelShaderConstantB(UINT StartRegister, BOOL *pConstantData, + UINT BoolCount); + virtual HRESULT __stdcall DrawRectPatch(UINT Handle, CONST float *pNumSegs, + CONST D3DRECTPATCH_INFO *pRectPatchInfo); + virtual HRESULT __stdcall DrawTriPatch(UINT Handle, CONST float *pNumSegs, + CONST D3DTRIPATCH_INFO *pTriPatchInfo); + virtual HRESULT __stdcall DeletePatch(UINT Handle); + virtual HRESULT __stdcall CreateQuery(D3DQUERYTYPE Type, IDirect3DQuery9 **ppQuery); + +private: + IDirect3DDevice9 *m_device; + D3D9DebugManager *m_DebugManager; + + uint32_t m_FrameCounter; + FrameTimer m_FrameTimer; +}; + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +// WrappedD3D9 + +class WrappedD3D9 : public IDirect3D9 +{ +public: + WrappedD3D9(IDirect3D9 *direct3D9) : m_direct3D(direct3D9) {} + /*** IUnknown methods ***/ + virtual HRESULT __stdcall QueryInterface(REFIID riid, void **ppvObj); + virtual ULONG __stdcall AddRef(); + virtual ULONG __stdcall Release(); + + /*** IDirect3D9 methods ***/ + virtual HRESULT __stdcall RegisterSoftwareDevice(void *pInitializeFunction); + virtual UINT __stdcall GetAdapterCount(); + virtual HRESULT __stdcall GetAdapterIdentifier(UINT Adapter, DWORD Flags, + D3DADAPTER_IDENTIFIER9 *pIdentifier); + virtual UINT __stdcall GetAdapterModeCount(UINT Adapter, D3DFORMAT Format); + virtual HRESULT __stdcall EnumAdapterModes(UINT Adapter, D3DFORMAT Format, UINT Mode, + D3DDISPLAYMODE *pMode); + virtual HRESULT __stdcall GetAdapterDisplayMode(UINT Adapter, D3DDISPLAYMODE *pMode); + virtual HRESULT __stdcall CheckDeviceType(UINT Adapter, D3DDEVTYPE DevType, D3DFORMAT AdapterFormat, + D3DFORMAT BackBufferFormat, BOOL bWindowed); + virtual HRESULT __stdcall CheckDeviceFormat(UINT Adapter, D3DDEVTYPE DeviceType, + D3DFORMAT AdapterFormat, DWORD Usage, + D3DRESOURCETYPE RType, D3DFORMAT CheckFormat); + virtual HRESULT __stdcall CheckDeviceMultiSampleType(UINT Adapter, D3DDEVTYPE DeviceType, + D3DFORMAT SurfaceFormat, BOOL Windowed, + D3DMULTISAMPLE_TYPE MultiSampleType, + DWORD *pQualityLevels); + virtual HRESULT __stdcall CheckDepthStencilMatch(UINT Adapter, D3DDEVTYPE DeviceType, + D3DFORMAT AdapterFormat, + D3DFORMAT RenderTargetFormat, + D3DFORMAT DepthStencilFormat); + virtual HRESULT __stdcall CheckDeviceFormatConversion(UINT Adapter, D3DDEVTYPE DeviceType, + D3DFORMAT SourceFormat, + D3DFORMAT TargetFormat); + virtual HRESULT __stdcall GetDeviceCaps(UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9 *pCaps); + virtual HMONITOR __stdcall GetAdapterMonitor(UINT Adapter); + virtual HRESULT __stdcall CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, + DWORD BehaviorFlags, + D3DPRESENT_PARAMETERS *pPresentationParameters, + IDirect3DDevice9 **ppReturnedDeviceInterface); + +private: + IDirect3D9 *m_direct3D; +}; \ No newline at end of file diff --git a/renderdoc/driver/d3d9/d3d9_hooks.cpp b/renderdoc/driver/d3d9/d3d9_hooks.cpp index 310521256..3b24353cb 100644 --- a/renderdoc/driver/d3d9/d3d9_hooks.cpp +++ b/renderdoc/driver/d3d9/d3d9_hooks.cpp @@ -27,6 +27,7 @@ #include "hooks/hooks.h" #include "driver/dx/official/d3d9.h" +#include "d3d9_device.h" #define DLL_NAME "d3d9.dll" @@ -135,9 +136,11 @@ private: static IDirect3D9 *WINAPI Create9_hook(UINT SDKVersion) { - RDCWARN("App creating d3d9 %x device - not hooked!", SDKVersion); + RDCLOG("App creating d3d9 %x", SDKVersion); - return d3d9hooks.Create9()(SDKVersion); + IDirect3D9 *realD3D = d3d9hooks.Create9()(SDKVersion); + + return new WrappedD3D9(realD3D); } }; diff --git a/renderdoc/driver/d3d9/renderdoc_d3d9.vcxproj b/renderdoc/driver/d3d9/renderdoc_d3d9.vcxproj index 5ed7627a2..bba11d021 100644 --- a/renderdoc/driver/d3d9/renderdoc_d3d9.vcxproj +++ b/renderdoc/driver/d3d9/renderdoc_d3d9.vcxproj @@ -184,6 +184,8 @@ + + @@ -192,6 +194,8 @@ + + diff --git a/renderdoc/driver/d3d9/renderdoc_d3d9.vcxproj.filters b/renderdoc/driver/d3d9/renderdoc_d3d9.vcxproj.filters index 3642cda93..723ee69bc 100644 --- a/renderdoc/driver/d3d9/renderdoc_d3d9.vcxproj.filters +++ b/renderdoc/driver/d3d9/renderdoc_d3d9.vcxproj.filters @@ -7,11 +7,23 @@ {069c5202-e850-427b-9353-250795a60436} + + {c6b1027e-abd1-4f79-828a-ad40bd685453} + + + {503975e6-f4c0-4efc-8ff1-77e4082c5998} + Hooks + + Debug + + + Common + @@ -29,5 +41,11 @@ official + + Debug + + + Common + \ No newline at end of file diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index 334b403dd..3a4240b2d 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -722,11 +722,9 @@ WrappedOpenGL::WrappedOpenGL(const char *logfile, const GLHookSet &funcs) : m_Re m_SuccessfulCapture = true; m_FailureReason = CaptureSucceeded; - m_FrameTimer.Restart(); - m_AppControlledCapture = false; - m_TotalTime = m_AvgFrametime = m_MinFrametime = m_MaxFrametime = 0.0; + m_FrameTimer.InitTimers(); m_RealDebugFunc = NULL; m_RealDebugFuncParam = NULL; @@ -2196,32 +2194,7 @@ void WrappedOpenGL::SwapBuffers(void *windowHandle) if(m_State == WRITING_IDLE) { - m_FrameTimes.push_back(m_FrameTimer.GetMilliseconds()); - m_TotalTime += m_FrameTimes.back(); - m_FrameTimer.Restart(); - - // update every second - if(m_TotalTime > 1000.0) - { - m_MinFrametime = 10000.0; - m_MaxFrametime = 0.0; - m_AvgFrametime = 0.0; - - m_TotalTime = 0.0; - - for(size_t i = 0; i < m_FrameTimes.size(); i++) - { - m_AvgFrametime += m_FrameTimes[i]; - if(m_FrameTimes[i] < m_MinFrametime) - m_MinFrametime = m_FrameTimes[i]; - if(m_FrameTimes[i] > m_MaxFrametime) - m_MaxFrametime = m_FrameTimes[i]; - } - - m_AvgFrametime /= double(m_FrameTimes.size()); - - m_FrameTimes.clear(); - } + m_FrameTimer.UpdateTimers(); uint32_t overlay = RenderDoc::Inst().GetOverlayBits(); @@ -2269,9 +2242,11 @@ void WrappedOpenGL::SwapBuffers(void *windowHandle) } if(overlay & eRENDERDOC_Overlay_FrameRate) { - overlayText += StringFormat::Fmt(" %.2lf ms (%.2lf .. %.2lf) (%.0lf FPS)", m_AvgFrametime, - m_MinFrametime, m_MaxFrametime, - m_AvgFrametime <= 0.0f ? 0.0f : 1000.0f / m_AvgFrametime); + overlayText += StringFormat::Fmt( + " %.2lf ms (%.2lf .. %.2lf) (%.0lf FPS)", m_FrameTimer.GetAvgFrameTime(), + m_FrameTimer.GetMinFrameTime(), m_FrameTimer.GetMaxFrameTime(), + m_FrameTimer.GetAvgFrameTime() <= 0.0f ? 0.0f + : 1000.0f / m_FrameTimer.GetAvgFrameTime()); } float y = 0.0f; diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index 724c9ec0b..eb25db67a 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -175,13 +175,11 @@ private: CaptureFailReason m_FailedReason; uint32_t m_Failures; + FrameTimer m_FrameTimer; + CaptureFailReason m_FailureReason; bool m_SuccessfulCapture; - PerformanceTimer m_FrameTimer; - vector m_FrameTimes; - double m_TotalTime, m_AvgFrametime, m_MinFrametime, m_MaxFrametime; - set m_HighTrafficResources; // we store two separate sets of maps, since for an explicit glMemoryBarrier diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 3b74dbfe9..64e0c7890 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -269,13 +269,11 @@ WrappedVulkan::WrappedVulkan(const char *logFilename) : m_RenderState(&m_Creatio m_AppControlledCapture = false; - m_FrameTimer.Restart(); - threadSerialiserTLSSlot = Threading::AllocateTLSSlot(); tempMemoryTLSSlot = Threading::AllocateTLSSlot(); debugMessageSinkTLSSlot = Threading::AllocateTLSSlot(); - m_TotalTime = m_AvgFrametime = m_MinFrametime = m_MaxFrametime = 0.0; + m_FrameTimer.InitTimers(); m_RootEventID = 1; m_RootDrawcallID = 1; diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index 63e5dc101..1bb49f897 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -253,14 +253,12 @@ private: uint32_t m_FrameCounter; - PerformanceTimer m_FrameTimer; - vector m_FrameTimes; - double m_TotalTime, m_AvgFrametime, m_MinFrametime, m_MaxFrametime; - vector m_CapturedFrames; FetchFrameRecord m_FrameRecord; vector m_Drawcalls; + FrameTimer m_FrameTimer; + struct PhysicalDeviceData { PhysicalDeviceData() : readbackMemIndex(0), uploadMemIndex(0), GPULocalMemIndex(0) diff --git a/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp index af9682d92..709438c74 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp @@ -539,32 +539,7 @@ VkResult WrappedVulkan::vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR if(m_State == WRITING_IDLE) { - m_FrameTimes.push_back(m_FrameTimer.GetMilliseconds()); - m_TotalTime += m_FrameTimes.back(); - m_FrameTimer.Restart(); - - // update every second - if(m_TotalTime > 1000.0) - { - m_MinFrametime = 10000.0; - m_MaxFrametime = 0.0; - m_AvgFrametime = 0.0; - - m_TotalTime = 0.0; - - for(size_t i = 0; i < m_FrameTimes.size(); i++) - { - m_AvgFrametime += m_FrameTimes[i]; - if(m_FrameTimes[i] < m_MinFrametime) - m_MinFrametime = m_FrameTimes[i]; - if(m_FrameTimes[i] > m_MaxFrametime) - m_MaxFrametime = m_FrameTimes[i]; - } - - m_AvgFrametime /= double(m_FrameTimes.size()); - - m_FrameTimes.clear(); - } + m_FrameTimer.UpdateTimers(); uint32_t overlay = RenderDoc::Inst().GetOverlayBits(); @@ -645,8 +620,10 @@ VkResult WrappedVulkan::vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR } if(overlay & eRENDERDOC_Overlay_FrameRate) { - overlayText += StringFormat::Fmt(" %.2lf ms (%.2lf .. %.2lf) (%.0lf FPS)", m_AvgFrametime, - m_MinFrametime, m_MaxFrametime, 1000.0f / m_AvgFrametime); + overlayText += StringFormat::Fmt( + " %.2lf ms (%.2lf .. %.2lf) (%.0lf FPS)", m_FrameTimer.GetAvgFrameTime(), + m_FrameTimer.GetMinFrameTime(), m_FrameTimer.GetMaxFrameTime(), + 1000.0f / m_FrameTimer.GetAvgFrameTime()); } float y = 0.0f;