mirror of https://github.com/PCSX2/pcsx2.git
gsdx ogl: massively extend glsl self test
* Support Mesa Nouveau IR (free driver for Nvidia's GPU) => Print intermediate representation + final shader => Dump GPR usage * Move dumped shader in /tmp/GSdx_Shader/<sub_dir> => Avoid the landing of 3 thousands of files in $PWD ^^ * Use function instead of macro
This commit is contained in:
parent
1c8de02c8d
commit
3234c8241b
|
@ -22,6 +22,7 @@
|
|||
#include "stdafx.h"
|
||||
#include "GSDeviceOGL.h"
|
||||
#include "GLState.h"
|
||||
#include "GSUtil.h"
|
||||
#include <fstream>
|
||||
|
||||
#include "res/glsl_source.h"
|
||||
|
@ -45,6 +46,8 @@ static const uint32 g_gs_cb_index = 22;
|
|||
|
||||
bool GSDeviceOGL::m_debug_gl_call = false;
|
||||
int GSDeviceOGL::s_n = 0;
|
||||
int GSDeviceOGL::m_shader_inst = 0;
|
||||
int GSDeviceOGL::m_shader_reg = 0;
|
||||
FILE* GSDeviceOGL::m_debug_gl_file = NULL;
|
||||
|
||||
GSDeviceOGL::GSDeviceOGL()
|
||||
|
@ -821,28 +824,67 @@ GLuint GSDeviceOGL::CompilePS(PSSelector sel)
|
|||
return m_shader->Compile("tfx.glsl", "ps_main", GL_FRAGMENT_SHADER, tfx_fs_all_glsl, macro);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::SelfShaderTestRun(const string& dir, const string& file, const PSSelector& sel, int& nb_shader)
|
||||
{
|
||||
#ifdef __unix__
|
||||
string out = "/tmp/GSdx_Shader/";
|
||||
GSmkdir(out.c_str());
|
||||
|
||||
out += dir + "/";
|
||||
GSmkdir(out.c_str());
|
||||
|
||||
out += file;
|
||||
#else
|
||||
string out = file;
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
// Nouveau actually
|
||||
if (GLLoader::mesa_amd_buggy_driver) {
|
||||
if (freopen(out.c_str(), "w", stderr) == NULL)
|
||||
fprintf(stderr, "Failed to redirect stderr\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
GLuint p = CompilePS(sel);
|
||||
nb_shader++;
|
||||
m_shader_inst += m_shader->DumpAsm(out, p);
|
||||
|
||||
#ifdef __linux__
|
||||
// Nouveau actually
|
||||
if (GLLoader::mesa_amd_buggy_driver) {
|
||||
if (freopen("/dev/tty", "w", stderr) == NULL)
|
||||
fprintf(stderr, "Failed to restore stderr\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GSDeviceOGL::SelfShaderTestPrint(const string& test, int& nb_shader)
|
||||
{
|
||||
fprintf(stderr, "%-25s\t\t%d shaders:\t%d instructions (M %4.2f)\t%d registers (M %4.2f)\n",
|
||||
test.c_str(), nb_shader,
|
||||
m_shader_inst, (float)m_shader_inst/(float)nb_shader,
|
||||
m_shader_reg, (float)m_shader_reg/(float)nb_shader);
|
||||
|
||||
m_shader_inst = 0;
|
||||
m_shader_reg = 0;
|
||||
nb_shader = 0;
|
||||
}
|
||||
|
||||
void GSDeviceOGL::SelfShaderTest()
|
||||
{
|
||||
#define RUN_TEST \
|
||||
do { \
|
||||
GLuint p = CompilePS(sel); \
|
||||
nb_shader++; \
|
||||
perf += m_shader->DumpAsm(file, p); \
|
||||
} while(0);
|
||||
string out = "";
|
||||
|
||||
#define PRINT_TEST(s) \
|
||||
do { \
|
||||
fprintf(stderr, "%s %d instructions for %d shaders (mean of %4.2f)\n", \
|
||||
s, perf, nb_shader, (float)perf/(float)nb_shader); \
|
||||
all += perf; \
|
||||
perf = 0; \
|
||||
nb_shader = 0; \
|
||||
} while(0);
|
||||
#ifdef __unix__
|
||||
setenv("NV50_PROG_DEBUG", "1", 1);
|
||||
#endif
|
||||
|
||||
string test;
|
||||
m_shader_inst = 0;
|
||||
m_shader_reg = 0;
|
||||
int nb_shader = 0;
|
||||
int perf = 0;
|
||||
int all = 0;
|
||||
// Test: SW blending
|
||||
|
||||
test = "SW_Blending";
|
||||
for (int colclip = 0; colclip < 2; colclip++) {
|
||||
for (int fmt = 0; fmt < 3; fmt++) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
|
@ -860,24 +902,24 @@ void GSDeviceOGL::SelfShaderTest()
|
|||
|
||||
std::string file = format("Shader_Blend_%d_%d_%d_%d__Cclip_%d__Dfmt_%d.glsl.asm",
|
||||
i, ib, i, i, colclip, fmt);
|
||||
RUN_TEST;
|
||||
SelfShaderTestRun(test, file, sel, nb_shader);
|
||||
}
|
||||
}
|
||||
}
|
||||
PRINT_TEST("Blend");
|
||||
SelfShaderTestPrint(test, nb_shader);
|
||||
|
||||
// Test: alpha test
|
||||
test = "Alpha_Test";
|
||||
for (int atst = 0; atst < 8; atst++) {
|
||||
PSSelector sel;
|
||||
sel.tfx = 4;
|
||||
|
||||
sel.atst = atst;
|
||||
std::string file = format("Shader_Atst_%d.glsl.asm", atst);
|
||||
RUN_TEST;
|
||||
SelfShaderTestRun(test, file, sel, nb_shader);
|
||||
}
|
||||
PRINT_TEST("Alpha Tst");
|
||||
SelfShaderTestPrint(test, nb_shader);
|
||||
|
||||
// Test: fbmask/fog/shuffle/read_ba
|
||||
test = "Fbmask__Fog__Shuffle__Read_ba";
|
||||
for (int read_ba = 0; read_ba < 2; read_ba++) {
|
||||
PSSelector sel;
|
||||
sel.tfx = 4;
|
||||
|
@ -889,11 +931,11 @@ void GSDeviceOGL::SelfShaderTest()
|
|||
sel.read_ba = read_ba;
|
||||
|
||||
std::string file = format("Shader_Fog__Fbmask__Shuffle__Read_ba_%d.glsl.asm", read_ba);
|
||||
RUN_TEST;
|
||||
SelfShaderTestRun(test, file, sel, nb_shader);
|
||||
}
|
||||
PRINT_TEST("Fbmask/fog/shuffle/read_ba");
|
||||
SelfShaderTestPrint(test, nb_shader);
|
||||
|
||||
// Test: Date
|
||||
test = "Date";
|
||||
for (int date = 1; date < 7; date++) {
|
||||
PSSelector sel;
|
||||
sel.tfx = 4;
|
||||
|
@ -901,11 +943,11 @@ void GSDeviceOGL::SelfShaderTest()
|
|||
|
||||
sel.date = date;
|
||||
std::string file = format("Shader_Date_%d.glsl.asm", date);
|
||||
RUN_TEST;
|
||||
SelfShaderTestRun(test, file, sel, nb_shader);
|
||||
}
|
||||
PRINT_TEST("Date");
|
||||
SelfShaderTestPrint(test, nb_shader);
|
||||
|
||||
// Test: FBA
|
||||
test = "FBA";
|
||||
for (int fmt = 0; fmt < 3; fmt++) {
|
||||
PSSelector sel;
|
||||
sel.tfx = 4;
|
||||
|
@ -915,11 +957,11 @@ void GSDeviceOGL::SelfShaderTest()
|
|||
sel.dfmt = fmt;
|
||||
sel.clr1 = 1;
|
||||
std::string file = format("Shader_Fba__Clr1__Dfmt_%d.glsl.asm", fmt);
|
||||
RUN_TEST;
|
||||
SelfShaderTestRun(test, file, sel, nb_shader);
|
||||
}
|
||||
PRINT_TEST("Fba/Clr1/Dfmt");
|
||||
SelfShaderTestPrint(test, nb_shader);
|
||||
|
||||
// Test: Fst/Tc/IIP
|
||||
test = "Fst__Tc__IIP";
|
||||
{
|
||||
PSSelector sel;
|
||||
sel.tfx = 1;
|
||||
|
@ -930,11 +972,11 @@ void GSDeviceOGL::SelfShaderTest()
|
|||
sel.tcoffsethack = 1;
|
||||
|
||||
std::string file = format("Shader_Fst__TC__Iip.glsl.asm");
|
||||
RUN_TEST;
|
||||
SelfShaderTestRun(test, file, sel, nb_shader);
|
||||
}
|
||||
PRINT_TEST("Fst/Tc/IIp");
|
||||
SelfShaderTestPrint(test, nb_shader);
|
||||
|
||||
// Test: tfx/tcc
|
||||
test = "Tfx__Tcc";
|
||||
for (int channel = 0; channel < 5; channel++) {
|
||||
for (int tfx = 0; tfx < 5; tfx++) {
|
||||
for (int tcc = 0; tcc < 2; tcc++) {
|
||||
|
@ -946,13 +988,13 @@ void GSDeviceOGL::SelfShaderTest()
|
|||
sel.tfx = tfx;
|
||||
sel.tcc = tcc;
|
||||
std::string file = format("Shader_Tfx_%d__Tcc_%d__Channel_%d.glsl.asm", tfx, tcc, channel);
|
||||
RUN_TEST;
|
||||
SelfShaderTestRun(test, file, sel, nb_shader);
|
||||
}
|
||||
}
|
||||
}
|
||||
PRINT_TEST("Tfx/Tcc/Channel");
|
||||
SelfShaderTestPrint(test, nb_shader);
|
||||
|
||||
// Test: Texture Sampling
|
||||
test = "Texture_Sampling";
|
||||
for (int depth = 0; depth < 4; depth++) {
|
||||
for (int fmt = 0; fmt < 16; fmt++) {
|
||||
if ((fmt & 3) == 3) continue;
|
||||
|
@ -975,19 +1017,14 @@ void GSDeviceOGL::SelfShaderTest()
|
|||
sel.wmt = wmt;
|
||||
std::string file = format("Shader_Ltf_%d__Aem_%d__TFmt_%d__Wms_%d__Wmt_%d__DepthFmt_%d.glsl.asm",
|
||||
ltf, aem, fmt, wms, wmt, depth);
|
||||
RUN_TEST;
|
||||
SelfShaderTestRun(test, file, sel, nb_shader);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PRINT_TEST("Texture Sampling");
|
||||
|
||||
fprintf(stderr, "\nTotal %d\n", all);
|
||||
|
||||
#undef RUN_TEST
|
||||
#undef PRINT_TEST
|
||||
SelfShaderTestPrint(test, nb_shader);
|
||||
}
|
||||
|
||||
GSTexture* GSDeviceOGL::CreateRenderTarget(int w, int h, bool msaa, int format)
|
||||
|
@ -1703,6 +1740,18 @@ void GSDeviceOGL::DebugOutputToFile(GLenum gl_source, GLenum gl_type, GLuint id,
|
|||
if (gl_severity != GL_DEBUG_SEVERITY_NOTIFICATION) {
|
||||
fprintf(stderr,"T:%s\tID:%d\tS:%s\t=> %s\n", type.c_str(), s_n, severity.c_str(), message.c_str());
|
||||
}
|
||||
#else
|
||||
// Print nouveau shader compiler info
|
||||
if (s_n == 0) {
|
||||
int t, local, gpr, inst, byte;
|
||||
int status = sscanf(message.c_str(), "type: %d, local: %d, gpr: %d, inst: %d, bytes: %d",
|
||||
&t, &local, &gpr, &inst, &byte);
|
||||
if (status == 5) {
|
||||
m_shader_inst += inst;
|
||||
m_shader_reg += gpr;
|
||||
fprintf(stderr,"T:%s\t\tS:%s\t=> %s\n", type.c_str(), severity.c_str(), message.c_str());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_debug_gl_file)
|
||||
|
|
|
@ -393,6 +393,8 @@ public:
|
|||
static const int m_MERGE_BLEND;
|
||||
|
||||
static int s_n;
|
||||
static int m_shader_inst;
|
||||
static int m_shader_reg;
|
||||
|
||||
private:
|
||||
uint32 m_msaa; // Level of Msaa
|
||||
|
@ -548,6 +550,8 @@ public:
|
|||
GLuint CreateSampler(PSSamplerSelector sel);
|
||||
GSDepthStencilOGL* CreateDepthStencil(OMDepthStencilSelector dssel);
|
||||
|
||||
void SelfShaderTestPrint(const string& test, int& nb_shader);
|
||||
void SelfShaderTestRun(const string& dir, const string& file, const PSSelector& sel, int& nb_shader);
|
||||
void SelfShaderTest();
|
||||
|
||||
|
||||
|
|
|
@ -400,7 +400,8 @@ D3D_FEATURE_LEVEL GSUtil::CheckDirect3D11Level(IDXGIAdapter *adapter, D3D_DRIVER
|
|||
|
||||
void GSmkdir(const char* dir)
|
||||
{
|
||||
if (mkdir(dir, 0777))
|
||||
int err = mkdir(dir, 0777);
|
||||
if (!err && errno != EEXIST)
|
||||
fprintf(stderr, "Failed to create directory: %s\n", dir);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue