mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-05 01:20:42 +00:00
8864a1d81e
* Remove redundant repeated calls when preparing multiple tests
667 lines
19 KiB
C++
667 lines
19 KiB
C++
/******************************************************************************
|
|
* The MIT License (MIT)
|
|
*
|
|
* Copyright (c) 2019-2025 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 "test_common.h"
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <algorithm>
|
|
|
|
const DefaultA2V DefaultTri[3] = {
|
|
{Vec3f(-0.5f, -0.5f, 0.0f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
|
|
{Vec3f(0.0f, 0.5f, 0.0f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 1.0f)},
|
|
{Vec3f(0.5f, -0.5f, 0.0f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(1.0f, 0.0f)},
|
|
};
|
|
|
|
/* XPM */
|
|
const char *SmileyTexture[63] = {
|
|
/* columns rows colors chars-per-pixel */
|
|
"48 48 14 1 ", " c #000017", ". c #FF0017", "X c #FF735C", "o c #00FF17", "O c #FF8B5C",
|
|
"+ c #D0B95C", "@ c #E7A25C", "# c #B9D05C", "$ c #8BFF45", "% c #A2E745", "& c #A2FF45",
|
|
"* c #A2E75C", "= c #1700FF", "- c #B9FFFF",
|
|
/* pixels */
|
|
"------------------------------------------------",
|
|
"------------------------------------------------",
|
|
"------------------------------------------------",
|
|
"------------------------------------------------",
|
|
"------------------------------------------------",
|
|
"--------------------- ---------------------",
|
|
"----------------- -----------------",
|
|
"--------------- XOOOOOOO@@ ---------------",
|
|
"------------- XXXOOOOOO@@@@@@@ -------------",
|
|
"------------ XXXOOOOOO@@@@@@@@@ ------------",
|
|
"----------- XXXXOOOOOO@@@@@@@@@@++ -----------",
|
|
"---------- XXXXOOOOOO@@@@@@@@@@++++ ----------",
|
|
"--------- XXXXOOOOOO@@@@@@@@@@++++++ ---------",
|
|
"-------- XXXXOOOOOO@@@@@@@@@++++++++# --------",
|
|
"-------- XXXOOOOOO@@@@@@@@@++++++++## --------",
|
|
"------- XXXOOOOOO@@@@@@@@@++++++++#### -------",
|
|
"------- XXOOOOO...@@@@@@@@+++++ooo###### -------",
|
|
"------ XOOOOO.....@@@@@@+++++ooooo##### ------",
|
|
"------ OOOOOO.....@@@@@++++++ooooo##### ------",
|
|
"------ OOOOOOO.....@@@@+++++++ooooo####%% ------",
|
|
"------ OOOOOO@.....@@@++++++++ooooo###%%* ------",
|
|
"----- OOOOO@@.....@@++++++++#ooooo##%%*% -----",
|
|
"----- OOOO@@@@...@@++++++++###ooo##%%*%% -----",
|
|
"----- OOO@@@@@@@@@++++++++########%%*%%% -----",
|
|
"----- O@@@@@@@@@@++++++++########%%*%%%% -----",
|
|
"----- @@@@@@@@@@++++++++########%%*%%%%% -----",
|
|
"----- @@@@@@@@@++++++++########%%*%%%%%& -----",
|
|
"------ @@@@@@@@++++++++########%%*%%%%%&& ------",
|
|
"------ @@@@==+++++++++########%%*%%==%&&& ------",
|
|
"------ @@@===+++++++########%%*%%===&&& ------",
|
|
"------ @@@+===+++++########%%*%%%==&&&$ ------",
|
|
"------- @@+++===+++#######%%%*%%%==&&&$$ -------",
|
|
"------- +++++===+#######%%%*%%%==&&&$$ -------",
|
|
"-------- +++++===######%%%%%%%===&&$$ --------",
|
|
"-------- +++++#====###%%*%%%====&&$$$ --------",
|
|
"--------- +++####===#%%*%%%====&&$$$ ---------",
|
|
"---------- +######===========&&&$$$ ----------",
|
|
"----------- #######%=======&&&&$$$ -----------",
|
|
"------------ ####%%*%%%%%&&&&$$ ------------",
|
|
"------------- ##%%*%%%%%&&&&$$ -------------",
|
|
"--------------- *%%%%%&&&& ---------------",
|
|
"----------------- -----------------",
|
|
"--------------------- ---------------------",
|
|
"------------------------------------------------",
|
|
"------------------------------------------------",
|
|
"------------------------------------------------",
|
|
"------------------------------------------------",
|
|
"------------------------------------------------"};
|
|
|
|
// since tolower is int -> int, this warns below. make a char -> char alternative
|
|
char toclower(char c)
|
|
{
|
|
return (char)tolower(c);
|
|
}
|
|
|
|
char tocupper(char c)
|
|
{
|
|
return (char)toupper(c);
|
|
}
|
|
|
|
uint16_t MakeHalf(float f)
|
|
{
|
|
bool sign = f < 0.0f;
|
|
f = sign ? -f : f;
|
|
|
|
if(f < 1e-15f)
|
|
return 0;
|
|
|
|
int exp;
|
|
f = frexpf(f, &exp);
|
|
|
|
uint32_t mantissa;
|
|
memcpy(&mantissa, &f, sizeof(mantissa));
|
|
mantissa = (mantissa & 0x007fffff) >> 13;
|
|
|
|
uint16_t ret = mantissa & 0x3ff;
|
|
ret |= ((exp + 14) << 10);
|
|
if(sign)
|
|
ret |= 0x8000;
|
|
|
|
return ret;
|
|
}
|
|
|
|
std::string strlower(const std::string &str)
|
|
{
|
|
std::string newstr(str);
|
|
std::transform(newstr.begin(), newstr.end(), newstr.begin(), toclower);
|
|
return newstr;
|
|
}
|
|
|
|
std::string strupper(const std::string &str)
|
|
{
|
|
std::string newstr(str);
|
|
std::transform(newstr.begin(), newstr.end(), newstr.begin(), tocupper);
|
|
return newstr;
|
|
}
|
|
|
|
std::string trim(const std::string &str)
|
|
{
|
|
const char *whitespace = "\t \n\r";
|
|
size_t start = str.find_first_not_of(whitespace);
|
|
size_t end = str.find_last_not_of(whitespace);
|
|
|
|
// no non-whitespace characters, return the empty string
|
|
if(start == std::string::npos)
|
|
return "";
|
|
|
|
// searching from the start found something, so searching from the end must have too.
|
|
return str.substr(start, end - start + 1);
|
|
}
|
|
|
|
static char printBuf[4096] = {};
|
|
static FILE *logFile = NULL;
|
|
|
|
#if defined(ANDROID)
|
|
#include <android/log.h>
|
|
#endif
|
|
|
|
static bool debugLogEnabled = true;
|
|
|
|
void SetDebugLogEnabled(bool enabled)
|
|
{
|
|
debugLogEnabled = enabled;
|
|
}
|
|
|
|
void DebugPrint(const char *fmt, ...)
|
|
{
|
|
if(!debugLogEnabled)
|
|
return;
|
|
|
|
va_list args;
|
|
va_start(args, fmt);
|
|
|
|
vsnprintf(printBuf, 4095, fmt, args);
|
|
|
|
va_end(args);
|
|
|
|
fputs(printBuf, stdout);
|
|
fflush(stdout);
|
|
|
|
if(logFile)
|
|
{
|
|
fputs(printBuf, logFile);
|
|
fflush(logFile);
|
|
}
|
|
|
|
#if defined(WIN32)
|
|
OutputDebugStringA(printBuf);
|
|
#endif
|
|
|
|
#if defined(ANDROID)
|
|
__android_log_print(ANDROID_LOG_DEBUG, "rd_demos", "%s", printBuf);
|
|
#endif
|
|
}
|
|
|
|
void OutputPrint(const char *fmt, ...)
|
|
{
|
|
va_list args;
|
|
va_start(args, fmt);
|
|
|
|
vsnprintf(printBuf, 4095, fmt, args);
|
|
|
|
va_end(args);
|
|
|
|
fputs(printBuf, stdout);
|
|
fflush(stdout);
|
|
|
|
if(logFile)
|
|
{
|
|
fputs(printBuf, logFile);
|
|
fflush(logFile);
|
|
}
|
|
|
|
#if defined(WIN32)
|
|
OutputDebugStringA(printBuf);
|
|
#endif
|
|
|
|
#if defined(ANDROID)
|
|
__android_log_print(ANDROID_LOG_INFO, "rd_demos", "%s", printBuf);
|
|
#endif
|
|
}
|
|
|
|
void LoadXPM(const char **XPM, Texture &tex)
|
|
{
|
|
uint32_t numColors = 0;
|
|
sscanf(XPM[0], "%u %u %u %*u", &tex.width, &tex.height, &numColors);
|
|
|
|
uint32_t colors[256] = {};
|
|
|
|
for(uint32_t c = 0; c < numColors; c++)
|
|
{
|
|
char ch = XPM[c + 1][0];
|
|
|
|
uint32_t col = 0;
|
|
|
|
sscanf(XPM[c + 1] + 1, " c #%x", &col);
|
|
|
|
// need to bgr swap, set full alpha
|
|
colors[ch] = 0xff000000 | ((col & 0xff) << 16) | (col & 0xff00) | ((col & 0xff0000) >> 16);
|
|
}
|
|
|
|
tex.data.resize(tex.width * tex.height);
|
|
|
|
for(uint32_t y = 0; y < tex.height; y++)
|
|
{
|
|
const char *row = XPM[1 + numColors + y];
|
|
|
|
for(uint32_t x = 0; x < tex.width; x++)
|
|
tex.data[y * tex.width + x] = colors[row[x]];
|
|
}
|
|
}
|
|
|
|
#ifndef HAVE_SHADERC
|
|
#define HAVE_SHADERC 0
|
|
#endif
|
|
|
|
// this define toggles on/off using the linked shaderc. This can be useful for quick testing without
|
|
// having to remove the built shaderc files
|
|
#define USE_LINKED_SHADERC (1 && HAVE_SHADERC)
|
|
|
|
#if !USE_LINKED_SHADERC && defined(ANDROID)
|
|
#error "can't execute shaderc on android"
|
|
#endif
|
|
|
|
#if USE_LINKED_SHADERC
|
|
#include <shaderc/shaderc.h>
|
|
#else
|
|
typedef void *shaderc_compiler_t;
|
|
#endif
|
|
|
|
static shaderc_compiler_t shaderc = NULL;
|
|
static std::string externalCompiler;
|
|
|
|
bool InternalSpvCompiler()
|
|
{
|
|
return bool(USE_LINKED_SHADERC);
|
|
}
|
|
|
|
bool SpvCompilationSupported()
|
|
{
|
|
if(shaderc)
|
|
return true;
|
|
|
|
#if USE_LINKED_SHADERC
|
|
shaderc = shaderc_compiler_initialize();
|
|
#endif
|
|
|
|
if(shaderc)
|
|
return true;
|
|
|
|
for(std::string compiler : {"glslc", "glslangValidator"})
|
|
{
|
|
FILE *pipe = popen((compiler + EXECUTABLE_SUFFIX " --version 2>&1").c_str(), "r");
|
|
|
|
if(!pipe)
|
|
continue;
|
|
|
|
int code = pclose(pipe);
|
|
|
|
if(WEXITSTATUS(code) == 0)
|
|
{
|
|
externalCompiler = compiler;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
std::vector<uint32_t> CompileShaderToSpv(const std::string &source_text, SPIRVTarget target,
|
|
ShaderLang lang, ShaderStage stage, const char *entry_point,
|
|
const std::map<std::string, std::string> ¯os)
|
|
{
|
|
std::vector<uint32_t> ret;
|
|
|
|
if(shaderc)
|
|
{
|
|
#if USE_LINKED_SHADERC
|
|
static bool logged = false;
|
|
|
|
if(!logged)
|
|
{
|
|
logged = true;
|
|
TEST_LOG("Compiling using built-in shaderc");
|
|
}
|
|
shaderc_compile_options_t opts = shaderc_compile_options_initialize();
|
|
|
|
if(lang == ShaderLang::glsl)
|
|
shaderc_compile_options_set_source_language(opts, shaderc_source_language_glsl);
|
|
else if(lang == ShaderLang::hlsl)
|
|
shaderc_compile_options_set_source_language(opts, shaderc_source_language_hlsl);
|
|
|
|
shaderc_compile_options_set_generate_debug_info(opts);
|
|
shaderc_compile_options_set_optimization_level(opts, shaderc_optimization_level_zero);
|
|
|
|
shaderc_shader_kind shader_kind = shaderc_glsl_vertex_shader;
|
|
|
|
switch(stage)
|
|
{
|
|
case ShaderStage::vert: shader_kind = shaderc_vertex_shader; break;
|
|
case ShaderStage::frag: shader_kind = shaderc_fragment_shader; break;
|
|
case ShaderStage::tesscontrol: shader_kind = shaderc_tess_control_shader; break;
|
|
case ShaderStage::tesseval: shader_kind = shaderc_tess_evaluation_shader; break;
|
|
case ShaderStage::geom: shader_kind = shaderc_geometry_shader; break;
|
|
case ShaderStage::comp: shader_kind = shaderc_compute_shader; break;
|
|
case ShaderStage::mesh: shader_kind = shaderc_mesh_shader; break;
|
|
case ShaderStage::task: shader_kind = shaderc_task_shader; break;
|
|
}
|
|
|
|
if(target == SPIRVTarget::opengl)
|
|
shaderc_compile_options_set_target_env(opts, shaderc_target_env_opengl, 0);
|
|
else if(target == SPIRVTarget::vulkan11)
|
|
shaderc_compile_options_set_target_env(opts, shaderc_target_env_vulkan,
|
|
shaderc_env_version_vulkan_1_1);
|
|
else if(target == SPIRVTarget::vulkan12)
|
|
shaderc_compile_options_set_target_env(opts, shaderc_target_env_vulkan,
|
|
shaderc_env_version_vulkan_1_2);
|
|
|
|
for(auto it : macros)
|
|
shaderc_compile_options_add_macro_definition(opts, it.first.c_str(), it.first.length(),
|
|
it.second.c_str(), it.second.length());
|
|
|
|
shaderc_compilation_result_t res;
|
|
|
|
if(lang == ShaderLang::spvasm)
|
|
res = shaderc_assemble_into_spv(shaderc, source_text.c_str(), source_text.size(), opts);
|
|
else
|
|
res = shaderc_compile_into_spv(shaderc, source_text.c_str(), source_text.size(), shader_kind,
|
|
"inshader", entry_point, opts);
|
|
|
|
shaderc_compilation_status status = shaderc_result_get_compilation_status(res);
|
|
|
|
if(status != shaderc_compilation_status_success)
|
|
{
|
|
TEST_ERROR("Couldn't compile shader with built-in shaderc: %s",
|
|
shaderc_result_get_error_message(res));
|
|
|
|
if(res)
|
|
shaderc_result_release(res);
|
|
|
|
return ret;
|
|
}
|
|
|
|
size_t sz = shaderc_result_get_length(res);
|
|
|
|
TEST_ASSERT((sz % 4) == 0, "shaderc result isn't 4-byte aligned");
|
|
|
|
ret.resize(sz / 4);
|
|
|
|
memcpy(&ret[0], shaderc_result_get_bytes(res), sz);
|
|
|
|
shaderc_result_release(res);
|
|
|
|
shaderc_compile_options_release(opts);
|
|
|
|
return ret;
|
|
#endif
|
|
}
|
|
|
|
std::string command_line;
|
|
|
|
std::string path = GetExecutableName();
|
|
path.erase(path.find_last_of("/\\"));
|
|
path += "/tmp";
|
|
|
|
MakeDir(path.c_str());
|
|
|
|
std::string infile = path + "/input";
|
|
std::string outfile = path + "/output";
|
|
|
|
if(externalCompiler == "glslc")
|
|
{
|
|
command_line = "glslc" EXECUTABLE_SUFFIX " -g -O0";
|
|
command_line += " -fentry-point=";
|
|
command_line += entry_point;
|
|
|
|
if(lang == ShaderLang::glsl)
|
|
command_line += " -x glsl";
|
|
else if(lang == ShaderLang::hlsl)
|
|
command_line += " -x hlsl";
|
|
|
|
for(auto it : macros)
|
|
command_line += " -D" + it.first + "=" + it.second;
|
|
|
|
// can't compile SPIR-V assembly if we specify a shader stage
|
|
if(lang != ShaderLang::spvasm)
|
|
{
|
|
switch(stage)
|
|
{
|
|
case ShaderStage::vert: command_line += " -fshader-stage=vert"; break;
|
|
case ShaderStage::frag: command_line += " -fshader-stage=frag"; break;
|
|
case ShaderStage::tesscontrol: command_line += " -fshader-stage=tesscontrol"; break;
|
|
case ShaderStage::tesseval: command_line += " -fshader-stage=tesseval"; break;
|
|
case ShaderStage::geom: command_line += " -fshader-stage=geom"; break;
|
|
case ShaderStage::comp: command_line += " -fshader-stage=comp"; break;
|
|
case ShaderStage::mesh: command_line += " -fshader-stage=mesh"; break;
|
|
case ShaderStage::task: command_line += " -fshader-stage=task"; break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
infile += ".spvasm";
|
|
}
|
|
|
|
if(target == SPIRVTarget::opengl)
|
|
command_line += " --target-env=opengl";
|
|
else if(target == SPIRVTarget::vulkan11)
|
|
command_line += " --target-env=vulkan1.1";
|
|
else if(target == SPIRVTarget::vulkan12)
|
|
command_line += " --target-env=vulkan1.2";
|
|
|
|
command_line += " -o ";
|
|
command_line += outfile;
|
|
command_line += " ";
|
|
command_line += infile;
|
|
}
|
|
else if(externalCompiler == "glslangValidator")
|
|
{
|
|
command_line = "glslangValidator" EXECUTABLE_SUFFIX " -g ";
|
|
command_line += " --entry-point ";
|
|
command_line += entry_point;
|
|
|
|
if(lang == ShaderLang::hlsl)
|
|
command_line += " -D";
|
|
|
|
if(lang == ShaderLang::spvasm)
|
|
{
|
|
TEST_ERROR("Can't compile SPIR-V assembly with glslangValidator");
|
|
return ret;
|
|
}
|
|
|
|
for(auto it : macros)
|
|
command_line += " -D" + it.first + "=" + it.second;
|
|
|
|
switch(stage)
|
|
{
|
|
case ShaderStage::vert: command_line += " -S vert"; break;
|
|
case ShaderStage::frag: command_line += " -S frag"; break;
|
|
case ShaderStage::tesscontrol: command_line += " -S tesscontrol"; break;
|
|
case ShaderStage::tesseval: command_line += " -S tesseval"; break;
|
|
case ShaderStage::geom: command_line += " -S geom"; break;
|
|
case ShaderStage::comp: command_line += " -S comp"; break;
|
|
case ShaderStage::mesh: command_line += " -S mesh"; break;
|
|
case ShaderStage::task: command_line += " -S task"; break;
|
|
}
|
|
|
|
if(target == SPIRVTarget::opengl)
|
|
command_line += " -G --target-env opengl";
|
|
else if(target == SPIRVTarget::vulkan11)
|
|
command_line += " -V --target-env vulkan1.1";
|
|
else if(target == SPIRVTarget::vulkan12)
|
|
command_line += " -V --target-env vulkan1.2";
|
|
else if(target == SPIRVTarget::vulkan)
|
|
command_line += " -V --target-env vulkan1.0";
|
|
|
|
command_line += " -o ";
|
|
command_line += outfile;
|
|
command_line += " ";
|
|
command_line += infile;
|
|
}
|
|
|
|
FILE *f = fopen(infile.c_str(), "wb");
|
|
if(f)
|
|
{
|
|
fwrite(source_text.c_str(), 1, source_text.size(), f);
|
|
fclose(f);
|
|
}
|
|
|
|
FILE *pipe = popen(command_line.c_str(), "r");
|
|
|
|
if(!pipe)
|
|
{
|
|
TEST_ERROR("Couldn't run %s to compile shaders.", externalCompiler.c_str());
|
|
return ret;
|
|
}
|
|
|
|
pclose(pipe);
|
|
|
|
f = fopen(outfile.c_str(), "rb");
|
|
if(f)
|
|
{
|
|
fseek(f, 0, SEEK_END);
|
|
ret.resize(ftell(f) / sizeof(uint32_t));
|
|
fseek(f, 0, SEEK_SET);
|
|
fread(&ret[0], sizeof(uint32_t), ret.size(), f);
|
|
fclose(f);
|
|
}
|
|
|
|
unlink(infile.c_str());
|
|
unlink(outfile.c_str());
|
|
|
|
return ret;
|
|
}
|
|
|
|
int GraphicsTest::maxFrameCount = -1;
|
|
std::string GraphicsTest::dataRoot;
|
|
int GraphicsTest::screenWidth = 400;
|
|
int GraphicsTest::screenHeight = 300;
|
|
bool GraphicsTest::debugDevice = false;
|
|
|
|
void GraphicsTest::Prepare(int argc, char **argv)
|
|
{
|
|
static bool prepared = false;
|
|
|
|
// nothing to do per-test if we've already prepared
|
|
if(prepared)
|
|
return;
|
|
|
|
#if USE_LINKED_SHADERC
|
|
TEST_LOG("Using linked shaderc");
|
|
#else
|
|
TEST_LOG("Requires glslc/shaderc for Vulkan tests");
|
|
#endif
|
|
|
|
prepared = true;
|
|
|
|
dataRoot = GetEnvVar("RENDERDOC_DEMOS_DATA");
|
|
|
|
if(dataRoot.empty())
|
|
dataRoot = GetCWD() + "/data/demos/";
|
|
|
|
// parse parameters
|
|
for(int i = 0; i < argc; i++)
|
|
{
|
|
if(!strcmp(argv[i], "--debug") || !strcmp(argv[i], "--validate"))
|
|
{
|
|
debugDevice = true;
|
|
}
|
|
|
|
if(i + 1 < argc && (!strcmp(argv[i], "--frames") || !strcmp(argv[i], "--framecount") ||
|
|
!strcmp(argv[i], "--max-frames")))
|
|
{
|
|
maxFrameCount = atoi(argv[i + 1]);
|
|
}
|
|
|
|
if(i + 1 < argc && !strcmp(argv[i], "--log"))
|
|
{
|
|
logFile = fopen(argv[i + 1], "w");
|
|
}
|
|
|
|
if(i + 1 < argc && (!strcmp(argv[i], "--width") || !strcmp(argv[i], "-w")))
|
|
{
|
|
screenWidth = atoi(argv[i + 1]);
|
|
|
|
if(screenWidth < 1)
|
|
screenWidth = 1;
|
|
if(screenWidth > 7680)
|
|
screenWidth = 7680;
|
|
}
|
|
|
|
if(i + 1 < argc && (!strcmp(argv[i], "--height") || !strcmp(argv[i], "-h")))
|
|
{
|
|
screenHeight = atoi(argv[i + 1]);
|
|
|
|
if(screenHeight < 1)
|
|
screenHeight = 1;
|
|
if(screenHeight > 4320)
|
|
screenHeight = 4320;
|
|
}
|
|
|
|
if(i + 1 < argc && !strcmp(argv[i], "--data"))
|
|
{
|
|
dataRoot = argv[i + 1];
|
|
while(dataRoot.back() == '/' || dataRoot.back() == '\\')
|
|
dataRoot.pop_back();
|
|
dataRoot += "/";
|
|
}
|
|
}
|
|
}
|
|
|
|
bool GraphicsTest::Init()
|
|
{
|
|
srand(0U);
|
|
|
|
pRENDERDOC_GetAPI RENDERDOC_GetAPI = NULL;
|
|
|
|
#if defined(WIN32)
|
|
HMODULE mod = GetModuleHandleA("renderdoc.dll");
|
|
if(mod)
|
|
RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)GetProcAddress(mod, "RENDERDOC_GetAPI");
|
|
#elif defined(ANDROID)
|
|
void *mod = dlopen("libVkLayer_GLES_RenderDoc.so", RTLD_NOW | RTLD_NOLOAD);
|
|
if(mod)
|
|
RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)dlsym(mod, "RENDERDOC_GetAPI");
|
|
#elif defined(__linux__)
|
|
void *mod = dlopen("librenderdoc.so", RTLD_NOW | RTLD_NOLOAD);
|
|
if(mod)
|
|
RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)dlsym(mod, "RENDERDOC_GetAPI");
|
|
#elif defined(__APPLE__)
|
|
void *mod = dlopen("librenderdoc.dylib", RTLD_NOW | RTLD_NOLOAD);
|
|
if(mod)
|
|
RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)dlsym(mod, "RENDERDOC_GetAPI");
|
|
#else
|
|
#error UNKNOWN PLATFORM
|
|
#endif
|
|
|
|
if(RENDERDOC_GetAPI)
|
|
{
|
|
int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_0_0, (void **)&rdoc);
|
|
|
|
if(ret != 1)
|
|
rdoc = NULL;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void GraphicsTest::Shutdown()
|
|
{
|
|
}
|
|
|
|
std::string GraphicsTest::GetDataPath(const std::string &filename)
|
|
{
|
|
return dataRoot + filename;
|
|
}
|
|
|
|
bool GraphicsTest::FrameLimit()
|
|
{
|
|
curFrame++;
|
|
if(maxFrameCount > 0 && curFrame >= maxFrameCount)
|
|
return false;
|
|
|
|
return true;
|
|
}
|