Mali offline compiled shaders using in OpenGLES2.0 Application - opengl-es

I am using Mali-400 GPU.
I want to use the Mali off-line shader compiler, to compile the Vertex shader and Fragment shaders.
I have compiled my Vertex shader and Fragment shader using ARM Mali off-line compiler with below step
malisc.exe --vertex -c Mali-400 -r r1p1 -d Mali-400_r5p0-01rel0 Vertex_shader.glsl -o vshader.out
malisc.exe --fragment -c Mali-400 -r r1p1 -d Mali-400_r5p0-01rel0 Fragm_shader.glsl -o fragment.out
I am using below like code,
my application compiles successfully, but application not running on my target.
copied the shader binaries content into a static array and usign that with glShaderBinary.
my code snippet:
char VertexShaderArray[] = {<initialized using shader binary data>};
char fragShaderArray[] = {<initialized using shader binary data>};
GLuint v, f, program;
v = glCreateShader(GL_VERTEX_SHADER);
f = glCreateShader(GL_FRAGMENT_SHADER);
glShaderBinary(1, &v, MALI_PROGRAM_BINARY_ARM, (void*)&VertexShaderArray, sizeof(char)*sizeof(VertexShaderArray));
glShaderBinary(1, &f, MALI_PROGRAM_BINARY_ARM, (void*)&fragShaderArray, sizeof(char)*sizeof(fragShaderArray));
program = glCreateProgram();
glAttachShader(program, v);
glAttachShader(program, f);
glLinkProgram(program);
glUseProgram(program);
I am getting a message on my target while running this application:
info: L0101 All attached shaders must be compiled prior to linking
Can some one please post the example code for using off-line compiled shaders in a OpenGLES2.0 application.

Related

How to use Cmake for OpenGL + Qt 5.8 in OS X Sierra?

I just tried to setup CMake for a project using Qt 5.8 to do OpenGL stuff in OS X Sierra. Here you can see my main CMakeLists
cmake_minimum_required (VERSION 3.8)
set (PROJECT_NAME "FluidEngine")
project (${PROJECT_NAME})
set (CMAKE_PREFIX_PATH "/Users/BRabbit27/Qt/5.8/clang_64")
set (CMAKE_AUTOMOC ON)
find_package (Qt5Widgets)
find_package (Qt5Gui)
find_package (Qt5OpenGL)
set (CPP_SOURCES "")
set (HPP_SOURCES "")
set (INCLUDE_PATHS "")
add_subdirectory (src)
include_directories (${INCLUDE_PATHS} ${OPENGL_INCLUDE_DIRS})
add_executable (${PROJECT_NAME} ${CPP_SOURCES} ${HPP_SOURCES})
target_link_libraries (${PROJECT_NAME} Qt5::Widgets Qt5::Gui Qt5::OpenGL )
It perfectly configures the xcode project, no errors.
Then my code for rendering a basic triangle looks like:
GLWindow::GLWindow(QWidget* parent) : QOpenGLWidget(parent)
{}
void GLWindow::initializeGL()
{
initializeOpenGLFunctions();
GLfloat verts[] =
{
0.f, 1.f,
-1.f, -1.f,
1.f, -1.f
};
GLuint myBufferID;
glGenBuffers(1, &myBufferID);
glBindBuffer(GL_ARRAY_BUFFER, myBufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
}
void GLWindow::resizeGL(int w, int h)
{
glViewport(0, 0, w, h);
}
void GLWindow::paintGL()
{
glDrawArrays(GL_TRIANGLES, 0, 3);
}
And what I get is a black window. I got this code from this video tutorial
Am I missing something in my cmake file or something subtle in OS X to use OpenGL? Since OS X is now promoting Metal, perhaps something must be enabled but I do not know what.
I already tried setting the version of OpenGL used in the main function
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QSurfaceFormat format;
format.setVersion(4, 1);
format.setProfile(QSurfaceFormat::CoreProfile);
QSurfaceFormat::setDefaultFormat(format);
GLWindow glwindow;
glwindow.show();
return app.exec();
}
Any idea?
UPDATE
Added project to github, you can clone it here to test in your machine.
The way I build the project is just cmake -GXcode .. assuming i'm in /path/to/project/build_xcode directory.
Hope this can help you reproduce and perhaps give me a clue on what I could be doing wrong.
I checked all the error messages and from there make my way to found the solution. Fortunately someone already replied in SO with a related problem and had a solution to the problem. You can find the complete answer here OpenGL: INVALID_OPERATION following glEnableVertexAttribArray
For short
You're seeing this error on OS X because it only supports the OpenGL
Core Profile if you're using OpenGL 3.x or higher. Your code is not
Core Profile compliant. You were most likely using the Compatibility
Profile on Windows.
Specifically, the Core Profile requires a Vertex Array Object (VAO) to
be bound for all vertex related calls. So before calling
glEnableVertexAttribArray(), or other similar functions, you will
need to create and bind a VAO.

