Live data from Hacker News

Weep for Graphics Programming

adriansampson.net

51–60 of 162 posts

Re: Weep for Graphics Programming

#51
post #33

I'm not sure why bytecode is supposed to be significantly better than storing the shaders as strings. Sure, you get rid of a complex parser and can more easily use it as a compiler target, but the core problem remains: the compiler can still not reason across the device boundary. The CPU compiler does not understand what happens on the GPU, and the GPU compiler has no idea what the CPU is going to do do it. Although…

I agree, CUDA took a step in the right direction by allowing annotated C++ source to be compiled for the device. As an HPC developer, I'm using the Kokkos C++ library https://github.com/kokkos/kokkos to switch between CUDA, OpenMP, or Serial modes from a single source code.

Re: Weep for Graphics Programming

#52
post #33

I'm not sure why bytecode is supposed to be significantly better than storing the shaders as strings. Sure, you get rid of a complex parser and can more easily use it as a compiler target, but the core problem remains: the compiler can still not reason across the device boundary. The CPU compiler does not understand what happens on the GPU, and the GPU compiler has no idea what the CPU is going to do do it. Although…

Furthark looks really nice, but what does the future look like for it? (I'm currently working on a Python hpc codebase with pyopencl and would be interested in reducing some of the manual labor required for cpu-gpu coordination)

Well, I still have a year left on my PhD, and I hope (with some reason) to get funding to continue after that. But I must emphasize that the language is still a little young and raw.

Re: Weep for Graphics Programming

#53
post #33

I'm not sure why bytecode is supposed to be significantly better than storing the shaders as strings. Sure, you get rid of a complex parser and can more easily use it as a compiler target, but the core problem remains: the compiler can still not reason across the device boundary. The CPU compiler does not understand what happens on the GPU, and the GPU compiler has no idea what the CPU is going to do do it. Although…

The issue is that every driver implementation ever ships with a slightly different implementation of that complex parser. That means (every mobile device)X(every OS update) and (every PC ad-in card)X(every driver update) all have the potential to misinterpret/reject your shaders in slightly different ways. Case in point: I recently learned that "#line 0" is a spec violation. A single OS revision of a single Android d…

Couldn't a bytecode format have the same problem? Probably not with respect to parsing, but the semantics could still differ.

Re: Weep for Graphics Programming

#54
post #8

When writing my first OpenGL code, I was stunned by the amount of boilerplate required. It is so bad it reminds me of COBOL. No one in their right mind would tolerate that monstrosity in a normal CPU program (except, possibly, some hardcore C++ fans). I think in order to solve this, we need three things: 1) Intermediate representation for compiled GPU code. Bytecode mentioned in the article sounds like it. 2) Cross-p…

> When writing my first OpenGL code, I was stunned by the amount of boilerplate required. Huh, actually the amount of boilerplate required for getting a triangle to the screen with OpenGL is minimal. - Create a context - fill a buffer with the triangle vertex data - load buffer to OpenGL - create vertex shader implementing vertex to position transformation - create vertex shader implementing pixel coloirization - iss…

And yet you've just described a decent amount of boilerplate.

The fact that future iterations of OpenGL and OpenGL ES have nuked the fixed function pipeline is sort of annoying. I'm not saying there should be more codepaths in the implementation, but if there were a default compiled fixed function vertex shader and fragment shader, it would be helpful.

What you've just described for rendering one primitive includes compiling two shaders, linking arguments, and specifying byte arrays before issuing commands, when this task used to be as simple as:

    glBegin(GL_TRIANGLES);
        glColor3f(1.0f, 0.0f, 0.0f);
        glVertex3f(0.0f, 1.0f, 1.0f);
        glColor3f(0.0f, 1.0f, 0.0f);
        glVertex3f(-0.866f, -0.5f, 1.0f);
        glColor3f(0.0f, 0.0f, 1.0f);
        glVertex3f(0.866f, -0.5f, 1.0f);
    glEnd();
Being able to draw a triangle in eight lines of code is much more encouraging to someone wanting to make a 3D game for mobile or the web than an estimated 50 lines, including two shaders they had to borrow from a textbook.

I would understand if immediate mode were gone, which might be better regardless. Still, things should be as simple as a glDrawArrays call without compiling shaders.

Not to mention, when working as a solo game developer, shaders feel like an orphan between artists and programmers.

Re: Weep for Graphics Programming

#55
Very well written. I get the sense that the reason we're all here now is that historically the people who use these APIs as client programmers have been somewhat bad at explaining what they want.

Re: Weep for Graphics Programming

#56
post #52

Earlier quoted context omitted.

