Welcome to Fractal Forums

Fractal Software => Fragmentarium => Topic started by: 3dickulus on April 26, 2015, 10:08:28 AM




Title: Frag to GPU asm dump
Post by: 3dickulus on April 26, 2015, 10:08:28 AM
Would this be useful to anyone? diff patch available for testing against Fragmentarium-master.
edit1:attached diff (rename as dump-frag-asm.diff)
edit2:this works for OpenGL 4.0 and up, not sure what will happen for versions below 4.0
edit3:as pointed out by _revers_ this only works for nVidia so I have enabled the menu option only if there is nVidia card present.


Title: Re: Frag to GPU asm dump
Post by: Syntopia on April 27, 2015, 05:42:33 PM
Neat - I usually use NVEmulate for this, but this looks handy.


Title: Re: Frag to GPU asm dump
Post by: cKleinhuis on April 27, 2015, 05:43:52 PM
i consider stuff like that as "too much" ;) but a development tool should feature that, and still there are hand-coded optimizations that could be edited, i believe this shader asm file can be send to compile as well ? perhaps think about an editor feature for a asm shader...


Title: Re: Frag to GPU asm dump
Post by: DarkBeam on April 27, 2015, 06:39:32 PM
Haha, I love :)


Title: Re: Frag to GPU asm dump
Post by: 3dickulus on April 28, 2015, 12:17:48 AM
lol, yeah, a bit much for a fractal prog but the amount of code to make that happen is so small it seems silly not to have this functionality available even if it is only used in rare cases or to study the conversion from GLSL to machine code.
The assembler code is contained in the binary object as text and would be very specific to the gfx card that generated it, not practical for redistribution unless it's for exactly matching hardware and drivers, more of a debugging tool bonus for the more hardcore hackers :D
If I can find the time or get inspired I might parse the variable names and insert them where relevant so that it makes easier reading, as for compiling this asm txt back into binary, I'm not sure that would be beneficial unless you just needed a particular routine or function for another application, cut, paste, hack, hack, hack  :evil1:

edit: I would be interested to hear what other hardware and versions this works with, mine is...
 - OpenGL Vendor: NVIDIA Corporation
 - OpenGL Version: 4.5.0 NVIDIA 346.46
 - OpenGL Renderer: GeForce GTX 760/PCIe/SSE2
 - OpenGL Shading Language Version: 4.50 NVIDIA


Title: Re: Frag to GPU asm dump
Post by: cKleinhuis on April 28, 2015, 12:25:22 AM
this just reminds me of the early shader days when i had the radeon 8500 and no high level languages existed, the first mandelbrot rendering i coded in tha gpu assembler, and i did even exploit the limitations by feeding iteration results back into the gpu ;) and it reminds me of one of my entries to the ShaderX book series


http://www.google.de/search?q=shaderx3

 O0 :angel1:


Title: Re: Frag to GPU asm dump
Post by: cKleinhuis on April 28, 2015, 12:27:43 AM
ah no, looking in the book, i was using hlsl shading language v1.0 at that time ;) but first steps where in asm only ... i embraced the high level shading languages so much and they are now at such a beautiful useable state, i love it


Title: Re: Frag to GPU asm dump
Post by: 3dickulus on April 28, 2015, 12:35:57 AM
honestly, I haven't got a clue how to recompile the asm but I'm sure it would need some careful hand crafting or a more intelligent extraction before feeding it to the ptx assembler, proper declarations etc. etc. etc. I know nvcc compiler can handle it but  :hmh:


Title: Re: Frag to GPU asm dump
Post by: Syntopia on April 28, 2015, 10:59:08 PM
To recompile it, I think you can just send it instead of GLSL. If the first line begins with "!!NVfp5.0" I think it should be recognized as assembly.
At least that is how I read this document: http://developer.download.nvidia.com/opengl/specs/GL_NV_gpu_program5.txt