MacOs OpenCL on HD 530 with clBuildProgram error(-11)

I have the latest mac pro(OS:10.12.2) ,with intel intergrated GPU HD 530(Gen9) which runs the OpenCL code. In my OpenCL code, I use vloadx and atomic_add instruction. change my OpenCL kernel code into bitcode like https://developer.apple.com/library/content/samplecode/OpenCLOfflineCompilation/Introduction/Intro.html#//apple_ref/doc/uid/DTS40011196-Intro-DontLinkElementID_2
. and create the program with clCreateProgramWithBinary. But when clBuildProgram, it returns error with -11 .and build log is "
error: undefined reference to _Z6vload2mPKU3AS1h()'
undefined reference to_Z8atom_addPVU3AS3ii()'
"
But in my mac air with HD 5500(Gen8), the code is ok.
Can someone tell me what should I do?
The problem here is, you cannot use incompatible binaries in different devices. Which means if you compile for Intel, you cannot use the compiled binary for AMD for example. What you need to do is compile the code for the specific device every time from the source.
If you do not want to use the OpenCL codes in different files, what you can do is put them inside your source file by stringifying them. Instead of reading a file, you use the kernel string inside your host code to pass as the kernel string. This will allow you to protect your IP. However, everytime, you need to build the code using clBuildProgram. You can also save the built program as binary, so after the first run, you won't degrade performance by building it everytime. To give an example, lets suppose you have a kernel.cl file as following:
__kernel void foo(__global int* in, __global int* out)
{
int idx = get_global_id(0);
out[idx] = in[idx] * in[idx];
}
You probably get this kernel code by reading the file with something like:
char *source_str;
fp = fopen("kernel.cl", "r");
source_str = (char *)malloc(MAX_SOURCE_SIZE);
source_size = fread(source_str, 1, MAX_SOURCE_SIZE, fp);
fclose(fp);
program = clCreateProgramWithSource(context, 1, (const char **)&source_str, (const size_t *)&source_size, &ret);
What you can do instead is something like:
const char* src = "__kernel void foo(__global int* in, __global int* out)\
{\
int idx = get_global_id(0);\
out[idx] = in[idx] * in[idx];\
}";
program = clCreateProgramWithSource(context, 1, (const char **)&src, (const size_t *)&src_size, &ret);
When you compile your C code, this string will be converted into binary, so you protect your source code.

Test Program Using GLEW Crashing on Launch

