Sgx Opengl Es 2.0 Application Development Recommendations


I've been speaking to someone in TI about this and they have suggested using Pixmaps. Although not available in the current release it should be in the next release. You can allocate memory through CMEM (you need to get both the physical and virtual address's) this means that the SGX will access the texture directly rather then having to do an upload. The only issue is that this feature is available in the NWS (No Window System) EGL drivers :huh: .

I agree with Exophase that the "best" (ease of implementation, low power, etc) method is to use one of the HW planes in the display controller. However, the geek in me thinks a rotating cube with different emulators running at the same time would be cool to see :D
 
Hey, thanks for the info. Looks like it'll be a good feature, windows be damned. Will you be able to access renderbuffers (framebuffer, depth/stencil if output) directly this way too? That'd be great.
 
linuxhacker said:
I've been speaking to someone in TI about this and they have suggested using Pixmaps. Although not available in the current release it should be in the next release.
strange. i thought pixmaps were already in.
 
Last edited by a moderator:
Sorry to grave dig, but i feel this is important.

Apparently, There's a new extension for the PowerVR driver, to enable fast texture uploads. Its called "GL_IMG_texture_stream", you can find out more about it here: http://imgtec.net/forum/forum_posts.asp?TID=475 .

It seems to rely on a new kernel module and directly loading data into the driver, maybe once its more mature they will make it easier to accomplish. It may not be fully functional in the TI Driver, but I don't think we'll have to worry about this in the future. Here's some code from TI's GLESLAYER:

[codebox]
#include <sys/mman.h> // mmap()
#if defined __linux__
#define LINUX //needed for imgdefs
#endif
#include <img_types.h>
#include "bc_cat.h"
//#include <glext.h>
#include <fcntl.h>
#include "sys/ioctl.h"
#include <unistd.h>

#define BC_CAT_DRV "/dev/bc_cat"
#define MAX_BUFFERS 1

char *buf_paddr[MAX_BUFFERS];
char *buf_vaddr[MAX_BUFFERS] = { (char *) MAP_FAILED };

#define GL_TEXTURE_STREAM_IMG 0x8C0D
#define GL_TEXTURE_NUM_STREAM_DEVICES_IMG 0x8C0E
#define GL_TEXTURE_STREAM_DEVICE_WIDTH_IMG 0x8C0F
#define GL_TEXTURE_STREAM_DEVICE_HEIGHT_IMG 0x8EA0
#define GL_TEXTURE_STREAM_DEVICE_FORMAT_IMG 0x8EA1
#define GL_TEXTURE_STREAM_DEVICE_NUM_BUFFERS_IMG 0x8EA2

typedef void (GL_APIENTRYP PFNGLTEXBINDSTREAMIMGPROC) (GLint device, GLint deviceoffset);
typedef const GLubyte *(GL_APIENTRYP PFNGLGETTEXSTREAMDEVICENAMEIMGPROC) (GLenum target);
typedef void (GL_APIENTRYP PFNGLGETTEXSTREAMDEVICEATTRIBUTEIVIMGPROC) (GLenum target, GLenum pname, GLint *params);
PFNGLTEXBINDSTREAMIMGPROC myglTexBindStreamIMG = NULL;
PFNGLGETTEXSTREAMDEVICEATTRIBUTEIVIMGPROC myglGetTexStreamDeviceAttributeivIMG = NULL;
PFNGLGETTEXSTREAMDEVICENAMEIMGPROC myglGetTexStreamDeviceNameIMG = NULL;
int numBuffers, bufferWidth, bufferHeight, bufferFormat;
int bcfd = -1; //file descriptor
bc_buf_params_t bc_param;
BCIO_package ioctl_var;

void img_stream_gl_draw(int numObjects)
{
int startIndex = 0;

for(int vertical = 0;vertical < numObjects;vertical ++)
for(int horizontal = 0;horizontal < numObjects;horizontal ++)
{
//update texture here if needed
//memset(textureData);
glDrawArrays(GL_TRIANGLE_STRIP, startIndex, 4);
startIndex += 4;
}
}