Title: Re: Frag to GPU asm dump
Post by: 3dickulus on April 29, 2015, 02:33:22 AM
I interpret that the same way, so assembler frags should be basically the same process  as GLSL frags, set vertex/fragment program text and send it to the GPU, that means technically Fragmentarium can already do this and just needs a little gui-ness to make it comfortable. A separate editing mode or language option switch? Hacking this into the existing code will be tricky, maybe a new branch for Qt5 + GLSL + GASM options? as QGLWidget and friends are to be replaced by functions prefixed with "QOpenGL" that don't work in quite the same way or have different prerequisites.

that is an extremely interesting document full of all kinds of goodies
Quote
    This extension also provides optional support for 64-bit-per-component variables and 64-bit floating-point arithmetic.

 :beer:  @Syntopia, I think that one will keep me up late tonight ;) maybe I'll learn enough to make something useable, or learn enough to know that I can't, either way it's still extremely interesting.


Title: Re: Frag to GPU asm dump
Post by: 3dickulus on April 29, 2015, 04:36:12 AM
well, the asm compiles using Qt stuff but no image, probably because Fragmentarium uses more than one shader and buffers and this program, QShaderEditor, is not designed with this in mind but a successful compile is promising :D


Title: Re: Frag to GPU asm dump
Post by: knighty on April 29, 2015, 04:53:22 PM
Nice feature!
With Polydraw (http://advsys.net/ken/download.htm) one can use either assembly or glsl. The source code is also provided.


Title: Re: Frag to GPU asm dump
Post by: 3dickulus on May 03, 2015, 10:23:50 AM
for anyone that applied the diff attached in the first post you also need to add
Code:
#define GL_PROGRAM_BINARY_LENGTH 0x8741
in the Fragmentarium-Source/ThirdPartyCode/glextensions.h file @ line 148  :gum:


Title: Re: Frag to GPU asm dump
Post by: 3dickulus on May 10, 2015, 10:42:17 PM
NOTE: the move to Qt5 negates the requirement for ThirdPartyCode/glextensions.h file as all GL functions are available through QOpenGLVersionFunctions and QOpenGLFunctions_4_1_Compatibility includes :D

edit: wow 500th post w00tw00t.


Title: Re: Frag to GPU asm dump
Post by: _revers_ on June 10, 2015, 10:34:35 PM
edit: I would be interested to hear what other hardware and versions this works with, mine is...

On my NVidia GeForce GTX 750 everything works as expected but on my AMD Radeon HD 5850 Fragmentarium crashes.
Graphics card details:
Code:
GL Vendor     : ATI Technologies Inc.
GL Renderer   : AMD Radeon HD 5800 Series
GL Version    : 4.4.13292 Compatibility Profile/Debug Context 14.502.1014.1001
GL Version    : 4.4
GLSL Version  : 4.40

I've implemented your method on my own and this is what I get on Radeon HD 5850 (only printable characters):

BufferShader.frag:
Code:
ELFc 4 B 4 ( 
 <D <D 13292 #version 440
#ifdef SYNTHCLIPSE
// #include <synthclipse>
#endif
layout(location = 0) in vec4 VertexPosition;

out vec2 coord;

void main(void)
{
gl_Position = VertexPosition;
coord = (VertexPosition).xy;
}


 #version 440
layout(location = 0) out vec4 glFragColor;
#ifdef SYNTHCLIPSE
// #include <synthclipse>
#endif
// This is a simple shader for rendering images
// from an accumulated buffer.

//! <vs shader="BufferShader.vert" />

//! <group name="Post"/>
uniform float Gamma; //! slider[0.0,2.0,5.0];
uniform float Exposure; //! slider[0.0,1.0,3.0];
uniform float Brightness; //! slider[0.0,1.0,5.0];
uniform float Contrast; //! slider[0.0,1.0,5.0];
uniform float Saturation; //! slider[0.0,1.0,5.0];
uniform int ToneMapping; //! slider[1,4,5];

/*
** Based on: http://mouaif.wordpress.com/2009/01/22/photoshop-gamma-correction-shader/
**
** Contrast, saturation, brightness
** Code of this function is from TGM's shader pack
** http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=21057
*/
// For all settings: 1.0 = 100% 0.5=50% 1.5 = 150%
vec3 ContrastSaturationBrightness(vec3 color, float brt, float sat, float con)
{
const vec3 LumCoeff = vec3(0.2125, 0.7154, 0.0721);
vec3 AvgLumin = vec3(0.5);
vec3 brtColor = color * brt;
float intensityf = dot(brtColor, LumCoeff);
vec3 intensity = vec3(intensityf, intensityf, intensityf);
vec3 satColor = mix(intensity, brtColor, sat);
vec3 conColor = mix(AvgLumin, satColor, con);
return conColor;
}

float sigmoid(float t) {
float K = 1.0-1./(1.0+exp(-0.5*Contrast*5.));
t -= 0.5;
float x = 1./(1.0+exp(-t*Contrast*5.))-K;
return x/((1.0-2.0*K));
}

vec3 sigmoid3(vec3 t) {
return vec3(sigmoid(t.x),sigmoid(t.y),sigmoid(t.z));
}

in vec2 coord;
uniform sampler2D frontbuffer;

void main() {
vec2 pos = (coord+1.0) * 0.5;
vec4 tex = texture(frontbuffer, pos);
vec3 c = tex.xyz/tex.a;

if (ToneMapping==1) {
// Linear
c = c*Exposure;
c = ContrastSaturationBrightness(c, Brightness, Saturation, Contrast);

} else if (ToneMapping==2) {
// ExponentialExposure
c = vec3(1.0)-exp(-c*Exposure);
c = ContrastSaturationBrightness(c, Brightness, Saturation, Contrast);

} else if (ToneMapping==3) {
// Filmic: http://filmicgames.com/archives/75
c*=Exposure;
vec3 x = max(vec3(0.),c-vec3(0.004));
c = (x*(6.2*x+.5))/(x*(6.2*x+1.7)+0.06);
c = pow(c, vec3(2.2)); // It already takes the Gamma into acount
c = ContrastSaturationBrightness(c, Brightness, Saturation, Contrast);

} else if (ToneMapping==4) {
// Reinhart
c*=Exposure;
c = c/(1.+c);
c = ContrastSaturationBrightness(c, Brightness, Saturation, Contrast);
} else if (ToneMapping==5) {
c = sigmoid3(c*Exposure+vec3(Brightness-1.0));

}
c = pow(c, vec3(1.0/Gamma));

glFragColor = vec4(c,1.0);
}


 | ELFc 4 X 4 (
 p p
 < @ #
m ^
m H
m vl
m z @
m `
m -
m !
m b
 @ 0 ] coord p Brightness l Contrast l Exposure l Gamma p Saturation p ToneMapping p = frontbuffer t VertexPosition . .text .inputs .outputs .constants .loopconstants .info .usageinfo .symbols .shstrtab T 0 8 % < 4 @ : E | N \ 8 ELFc 4 4 (
 ( ( $ k Q $ B P( @ - @ \ PE @ G @ Pi @ k @ P @ @ P @ @ @ , _ ` G 6 D 7 D p 6 D I 8 k 8 k 8 k@ 8 k` $ @ C @@! H D @ @ ` /O _ _ _ @_ `Y>t$7?*= @ ` ~b ~bO~bo `$ ,@! P X @ T ` o;? @ 0 `@ ` 0 @ @ 0 O _~ _ _ @_ `Y>t$7?*= ~ @ ` }b }bO}bo `$ ,@! D c @ c/ H coo /O c c/ cO co ff@? c/ O coOu=ff@ C o C ` O} C @~ A / A @ A @ O @ @@ @ /@ O _ _ _ @_ `Y>t$7?*= @ ` }b }bO}bo `$ ,@! @ H O Do, ( o C ~ ` C ` ~ @ C O _~ _ _ @_ `Y>t$7?*= ~ @ ` }b }bO}bo `$ ,@! ` H c D c/ @ cO ` @ @ `;? `@ @ ` @ o C ;? 0 /@ o@ @ / @ / C } / C } o~ C `} `~ C ` @ ` CO ? A A O A @ @ ~@ @ @ N ] D 5 D \ D N ] D 5 D \ D N ] D 5 D "" \ D "" ,
m k Q p Brightness l Contrast l Exposure l Gamma p Saturation p ToneMapping p = frontbuffer p F glFragColor . .text .inputs .outputs .constants .loopconstants .info .usageinfo .symbols .shstrtab T @ L , x % | 4 : ( E x N < \ +| < @ #
m ^
m H
m vl
m z @
m `
m -
m !
m b
 @ P( @ - @ \ PE @ G @ Pi @ k @ P @ @ P @ @ @ , _ ` G 6 D 7 D p 6 D I 8 k 8 k 8 k@ 8 k` $ @ C @@! H D @ @ ` /O _ _ _ @_ `Y>t$7?*= @ ` ~b ~bO~bo `$ ,@! P X @ T ` o;? @ 0 `@ ` 0 @ @ 0 O _~ _ _ @_ `Y>t$7?*= ~ @ ` }b }bO}bo `$ ,@! D c @ c/ H coo /O c c/ cO co ff@? c/ O coOu=ff@ C o C ` O} C @~ A / A @ A @ O @ @@ @ /@ O _ _ _ @_ `Y>t$7?*= @ ` }b }bO}bo `$ ,@! @ H O Do, ( o C ~ ` C ` ~ @ C O _~ _ _ @_ `Y>t$7?*= ~ @ ` }b }bO}bo `$ ,@! ` H c D c/ @ cO ` @ @ `;? `@ @ ` @ o C ;? 0 /@ o@ @ / @ / C } / C } o~ C `} `~ C ` @ ` CO ? A A O A @ @ ~@ @ @ N ] D 5 D \ D N ] D 5 D \ D N ] D 5 D "" \ D "" @(#) AMD OpenGL Driver version: 13292asicID: Z __Shader_V_Source_0_ __Shader_F_Source_0_ __Shader_V_AsicID_9_Key_0_ __Shader_V_AsicID_9_BinaryInfo_0_ __Shader_V_AsicID_9_ElfBinary_0_ __Shader_V_Stage_AsicID_9_ __Shader_F_AsicID_9_Key_0_ __Shader_F_AsicID_9_BinaryInfo_0_ __Shader_F_AsicID_9_ElfBinary_0_ __Shader_F_Stage_AsicID_9_ __Shader_V_AsicID_9_Text_ __Shader_F_AsicID_9_Text_ + , F 0 h @ ( , , X h ( ( h 7 ( . .setting .parameter .source .internal .crc .text .comment .strtab .symtab .shstrtab T d (
 l * ) 6 . 6 4 ? 4 = @ T E \A M ,B X

Unfortunately on AMD platforms you won't get shader assembly so easly.

I've also tested your method on some Intel video card at work and it also failed due to fact that glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS) returned "0".


Title: Re: Frag to GPU asm dump
Post by: 3dickulus on June 11, 2015, 12:59:26 AM
hmm, not surprising that it doesn't work on other cards and a little disappointing that it causes a crash, sorry about that but I have no other cards to test on, I will add a nVidia flag and warning like "Do you really want to continue?" or something, maybe just enable the menu option only if there is nVidia card present.

did it crash on Intel card? did it display anything?

Thanks for the feedback :D


Title: Re: Frag to GPU asm dump
Post by: _revers_ on June 11, 2015, 07:18:42 PM
Well, Fragmentarium didn't even start. During startup I get message about OpenGL module/profile absence (or something like that).
But there is installed OpenGL driver on this machine (BTW OS used on it is Ubuntu 14.04 x64). It supports OpenGL 3.3 Core Profile.
Maybe Core Profile is the problem? Fragmentarium uses Compatibility Profile?

But from your source I can tell you it will eventually crash since you do not check if "formats" returned from glGetIntegerv() is greater than "0":
Code:
    GLint formats = 0;
    glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &formats);
    GLint binaryFormats[formats];


Title: Re: Frag to GPU asm dump
Post by: Syntopia on June 11, 2015, 10:01:42 PM
Fragmentarium (at least my legacy version) uses immediate mode OpenGL calls (glBegin(...)), so it needs compatibility.
The default requested QGLWidget context should be a OpenGL 2.x ccontext.

