Sign in to follow this  
gwiazdorrr

Vector swizzling in C++

Recommended Posts

Haven't gotten a chance to look at your library, but why would one want to run GLSL code as C/C++ code. The majority of the issue encountered when writing shaders are usually related/closely tied to the driver implementation. Most high level shading languague HLSL/GLSL provide means to identify simple errors, which, when identified are easy to correct. The more esoteric ones such as application crashing / visualy anomalies are usually not easy to track down, and running the code on the CPU is not going to help identify the issue. If the bulk of the shader code is just arithmetic operations, then a library like yours would help in validation at least to the point where stuff like floating point behavior is similiar. Another good use would be for syntax verification like you alluded to, which would be a plus.

Share this post


Link to post
Share on other sites

Haven't gotten a chance to look at your library, but why would one want to run GLSL code as C/C++ code. The majority of the issue encountered when writing shaders are usually related/closely tied to the driver implementation. Most high level shading languague HLSL/GLSL provide means to identify simple errors, which, when identified are easy to correct. The more esoteric ones such as application crashing / visualy anomalies are usually not easy to track down, and running the code on the CPU is not going to help identify the issue. If the bulk of the shader code is just arithmetic operations, then a library like yours would help in validation at least to the point where stuff like floating point behavior is similiar. Another good use would be for syntax verification like you alluded to, which would be a plus.


I disagree. I think being able to run shader coder in a debugger would be fantastic. Setting breakpoints as being able to inspect values would be a great help in debugging. This also opens up the possibility of unit testing. That way, you can get the shader code working in at least one spot, then try and work out the problems you described later.

Share this post


Link to post
Share on other sites

Here steps in the CxxSwizzle (https://github.com/gwiazdorrr/CxxSwizzle), which I myself wrote in my free time. Bottom line, you can take almost any GLSL fragment shader and run it as C++ code, without any changes. Just like that. Conditional breakpoints, assertions, logs - there simply isn't a shader debugging solution (to my knowledge) that enables you to do that.
 
Feature list is still incomplete, but missing are mostly functions, which are the least difficult to implement (it's just a chore). Also, math implementation is extremely naive and slow, but due to the component structure of the code the "backend" can be easily moved to SSE based one, for instance.
 
Anyway, the syntactic compability with GLSL has been achieved, with little or no code repetition, using industry-available C++ features (subset of MSVC 2010, also tested on g++4.8.1). If you ever wanted to step through a shader and see "how it works" you now can.
 
I am extremely interested in (constructive) criticism of the library and, perhaps, discovering a better way of rich shader debugging. This one is slow as hell, but, well.. works. So? smile.png


When I first read that you achieved vector swizzling in c++ I couldn't think of how to replicate it. So I had to look at your code. I have to say, you have a pretty clever solution. Although I can see how it would be slow but good work.

Share this post


Link to post
Share on other sites

Haven't gotten a chance to look at your library, but why would one want to run GLSL code as C/C++ code. The majority of the issue encountered when writing shaders are usually related/closely tied to the driver implementation. Most high level shading languague HLSL/GLSL provide means to identify simple errors, which, when identified are easy to correct. The more esoteric ones such as application crashing / visualy anomalies are usually not easy to track down, and running the code on the CPU is not going to help identify the issue. If the bulk of the shader code is just arithmetic operations, then a library like yours would help in validation at least to the point where stuff like floating point behavior is similiar. Another good use would be for syntax verification like you alluded to, which would be a plus.

 

I think the way we think about debugging shaders is... well, dictated by the fact that there are no ways of doing it. We learned to cope with this. Some errors can be picked up by the compiler, some can be easily identified just by observing output. Hell, with CPU code you can debug print messages if for any reason you can't use debugger. With shaders you can't even do that!

 

While it's true that most shaders are short, they are by no means simple and they are getting increasingly complex. Ability to step through the code gives you an opportunity to get a better understanding of what's going on. You can also easily print results and partial results to, say, a CSV file and then plot them to see how input translates to output in more analytic way. Also, as @HappyCoder mention, you can now unit test your shaders or even single shader functions in isolation. Givin these options was the purpose of the library.

 

As the saying goes, "you cannot have too much of a good thing".

 

 

When I first read that you achieved vector swizzling in c++ I couldn't think of how to replicate it. So I had to look at your code. I have to say, you have a pretty clever solution. Although I can see how it would be slow but good work.

 

At least with MSVC almost all static_for loops are unrolled and almost all functions are inlined, so the perfomance suffers mostly to naive math implementation (per-component, no vectorisation).

 

I didn't focus on the performance, since even using SSE it would be suboptimal. You just shouldn't write your CPU code like you write your shaders. For instance, SSE prefers "structure of arrays" (SoA) approach rather than "array of structures" (AoS) - this becomes obvious when you have to process less than 4-component vector and do not use the full width of registers. Still, for some non-critical code it may be an option.

Share this post


Link to post
Share on other sites

The simple way of using SSE with a shader is to process 4 pixels/verts/etc simultaneously. That way you can treat all the maths as scalar, but do it for four pixels at once (or 8 with AVX).

 

However what will really kill performance on the CPU is texture sampling.

Share this post


Link to post
Share on other sites


However what will really kill performance on the CPU is texture sampling.

I worked on SW rasterizer for 3 years, and I have to agree. You have to architect your entire solution around texture-sampling.

 

For shader debugging, though, performance shouldn't really matter. The main issue there is discrepancy in the results between the CPU and the GPU. It might look like the same shader, but the compiled code will have different instructions flow. Then you have to generate shader inputs, so some more differences. And different texture sampler implementation, so more differences.

All those small differences accumulate. In many cases it's not really a problem, but there are plenty of cases where it's a real issue, especially when a shader suffers from numerical instability.

 

PIX's shader debugger is a good example - it uses the DX reference rasterizer, and I saw many cases where the results were different than what the GPU was outputing (and our SW rast was different than both of them).

Share this post


Link to post
Share on other sites

Well, I guess you just have to pick your tools right.

 

Trying to resolve a visual bug in a complex application? Use PIX or Nsight or any other GPU/pipeline capture tool. They all work "on top" of your code, however complex it is. No changes needed, so if the bug is an effect of complex interactions, you have a chance of finding out the source that way.

 

Prototyping? Trying to understand how something works? Not sure if the driver is to blame? Well, depending on how much you rely on the debugger, you might choose CxxSwizzle.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this