clray

changeset 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
files src/clray.cc src/ocl.cc src/ocl.h src/rt.cc
diffstat 4 files changed, 113 insertions(+), 11 deletions(-) [+]
line diff
     1.1 --- a/src/clray.cc	Fri Aug 27 19:00:14 2010 +0100
     1.2 +++ b/src/clray.cc	Fri Aug 27 20:39:55 2010 +0100
     1.3 @@ -135,13 +135,14 @@
     1.4  
     1.5  void cleanup()
     1.6  {
     1.7 -	printf("destroying renderer...\n");
     1.8 +	printf("destroying renderer ...\n");
     1.9  	destroy_renderer();
    1.10  
    1.11 -	printf("shutting down OpenCL...\n");
    1.12 +	printf("shutting down OpenCL ...\n");
    1.13  	destroy_opencl();
    1.14  
    1.15 -	printf("done cleaning up\n");
    1.16 +	printf("cleaning up OpenGL resources ...\n");
    1.17 +	glDeleteTextures(1, &tex);
    1.18  }
    1.19  
    1.20  static Matrix4x4 mat, inv_mat, inv_trans;
     2.1 --- a/src/ocl.cc	Fri Aug 27 19:00:14 2010 +0100
     2.2 +++ b/src/ocl.cc	Fri Aug 27 20:39:55 2010 +0100
     2.3 @@ -122,17 +122,63 @@
     2.4  	}
     2.5  
     2.6  	CLMemBuffer *mbuf = new CLMemBuffer;
     2.7 +	mbuf->type = MEM_BUFFER;
     2.8  	mbuf->mem = mem;
     2.9  	mbuf->size = sz;
    2.10 +	mbuf->xsz = mbuf->ysz = 0;
    2.11  	mbuf->ptr = 0;
    2.12  	mbuf->tex = 0;
    2.13  	return mbuf;
    2.14  }
    2.15  
    2.16 -CLMemBuffer *create_mem_buffer(int rdwr, unsigned int tex)
    2.17 +CLMemBuffer *create_image_buffer(int rdwr, int xsz, int ysz, const void *pixels)
    2.18  {
    2.19 -	int err;
    2.20 +	int err, pitch;
    2.21  	cl_mem mem;
    2.22 +	cl_mem_flags flags = rdwr | CL_MEM_ALLOC_HOST_PTR;
    2.23 +
    2.24 +	if(pixels) {
    2.25 +		flags |= CL_MEM_COPY_HOST_PTR;
    2.26 +		pitch = xsz * 4 * sizeof(float);
    2.27 +	} else {
    2.28 +		pitch = 0;
    2.29 +	}
    2.30 +
    2.31 +	cl_image_format fmt = {CL_RGBA, CL_FLOAT};
    2.32 +
    2.33 +	if(!(mem = clCreateImage2D(ctx, flags, &fmt, xsz, ysz, pitch, (void*)pixels, &err))) {
    2.34 +		fprintf(stderr, "failed to create %dx%d image: %s\n", xsz, ysz, clstrerror(err));
    2.35 +		return 0;
    2.36 +	}
    2.37 +
    2.38 +	CLMemBuffer *mbuf = new CLMemBuffer;
    2.39 +	mbuf->type = IMAGE_BUFFER;
    2.40 +	mbuf->mem = mem;
    2.41 +	mbuf->size = ysz * pitch;
    2.42 +	mbuf->xsz = xsz;
    2.43 +	mbuf->ysz = ysz;
    2.44 +	mbuf->ptr = 0;
    2.45 +	mbuf->tex = 0;
    2.46 +	return mbuf;
    2.47 +}
    2.48 +
    2.49 +CLMemBuffer *create_image_buffer(int rdwr, unsigned int tex)
    2.50 +{
    2.51 +	int err, xsz, ysz;
    2.52 +	cl_mem mem;
    2.53 +
    2.54 +	glGetError();	// clear previous OpenGL errors
    2.55 +
    2.56 +	glPushAttrib(GL_TEXTURE_BIT);
    2.57 +	glBindTexture(GL_TEXTURE_2D, tex);
    2.58 +	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &xsz);
    2.59 +	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &ysz);
    2.60 +	glPopAttrib();
    2.61 +
    2.62 +	if(glGetError()) {
    2.63 +		fprintf(stderr, "create_image_buffer: GL error while retreiving texture parameters for texture %u\n", tex);
    2.64 +		return 0;
    2.65 +	}
    2.66  
    2.67  	if(!(mem = clCreateFromGLTexture2D(ctx, rdwr, GL_TEXTURE_2D, 0, tex, &err))) {
    2.68  		fprintf(stderr, "failed to create memory buffer from GL texture %u: %s\n", tex, clstrerror(err));
    2.69 @@ -140,10 +186,14 @@
    2.70  	}
    2.71  
    2.72  	CLMemBuffer *mbuf = new CLMemBuffer;
    2.73 +	mbuf->type = IMAGE_BUFFER;
    2.74  	mbuf->mem = mem;
    2.75  	mbuf->size = 0;
    2.76 +	mbuf->xsz = xsz;
    2.77 +	mbuf->ysz = ysz;
    2.78  	mbuf->ptr = 0;
    2.79  	mbuf->tex = tex;
    2.80 +
    2.81  	return mbuf;
    2.82  }
    2.83  
    2.84 @@ -166,10 +216,27 @@
    2.85  #endif
    2.86  
    2.87  	int err;
    2.88 -	mbuf->ptr = clEnqueueMapBuffer(cmdq, mbuf->mem, 1, rdwr, 0, mbuf->size, 0, 0, ev, &err);
    2.89 -	if(!mbuf->ptr) {
    2.90 -		fprintf(stderr, "failed to map buffer: %s\n", clstrerror(err));
    2.91 -		return 0;
    2.92 +
    2.93 +	if(mbuf->type == MEM_BUFFER) {
    2.94 +		mbuf->ptr = clEnqueueMapBuffer(cmdq, mbuf->mem, 1, rdwr, 0, mbuf->size, 0, 0, ev, &err);
    2.95 +		if(!mbuf->ptr) {
    2.96 +			fprintf(stderr, "failed to map buffer: %s\n", clstrerror(err));
    2.97 +			return 0;
    2.98 +		}
    2.99 +	} else {
   2.100 +		assert(mbuf->type == IMAGE_BUFFER);
   2.101 +
   2.102 +		size_t orig[] = {0, 0, 0};
   2.103 +		size_t rgn[] = {mbuf->xsz, mbuf->ysz, 1};
   2.104 +		size_t pitch;
   2.105 +
   2.106 +		mbuf->ptr = clEnqueueMapImage(cmdq, mbuf->mem, 1, rdwr, orig, rgn, &pitch, 0, 0, 0, ev, &err);
   2.107 +		if(!mbuf->ptr) {
   2.108 +			fprintf(stderr, "failed to map image: %s\n", clstrerror(err));
   2.109 +			return 0;
   2.110 +		}
   2.111 +
   2.112 +		assert(pitch == mbuf->xsz * 4 * sizeof(float));
   2.113  	}
   2.114  	return mbuf->ptr;
   2.115  }
   2.116 @@ -177,6 +244,7 @@
   2.117  void unmap_mem_buffer(CLMemBuffer *mbuf, cl_event *ev)
   2.118  {
   2.119  	if(!mbuf || !mbuf->ptr) return;
   2.120 +
   2.121  	clEnqueueUnmapMemObject(cmdq, mbuf->mem, mbuf->ptr, 0, 0, ev);
   2.122  	mbuf->ptr = 0;
   2.123  }
   2.124 @@ -351,12 +419,29 @@
   2.125  	return true;
   2.126  }
   2.127  
   2.128 +bool CLProgram::set_arg_image(int idx, int rdwr, int xsz, int ysz, const void *pix)
   2.129 +{
   2.130 +	printf("create argument %d from %dx%d image\n", idx, xsz, ysz);
   2.131 +	CLMemBuffer *buf;
   2.132 +
   2.133 +	if(!(buf = create_image_buffer(rdwr, xsz, ysz, pix))) {
   2.134 +		return false;
   2.135 +	}
   2.136 +
   2.137 +	if((int)args.size() <= idx) {
   2.138 +		args.resize(idx + 1);
   2.139 +	}
   2.140 +	args[idx].type = ARGTYPE_MEM_BUF;
   2.141 +	args[idx].v.mbuf = buf;
   2.142 +	return true;
   2.143 +}
   2.144 +
   2.145  bool CLProgram::set_arg_texture(int idx, int rdwr, unsigned int tex)
   2.146  {
   2.147  	printf("create argument %d from texture %u\n", idx, tex);
   2.148  	CLMemBuffer *buf;
   2.149  
   2.150 -	if(!(buf = create_mem_buffer(rdwr, tex))) {
   2.151 +	if(!(buf = create_image_buffer(rdwr, tex))) {
   2.152  		return false;
   2.153  	}
   2.154  
     3.1 --- a/src/ocl.h	Fri Aug 27 19:00:14 2010 +0100
     3.2 +++ b/src/ocl.h	Fri Aug 27 20:39:55 2010 +0100
     3.3 @@ -22,9 +22,17 @@
     3.4  	MAP_RDWR	= CL_MAP_READ | CL_MAP_WRITE
     3.5  };
     3.6  
     3.7 +enum {
     3.8 +	MEM_BUFFER,
     3.9 +	IMAGE_BUFFER
    3.10 +};
    3.11 +
    3.12  struct CLMemBuffer {
    3.13 +	int type;
    3.14  	cl_mem mem;
    3.15 +
    3.16  	size_t size;
    3.17 +	size_t xsz, ysz;
    3.18  	void *ptr;
    3.19  	unsigned int tex;
    3.20  };
    3.21 @@ -34,7 +42,10 @@
    3.22  void destroy_opencl();
    3.23  
    3.24  CLMemBuffer *create_mem_buffer(int rdwr, size_t sz, const void *buf);
    3.25 -CLMemBuffer *create_mem_buffer(int rdwr, unsigned int tex);
    3.26 +
    3.27 +CLMemBuffer *create_image_buffer(int rdwr, int xsz, int ysz, const void *pixels = 0);
    3.28 +CLMemBuffer *create_image_buffer(int rdwr, unsigned int tex);
    3.29 +
    3.30  void destroy_mem_buffer(CLMemBuffer *mbuf);
    3.31  
    3.32  void *map_mem_buffer(CLMemBuffer *mbuf, int rdwr, cl_event *ev = 0);
    3.33 @@ -87,6 +98,7 @@
    3.34  	bool set_argi(int arg, int val);
    3.35  	bool set_argf(int arg, float val);
    3.36  	bool set_arg_buffer(int arg, int rdwr, size_t sz, const void *buf = 0);
    3.37 +	bool set_arg_image(int arg, int rdwr, int xsz, int ysz, const void *pix = 0);
    3.38  	bool set_arg_texture(int arg, int rdwr, unsigned int tex);
    3.39  	CLMemBuffer *get_arg_buffer(int arg);
    3.40  	int get_num_args() const;
     4.1 --- a/src/rt.cc	Fri Aug 27 19:00:14 2010 +0100
     4.2 +++ b/src/rt.cc	Fri Aug 27 20:39:55 2010 +0100
     4.3 @@ -94,7 +94,11 @@
     4.4  	// XXX now we can actually destroy the original kdtree and keep only the GPU version
     4.5  
     4.6  	/* setup argument buffers */
     4.7 +#ifdef CLGL_INTEROP
     4.8  	prog->set_arg_texture(KARG_FRAMEBUFFER, ARG_WR, tex);
     4.9 +#else
    4.10 +	prog->set_arg_image(KARG_FRAMEBUFFER, ARG_WR, xsz, ysz);
    4.11 +#endif
    4.12  	prog->set_arg_buffer(KARG_RENDER_INFO, ARG_RD, sizeof rinf, &rinf);
    4.13  	prog->set_arg_buffer(KARG_FACES, ARG_RD, rinf.num_faces * sizeof(Face), faces);
    4.14  	prog->set_arg_buffer(KARG_MATLIB, ARG_RD, scn->get_num_materials() * sizeof(Material), scn->get_materials());