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 "stdafx.h"
|
||||||
#include "GSDeviceOGL.h"
|
#include "GSDeviceOGL.h"
|
||||||
#include "GLState.h"
|
#include "GLState.h"
|
||||||
|
#include "GSUtil.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#include "res/glsl_source.h"
|
#include "res/glsl_source.h"
|
||||||
|
@ -45,6 +46,8 @@ static const uint32 g_gs_cb_index = 22;
|
||||||
|
|
||||||
bool GSDeviceOGL::m_debug_gl_call = false;
|
bool GSDeviceOGL::m_debug_gl_call = false;
|
||||||
int GSDeviceOGL::s_n = 0;
|
int GSDeviceOGL::s_n = 0;
|
||||||
|
int GSDeviceOGL::m_shader_inst = 0;
|
||||||
|
int GSDeviceOGL::m_shader_reg = 0;
|
||||||
FILE* GSDeviceOGL::m_debug_gl_file = NULL;
|
FILE* GSDeviceOGL::m_debug_gl_file = NULL;
|
||||||
|
|
||||||
GSDeviceOGL::GSDeviceOGL()
|
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);
|
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()
|
void GSDeviceOGL::SelfShaderTest()
|
||||||
{
|
{
|
||||||
#define RUN_TEST \
|
string out = "";
|
||||||
do { \
|
|
||||||
GLuint p = CompilePS(sel); \
|
|
||||||
nb_shader++; \
|
|
||||||
perf += m_shader->DumpAsm(file, p); \
|
|
||||||
} while(0);
|
|
||||||
|
|
||||||
#define PRINT_TEST(s) \
|
#ifdef __unix__
|
||||||
do { \
|
setenv("NV50_PROG_DEBUG", "1", 1);
|
||||||
fprintf(stderr, "%s %d instructions for %d shaders (mean of %4.2f)\n", \
|
#endif
|
||||||
s, perf, nb_shader, (float)perf/(float)nb_shader); \
|
|
||||||
all += perf; \
|
|
||||||
perf = 0; \
|
|
||||||
nb_shader = 0; \
|
|
||||||
} while(0);
|
|
||||||
|
|
||||||
|
string test;
|
||||||
|
m_shader_inst = 0;
|
||||||
|
m_shader_reg = 0;
|
||||||
int nb_shader = 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 colclip = 0; colclip < 2; colclip++) {
|
||||||
for (int fmt = 0; fmt < 3; fmt++) {
|
for (int fmt = 0; fmt < 3; fmt++) {
|
||||||
for (int i = 0; i < 3; i++) {
|
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",
|
std::string file = format("Shader_Blend_%d_%d_%d_%d__Cclip_%d__Dfmt_%d.glsl.asm",
|
||||||
i, ib, i, i, colclip, fmt);
|
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++) {
|
for (int atst = 0; atst < 8; atst++) {
|
||||||
PSSelector sel;
|
PSSelector sel;
|
||||||
sel.tfx = 4;
|
sel.tfx = 4;
|
||||||
|
|
||||||
sel.atst = atst;
|
sel.atst = atst;
|
||||||
std::string file = format("Shader_Atst_%d.glsl.asm", 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++) {
|
for (int read_ba = 0; read_ba < 2; read_ba++) {
|
||||||
PSSelector sel;
|
PSSelector sel;
|
||||||
sel.tfx = 4;
|
sel.tfx = 4;
|
||||||
|
@ -889,11 +931,11 @@ void GSDeviceOGL::SelfShaderTest()
|
||||||
sel.read_ba = read_ba;
|
sel.read_ba = read_ba;
|
||||||
|
|
||||||
std::string file = format("Shader_Fog__Fbmask__Shuffle__Read_ba_%d.glsl.asm", 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++) {
|
for (int date = 1; date < 7; date++) {
|
||||||
PSSelector sel;
|
PSSelector sel;
|
||||||
sel.tfx = 4;
|
sel.tfx = 4;
|
||||||
|
@ -901,11 +943,11 @@ void GSDeviceOGL::SelfShaderTest()
|
||||||
|
|
||||||
sel.date = date;
|
sel.date = date;
|
||||||
std::string file = format("Shader_Date_%d.glsl.asm", 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++) {
|
for (int fmt = 0; fmt < 3; fmt++) {
|
||||||
PSSelector sel;
|
PSSelector sel;
|
||||||
sel.tfx = 4;
|
sel.tfx = 4;
|
||||||
|
@ -915,11 +957,11 @@ void GSDeviceOGL::SelfShaderTest()
|
||||||
sel.dfmt = fmt;
|
sel.dfmt = fmt;
|
||||||
sel.clr1 = 1;
|
sel.clr1 = 1;
|
||||||
std::string file = format("Shader_Fba__Clr1__Dfmt_%d.glsl.asm", fmt);
|
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;
|
PSSelector sel;
|
||||||
sel.tfx = 1;
|
sel.tfx = 1;
|
||||||
|
@ -930,11 +972,11 @@ void GSDeviceOGL::SelfShaderTest()
|
||||||
sel.tcoffsethack = 1;
|
sel.tcoffsethack = 1;
|
||||||
|
|
||||||
std::string file = format("Shader_Fst__TC__Iip.glsl.asm");
|
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 channel = 0; channel < 5; channel++) {
|
||||||
for (int tfx = 0; tfx < 5; tfx++) {
|
for (int tfx = 0; tfx < 5; tfx++) {
|
||||||
for (int tcc = 0; tcc < 2; tcc++) {
|
for (int tcc = 0; tcc < 2; tcc++) {
|
||||||
|
@ -946,13 +988,13 @@ void GSDeviceOGL::SelfShaderTest()
|
||||||
sel.tfx = tfx;
|
sel.tfx = tfx;
|
||||||
sel.tcc = tcc;
|
sel.tcc = tcc;
|
||||||
std::string file = format("Shader_Tfx_%d__Tcc_%d__Channel_%d.glsl.asm", tfx, tcc, channel);
|
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 depth = 0; depth < 4; depth++) {
|
||||||
for (int fmt = 0; fmt < 16; fmt++) {
|
for (int fmt = 0; fmt < 16; fmt++) {
|
||||||
if ((fmt & 3) == 3) continue;
|
if ((fmt & 3) == 3) continue;
|
||||||
|
@ -975,19 +1017,14 @@ void GSDeviceOGL::SelfShaderTest()
|
||||||
sel.wmt = wmt;
|
sel.wmt = wmt;
|
||||||
std::string file = format("Shader_Ltf_%d__Aem_%d__TFmt_%d__Wms_%d__Wmt_%d__DepthFmt_%d.glsl.asm",
|
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);
|
ltf, aem, fmt, wms, wmt, depth);
|
||||||
RUN_TEST;
|
SelfShaderTestRun(test, file, sel, nb_shader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PRINT_TEST("Texture Sampling");
|
SelfShaderTestPrint(test, nb_shader);
|
||||||
|
|
||||||
fprintf(stderr, "\nTotal %d\n", all);
|
|
||||||
|
|
||||||
#undef RUN_TEST
|
|
||||||
#undef PRINT_TEST
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GSTexture* GSDeviceOGL::CreateRenderTarget(int w, int h, bool msaa, int format)
|
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) {
|
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());
|
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
|
#endif
|
||||||
|
|
||||||
if (m_debug_gl_file)
|
if (m_debug_gl_file)
|
||||||
|
|
|
@ -393,6 +393,8 @@ public:
|
||||||
static const int m_MERGE_BLEND;
|
static const int m_MERGE_BLEND;
|
||||||
|
|
||||||
static int s_n;
|
static int s_n;
|
||||||
|
static int m_shader_inst;
|
||||||
|
static int m_shader_reg;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32 m_msaa; // Level of Msaa
|
uint32 m_msaa; // Level of Msaa
|
||||||
|
@ -548,6 +550,8 @@ public:
|
||||||
GLuint CreateSampler(PSSamplerSelector sel);
|
GLuint CreateSampler(PSSamplerSelector sel);
|
||||||
GSDepthStencilOGL* CreateDepthStencil(OMDepthStencilSelector dssel);
|
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();
|
void SelfShaderTest();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -400,7 +400,8 @@ D3D_FEATURE_LEVEL GSUtil::CheckDirect3D11Level(IDXGIAdapter *adapter, D3D_DRIVER
|
||||||
|
|
||||||
void GSmkdir(const char* dir)
|
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);
|
fprintf(stderr, "Failed to create directory: %s\n", dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue