diff --git a/Source/Core/VideoBackends/D3D/NativeVertexFormat.cpp b/Source/Core/VideoBackends/D3D/NativeVertexFormat.cpp index 4b2951a689..be29d9fbfe 100644 --- a/Source/Core/VideoBackends/D3D/NativeVertexFormat.cpp +++ b/Source/Core/VideoBackends/D3D/NativeVertexFormat.cpp @@ -20,16 +20,15 @@ class D3DVertexFormat : public NativeVertexFormat ID3D11InputLayout* m_layout; public: - D3DVertexFormat() : m_num_elems(0), m_layout(nullptr) {} + D3DVertexFormat(const PortableVertexDeclaration& vtx_decl); ~D3DVertexFormat() { SAFE_RELEASE(m_layout); } - void Initialize(const PortableVertexDeclaration &_vtx_decl); void SetupVertexPointers(); }; -NativeVertexFormat* VertexManager::CreateNativeVertexFormat() +NativeVertexFormat* VertexManager::CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl) { - return new D3DVertexFormat(); + return new D3DVertexFormat(vtx_decl); } static const DXGI_FORMAT d3d_format_lookup[5*4*2] = @@ -57,9 +56,10 @@ DXGI_FORMAT VarToD3D(VarType t, int size, bool integer) return retval; } -void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl) +D3DVertexFormat::D3DVertexFormat(const PortableVertexDeclaration& _vtx_decl) + : m_num_elems(0), m_layout(nullptr) { - vtx_decl = _vtx_decl; + this->vtx_decl = _vtx_decl; memset(m_elems, 0, sizeof(m_elems)); const AttributeFormat* format = &_vtx_decl.position; diff --git a/Source/Core/VideoBackends/D3D/VertexManager.h b/Source/Core/VideoBackends/D3D/VertexManager.h index d963f81266..2cc6b555d7 100644 --- a/Source/Core/VideoBackends/D3D/VertexManager.h +++ b/Source/Core/VideoBackends/D3D/VertexManager.h @@ -15,7 +15,7 @@ public: VertexManager(); ~VertexManager(); - NativeVertexFormat* CreateNativeVertexFormat() override; + NativeVertexFormat* CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl) override; void CreateDeviceObjects() override; void DestroyDeviceObjects() override; diff --git a/Source/Core/VideoBackends/OGL/NativeVertexFormat.cpp b/Source/Core/VideoBackends/OGL/NativeVertexFormat.cpp index f7f3ab301a..004692999f 100644 --- a/Source/Core/VideoBackends/OGL/NativeVertexFormat.cpp +++ b/Source/Core/VideoBackends/OGL/NativeVertexFormat.cpp @@ -21,19 +21,9 @@ namespace OGL { -NativeVertexFormat* VertexManager::CreateNativeVertexFormat() +NativeVertexFormat* VertexManager::CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl) { - return new GLVertexFormat(); -} - -GLVertexFormat::GLVertexFormat() -{ - -} - -GLVertexFormat::~GLVertexFormat() -{ - glDeleteVertexArrays(1, &VAO); + return new GLVertexFormat(vtx_decl); } static inline GLuint VarToGL(VarType t) @@ -56,7 +46,7 @@ static void SetPointer(u32 attrib, u32 stride, const AttributeFormat &format) glVertexAttribPointer(attrib, format.components, VarToGL(format.type), true, stride, (u8*)nullptr + format.offset); } -void GLVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl) +GLVertexFormat::GLVertexFormat(const PortableVertexDeclaration& _vtx_decl) { this->vtx_decl = _vtx_decl; u32 vertex_stride = _vtx_decl.stride; @@ -74,22 +64,27 @@ void GLVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vm->m_index_buffers); glBindBuffer(GL_ARRAY_BUFFER, vm->m_vertex_buffers); - SetPointer(SHADER_POSITION_ATTRIB, vertex_stride, vtx_decl.position); + SetPointer(SHADER_POSITION_ATTRIB, vertex_stride, _vtx_decl.position); for (int i = 0; i < 3; i++) - SetPointer(SHADER_NORM0_ATTRIB+i, vertex_stride, vtx_decl.normals[i]); + SetPointer(SHADER_NORM0_ATTRIB+i, vertex_stride, _vtx_decl.normals[i]); for (int i = 0; i < 2; i++) - SetPointer(SHADER_COLOR0_ATTRIB+i, vertex_stride, vtx_decl.colors[i]); + SetPointer(SHADER_COLOR0_ATTRIB+i, vertex_stride, _vtx_decl.colors[i]); for (int i = 0; i < 8; i++) - SetPointer(SHADER_TEXTURE0_ATTRIB+i, vertex_stride, vtx_decl.texcoords[i]); + SetPointer(SHADER_TEXTURE0_ATTRIB+i, vertex_stride, _vtx_decl.texcoords[i]); - SetPointer(SHADER_POSMTX_ATTRIB, vertex_stride, vtx_decl.posmtx); + SetPointer(SHADER_POSMTX_ATTRIB, vertex_stride, _vtx_decl.posmtx); vm->m_last_vao = VAO; } +GLVertexFormat::~GLVertexFormat() +{ + glDeleteVertexArrays(1, &VAO); +} + void GLVertexFormat::SetupVertexPointers() { } diff --git a/Source/Core/VideoBackends/OGL/Render.h b/Source/Core/VideoBackends/OGL/Render.h index a6544a6049..b939911cee 100644 --- a/Source/Core/VideoBackends/OGL/Render.h +++ b/Source/Core/VideoBackends/OGL/Render.h @@ -83,10 +83,6 @@ public: void SetInterlacingMode() override; void SetViewport() override; - // TODO: Implement and use these - void ApplyState(bool bUseDstAlpha) override {} - void RestoreState() override {} - void RenderText(const std::string& text, int left, int top, u32 color) override; void FlipImageData(u8 *data, int w, int h, int pixel_width = 3); diff --git a/Source/Core/VideoBackends/OGL/VertexManager.h b/Source/Core/VideoBackends/OGL/VertexManager.h index 11d7e69e48..d674d5d792 100644 --- a/Source/Core/VideoBackends/OGL/VertexManager.h +++ b/Source/Core/VideoBackends/OGL/VertexManager.h @@ -15,10 +15,9 @@ namespace OGL class GLVertexFormat : public NativeVertexFormat { public: - GLVertexFormat(); + GLVertexFormat(const PortableVertexDeclaration& vtx_decl); ~GLVertexFormat(); - void Initialize(const PortableVertexDeclaration &_vtx_decl) override; void SetupVertexPointers() override; GLuint VAO; @@ -31,7 +30,7 @@ class VertexManager : public VertexManagerBase public: VertexManager(); ~VertexManager(); - NativeVertexFormat* CreateNativeVertexFormat() override; + NativeVertexFormat* CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl) override; void CreateDeviceObjects() override; void DestroyDeviceObjects() override; diff --git a/Source/Core/VideoCommon/FramebufferManagerBase.cpp b/Source/Core/VideoCommon/FramebufferManagerBase.cpp index 7981dfce4d..b01c39a5f3 100644 --- a/Source/Core/VideoCommon/FramebufferManagerBase.cpp +++ b/Source/Core/VideoCommon/FramebufferManagerBase.cpp @@ -59,9 +59,12 @@ const XFBSourceBase* const* FramebufferManagerBase::GetRealXFBSource(u32 xfbAddr m_realXFBSource = nullptr; } - if (!m_realXFBSource) + if (!m_realXFBSource && g_framebuffer_manager) m_realXFBSource = g_framebuffer_manager->CreateXFBSource(fbWidth, fbHeight, 1); + if (!m_realXFBSource) + return nullptr; + m_realXFBSource->srcAddr = xfbAddr; m_realXFBSource->srcWidth = MAX_XFB_WIDTH; @@ -118,13 +121,21 @@ const XFBSourceBase* const* FramebufferManagerBase::GetVirtualXFBSource(u32 xfbA void FramebufferManagerBase::CopyToXFB(u32 xfbAddr, u32 fbStride, u32 fbHeight, const EFBRectangle& sourceRc, float Gamma) { if (g_ActiveConfig.bUseRealXFB) - g_framebuffer_manager->CopyToRealXFB(xfbAddr, fbStride, fbHeight, sourceRc, Gamma); + { + if (g_framebuffer_manager) + g_framebuffer_manager->CopyToRealXFB(xfbAddr, fbStride, fbHeight, sourceRc, Gamma); + } else + { CopyToVirtualXFB(xfbAddr, fbStride, fbHeight, sourceRc, Gamma); + } } void FramebufferManagerBase::CopyToVirtualXFB(u32 xfbAddr, u32 fbStride, u32 fbHeight, const EFBRectangle& sourceRc, float Gamma) { + if (!g_framebuffer_manager) + return; + VirtualXFBListType::iterator vxfb = FindVirtualXFB(xfbAddr, sourceRc.GetWidth(), fbHeight); if (m_virtualXFBList.end() == vxfb) @@ -160,6 +171,9 @@ void FramebufferManagerBase::CopyToVirtualXFB(u32 xfbAddr, u32 fbStride, u32 fbH if (!vxfb->xfbSource) { vxfb->xfbSource = g_framebuffer_manager->CreateXFBSource(target_width, target_height, m_EFBLayers); + if (!vxfb->xfbSource) + return; + vxfb->xfbSource->texWidth = target_width; vxfb->xfbSource->texHeight = target_height; } diff --git a/Source/Core/VideoCommon/NativeVertexFormat.h b/Source/Core/VideoCommon/NativeVertexFormat.h index 0f48341deb..ff461a02fd 100644 --- a/Source/Core/VideoCommon/NativeVertexFormat.h +++ b/Source/Core/VideoCommon/NativeVertexFormat.h @@ -108,7 +108,6 @@ class NativeVertexFormat : NonCopyable public: virtual ~NativeVertexFormat() {} - virtual void Initialize(const PortableVertexDeclaration &vtx_decl) = 0; virtual void SetupVertexPointers() = 0; u32 GetVertexStride() const { return vtx_decl.stride; } diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h index c717483d1e..ad53f2f20c 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -58,19 +58,22 @@ public: PP_EFB_COPY_CLOCKS }; - virtual void SetColorMask() = 0; - virtual void SetBlendMode(bool forceUpdate) = 0; - virtual void SetScissorRect(const EFBRectangle& rc) = 0; - virtual void SetGenerationMode() = 0; - virtual void SetDepthMode() = 0; - virtual void SetLogicOpMode() = 0; - virtual void SetDitherMode() = 0; - virtual void SetSamplerState(int stage, int texindex, bool custom_tex) = 0; - virtual void SetInterlacingMode() = 0; - virtual void SetViewport() = 0; + virtual void SetColorMask() {} + virtual void SetBlendMode(bool forceUpdate) {} + virtual void SetScissorRect(const EFBRectangle& rc) {} + virtual void SetGenerationMode() {} + virtual void SetDepthMode() {} + virtual void SetLogicOpMode() {} + virtual void SetDitherMode() {} + virtual void SetSamplerState(int stage, int texindex, bool custom_tex) {} + virtual void SetInterlacingMode() {} + virtual void SetViewport() {} - virtual void ApplyState(bool bUseDstAlpha) = 0; - virtual void RestoreState() = 0; + virtual void ApplyState(bool bUseDstAlpha) {} + virtual void RestoreState() {} + + virtual void ResetAPIState() {} + virtual void RestoreAPIState() {} // Ideal internal resolution - determined by display resolution (automatic scaling) and/or a multiple of the native EFB resolution static int GetTargetWidth() { return s_target_width; } @@ -117,10 +120,6 @@ public: virtual u16 BBoxRead(int index) = 0; virtual void BBoxWrite(int index, u16 value) = 0; - // What's the real difference between these? Too similar names. - virtual void ResetAPIState() = 0; - virtual void RestoreAPIState() = 0; - // Finish up the current frame, print some stats static void Swap(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc,float Gamma = 1.0f); virtual void SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc, float Gamma = 1.0f) = 0; diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index f6d07a476b..c5330d6b86 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -265,20 +265,23 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::DoPartialTextureUpdates(Tex newconfig.height = h; newconfig.rendertarget = true; TCacheEntryBase* newentry = AllocateTexture(newconfig); - newentry->SetGeneralParameters(entry_to_update->addr, entry_to_update->size_in_bytes, entry_to_update->format); - newentry->SetDimensions(entry_to_update->native_width, entry_to_update->native_height, 1); - newentry->SetHashes(entry_to_update->base_hash, entry_to_update->hash); - newentry->frameCount = frameCount; - newentry->is_efb_copy = false; - srcrect.right = entry_to_update->config.width; - srcrect.bottom = entry_to_update->config.height; - dstrect.right = w; - dstrect.bottom = h; - newentry->CopyRectangleFromTexture(entry_to_update, srcrect, dstrect); - entry_to_update = newentry; - u64 key = iter_t->first; - iter_t = FreeTexture(iter_t); - textures_by_address.emplace(key, entry_to_update); + if (newentry) + { + newentry->SetGeneralParameters(entry_to_update->addr, entry_to_update->size_in_bytes, entry_to_update->format); + newentry->SetDimensions(entry_to_update->native_width, entry_to_update->native_height, 1); + newentry->SetHashes(entry_to_update->base_hash, entry_to_update->hash); + newentry->frameCount = frameCount; + newentry->is_efb_copy = false; + srcrect.right = entry_to_update->config.width; + srcrect.bottom = entry_to_update->config.height; + dstrect.right = w; + dstrect.bottom = h; + newentry->CopyRectangleFromTexture(entry_to_update, srcrect, dstrect); + entry_to_update = newentry; + u64 key = iter_t->first; + iter_t = FreeTexture(iter_t); + textures_by_address.emplace(key, entry_to_update); + } } } srcrect.right = entry->config.width; @@ -544,15 +547,18 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::Load(const u32 stage) config.layers = FramebufferManagerBase::GetEFBLayers(); TCacheEntryBase *decoded_entry = AllocateTexture(config); - decoded_entry->SetGeneralParameters(address, texture_size, full_format); - decoded_entry->SetDimensions(entry->native_width, entry->native_height, 1); - decoded_entry->SetHashes(base_hash, full_hash); - decoded_entry->frameCount = FRAMECOUNT_INVALID; - decoded_entry->is_efb_copy = false; + if (decoded_entry) + { + decoded_entry->SetGeneralParameters(address, texture_size, full_format); + decoded_entry->SetDimensions(entry->native_width, entry->native_height, 1); + decoded_entry->SetHashes(base_hash, full_hash); + decoded_entry->frameCount = FRAMECOUNT_INVALID; + decoded_entry->is_efb_copy = false; - g_texture_cache->ConvertTexture(decoded_entry, entry, &texMem[tlutaddr], (TlutFormat)tlutfmt); - textures_by_address.emplace((u64)address, decoded_entry); - return ReturnEntry(stage, decoded_entry); + g_texture_cache->ConvertTexture(decoded_entry, entry, &texMem[tlutaddr], (TlutFormat)tlutfmt); + textures_by_address.emplace((u64)address, decoded_entry); + return ReturnEntry(stage, decoded_entry); + } } // Search the texture cache for normal textures by hash @@ -611,6 +617,21 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::Load(const u32 stage) } } + // how many levels the allocated texture shall have + const u32 texLevels = hires_tex ? (u32)hires_tex->m_levels.size() : tex_levels; + + // create the entry/texture + TCacheEntryConfig config; + config.width = width; + config.height = height; + config.levels = texLevels; + + TCacheEntryBase* entry = AllocateTexture(config); + GFX_DEBUGGER_PAUSE_AT(NEXT_NEW_TEXTURE, true); + + if (!entry) + return nullptr; + if (!hires_tex) { if (!(texformat == GX_TF_RGBA8 && from_tmem)) @@ -625,18 +646,6 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::Load(const u32 stage) } } - // how many levels the allocated texture shall have - const u32 texLevels = hires_tex ? (u32)hires_tex->m_levels.size() : tex_levels; - - // create the entry/texture - TCacheEntryConfig config; - config.width = width; - config.height = height; - config.levels = texLevels; - - TCacheEntryBase* entry = AllocateTexture(config); - GFX_DEBUGGER_PAUSE_AT(NEXT_NEW_TEXTURE, true); - iter = textures_by_address.emplace((u64)address, entry); if (g_ActiveConfig.iSafeTextureCache_ColorSamples == 0 || std::max(texture_size, palette_size) <= (u32)g_ActiveConfig.iSafeTextureCache_ColorSamples * 8) @@ -1120,26 +1129,29 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo TCacheEntryBase* entry = AllocateTexture(config); - entry->SetGeneralParameters(dstAddr, 0, dstFormat); - entry->SetDimensions(tex_w, tex_h, 1); - - entry->frameCount = FRAMECOUNT_INVALID; - entry->SetEfbCopy(dstStride); - entry->is_custom_tex = false; - - entry->FromRenderTarget(dst, srcFormat, srcRect, scaleByHalf, cbufid, colmat); - - u64 hash = entry->CalculateHash(); - entry->SetHashes(hash, hash); - - if (g_ActiveConfig.bDumpEFBTarget) + if (entry) { - static int count = 0; - entry->Save(StringFromFormat("%sefb_frame_%i.png", File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(), - count++), 0); - } + entry->SetGeneralParameters(dstAddr, 0, dstFormat); + entry->SetDimensions(tex_w, tex_h, 1); - textures_by_address.emplace((u64)dstAddr, entry); + entry->frameCount = FRAMECOUNT_INVALID; + entry->SetEfbCopy(dstStride); + entry->is_custom_tex = false; + + entry->FromRenderTarget(dst, srcFormat, srcRect, scaleByHalf, cbufid, colmat); + + u64 hash = entry->CalculateHash(); + entry->SetHashes(hash, hash); + + if (g_ActiveConfig.bDumpEFBTarget) + { + static int count = 0; + entry->Save(StringFromFormat("%sefb_frame_%i.png", File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(), + count++), 0); + } + + textures_by_address.emplace((u64)dstAddr, entry); + } } } @@ -1155,6 +1167,9 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::AllocateTexture(const TCach else { entry = g_texture_cache->CreateTexture(config); + if (!entry) + return nullptr; + INCSTAT(stats.numTexturesCreated); } diff --git a/Source/Core/VideoCommon/VertexLoaderManager.cpp b/Source/Core/VideoCommon/VertexLoaderManager.cpp index 50f50cb78e..25c4c6adb0 100644 --- a/Source/Core/VideoCommon/VertexLoaderManager.cpp +++ b/Source/Core/VideoCommon/VertexLoaderManager.cpp @@ -152,8 +152,7 @@ static VertexLoaderBase* RefreshLoader(int vtx_attr_group, bool preprocess = fal std::unique_ptr& native = s_native_vertex_map[format]; if (!native) { - native.reset(g_vertex_manager->CreateNativeVertexFormat()); - native->Initialize(format); + native.reset(g_vertex_manager->CreateNativeVertexFormat(format)); } loader->m_native_vertex_format = native.get(); } diff --git a/Source/Core/VideoCommon/VertexManagerBase.h b/Source/Core/VideoCommon/VertexManagerBase.h index 316bcd4123..26b02ae122 100644 --- a/Source/Core/VideoCommon/VertexManagerBase.h +++ b/Source/Core/VideoCommon/VertexManagerBase.h @@ -50,7 +50,7 @@ public: static void Flush(); - virtual ::NativeVertexFormat* CreateNativeVertexFormat() = 0; + virtual NativeVertexFormat* CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl) = 0; static void DoState(PointerWrap& p);