int test8_init_texture_streaming()
{
const GLubyte *pszGLExtensions;
const GLubyte *pszStreamDeviceName;
int idx;


//setup driver now
if ((bcfd = open(BC_CAT_DRV, O_RDWR|O_NDELAY)) == -1) {
SGX_PERF_printf("Error opening bc driver - is bc_cat module inserted ?\n");
return 3;
}
bc_param.count = 1;
bc_param.width = inTextureWidth;
bc_param.height = inTextureHeight;
bc_param.pixel_fmt = PVRSRV_PIXEL_FORMAT_FOURCC_ORG_UYVY;
bc_param.type = BC_MEMORY_MMAP;
if (ioctl(bcfd, BCIOREQ_BUFFERS, &bc_param) != 0) {
SGX_PERF_printf("ERROR: BCIOREQ_BUFFERS failed\n");
return 4;
}
if (ioctl(bcfd, BCIOGET_BUFFERCOUNT, &ioctl_var) != 0) {
SGX_PERF_printf("Error ioctl BCIOGET_BUFFERCOUNT");
return 5;
}
if (ioctl_var.output == 0) {
SGX_PERF_printf("no buffers available from driver \n");
return 6;
}

/* Retrieve GL extension string */
pszGLExtensions = glGetString(GL_EXTENSIONS);

if (!pszGLExtensions || !strstr((char *)pszGLExtensions, "GL_IMG_texture_stream2"))
{
SGX_PERF_printf("TEST8: GL_IMG_texture_stream unsupported\n");
return 1;
}

myglTexBindStreamIMG = (PFNGLTEXBINDSTREAMIMGPROC)eglGetProcAddress("glTexBindStreamIMG");
myglGetTexStreamDeviceAttributeivIMG =
(PFNGLGETTEXSTREAMDEVICEATTRIBUTEIVIMGPROC)eglGetProcAddress("glGetTexStreamDeviceAttributeivIMG");
myglGetTexStreamDeviceNameIMG =
(PFNGLGETTEXSTREAMDEVICENAMEIMGPROC)eglGetProcAddress("glGetTexStreamDeviceNameIMG");

if(!myglTexBindStreamIMG || !myglGetTexStreamDeviceAttributeivIMG || !myglGetTexStreamDeviceNameIMG)
{
SGX_PERF_printf("TEST8: GL_IMG_texture_stream unsupported\n");
return 2;
}

pszStreamDeviceName = myglGetTexStreamDeviceNameIMG(0);
myglGetTexStreamDeviceAttributeivIMG(0, GL_TEXTURE_STREAM_DEVICE_NUM_BUFFERS_IMG, &numBuffers);
myglGetTexStreamDeviceAttributeivIMG(0, GL_TEXTURE_STREAM_DEVICE_WIDTH_IMG, &bufferWidth);
myglGetTexStreamDeviceAttributeivIMG(0, GL_TEXTURE_STREAM_DEVICE_HEIGHT_IMG, &bufferHeight);
myglGetTexStreamDeviceAttributeivIMG(0, GL_TEXTURE_STREAM_DEVICE_FORMAT_IMG, &bufferFormat);

glTexParameteri(GL_TEXTURE_STREAM_IMG, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_STREAM_IMG, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

SGX_PERF_printf("\nStream Device %s: numBuffers = %d, width = %d, height = %d, format = %x\n",
pszStreamDeviceName, numBuffers, bufferWidth, bufferHeight, bufferFormat);

for (idx = 0; idx < MAX_BUFFERS; idx++) {
ioctl_var.input = idx;

if (ioctl(bcfd, BCIOGET_BUFFERPHYADDR, &ioctl_var) != 0) {
SGX_PERF_printf("BCIOGET_BUFFERADDR: failed\n");
return 7;
}
SGX_PERF_printf("phyaddr[%d]: 0x%x\n", idx, ioctl_var.output);

buf_paddr[idx] = (char*)ioctl_var.output;
buf_vaddr[idx] = (char *)mmap(NULL, inTextureWidth*inTextureHeight*2,
PROT_READ | PROT_WRITE, MAP_SHARED,
bcfd, (long)buf_paddr[idx]);

if (buf_vaddr[idx] == MAP_FAILED) {
SGX_PERF_printf("Error: failed mmap\n");
return 8;
}

if((inTextureWidth == 160) && (inTextureHeight == 128)) //only for 256x256
memcpy(buf_vaddr[idx], yukio_160x128yuv, 160*128*2);
else
{
for (int iii= 0; iii < inTextureHeight; iii++)
memset(((char *) buf_vaddr[idx] + (inTextureWidth*iii*2)) , 0xa8, inTextureWidth*2);
}
}

return 0;
}
void test8_deinit_texture_streaming()
{
int idx;
for (idx = 0; idx < MAX_BUFFERS; idx++) {
if (buf_vaddr[idx] != MAP_FAILED)
munmap(buf_vaddr[idx], inTextureWidth*inTextureHeight*2);
}
if (bcfd > -1)
close(bcfd);
}

/* Texture streaming extension - nonEGLImage */
void test8()
{
timeval startTime, endTime;
unsigned long diffTime2;
int i;
int bufferIndex = 0;
int err;
static GLfloat texcoord_img[] =
{0,0, 1,0, 0,1, 1,1};
float angle = 0;

//initialise texture streaming
err = test8_init_texture_streaming();
if(err)
{
SGX_PERF_ERR_printf("TEST8: Init failed with err = %d\n", err);
goto deinit;
}
//initialise gl vertices
float *pVertexArray, *pTexCoordArray;

common_init_gl_vertices(inNumberOfObjectsPerSide, &pVertexArray);
common_init_gl_texcoords(inNumberOfObjectsPerSide, &pTexCoordArray);

//override the texturecoords for this extension only
glDisableVertexAttribArray(TEXCOORD_ARRAY);
glEnableVertexAttribArray(TEXCOORD_ARRAY);
glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, 0, (const void*)texcoord_img);
//override the texture binding
//glEnable(GL_TEXTURE_STREAM_IMG);

gettimeofday(&startTime, NULL);
SGX_PERF_printf("TEST8: Entering DrawArrays loop\n");
for(i = 0;(i < NUM_TEST_ITERATION)&&(!quitSignal);i ++)
{
glClear(GL_COLOR_BUFFER_BIT);
if(inRotationEnabled)
{
calculate_rotation_z(mat_z, 0);
calculate_rotation_y(mat_y, angle);
calculate_rotation_x(mat_x, 0);
matrix_mult(mat_z, mat_y, mat_temp);
matrix_mult(mat_temp, mat_x, mat_final);
glUniformMatrix4fv( matrixLocation, 1, GL_FALSE, mat_final);
angle += ANGLE_DELTA;
}

myglTexBindStreamIMG(0, bufferIndex);
img_stream_gl_draw(inNumberOfObjectsPerSide);
common_eglswapbuffers (eglDisplay, eglSurface);
}
err = glGetError();
if(err)
SGX_PERF_ERR_printf("Error in glTexBindStream loop err = %d", err);
SGX_PERF_printf("Exiting DrawArrays loop\n");
gettimeofday(&endTime, NULL);
diffTime2 = (tv_diff(&startTime, &endTime))/NUM_TEST_ITERATION;
common_log(8, diffTime2);
deinit:
test8_deinit_texture_streaming();
common_deinit_gl_vertices(pVertexArray);
}
#endif


[/codebox]
 
Nice!

Now I hope they just eventually add extensions for accessing depth/stencil and depth textures and the like.
 
Back
Top