I have never heard about a graphics driver abandoning compatibility context completely. Are you able to run glxgears?


Title: Re: Frag to GPU asm dump
Post by: _revers_ on June 11, 2015, 10:23:40 PM
I will check tomorrow at work.

EDIT:
It seems like in Mesa drivers (which Intel uses) indeed there is no "Compatiblity Profile" in OpenGL 3.x context, but one can instead create OpenGL 1 or 2 context. (http://stackoverflow.com/questions/28903722/can-i-get-a-opengl-compatibility-context-with-mesa-in-linux)
So I suppose that glxgears demo will work, and this is not the case with Fragmentarium failure. Maybe it's something with Qt?


Title: Re: Frag to GPU asm dump
Post by: Syntopia on June 12, 2015, 12:18:04 AM
I think 3dickulus added the 'glGetProgramBinary to the list of required functions. This is OpenGL 3.0+, so with that function a compatibility mode is required.


Title: Re: Frag to GPU asm dump
Post by: 3dickulus on June 12, 2015, 01:03:06 AM
using...
Code:
#include <QOpenGLVersionFunctions>
#include <QOpenGLFunctions_4_1_Compatibility>
...means ThirdPartyCode/glextensions.h is no longer required as everything is made available in QGLWidget by
Code:
 class DisplayWidget : public QGLWidget, protected QOpenGLFunctions_4_1_Compatibility {
    Q_OBJECT
public:
...etc...

I only added 4 #defines that didn't resolve.
Code:
#define GL_RGBA32F 0x8814
#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
#define GL_PROGRAM_BINARY_FORMATS 0x87FF
#define GL_PROGRAM_BINARY_LENGTH 0x8741


Title: Re: Frag to GPU asm dump
Post by: _revers_ on June 12, 2015, 06:32:39 PM
I am able to run glxgears demo on the Intel machine.
The exact error during Fragmentarium startup is:
"OpenGL features are missing.

Failed to resolve OpenGL functions required to run this application.
The program will now exit."

Driver details:
Code:
Platform: Linux Ubuntu 14.04 x64
GL Vendor     : Intel Open Source Technology Center
GL Renderer   : Mesa DRI Intel(R) Haswell Desktop
GL Version    : 3.3 (Core Profile) Mesa 10.3.0
GL Version    : 3.3
GLSL Version  : 3.30


Title: Re: Frag to GPU asm dump
Post by: Syntopia on June 12, 2015, 08:07:04 PM
That is as expected.

3dickulus, using  QOpenGLFunctions_4_1_Compatibility will not help. Revers' GPU only offers legacy modes (OpenGL 1.x, OpenGL 2.x) and modern OpenGL 3/4 Core contexts. But Fragmentarium cannot run in a core context - it needs compatibility - and the glGetBInaryProgram requires OpenGL 3 or later.

This is the same situation as on Mac, where there are two completely different implementations, legacy OpenGL 2.1 and moderne OpenGL 3.3/4.1 core contexts:
https://developer.apple.com/opengl/capabilities/index.html

The best solution would be to get rid of the glBegin/glEnd stuff (and the matrix stack), and instead use VBO's. After all we are only drawing a single quad.


Title: Re: Frag to GPU asm dump
Post by: 3dickulus on June 13, 2015, 01:20:19 AM
my reply above is only for reference as to what I used in DisplayWidget source, not meant as a fix suggestion, I tried 3_0 to 4_0 but 4_1 is the one that compiles with no errors
glGetBInaryProgram doesn't seem to be in the QOpenGLFunctions until you get to 4_1 but should be available back to 3_0

I think the solution in this case is simply no AsmBrowser if GL Vers < 4.1 , this is ok (with me) as it only works with one brand anyways so will try to set it up to warn but not exit.

edit: it does compile an run with QOpenGLFunctions_1_0 up to and inculding QOpenGLFunctions_4_1_Core and Compat (not thoroughly tested) without the AsmBrowser stuff


Title: Re: Frag to GPU asm dump
Post by: 3dickulus on June 13, 2015, 05:07:12 AM
for now I have added...
Code:
/// comment this out to compile with AsmBrowser enabled requires GL => 4.1
#define ASMBROWSER
as line 3 and 4 of DisplayWidget.h and ifdefed a few things like...
Code:
#ifdef ASMBROWSER
class DisplayWidget : public QGLWidget, protected QOpenGLFunctions_4_1_Compatibility {
#else
class DisplayWidget : public QGLWidget, protected QOpenGLFunctions {
#endif
I think this should make a legacy or modern GL version at compile time (haven't seen black screen for a while I think I fixed that too)

the changes are now in the sources on my website (might be slow it's been recruited for rendering duties)

@_revers_ you compile from source?


Title: Re: Frag to GPU asm dump
Post by: _revers_ on June 13, 2015, 08:55:07 AM
Yes, I've compiled from the source. I'll check on Monday if your fix works (now I don't have access to this computer). Also I will check if original Syntopia's Fragmentarium works.


Title: Re: Frag to GPU asm dump
Post by: _revers_ on June 14, 2015, 11:05:22 AM
@3dickulus

Can I use your technique for extracting assembly code in the Synthclipse? I would like to implement similar assembly preview. I think the preview might be useful for example to see how much ASM instructions shader uses (One of my experimental shaders uses 11 000 asm instructions, though it is designed to be maximally configurable, not optimal :) ).


Title: Re: Frag to GPU asm dump
Post by: 3dickulus on June 14, 2015, 11:25:56 AM
yes of course, thanks for asking :)
the AsmBrowser class just extracts text from nV binary, very unsophisticated, I had planned to parse the variable names and put them into the code where they belong for better readability.

I recently found out (Qt Docs) that Compatibility doesn't work on Mac, needs Core profile above GLv3.0, I have changed this and it compiles and runs fine on linux and win but I don't have access to a Mac for testing. (latest source tweek uploaded minutes ago)

edit: 2 exe files on the website (http://www.digilanti.org/fragmentarium/) one for nVidia GL v4.1 and up (nV suffix) and one for legacy GL, the difference is the nVidia version has the Shader Asm Browser and uses GL 4.1 Core profile.


Title: Re: Frag to GPU asm dump
Post by: _revers_ on June 14, 2015, 02:11:39 PM
Thanks :)


Title: Re: Frag to GPU asm dump
Post by: _revers_ on June 15, 2015, 07:30:19 PM
Fragmentarium 1.0.7 works (on the Intel machine) with removed flag "ASMBROWSER". Fragmentarium 1.0.0 works without any modification.


Title: Re: Frag to GPU asm dump
Post by: 3dickulus on June 16, 2015, 02:02:23 AM
 O0 I hope it was a recent copy of the source, I have been trying to track down the random black screen issue, every time I think it's fixed it shows up after running and exiting a number of times, just ran and rendered a few seconds ago again and it (latest on website) seems fine, no black screen yet. :angel1:

edit:I've moved just about everything to Qt5s QOpenGL stuff vs QGL except for QGLWidget, I think this is the source of the bug and hope it will be gone for good when/if I get things converted over to QOpenGLSurface and friends.