Skip to content

Commit

Permalink
nullvideo: initial release of null video backend
Browse files Browse the repository at this point in the history
  • Loading branch information
degasus authored and vladfi1 committed Jan 1, 2022
1 parent 3fb06fa commit 032430c
Show file tree
Hide file tree
Showing 15 changed files with 619 additions and 1 deletion.
1 change: 1 addition & 0 deletions Source/Core/Core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ set(LIBS
vcdcom
vcddec
vcdenc
videonull
videoogl
videosoftware
z
Expand Down
1 change: 1 addition & 0 deletions Source/Core/VideoBackends/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
add_subdirectory(OGL)
add_subdirectory(Null)
add_subdirectory(Software)
add_subdirectory(Vulkan)

Expand Down
14 changes: 14 additions & 0 deletions Source/Core/VideoBackends/Null/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
set(SRCS
NullBackend.cpp
Render.cpp
VertexManager.cpp
ShaderCache.cpp
)

set(LIBS
videocommon
common
)

add_dolphin_library(videonull "${SRCS}" "${LIBS}")

29 changes: 29 additions & 0 deletions Source/Core/VideoBackends/Null/FramebufferManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2015 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.

#include "VideoCommon/FramebufferManagerBase.h"

class XFBSource : public XFBSourceBase
{
public:
void DecodeToTexture(u32 xfb_addr, u32 fb_width, u32 fb_height) override {}
void CopyEFB(float gamma) override {}
};

class FramebufferManager : public FramebufferManagerBase
{
public:
std::unique_ptr<XFBSourceBase> CreateXFBSource(unsigned int target_width,
unsigned int target_height,
unsigned int layers) override
{
return std::make_unique<XFBSource>();
}

void GetTargetSize(unsigned int* width, unsigned int* height) override {}
void CopyToRealXFB(u32 xfb_addr, u32 fb_stride, u32 fb_height, const EFBRectangle& source_rc,
float gamma = 1.0f) override
{
}
};
127 changes: 127 additions & 0 deletions Source/Core/VideoBackends/Null/NullBackend.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// Copyright 2015 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.

// Null Backend Documentation

// This backend tries not to do anything in the backend,
// but everything in VideoCommon.

#include "Core/Host.h"

#include "VideoBackends/Null/FramebufferManager.h"
#include "VideoBackends/Null/PerfQuery.h"
#include "VideoBackends/Null/Render.h"
#include "VideoBackends/Null/ShaderCache.h"
#include "VideoBackends/Null/TextureCache.h"
#include "VideoBackends/Null/VertexManager.h"
#include "VideoBackends/Null/VideoBackend.h"

#include "VideoCommon/BPStructs.h"
#include "VideoCommon/CommandProcessor.h"
#include "VideoCommon/Fifo.h"
#include "VideoCommon/IndexGenerator.h"
#include "VideoCommon/OnScreenDisplay.h"
#include "VideoCommon/OpcodeDecoding.h"
#include "VideoCommon/PixelEngine.h"
#include "VideoCommon/PixelShaderManager.h"
#include "VideoCommon/VertexLoaderManager.h"
#include "VideoCommon/VertexShaderManager.h"
#include "VideoCommon/VideoBackendBase.h"
#include "VideoCommon/VideoConfig.h"

namespace Null
{
static void InitBackendInfo()
{
g_Config.backend_info.APIType = API_NONE;
g_Config.backend_info.bSupportsExclusiveFullscreen = true;
g_Config.backend_info.bSupportsDualSourceBlend = true;
g_Config.backend_info.bSupportsEarlyZ = true;
g_Config.backend_info.bSupportsPrimitiveRestart = true;
g_Config.backend_info.bSupportsOversizedViewports = true;
g_Config.backend_info.bSupportsGeometryShaders = true;
g_Config.backend_info.bSupports3DVision = false;
g_Config.backend_info.bSupportsPostProcessing = false;
g_Config.backend_info.bSupportsPaletteConversion = true;
g_Config.backend_info.bSupportsClipControl = true;

// aamodes: We only support 1 sample, so no MSAA
g_Config.backend_info.AAModes = {1};
}

void VideoBackend::ShowConfig(void* parent)
{
InitBackendInfo();
Host_ShowVideoConfig(parent, GetDisplayName(), "gfx_null");
}

bool VideoBackend::Initialize(void* window_handle)
{
InitializeShared();
InitBackendInfo();

// Load Configs
g_Config.Load(File::GetUserPath(D_CONFIG_IDX) + "GFX.ini");
g_Config.GameIniLoad();
g_Config.UpdateProjectionHack();
g_Config.VerifyValidity();
UpdateActiveConfig();

// Do our OSD callbacks
OSD::DoCallbacks(OSD::CallbackType::Initialization);

// Initialize VideoCommon
CommandProcessor::Init();
PixelEngine::Init();
BPInit();
Fifo::Init();
OpcodeDecoder::Init();
IndexGenerator::Init();
VertexShaderManager::Init();
PixelShaderManager::Init();
VertexLoaderManager::Init();
Host_Message(WM_USER_CREATE);

return true;
}

// This is called after Initialize() from the Core
// Run from the graphics thread
void VideoBackend::Video_Prepare()
{
g_renderer = std::make_unique<Renderer>();
g_vertex_manager = std::make_unique<VertexManager>();
g_perf_query = std::make_unique<PerfQuery>();
g_framebuffer_manager = std::make_unique<FramebufferManager>();
g_texture_cache = std::make_unique<TextureCache>();
VertexShaderCache::s_instance = std::make_unique<VertexShaderCache>();
GeometryShaderCache::s_instance = std::make_unique<GeometryShaderCache>();
PixelShaderCache::s_instance = std::make_unique<PixelShaderCache>();
}

void VideoBackend::Shutdown()
{
// Shutdown VideoCommon
Fifo::Shutdown();
VertexLoaderManager::Shutdown();
VertexShaderManager::Shutdown();
PixelShaderManager::Shutdown();
OpcodeDecoder::Shutdown();

// Do our OSD callbacks
OSD::DoCallbacks(OSD::CallbackType::Shutdown);
}

void VideoBackend::Video_Cleanup()
{
PixelShaderCache::s_instance.reset();
VertexShaderCache::s_instance.reset();
GeometryShaderCache::s_instance.reset();
g_texture_cache.reset();
g_perf_query.reset();
g_vertex_manager.reset();
g_framebuffer_manager.reset();
g_renderer.reset();
}
}
24 changes: 24 additions & 0 deletions Source/Core/VideoBackends/Null/PerfQuery.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2015 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.

#pragma once

#include "VideoCommon/PerfQueryBase.h"

namespace Null
{
class PerfQuery : public PerfQueryBase
{
public:
PerfQuery() {}
~PerfQuery() override {}
void EnableQuery(PerfQueryGroup type) override {}
void DisableQuery(PerfQueryGroup type) override {}
void ResetQuery() override {}
u32 GetQueryResult(PerfQueryType type) override { return 0; }
void FlushResults() override {}
bool IsFlushed() const { return true; }
};

} // namespace
46 changes: 46 additions & 0 deletions Source/Core/VideoBackends/Null/Render.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright 2015 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.

#include "Common/Logging/Log.h"

#include "VideoBackends/Null/Render.h"

#include "VideoCommon/VideoConfig.h"

namespace Null
{
// Init functions
Renderer::Renderer()
{
g_Config.bRunning = true;
UpdateActiveConfig();
}

Renderer::~Renderer()
{
g_Config.bRunning = false;
UpdateActiveConfig();
}

void Renderer::RenderText(const std::string& text, int left, int top, u32 color)
{
NOTICE_LOG(VIDEO, "RenderText: %s\n", text.c_str());
}

TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
{
TargetRectangle result;
result.left = rc.left;
result.top = rc.top;
result.right = rc.right;
result.bottom = rc.bottom;
return result;
}

void Renderer::SwapImpl(u32, u32, u32, u32, const EFBRectangle&, float)
{
UpdateActiveConfig();
}

} // namespace Null
39 changes: 39 additions & 0 deletions Source/Core/VideoBackends/Null/Render.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2015 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.

#pragma once

#include "VideoCommon/RenderBase.h"

namespace Null
{
class Renderer : public ::Renderer
{
public:
Renderer();
~Renderer();

void RenderText(const std::string& pstr, int left, int top, u32 color) override;
u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override { return 0; }
void PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points) override {}
u16 BBoxRead(int index) override { return 0; }
void BBoxWrite(int index, u16 value) override {}
int GetMaxTextureSize() override { return 16 * 1024; }
TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc) override;

void SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, const EFBRectangle& rc,
float gamma) override;

