Beispiel #1
0
	void CQuad::draw() {

		CHECK_GLERROR("");
		glBegin(GL_QUADS);
			glMultiTexCoord2fARB(GL_TEXTURE0_ARB,u0, v0); glVertex2f(x0, y0);
			glMultiTexCoord2fARB(GL_TEXTURE0_ARB,u0, v1); glVertex2f(x0, y1);
			glMultiTexCoord2fARB(GL_TEXTURE0_ARB,u1, v1); glVertex2f(x1, y1);
			glMultiTexCoord2fARB(GL_TEXTURE0_ARB,u1, v0); glVertex2f(x1, y0);

		glEnd();
		CHECK_GLERROR("");
	}
Beispiel #2
0
// Initialize the runtime, in particular all fields in halide_opengl_state.
EXPORT int halide_opengl_init(void *user_context) {
    if (ST.initialized) return 0;

    // Make a context if there isn't one
    if (halide_opengl_create_context(user_context)) {
        halide_printf(user_context, "Failed to make opengl context\n");
        return 1;
    }

    // Initialize pointers to OpenGL functions.
#define GLFUNC(TYPE, VAR)                                               \
    ST.VAR = (TYPE)halide_opengl_get_proc_address(user_context, "gl" #VAR); \
    if (!ST.VAR) {                                                      \
        halide_printf(user_context, "Could not load function pointer for %s\n", "gl" #VAR); \
        return 1;                                                         \
    }
    USED_GL_FUNCTIONS;
#undef GLFUNC

    ST.kernels = NULL;
    ST.textures = NULL;

    // Initialize all OpenGL objects that are shared between kernels.
    ST.GenFramebuffers(1, &ST.framebuffer_id);
    CHECK_GLERROR(1);

    ST.vertex_shader_id = halide_opengl_make_shader(user_context,
        GL_VERTEX_SHADER, vertex_shader_src, NULL);
    if (ST.vertex_shader_id == 0) {
	halide_error(user_context, "Failed to create vertex shader");
	return 1;
    }

    GLuint buf;
    ST.GenBuffers(1, &buf);
    ST.BindBuffer(GL_ARRAY_BUFFER, buf);
    ST.BufferData(GL_ARRAY_BUFFER,
                  sizeof(square_vertices), square_vertices, GL_STATIC_DRAW);
    CHECK_GLERROR(1);
    ST.vertex_buffer = buf;

    ST.GenBuffers(1, &buf);
    ST.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
    ST.BufferData(GL_ELEMENT_ARRAY_BUFFER,
                  sizeof(square_indices), square_indices, GL_STATIC_DRAW);
    CHECK_GLERROR(1);
    ST.element_buffer = buf;

    ST.initialized = true;
    return 0;
}
Beispiel #3
0
	inline bool CShader::set<float>( const std::string & pName, const float & v) const
	{
		const GLint iP= getParamLocation(pName);
		if (iP < 0) return false;
		glUniform1f(iP, static_cast<GLfloat>(v));CHECK_GLERROR("");
		return true;
	}
Beispiel #4
0
	inline bool CShader::set<float>( const std::string & pName, const float & v0, const float & v1 ) const
	{
		const GLint iP= getParamLocation(pName);
		if (iP < 0) return false;
		glUniform2f(iP, v0, v1);CHECK_GLERROR("");
		return true;
	}
Beispiel #5
0
	inline bool CShader::setArray<CVector4i>( const std::string & pName, int count, const CVector4i * v) const
	{
		const GLint iP= getParamLocation(pName);
		if (iP < 0) return false;
		glUniform4iv(iP, static_cast<const GLint>(count), (const GLint*)(v));CHECK_GLERROR("");
		return true;
	}
Beispiel #6
0
	inline bool CShader::set<int>( const std::string & pName, const int & v0, const int & v1, const int & v2, const int & v3 ) const
	{
		const GLint iP= getParamLocation(pName);
		if (iP < 0) return false;
		glUniform4i(iP, v0, v1, v2, v3);CHECK_GLERROR("");
		return true;
	}
Beispiel #7
0
// Delete all texture information associated with a buffer. The OpenGL texture
// itself is only deleted if it was actually allocated by Halide and not
// provided by the host application.
EXPORT int halide_opengl_dev_free(void *user_context, buffer_t *buf) {
    CHECK_INITIALIZED(1);

    GLuint tex = get_texture_id(buf);
    if (tex == 0) {
        return 0;
    }

    // Look up corresponding HalideOpenGLTexture and unlink it from the list.
    HalideOpenGLTexture **ptr = &ST.textures;
    HalideOpenGLTexture *texinfo = *ptr;
    for (; texinfo != NULL; ptr = &texinfo->next, texinfo = *ptr) {
        if (texinfo->id == tex) {
            *ptr = texinfo->next;
            texinfo->next = NULL;
            break;
        }
    }
    if (!texinfo) {
        halide_error(user_context, "Internal error: texture not found");
        return 1;
    }

    // Delete texture if it was allocated by us.
    if (texinfo->halide_allocated) {
        ST.DeleteTextures(1, &tex);
        CHECK_GLERROR(1);
        buf->dev = 0;
    }

    free(texinfo);
    return 0;
}
Beispiel #8
0
void App::printInfo()
{
#define PRINT(x) { printf( "%s\t\"%s\"\n", #x, (char*)glGetString(x) ); }
    PRINT( GL_RENDERER );
    PRINT( GL_VERSION );
    PRINT( GL_VENDOR );
    PRINT( GL_SHADING_LANGUAGE_VERSION );
    //PRINT( GL_EXTENSIONS );
#undef PRINT

#define PRINT(x) { GLint i=0; glGetIntegerv(x,&i); printf( "%s\t%d\n", #x, i ); }
    PRINT( GL_DEPTH_BITS );
    PRINT( GL_STENCIL_BITS );
    //PRINT( GL_MAX_MODELVIEW_STACK_DEPTH );
    //PRINT( GL_MAX_PROJECTION_STACK_DEPTH );
    PRINT( GL_MAX_TEXTURE_SIZE );
#undef PRINT

    CHECK_GLERROR( "App::printInfo" );

#define PRINT(x) printf( "%s\t%d\n", #x, static_cast<int>(x) );
    //PRINT( sizeof(Viewer) );
    //PRINT( sizeof(Camera) );
#undef PRINT
}
Beispiel #9
0
void App::draw()
{
    if( _needUpdate )  update();

    setTime( getElapsedTime() );                // [seconds]
    _scene->animate( *this, _config );

    _viewer->frame( *_scene );
    CHECK_GLERROR( "App::draw" );

    updateStats();
}
Beispiel #10
0
bool App::create( int argc, char** argv )
{
    const char* configFilename = APP_NAME "_config.txt";

    switch( argc )
    {
        case 1:
            // use default configFilename
            break;

        case 2:
            configFilename = argv[1];
            break;

        default:        // print usage
            printf( "\nusage: %s [configFilename]\n\n", argv[0] );
            return false;
    }

    char cwd[512];
    if( getcwd( cwd, sizeof(cwd)-1 ) == NULL )  cwd[0] = '\0';

    printf( "CWD\t\"%s\"\n", cwd );
    printf( "configFilename\t\"%s\"\n", configFilename );

    _config.create( configFilename );
    registerLuaFunctions();

    if( ! _config.loadFile() )  return false;

    printf( "instanceName\t\"%s\"\n", _instanceName.c_str() );

    if( ! createGlSurface() )  return false;

    // now an OpenGL context exists

    _viewer = Viewer::factory( Viewer::getType( _config ) );
    _scene = Scene::factory( Scene::getType( _config ) );

    CHECK_GLERROR( "App::create" );

    printInfo();
    printf( "\n" );

    resetStats();

    return true;
}
Beispiel #11
0
// Release all data allocated by the runtime.
//
// The OpenGL context itself is generally managed by the host application, so
// we leave it untouched.
EXPORT void halide_opengl_release(void *user_context) {
    CHECK_INITIALIZED();
    ST.DeleteShader(ST.vertex_shader_id);
    ST.DeleteFramebuffers(1, &ST.framebuffer_id);

    HalideOpenGLKernel *cur = ST.kernels;
    while (cur) {
        HalideOpenGLKernel *next = cur->next;
        halide_opengl_delete_kernel(user_context, cur);
        cur = next;
    }

    // Delete all textures that were allocated by us.
    HalideOpenGLTexture *tex = ST.textures;
    int freed_textures = 0;
    while (tex) {
        HalideOpenGLTexture *next = tex->next;
        if (tex->halide_allocated) {
            ST.DeleteTextures(1, &tex->id);
            CHECK_GLERROR();
            freed_textures++;
        }
        free(tex);
        tex = next;
    }
#ifdef DEBUG
    if (freed_textures > 0) {
        halide_printf(user_context,
            "halide_opengl_release: deleted %d dangling texture(s).\n",
            freed_textures);
    }
#endif

    ST.DeleteBuffers(1, &ST.vertex_buffer);
    ST.DeleteBuffers(1, &ST.element_buffer);

    ST.vertex_shader_id = 0;
    ST.framebuffer_id = 0;
    ST.vertex_buffer = 0;
    ST.element_buffer = 0;
    ST.kernels = NULL;
    ST.textures = NULL;
    ST.initialized = false;
}
Beispiel #12
0
	inline bool CShader::set<CVector2i>( const std::string & pName, const CVector2i & v) const
	{
		return set<int>(pName, v[0], v[1]); CHECK_GLERROR("");
	}
Beispiel #13
0
	inline bool CShader::set<CVector3f>( const std::string & pName, const CVector3f & v) const
	{
		return set<float>(pName, v[0], v[1], v[2]); CHECK_GLERROR("");
	}
Beispiel #14
0
EXPORT int halide_opengl_dev_run(
    void *user_context,
    void *state_ptr,
    const char *entry_name,
    int blocksX, int blocksY, int blocksZ,
    int threadsX, int threadsY, int threadsZ,
    int shared_mem_bytes,
    size_t arg_sizes[],
    void *args[])
{
    CHECK_INITIALIZED(1);

    HalideOpenGLKernel *kernel = halide_opengl_find_kernel(entry_name);
    if (!kernel) {
        halide_printf(user_context, "Could not find a kernel named '%s'\n",
                      entry_name);
        return 1;
    }

    ST.UseProgram(kernel->program_id);

    HalideOpenGLArgument *kernel_arg;

    // Copy input arguments to corresponding GLSL uniforms.
    GLint num_active_textures = 0;
    kernel_arg = kernel->arguments;
    for (int i = 0; args[i]; i++, kernel_arg = kernel_arg->next) {
        if (!kernel_arg) {
            halide_printf(user_context, "Argument %d: size=%d value=%p\n", i,
                          arg_sizes[i], args[i]);
            halide_error(user_context,
                         "Too many arguments passed to halide_opengl_dev_run");
            return 1;
        }

        if (kernel_arg->kind == ARGKIND_OUTBUF) {
            // Outbuf textures are handled explicitly below
            continue;
        } else if (kernel_arg->kind == ARGKIND_INBUF) {
            GLint loc =
                ST.GetUniformLocation(kernel->program_id, kernel_arg->name);
            if (loc == -1) {
                halide_error(user_context, "No sampler defined for input texture.\n");
                return 1;
            }
            GLuint tex = *((GLuint *)args[i]);
            ST.ActiveTexture(GL_TEXTURE0 + num_active_textures);
            ST.BindTexture(GL_TEXTURE_2D, tex);
            ST.Uniform1iv(loc, 1, &num_active_textures);
            num_active_textures++;
            // TODO: check maximum number of active textures
        } else if (kernel_arg->kind == ARGKIND_VAR) {
            GLint loc =
                ST.GetUniformLocation(kernel->program_id, kernel_arg->name);
            if (loc == -1) {
                // Argument was probably optimized away by GLSL compiler.
#ifdef DEBUG
                halide_printf(user_context, "Ignoring argument '%s'\n",
                              kernel_arg->name);
#endif
                continue;
            }

            switch (kernel_arg->type) {
            case ARGTYPE_INT:
#ifdef DEBUG
                halide_printf(user_context, "Int argument %d (%s): %d\n", i,
                              kernel_arg->name, *((int *)args[i]));
#endif
                ST.Uniform1iv(loc, 1, (GLint *)args[i]);
                break;
            case ARGTYPE_FLOAT: {
#ifdef DEBUG
                halide_printf(user_context, "Float argument %d (%s): %g\n", i,
                              kernel_arg->name, *((float *)args[i]));
#endif
                ST.Uniform1fv(loc, 1, (GLfloat *)args[i]);
                break;
            }
            case ARGTYPE_NONE:
            default:
                halide_error(user_context, "Unknown kernel argument type");
                return 1;
            }
        }
    }
    if (kernel_arg) {
        halide_error(user_context, "Too few arguments passed to halide_opengl_dev_run");
        return 1;
    }

    // Prepare framebuffer for rendering to output textures.
    GLint output_min[2] = { 0, 0 };
    GLint output_extent[2] = { 0, 0 };
    ST.BindFramebuffer(GL_FRAMEBUFFER, ST.framebuffer_id);
    ST.Disable(GL_CULL_FACE);
    ST.Disable(GL_DEPTH_TEST);

    GLint num_output_textures = 0;
    kernel_arg = kernel->arguments;
    for (int i = 0; args[i]; i++, kernel_arg = kernel_arg->next) {
        if (kernel_arg->kind != ARGKIND_OUTBUF) continue;

        // TODO: GL_MAX_COLOR_ATTACHMENTS
        if (num_output_textures >= 1) {
            halide_error(user_context,
			 "OpenGL ES 2.0 only supports one single output texture");
	    return 1;
        }

        GLuint tex = *((GLuint*)args[i]);
#ifdef DEBUG
        halide_printf(user_context, "Output texture %d: %d\n", num_output_textures, tex);
#endif
        ST.FramebufferTexture2D(GL_FRAMEBUFFER,
                                GL_COLOR_ATTACHMENT0 + num_output_textures,
                                GL_TEXTURE_2D, tex, 0);
        CHECK_GLERROR(1);

        HalideOpenGLTexture *texinfo = halide_opengl_find_texture(tex);
	if (!texinfo) {
	    halide_error(user_context, "Undefined output texture");
	    return 1;
	}
        output_min[0] = texinfo->min[0];
        output_min[1] = texinfo->min[1];
        output_extent[0] = texinfo->extent[0];
        output_extent[1] = texinfo->extent[1];
        num_output_textures++;
    }
    // TODO: GL_MAX_DRAW_BUFFERS
    if (num_output_textures == 0) {
        halide_printf(user_context, "Warning: kernel '%s' has no output\n",
                      kernel->name);
        // TODO: cleanup
        return 1;
    } else {
        GLenum *draw_buffers = (GLenum*)
            malloc(num_output_textures * sizeof(GLenum));
        for (int i=0; i<num_output_textures; i++)
            draw_buffers[i] = GL_COLOR_ATTACHMENT0 + i;
        ST.DrawBuffers(num_output_textures, draw_buffers);
        CHECK_GLERROR(1);
        free(draw_buffers);
    }

    // Check that framebuffer is set up correctly
    GLenum status = ST.CheckFramebufferStatus(GL_FRAMEBUFFER);
    CHECK_GLERROR(1);
    if (status != GL_FRAMEBUFFER_COMPLETE) {
        halide_printf(user_context, "Setting up GL framebuffer %d failed (%x)\n",
                      ST.framebuffer_id, status);
        // TODO: cleanup
        return 1;
    }

    // Set vertex attributes
    GLint loc = ST.GetUniformLocation(kernel->program_id, "output_extent");
    ST.Uniform2iv(loc, 1, output_extent);
    CHECK_GLERROR(1);
    loc = ST.GetUniformLocation(kernel->program_id, "output_min");
    ST.Uniform2iv(loc, 1, output_min);
    CHECK_GLERROR(1);

    // Setup viewport
    ST.Viewport(0, 0, output_extent[0], output_extent[1]);


    // Execute shader
    GLint position = ST.GetAttribLocation(kernel->program_id,
                                          "position");
    ST.BindBuffer(GL_ARRAY_BUFFER, ST.vertex_buffer);
    ST.VertexAttribPointer(position,
                           2,
                           GL_FLOAT,
                           GL_FALSE,    // normalized?
                           sizeof(GLfloat)*2,
                           NULL);
    ST.EnableVertexAttribArray(position);
    ST.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, ST.element_buffer);
    ST.DrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, NULL);
    CHECK_GLERROR(1);
    ST.DisableVertexAttribArray(position);

    // Cleanup
    for (int i = 0; i < num_active_textures; i++) {
        ST.ActiveTexture(GL_TEXTURE0 + i);
        ST.BindTexture(GL_TEXTURE_2D, 0);
    }
    ST.BindFramebuffer(GL_FRAMEBUFFER, 0);
    return 0;
}
Beispiel #15
0
// Copy image data from texture back to host memory.
EXPORT int halide_opengl_copy_to_host(void *user_context, buffer_t *buf) {
    CHECK_INITIALIZED(1);
    if (!buf->dev_dirty) {
        return 0;
    }

    if (!buf->host || !buf->dev) {
#ifdef DEBUG
        print_buffer(user_context, buf);
#endif
        halide_error(user_context, "Invalid copy_to_host operation");
        return 1;
    }

    GLuint tex = get_texture_id(buf);
#ifdef DEBUG
    halide_printf(user_context, "halide_copy_to_host: %d\n", tex);
#endif

    GLint format;
    GLint type;
    if (!get_texture_format(user_context, buf, &format, &type)) {
        halide_error(user_context, "Invalid texture format\n");
        return 1;
    }
    GLint width = buf->extent[0];
    GLint height = buf->extent[1];

    ST.BindTexture(GL_TEXTURE_2D, tex);
    CHECK_GLERROR(1);
    bool is_interleaved =
        (buf->stride[2] == 1 && buf->stride[0] == buf->extent[2]);
    if (is_interleaved) {
        // TODO: GL_UNPACK_ROW_LENGTH
        ST.PixelStorei(GL_PACK_ROW_LENGTH, buf->extent[1]);
        ST.PixelStorei(GL_PACK_ALIGNMENT, 1);
        ST.GetTexImage(GL_TEXTURE_2D, 0, format, type, buf->host);
        CHECK_GLERROR(1);
    } else {
        #ifdef DEBUG
        halide_printf(user_context, "Warning: In copy_to_host, host buffer is not interleaved. Doing slow deinterleave.\n");
        #endif

        size_t size = width * height * buf->extent[2] * buf->elem_size;
        uint8_t *tmp = (uint8_t*)halide_malloc(user_context, size);

        ST.PixelStorei(GL_PACK_ALIGNMENT, 1);
        ST.GetTexImage(GL_TEXTURE_2D, 0, format, type, tmp);
        CHECK_GLERROR(1);

        switch (type) {
        case GL_UNSIGNED_BYTE:
            interleaved_to_halide<uint8_t>(buf, (uint8_t*)tmp, width, height, buf->extent[2]);
            break;
        case GL_UNSIGNED_SHORT:
            interleaved_to_halide<uint16_t>(buf, (uint16_t*)tmp, width, height, buf->extent[2]);
            break;
        case GL_FLOAT:
            interleaved_to_halide<float>(buf, (float*)tmp, width, height, buf->extent[2]);
            break;
        }

        halide_free(user_context, tmp);
    }

    ST.BindTexture(GL_TEXTURE_2D, 0);
    buf->dev_dirty = false;
    return 0;
}
Beispiel #16
0
// Allocate a new texture matching the dimension and color format of the
// specified buffer.
EXPORT int halide_opengl_dev_malloc(void *user_context, buffer_t *buf) {
    if (int error = halide_opengl_init(user_context))
        return error;

    if (!buf) {
        halide_error(user_context, "Invalid buffer");
        return 1;
    }

    // If the texture was already created by the host application, check that
    // it has the correct format. Otherwise, allocate and set up an
    // appropriate texture.
    GLuint tex = get_texture_id(buf);
    bool halide_allocated = false;
    GLint format = 0;
    GLint width, height;
    if (tex != 0) {
        ST.BindTexture(GL_TEXTURE_2D, tex);
        ST.GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
        ST.GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
        CHECK_GLERROR(1);
        if (width < buf->extent[0] || height < buf->extent[1]) {
#ifdef DEBUG
            halide_printf(user_context, "Texture size: %dx%d, buffer size: %dx%d\n",
                          width, height, buf->extent[0], buf->extent[1]);
#endif
            halide_error(user_context, "Existing texture is smaller than buffer");
            return 1;
        }
    } else {
        if (buf->extent[3] > 1) {
            halide_error(user_context, "3D textures are not supported");
            return 1;
        }

        // Generate texture ID
        ST.GenTextures(1, &tex);
        CHECK_GLERROR(1);

        // Set parameters for this texture: no interpolation and clamp to edges.
        ST.BindTexture(GL_TEXTURE_2D, tex);
        ST.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        ST.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        ST.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        ST.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        CHECK_GLERROR(1);

        // Create empty texture here and fill it with glTexSubImage2D later.
        GLint type = GL_UNSIGNED_BYTE;
        if (!get_texture_format(user_context, buf, &format, &type)) {
            halide_error(user_context, "Invalid texture format\n");
            return 1;
        }
        width = buf->extent[0];
        height = buf->extent[1];

        ST.TexImage2D(GL_TEXTURE_2D, 0, format,
                      width, height, 0, format, type, NULL);
        CHECK_GLERROR(1);

        buf->dev = tex;
        halide_allocated = true;
#ifdef DEBUG
        halide_printf(user_context, "Allocated texture %d of size %d x %d\n", tex, width, height);
#endif

        ST.BindTexture(GL_TEXTURE_2D, 0);
    }

    // Record main information about texture and remember it for later. In
    // halide_opengl_dev_run we are only given the texture ID and not the full
    // buffer_t, so we copy the interesting information here.
    HalideOpenGLTexture *texinfo = (HalideOpenGLTexture*)
        malloc(sizeof(HalideOpenGLTexture));
    texinfo->id = tex;
    for (int i=0; i<3; i++) {
        texinfo->min[i] = buf->min[i];
        texinfo->extent[i] = buf->extent[i];
    }
    texinfo->format = format;
    texinfo->halide_allocated = halide_allocated;

    texinfo->next = ST.textures;
    ST.textures = texinfo;
    return 0;
}