Furthark looks really nice, but what does the future look like for it? (I'm currently working on a Python hpc codebase with pyopencl and would be interested in reducing some of the manual labor required for cpu-gpu coordination)

Well, I still have a year left on my PhD, and I hope (with some reason) to get funding to continue after that. But I must emphasize that the language is still a little young and raw.

I just read the paper and it looks better than most of the alternatives for GPU programming.

Re: Weep for Graphics Programming

#57
post #25
post #5

OpenCL was moving to LLVM IR away from programs-as-source-code-strings at some point. Still, you ought to have a JIT step if you want to be able to ship the same binary to multiple systems with GPUs not compatible at the binary level. And BTW shipping LLVM IR on the CPU would make things better in terms of supporting CPUs with incompatible ISAs... whether that ever overtakes native binaries is a question (it did to a…

In CUDA you can write your device kernel as a templated function and the compiler will specialise it based on how it's called by the host. In some cases this can result in big speed-ups while keeping the code simple and maintainable. You could get the same speed from specialising the code by hand, or with a separate code generation tool; but having that ability built in to the compiler makes it very easy to use. It's…

func(c,d) isn't faster than func(a,b,c,d) if the compiler sees that a,b are constants and the call to func is in the same file as its definition; the only thing CPU+GPU code adds here relatively to CPU-only code is, perhaps you need to write a wrapper along the lines of func_ab(c,d) { func(a,b,c,d) }, a bit ugly but the code is still pretty simple and maintainable. (And unlike the case with templates at least you can make sense of the symbol table etc. etc.)

As to runtime errors because of misspelling a parameter name, this is going to be fixed the first time you run the program and you live happily ever after; I don't mind these errors in Python very much and I don't mind it in C programs using strings to refer to variable names in whatever context that may happen.

Overall the amount of "dynamism" in CPU/GPU programming IMO does not result in wasting almost any optimization opportunities nor does it make the program significantly harder to get right, but I'm prepared to change my mind given counterexamples (certainly in Python it's really easy to demonstrate missed optimization opportunities relatively to C due to its dynamism... The amount of dynamism in CPU/GPU programming however is IMO trivial and hence the issues resulting from it are also rather trivial.)

Re: Weep for Graphics Programming

#58
It seems unlikely that any of this will change, because control is in the hands of a relatively few powerful organizations who honestly have no interest in making life easier for software engineers working on graphics programming; and those engineers who do have to put up with it have long since given up or chalk it up to experience; and those developers would probably resist any changes now simply because change requires more work and learning how to do things all over again.

The hardware developers (AMD/nVidia/Intel) have an interest in not changing their device drivers, the software vendors (OpenGL and DirectX) have little interest in redeveloping technology, and the software developers with the most capital, game engine developers, have already found workarounds and hire enough engineers to plug leaks in their lifeboats. The state of tools for game developers is so shoddy as well that trying to retrofit language compilers and shader compilers to work together seems like a drawn out task.

It's sort of a David and Goliath situation if you think you can change the graphics programming landscape on your own. Plus, we all know how poorly these standards are developed over time.

Re: Weep for Graphics Programming

#59
post #54

Earlier quoted context omitted.

> When writing my first OpenGL code, I was stunned by the amount of boilerplate required. Huh, actually the amount of boilerplate required for getting a triangle to the screen with OpenGL is minimal. - Create a context - fill a buffer with the triangle vertex data - load buffer to OpenGL - create vertex shader implementing vertex to position transformation - create vertex shader implementing pixel coloirization - iss…

And yet you've just described a decent amount of boilerplate. The fact that future iterations of OpenGL and OpenGL ES have nuked the fixed function pipeline is sort of annoying. I'm not saying there should be more codepaths in the implementation, but if there were a default compiled fixed function vertex shader and fragment shader, it would be helpful. What you've just described for rendering one primitive includes c…

It's staggering! The above is immediate-mode code which is what's gone and that's how a lot of people learned OpenGL 1-3.

Anton Gerdelans's tutorials are the best I've found and just look at how much typing there is:

Code:

https://github.com/capnramses/antons_opengl_tutorials_book/b...

Explanation:

http://antongerdelan.net/opengl/hellotriangle.html

Once you can get through that mess, the effort/reward ration seems to be a bit more incremental, but the triangle program a pretty good illustration of that first cliff, and how much it's grown.

Re: Weep for Graphics Programming

#60
He listed some of the downsides of the OpenGL approach to shaders, but he forgot to address the (IMHO) really big advantage: You can use OpenGL in every programming language that is able to call C functions, which is basically every programming language.

Somebody in this thread mentioned CUDA, which is great, but it also has the downside that you practically have to use C++ on the CPU side. You also can use e.g. python, but when you do you are back to compiling CUDA code at runtime.

Sure, you could argue that we can simply create a new programming language for applications that use the graphics card (Or use C++ like CUDA). The problem with this is that few people would use it just because its a bit easier to do CPU-GPU communication. An there is a second much larger problem: Different graphics API vendors would create different programming languages which makes it much harder for a application to support multiple graphics API as a lot of games do today with DirectX and OpenGL.

Perhaps there is another better solution, but I can't see it right now.

Post reply on HN