is it possible to read data from vertex shader? - opengl-es

I am trying to write a simple GPGPU benchmark. To load the data into vertex buffer array, do some computation in the vertex shader, and read the data back. Is it possible? I am planning to run this on SGX GPUs.
Is there any way to do that? I dont want it to go through the transformation, clipping, Tiling phases, and pixel processing. that incurs additional overhead, and changes my data.
can I read back the data and examine it in the CPU? is there anyway in opengl es?
I can do the computations in pixel shader aswell, by sending data through a texture and multiplying with some constants and writing it to another frame buffer. but how do I get it back? i dont really want to present it to the screen.
is there anyway to do that? can somebody point me to some tutorials if available?

Reading Vertex output: Look for Transform Feedback - But you will have to have OpenGL ES 3.0 to use this.
For ES2.0 I suggest using fragment shader and Render To Texture techniques. Here is some link with tutorial
After rendering to texture you basically have to read pixels of the texture.
Nice tutorial on reading the data here
tutorial about feedback: http://open.gl/feedback

You cannot read data from vertex shader directly in OpenGL ES 2.0.
So, you can sed your data to pixel/fragment shader, attach it to Frame Buffer Object(FBO) and then use glReadPixels to get the data as texture in your CPU.
This link discribes the concept and code snnipet:
here.
Hope this might help.

"...computation in the vertex shader, and read the data back. Is it possible? I am planning to run this on SGX GPUs."
As SGX supports Opengles 2.0 not 3.0, PowerVR SGX doesn't support reading vertex shader output.(OpenGL ES 2.0 spec doesn't include such functionality).
"can I read back the data and examine it in the CPU? is there anyway in opengl es?"
You can use framebuffer objects and read the same using glRead API. You can read about FrameBuffer Objects here
Ref: http://en.wikipedia.org/wiki/Framebuffer_Object
Ref: Reading the pixels values from the Frame Buffer Object (FBO) using Pixel Buffer Object (PBO)
If GPGPU calculation you are after, then i recommend you should go for OpenCL.
SGX Supports OpenCL EP 1.1.

While writing from vertex shader to offscreen is not possible in OpenGL ES2, you can do that from pixel shader.
First you need to render to the offscreen buffer, then you can either render that as a texture to another object on screen, or you can read it back using readPixels the usual way. A simple list of steps is given in https://gist.github.com/prabindh/9201855.

Related

How to let a vertex shader in OpenGL ES 2.0 perform GPGPU computing?

I'm doing a project using OpenCL and thought it can work on Mali 400 GPU. But I recently found that Mali 400 GPU only support OpenGL ES 2.0 standard.
I still have to use this GPU, So is there any way to let a shader act nearly the same as OpenCL kernel or CUDA kernel?
There are some main features I expect but not sure glsl will support:
For example, I created a global memory for GPU, and I want to read/write the global memory in shader, how should I pass the variable from host to vertex shader, can I expect that data be both 'in and out' like this?
layout (location = 0) inout vec3 a_Data;
I want to fetch a_Data as 64 float values, is there a easy way to declare it like vec64 or float[64], or I have to use multiple vec4 to assemble it?
So is there any way to let a vertex shader act nearly the same as OpenCL kernel or CUDA kernel?
No.
In ES 2.0, vertex shaders have no mechanism to write to memory. At all. All of their output variables go to the rasterizer to generate fragments to be processed by the fragment shader.
The only way to do GPGPU processing on such hardware is to use the fragment shader to write data. That means you have to manipulate your data to look like a rendering operation. Your vertex positions needs to set up your fragment shader to be able to write values to the appropriate places. And your fragment shader needs to be able to acquire whatever information it needs based on what the VS provides (which is at a per-vertex granularity and interpolated for each fragment).

culling instanced meshes without geometry shader