void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable,
u32 color, u32 z) override
{
}

void ReinterpretPixelData(unsigned int convtype) override {}
bool SaveScreenshot(const std::string& filename, const TargetRectangle& rc) override
{
return false;
}
};
}
76 changes: 76 additions & 0 deletions Source/Core/VideoBackends/Null/ShaderCache.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright 2015 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.

#include "VideoBackends/Null/ShaderCache.h"

#include "VideoCommon/Debugger.h"
#include "VideoCommon/Statistics.h"

namespace Null
{
template <typename Uid>
ShaderCache<Uid>::ShaderCache()
{
Clear();

SETSTAT(stats.numPixelShadersCreated, 0);
SETSTAT(stats.numPixelShadersAlive, 0);
}

template <typename Uid>
ShaderCache<Uid>::~ShaderCache()
{
Clear();
}

template <typename Uid>
void ShaderCache<Uid>::Clear()
{
m_shaders.clear();
m_last_entry = nullptr;
}

template <typename Uid>
bool ShaderCache<Uid>::SetShader(DSTALPHA_MODE dst_alpha_mode, u32 primitive_type)
{
Uid uid = GetUid(dst_alpha_mode, primitive_type, API_OPENGL);

// Check if the shader is already set
if (m_last_entry)
{
if (uid == m_last_uid)
{
return true;
}
}

m_last_uid = uid;

// Check if the shader is already in the cache
auto iter = m_shaders.find(uid);
if (iter != m_shaders.end())
{
const std::string& entry = iter->second;
m_last_entry = &entry;

GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
return true;
}

// Need to compile a new shader
ShaderCode code = GenerateCode(dst_alpha_mode, primitive_type, API_OPENGL);
m_shaders.emplace(uid, code.GetBuffer());

GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
return true;
}

template class ShaderCache<VertexShaderUid>;
template class ShaderCache<GeometryShaderUid>;
template class ShaderCache<PixelShaderUid>;

std::unique_ptr<VertexShaderCache> VertexShaderCache::s_instance;
std::unique_ptr<GeometryShaderCache> GeometryShaderCache::s_instance;
std::unique_ptr<PixelShaderCache> PixelShaderCache::s_instance;
}
Loading

0 comments on commit 032430c

Please sign in to comment.