I am trying to work with OpenGL on Windows in Eclipse using MinGW.
So far I've been able to set up GLFW correctly and now I am trying to load OpenGL pointers with GLEW.
I downloaded the GLEW source and built it using the instructions at Building glew on windows with mingw and that didn't appear to cause any problems.
I have a test program that I am trying to run. The program runs and opens the window if I comment out the calls to GLEW (lines 32 to 40)
/*USE OUR OPENING LIBRARY GLEW TO LOAD OPENGL FUNCTIONS*/
glewExperimental = GL_TRUE;
glewInit();
/*Test that GLEW was loaded by calling the OpenGL function glGenBuffers*/
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
printf("%u\n", vertexBuffer);
However when I try to make any calls to glew - either set glewExperimental or call glewInit() - the program builds fine but when I run it the program crashes with the error message "HelloGLEW.exe has stopped working". This is the full error message and there are no other error messages.
Can anyone explain/theorise as to the cause of the problem and suggest how to fix them? Or possibly someone had the same problem and can explain how they solved it.
This is the full program code:
//Opening Toolkit: GLEW (OpenGL Extention Wrangler)
#define GLEW_STATIC
#include <GL/glew.h>
//Window Toolkit: GLFW
#include <GLFW/glfw3.h>
#include <stdio.h>
int main(void)
{
/* USE GLFW TO CREATE OUR CONTEXT AND WINDOW*/
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Hello GLEW", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
/*USE OUR OPENING LIBRARY GLEW TO LOAD OPENGL FUNCTIONS*/
glewExperimental = GL_TRUE;
glewInit();
/*Test that GLEW was loaded by calling the OpenGL function glGenBuffers*/
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
printf("%u\n", vertexBuffer);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
I've linked it with glew32, glu32, glfw3, opengl32 and gdi32 in that order. Here are the compilation commands:
g++ "-IC:\\Libraries\\GLFW3\\include" "-IC:\\Libraries\\GLEW\\include" -O0 -g3 -Wall -c -fmessage-length=0 -o main.o "..\\main.cpp"
g++ "-LC:\\Libraries\\GLFW3\\i386\\lib-mingw" "-LC:\\Libraries\\GLEW\\lib" -o HelloGLEW.exe main.o -lglew32 -lglu32 -lglfw3 -lopengl32 -lgdi32
Like I said can anyone explain/theorise as to the cause of the problem and suggest how to fix them? Or possibly someone had the same problem and can explain how they solved it.

CUDA 5.0 "Generate Relocatable Device Code" leads to invalid device symbol error

I am trying to do separate compilation using CUDA 5. For this reason I set the "Generate Relocatable Device Code" to "Yes (-rdc=true)" in Visual Studio 2010. The program compiles without errors, however,
I get an invalid device symbol error when I try to initialize device constants using cudaMemcpyToSymbol.
i.e. I have the following constant
__constant__ float gdDomainOrigin[2];
and try to initialize it with
cudaMemcpyToSymbol(gdDomainOrigin, mDomainOrigin, 2*sizeof(float));
which leads to the error. The error does not occur, when I compile everything as a whole, without the aforementioned option set. Could anybody please help me with that?
I can't reproduce this. If build an application from two .cu files, one containing a __constant__ symbol and a simple kernel, and the other containing the runtime API incantations to populate that constant memory and call the kernel, it works only when relocatable device code is enabled, viz:
__constant__ float gdDomainOrigin[2];
__global__
void kernel(float *inout)
{
inout[0] = gdDomainOrigin[0];
inout[1] = gdDomainOrigin[1];
}
and
#include <cstdio>
extern __constant__ float gdDomainOrigin;
extern __global__ void kernel(float *);
inline
void gpuAssert(cudaError_t code, char * file, int line, bool Abort=true)
{
if (code != 0) {
fprintf(stderr, "GPUassert: %s %s %d\n",
cudaGetErrorString(code),file,line);
if (Abort) exit(code);
}
}
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
int main(void)
{
const float mDomainOrigin[2] = { 1.234f, 5.6789f };
const size_t sz = sizeof(float) * size_t(2);
float * dbuf, * hbuf;
gpuErrchk( cudaFree(0) );
gpuErrchk( cudaMemcpyToSymbol(gdDomainOrigin, mDomainOrigin, sz) );
gpuErrchk( cudaMalloc((void **)&dbuf, sz) );
kernel<<<1,1>>>(dbuf);
gpuErrchk( cudaPeekAtLastError() );
hbuf = new float[2];
gpuErrchk( cudaMemcpy(hbuf, dbuf, sz, cudaMemcpyDeviceToHost) );
fprintf(stdout, "%f %f\n", hbuf[0], hbuf[1]);
return 0;
}
Compiling and running these in CUDA 5 on a 64 bit linux system with a Kepler GPU produces the following:
$ nvcc -arch=sm_30 -o shared shared.cu shared_dev.cu
$ ./shared
GPUassert: invalid device symbol shared.cu 23
$ nvcc -arch=sm_30 -rdc=true -o shared shared.cu shared_dev.cu
$ ./shared
1.234000 5.678900
You can see that in the first compilation, without relocatable GPU code generation, the symbol isn't found. In the second case, with relocatable GPU code generation, it is found, and the elf header in the object file looks just as you would expect:
$ nvcc -arch=sm_30 -rdc=true -c shared_dev.cu
$ cuobjdump -symbols shared_dev.o
Fatbin elf code:
================
arch = sm_30
code version = [1,6]
producer = cuda
host = linux
compile_size = 64bit
identifier = shared_dev.cu
symbols:
STT_SECTION STB_LOCAL .text._Z6kernelPf
STT_SECTION STB_LOCAL .nv.constant3
STT_SECTION STB_LOCAL .nv.constant0._Z6kernelPf
STT_CUDA_OBJECT STB_LOCAL _param
STT_SECTION STB_LOCAL .nv.callgraph
STT_FUNC STB_GLOBAL _Z6kernelPf
STT_CUDA_OBJECT STB_GLOBAL gdDomainOrigin
Fatbin ptx code:
================
arch = sm_30
code version = [3,1]
producer = cuda
host = linux
compile_size = 64bit
compressed
identifier = shared_dev.cu
ptxasOptions = --compile-only
Perhaps you could try my code and compilation/diagnostic steps and see what happens with your Windows toolchain.

My openGL shaders will not link outside of eclipse?

So I am trying to build a simple spirograph generator for school and everything went fine while in eclipse CDT for windows 7. My program assigns a default shader to each spirograph generated (5 max). There are also 3 other shader programs the user can assign by choice to any spirograph. Inside eclipse it works exactly as it should, but when being ran outside eclipse the shaders fail to link. The program uses GLUT and GLEW and I have included the necessary .dll's in the executable's directory. I've been trying to fix this for a good 4 hours and have no idea what would cause a failure to link outside of eclipse that wouldn't fail all the time.
Im not going to include all of the shaders but here are the first 2 that fail to link and cause the application to terminate
#version 330
layout (location = 0) in vec4 vPosition;
uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;
out vec4 color;
void main()
{
gl_Position = proj * view * model * vPosition;
color = vec4(
(4 - vPosition.z) * (4 - vPosition.z) / 16.0,
(2.0 - abs( 2.0 - vPosition.z )) / 2.0,
vPosition.z * vPosition.z / 16.0,
1.0
);
}
and fragment shader
#version 330
in vec4 color;
void main()
{
gl_FragColor = color;
}
and printlog
Vertex shader was successfully compiled to run on hardware.
Fragment shader was successfully compiled to run on hardware.
Fragment shader(s) failed to link, vertex shader(s) failed to link.
ERROR: error(#280) Not all shaders have valid object code
ERROR: error(#280) Not all shaders have valid object code
The InitShader() function that I use to compile and link the shaders has worked for the applications I have done in the past. The only thing I am doing different is I am using it to produce a few different shader programs and assign them to programs[] rather than just compile 1 and run it for the whole application.
program[0] = InitShader("shaders/vshader.glsl", "shaders/fshader.glsl");
program[1] = InitShader("shaders/vshader2.glsl", "shaders/fshader.glsl");
program[2] = InitShader("shaders/vshader3.glsl", "shaders/fshader.glsl");
program[3] = InitShader("shaders/vshaderw.glsl", "shaders/fshader.glsl");
But either way, here is the code for InitShader().
GLuint InitShader(const char* source, GLenum type)
{
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, (const GLchar**) &source, NULL );
glCompileShader(shader);
printLog( shader );
return shader;
}
GLuint InitShader(const char* vfile, const char *ffile) {
GLuint program = glCreateProgram();
GLuint shader;
// stringify and attach vshader
std::ifstream vertstream(vfile);
std::string vert((std::istreambuf_iterator<char>(vertstream)), std::istreambuf_iterator<char>());
shader = InitShader(vert.c_str(), GL_VERTEX_SHADER);
glAttachShader( program, shader );
// stringify and attach fshader
std::ifstream fragstream(ffile);
std::string frag((std::istreambuf_iterator<char>(fragstream)), std::istreambuf_iterator<char>());
shader = InitShader(frag.c_str(), GL_FRAGMENT_SHADER);
glAttachShader( program, shader );
// link program
glLinkProgram(program);
printLog(program);
// link and error check
GLint linked;
glGetProgramiv( program, GL_LINK_STATUS, &linked );
if ( !linked ) {
fprintf(stderr, "Shaders failed to link!\n");
exit( EXIT_FAILURE );
}
// use program object
glUseProgram(program);
return program;
}
Its 4am here so my grey cells are about spent haha. And fyi its not really homework help, the executable is not required to run outside of eclipse for the class, I just want to know how to create stand alone programs for myself.
The cause of your problem lies here:
program[0] = InitShader("shaders/vshader.glsl", "shaders/fshader.glsl");
The paths to the shader source files are relative. Chances are, that Eclipse runs your program from a different working directory (probably your project root) than what's the working directory when executing the program directly.
Solution: Either
make sure the working directory on program startup matches the relative paths used internally (very unreliable)
use absolute paths within the program (very unflexible)
or, what I suggest
determine the location of the shader files at runtime (command line option, location of the executable binary, etc) and adjust the paths accordingly at runtime.

Resources