Whats an effective way to cull instanced meshes
(f.e. 2000 trees, each with ~ 17 triangles) without using the geometry shader ?
Unfortunately my software supports only OpenGL ES 3.0, so have to cull in the vertex shader or somewhere else.
Another solution would be to rearrange the instance buffer in each frame.
GPU culling is pointless if it cannot be done efficiently; that is, after all, the whole point of putting culling on the GPU to begin with.
Efficient GPU culling requires the following:
A way to conditionally write data to GPU memory from a shader, and with a controllable format.
A way to have rendering commands executed based on data stored entirely within GPU memory, without CPU/GPU synchronization.
OpenGL ES 3.0 lacks a mechanism for doing either of these. Geometry shaders and transform feedback are the older means for doing #1, but it could also be done with compute shaders and SSBOs/image load/store. Of course, ES 3.0 has neither sets of functionality; you'd need ES 3.1 for that.
ES 3.0 also has no indirect rendering features, which could be used to actually render with the GPU-generated data without any read-back of data from the CPU. So even if you had a way to do #1, you'd have to read the data back on the CPU to be able to use it in a rendering command.
So unless CPU culling is somehow more expensive than doing a full GPU/CPU sync (it almost certainly isn't), it's best to just do the culling on the CPU.

In opengl ES can I use a vertex buffer array buffer etc for shader shared matrices?

As OpenGL ES does not support shared "uniform blocks" I was wondering if there is a way I can put matrices that can be referenced by a number of different shaders, a simple example would be a worldToViewport or worldToEye which would not change for an entire frame and which all shaders would reference. I saw one post where one uses 3 or 4 dot calls on a vertex to transform it from 4 "column vectors", but wondering if there is a way to assign the buffer data to a "mat4" in the shader.
Ah yes the need for this is webGL which at the moment it seems only to support openGLES 2.0.
I wonder if it supports indexed attribute buffers as I assume they don't need to be any specified size relative to the size of the position vertex array.
Then if one can use a hard coded or calculated index into the attribute buffer ( in the shader ) and if one can bind more than one attribute buffer at a time, and access all "bound to the shader" buffers simultaneously in a shader ...
I see if all true might work. I need a good language/architecture reference on shaders as I am somewhat new to shader programming as I I'm trying to deign a wall without knowing the shapes of the bricks :)
Vertex attributes are per-vertex, so there is no way so share vertex attributes amongst multiple vertices.
OpenGL ES 2.0 upwards has CPU-side uniforms, which must be uploaded individually from the CPU at draw time. Uniforms belong to the program object, so for uniforms which are constant for a frame you only have to modify each program once, so the cost isn't necessarily proportional to draw count.
OpenGL ES 3.0 onwards has Uniform Buffer Objects (UBOs) which allow you to load uniforms from a buffer in memory.
I'm not sure what you mean by "doesn't support shared uniform blocks", as that's pretty much what a UBO is, albeit it won't work on older hardware which only supports OpenGL ES 2.x.

How can I perform arbitrary computation in OpenGL ES 3.0 (prior to compute shaders)

Prior to the introduction of compute shaders in OpenGL ES 3.1, what techniques or tricks can be used to perform general computations on the GPU? e.g. I am animating a particle system and I'd like to farm out some work to the GPU. Can I make use of vertex shaders with "fake" vertex data somehow?
EDIT:
I found this example which looks helpful: http://ciechanowski.me/blog/2014/01/05/exploring_gpgpu_on_ios/
You can use vertex shaders and transform feedback to output the results to an application accessible buffer. The main downside is that you can't have cross-thread data sharing between "work items" like you can with a compute shader, so they are not 100% equivalent.

How to add a shader to a fixed-pipeline OpenGL app

I am updating an existing app for Mac OS that is based on the older fixed-pipeline OpenGL. (OpenGL 2, I guess it is.) It uses an NSOpenGLView and an ortho projection to create animated kaleidoscopes, with either still images or input from a connected video camera.
It was written before HD cameras were available (or at least readily so.) It's written to expect YCBCR_422 video frames from Quicktime (k422YpCbCr8CodecType) and passes the frames to OpenGL as GL_YCBCR_422_APPLE to map them to a texture.
My company decided it was time to update the app to support the new crop of HD cameras, and I am not sure how to proceed.
I have a decent amount of OpenGL experience, but my knowledge is spotty and has gaps in it.
I'm using the delegate method captureOutput:didOutputVideoFrame:withSampleBuffer:fromConnection to receive frames from the camera via a QTCaptureDecompressedVideoOutput
I have a Logitech c615 for testing, and the buffers I'm getting are reported as being in 32 bit RGBA (GL_RGBA8) format. I believe it's actually in ARGB format.
However, according to the docs on glTexImage2D, the only supported input pixel formats are GL_COLOR_INDEX, GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_RGB, GL_BGR GL_RGBA, GL_BGRA, GL_LUMINANCE, or GL_LUMINANCE_ALPHA.
I would like to add a fragment shader that would swizzle my texture data into RGBA format when I map my texture into my output mesh.
Since writing this app I've learned the basics of shaders from writing iOS apps for OpenGL ES 2, which does not support fixed pipeline OpenGL at all.
I really don't want to rewrite the app to be fully shader based if I can help it. I'd like to implement an optional fragment shader that I can use to swizzle my pixel data for video sources when I need it, but continue to use the fixed pipeline for managing my projection matrix and model view matrix.
How do you go about adding a shader to the (otherwise fixed) rendering pipeline?
I don't like to ask this, but what exactly is your problem now? It is not that difficult to attach shaders to the fixed function pipeline; all you need is to reimplement that tiny bit of functionality that vertex and fragment shaders are replacing. You can use built-in GLSL variables like gl_ModelViewMatrix or such to use values that have been setup by your legacy OpenGL code; you can find some of them here: http://www.hamed3d.org/Res/GLSL_Reference/0321552628_AppI.pdf

Resources