clray

diff src/ocl.cc @ 41:057b8575a1c1

- changed the membuffer into an imagebuffer for the non-GL/CL-interop case - fixed the segfault
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 27 Aug 2010 20:39:55 +0100
parents 1bcbb53b3505
children 1169f3d04135
line diff
     1.1 --- a/src/ocl.cc	Fri Aug 27 19:00:14 2010 +0100
     1.2 +++ b/src/ocl.cc	Fri Aug 27 20:39:55 2010 +0100
     1.3 @@ -122,17 +122,63 @@
     1.4  	}
     1.5  
     1.6  	CLMemBuffer *mbuf = new CLMemBuffer;
     1.7 +	mbuf->type = MEM_BUFFER;
     1.8  	mbuf->mem = mem;
     1.9  	mbuf->size = sz;
    1.10 +	mbuf->xsz = mbuf->ysz = 0;
    1.11  	mbuf->ptr = 0;
    1.12  	mbuf->tex = 0;
    1.13  	return mbuf;
    1.14  }
    1.15  
    1.16 -CLMemBuffer *create_mem_buffer(int rdwr, unsigned int tex)
    1.17 +CLMemBuffer *create_image_buffer(int rdwr, int xsz, int ysz, const void *pixels)
    1.18  {
    1.19 -	int err;
    1.20 +	int err, pitch;
    1.21  	cl_mem mem;
    1.22 +	cl_mem_flags flags = rdwr | CL_MEM_ALLOC_HOST_PTR;
    1.23 +
    1.24 +	if(pixels) {
    1.25 +		flags |= CL_MEM_COPY_HOST_PTR;
    1.26 +		pitch = xsz * 4 * sizeof(float);
    1.27 +	} else {
    1.28 +		pitch = 0;
    1.29 +	}
    1.30 +
    1.31 +	cl_image_format fmt = {CL_RGBA, CL_FLOAT};
    1.32 +
    1.33 +	if(!(mem = clCreateImage2D(ctx, flags, &fmt, xsz, ysz, pitch, (void*)pixels, &err))) {
    1.34 +		fprintf(stderr, "failed to create %dx%d image: %s\n", xsz, ysz, clstrerror(err));
    1.35 +		return 0;
    1.36 +	}
    1.37 +
    1.38 +	CLMemBuffer *mbuf = new CLMemBuffer;
    1.39 +	mbuf->type = IMAGE_BUFFER;
    1.40 +	mbuf->mem = mem;
    1.41 +	mbuf->size = ysz * pitch;
    1.42 +	mbuf->xsz = xsz;
    1.43 +	mbuf->ysz = ysz;
    1.44 +	mbuf->ptr = 0;
    1.45 +	mbuf->tex = 0;
    1.46 +	return mbuf;
    1.47 +}
    1.48 +
    1.49 +CLMemBuffer *create_image_buffer(int rdwr, unsigned int tex)
    1.50 +{
    1.51 +	int err, xsz, ysz;
    1.52 +	cl_mem mem;
    1.53 +
    1.54 +	glGetError();	// clear previous OpenGL errors
    1.55 +
    1.56 +	glPushAttrib(GL_TEXTURE_BIT);
    1.57 +	glBindTexture(GL_TEXTURE_2D, tex);
    1.58 +	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &xsz);
    1.59 +	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &ysz);
    1.60 +	glPopAttrib();
    1.61 +
    1.62 +	if(glGetError()) {
    1.63 +		fprintf(stderr, "create_image_buffer: GL error while retreiving texture parameters for texture %u\n", tex);
    1.64 +		return 0;
    1.65 +	}
    1.66  
    1.67  	if(!(mem = clCreateFromGLTexture2D(ctx, rdwr, GL_TEXTURE_2D, 0, tex, &err))) {
    1.68  		fprintf(stderr, "failed to create memory buffer from GL texture %u: %s\n", tex, clstrerror(err));
    1.69 @@ -140,10 +186,14 @@
    1.70  	}
    1.71  
    1.72  	CLMemBuffer *mbuf = new CLMemBuffer;
    1.73 +	mbuf->type = IMAGE_BUFFER;
    1.74  	mbuf->mem = mem;
    1.75  	mbuf->size = 0;
    1.76 +	mbuf->xsz = xsz;
    1.77 +	mbuf->ysz = ysz;
    1.78  	mbuf->ptr = 0;
    1.79  	mbuf->tex = tex;
    1.80 +
    1.81  	return mbuf;
    1.82  }
    1.83  
    1.84 @@ -166,10 +216,27 @@
    1.85  #endif
    1.86  
    1.87  	int err;
    1.88 -	mbuf->ptr = clEnqueueMapBuffer(cmdq, mbuf->mem, 1, rdwr, 0, mbuf->size, 0, 0, ev, &err);
    1.89 -	if(!mbuf->ptr) {
    1.90 -		fprintf(stderr, "failed to map buffer: %s\n", clstrerror(err));
    1.91 -		return 0;
    1.92 +
    1.93 +	if(mbuf->type == MEM_BUFFER) {
    1.94 +		mbuf->ptr = clEnqueueMapBuffer(cmdq, mbuf->mem, 1, rdwr, 0, mbuf->size, 0, 0, ev, &err);
    1.95 +		if(!mbuf->ptr) {
    1.96 +			fprintf(stderr, "failed to map buffer: %s\n", clstrerror(err));
    1.97 +			return 0;
    1.98 +		}
    1.99 +	} else {
   1.100 +		assert(mbuf->type == IMAGE_BUFFER);
   1.101 +
   1.102 +		size_t orig[] = {0, 0, 0};
   1.103 +		size_t rgn[] = {mbuf->xsz, mbuf->ysz, 1};
   1.104 +		size_t pitch;
   1.105 +
   1.106 +		mbuf->ptr = clEnqueueMapImage(cmdq, mbuf->mem, 1, rdwr, orig, rgn, &pitch, 0, 0, 0, ev, &err);
   1.107 +		if(!mbuf->ptr) {
   1.108 +			fprintf(stderr, "failed to map image: %s\n", clstrerror(err));
   1.109 +			return 0;
   1.110 +		}
   1.111 +
   1.112 +		assert(pitch == mbuf->xsz * 4 * sizeof(float));
   1.113  	}
   1.114  	return mbuf->ptr;
   1.115  }
   1.116 @@ -177,6 +244,7 @@
   1.117  void unmap_mem_buffer(CLMemBuffer *mbuf, cl_event *ev)
   1.118  {
   1.119  	if(!mbuf || !mbuf->ptr) return;
   1.120 +
   1.121  	clEnqueueUnmapMemObject(cmdq, mbuf->mem, mbuf->ptr, 0, 0, ev);
   1.122  	mbuf->ptr = 0;
   1.123  }
   1.124 @@ -351,12 +419,29 @@
   1.125  	return true;
   1.126  }
   1.127  
   1.128 +bool CLProgram::set_arg_image(int idx, int rdwr, int xsz, int ysz, const void *pix)
   1.129 +{
   1.130 +	printf("create argument %d from %dx%d image\n", idx, xsz, ysz);
   1.131 +	CLMemBuffer *buf;
   1.132 +
   1.133 +	if(!(buf = create_image_buffer(rdwr, xsz, ysz, pix))) {
   1.134 +		return false;
   1.135 +	}
   1.136 +
   1.137 +	if((int)args.size() <= idx) {
   1.138 +		args.resize(idx + 1);
   1.139 +	}
   1.140 +	args[idx].type = ARGTYPE_MEM_BUF;
   1.141 +	args[idx].v.mbuf = buf;
   1.142 +	return true;
   1.143 +}
   1.144 +
   1.145  bool CLProgram::set_arg_texture(int idx, int rdwr, unsigned int tex)
   1.146  {
   1.147  	printf("create argument %d from texture %u\n", idx, tex);
   1.148  	CLMemBuffer *buf;
   1.149  
   1.150 -	if(!(buf = create_mem_buffer(rdwr, tex))) {
   1.151 +	if(!(buf = create_image_buffer(rdwr, tex))) {
   1.152  		return false;
   1.153  	}
   1.154