Ejemplo n.º 1
0
void xfer_dobj_flag(Data_Obj *dpto, Data_Obj *dpfr, uint32_t flagbit)
{
	if( OBJ_FLAGS(dpfr) & flagbit ){
		SET_OBJ_FLAG_BITS(dpto, flagbit);
	} else {
		CLEAR_OBJ_FLAG_BITS(dpto, flagbit);
	}
}
Ejemplo n.º 2
0
static void _update_pf_viewer(QSP_ARG_DECL  Platform_Viewer *pvp, Data_Obj *dp) 
{
#ifdef HAVE_OPENGL
	int t;
	//cudaError_t e;

	// unmap buffer before using w/ GL
	if( BUF_IS_MAPPED(dp) ){
		if( (*PF_UNMAPBUF_FN(PFDEV_PLATFORM(OBJ_PFDEV(dp))))
				(QSP_ARG  dp) < 0 ) {
			warn("update_pf_viewer:  buffer unmap error!?");
		}
		CLEAR_OBJ_FLAG_BITS(dp, DT_BUF_MAPPED);
		// propagate change to children and parents
		propagate_flag(dp,DT_BUF_MAPPED);

	}

	glClear(GL_COLOR_BUFFER_BIT);

	glBindTexture(GL_TEXTURE_2D, OBJ_TEX_ID(dp));
	// is glBindBuffer REALLY part of libGLEW???
//#ifdef HAVE_LIBGLEW
	glBindBuffer(GL_PIXEL_UNPACK_BUFFER, OBJ_BUF_ID(dp));
//#endif // HAVE_LIBGLEW

	t=gl_pixel_type(dp);
	glTexSubImage2D(GL_TEXTURE_2D, 0,	// target, level
		0, 0,				// x0, y0
		OBJ_COLS(dp), OBJ_ROWS(dp), 	// dx, dy
		t,
		GL_UNSIGNED_BYTE,		// type
		OFFSET(0));			// offset into PIXEL_UNPACK_BUFFER

//#ifdef HAVE_LIBGLEW
	glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
//#endif // HAVE_LIBGLEW

	glBegin(GL_QUADS);
	glTexCoord2f(0, 1); glVertex2f(-1.0, -1.0);
	glTexCoord2f(0, 0); glVertex2f(-1.0, 1.0);
	glTexCoord2f(1, 0); glVertex2f(1.0, 1.0);
	glTexCoord2f(1, 1); glVertex2f(1.0, -1.0);
	glEnd();
	glBindTexture(GL_TEXTURE_2D, 0);

	if( (*PF_MAPBUF_FN(PFDEV_PLATFORM(OBJ_PFDEV(dp))))(QSP_ARG  dp) < 0 ){
		warn("update_pf_viewer:  Error mapping buffer!?");
	}


	SET_OBJ_FLAG_BITS(dp, DT_BUF_MAPPED);
	// propagate change to children and parents
	propagate_flag(dp,DT_BUF_MAPPED);
#else // ! HAVE_OPENGL
	NO_OGL_MSG
#endif // ! HAVE_OPENGL
}
Ejemplo n.º 3
0
Archivo: size.c Proyecto: E-LLP/QuIP
int enlarge(QSP_ARG_DECL  Data_Obj *big_dp,Data_Obj *lil_dp)		/* reduce into lil_dp */
{
	if( change_size(QSP_ARG  big_dp,lil_dp) < 0 )
		return(-1);

	SET_OBJ_FLAG_BITS(big_dp, DT_ASSIGNED);

	return(0);
}
Ejemplo n.º 4
0
static COMMAND_FUNC( do_protect )
{
	Data_Obj *dp;

	dp=pick_obj("");
	if( dp == NULL ) return;
	if( IS_STATIC(dp) ){
		sprintf(ERROR_STRING,"do_protect:  Object %s is already static!?",OBJ_NAME(dp));
		warn(ERROR_STRING);
		return;
	}
	SET_OBJ_FLAG_BITS(dp,DT_STATIC);
}
Ejemplo n.º 5
0
static void cuda_display_finish(QSP_ARG_DECL  Data_Obj *dp)
{
	cudaError_t e;

	// re-map so we can use again with CUDA
	// BUG?  Is it safe to do this before the call to swap_buffers???
	//cutilSafeCall(cudaGLMapBufferObject( &OBJ_DATA_PTR(dp),  OBJ_BUF_ID(dp) ));

	e = cudaGLMapBufferObject( &OBJ_DATA_PTR(dp),  OBJ_BUF_ID(dp) );

	if( e != cudaSuccess ){
		WARN("Error mapping buffer object!?");
		// should we return now, with possibly other cleanup???
	}

	SET_OBJ_FLAG_BITS(dp, DT_BUF_MAPPED);
	// propagate change to children and parents
	propagate_flag(dp,DT_BUF_MAPPED);
}
Ejemplo n.º 6
0
static void _make_zombie(QSP_ARG_DECL  Data_Obj *dp)
{
	static int n_zombie=1;
	char zname[LLEN];

	/* this function removes it from the hash table and
	 * active item list, doesn't add the structure to the
	 * item free list.  This is why we release the node
	 * and later free the object...
	 *
	 * I think the idea here is that there might be a dangling reference
	 * to an image - for instance, if we display an image, then delete it,
	 * and then later want to refresh the window...
	 */
	zombie_item(dobj_itp,(Item *)dp);

	sprintf(zname,"Z.%s.%d",OBJ_NAME(dp),n_zombie++);
fprintf(stderr,"make_zombie, changing object %s to %s\n",OBJ_NAME(dp),zname);
	rls_str( (char *) OBJ_NAME(dp) );	/* unsave old name, make_zombie */
	SET_OBJ_NAME(dp,savestr(zname));

	SET_OBJ_FLAG_BITS(dp,DT_ZOMBIE);
} // make_zombie
Ejemplo n.º 7
0
// This is the normal display path
static void update_pf_viewer(QSP_ARG_DECL  Platform_Viewer *pvp, Data_Obj *dp) 
{
#ifdef HAVE_OPENGL
	int t;
	//cudaError_t e;

	// unmap buffer before using w/ GL
	if( BUF_IS_MAPPED(dp) ){
		if( (*PF_UNMAPBUF_FN(PFDEV_PLATFORM(OBJ_PFDEV(dp))))
				(QSP_ARG  dp) < 0 ) {
			WARN("update_pf_viewer:  buffer unmap error!?");
		}
#ifdef FOOBAR
		e = cudaGLUnmapBufferObject( OBJ_BUF_ID(dp) );   
		if( e != cudaSuccess ){
			describe_cuda_driver_error2("update_pf_viewer",
				"cudaGLUnmapBufferObject",e);
			NERROR1("failed to unmap buffer object");
		}
#endif // FOOBAR
		CLEAR_OBJ_FLAG_BITS(dp, DT_BUF_MAPPED);
		// propagate change to children and parents
		propagate_flag(dp,DT_BUF_MAPPED);

	}

	//
	//bind_texture(OBJ_DATA_PTR(dp));

	glClear(GL_COLOR_BUFFER_BIT);

/*
sprintf(ERROR_STRING,"update_pf_viewer:  tex_id = %d, buf_id = %d",
OBJ_TEX_ID(dp),OBJ_BUF_ID(dp));
advise(ERROR_STRING);
*/
	glBindTexture(GL_TEXTURE_2D, OBJ_TEX_ID(dp));
	// is glBindBuffer REALLY part of libGLEW???
//#ifdef HAVE_LIBGLEW
	glBindBuffer(GL_PIXEL_UNPACK_BUFFER, OBJ_BUF_ID(dp));
//#endif // HAVE_LIBGLEW

#ifdef FOOBAR
	switch(OBJ_COMPS(dp)){
		/* what used to be here??? */
	}
#endif /* FOOBAR */

	t=gl_pixel_type(dp);
	glTexSubImage2D(GL_TEXTURE_2D, 0,	// target, level
		0, 0,				// x0, y0
		OBJ_COLS(dp), OBJ_ROWS(dp), 	// dx, dy
		t,
		GL_UNSIGNED_BYTE,		// type
		OFFSET(0));			// offset into PIXEL_UNPACK_BUFFER

//#ifdef HAVE_LIBGLEW
	glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
//#endif // HAVE_LIBGLEW

	glBegin(GL_QUADS);
	glTexCoord2f(0, 1); glVertex2f(-1.0, -1.0);
	glTexCoord2f(0, 0); glVertex2f(-1.0, 1.0);
	glTexCoord2f(1, 0); glVertex2f(1.0, 1.0);
	glTexCoord2f(1, 1); glVertex2f(1.0, -1.0);
	glEnd();
	glBindTexture(GL_TEXTURE_2D, 0);

#ifdef FOOBAR
	e = cudaGLMapBufferObject( &OBJ_DATA_PTR(dp),  OBJ_BUF_ID(dp) );
	if( e != cudaSuccess ){
		WARN("Error mapping buffer object!?");
		// should we return now, with possibly other cleanup???
	}
#endif // FOOBAR
	if( (*PF_MAPBUF_FN(PFDEV_PLATFORM(OBJ_PFDEV(dp))))(QSP_ARG  dp) < 0 ){
		WARN("update_pf_viewer:  Error mapping buffer!?");
	}


	SET_OBJ_FLAG_BITS(dp, DT_BUF_MAPPED);
	// propagate change to children and parents
	propagate_flag(dp,DT_BUF_MAPPED);
#else // ! HAVE_OPENGL
	NO_OGL_MSG
#endif // ! HAVE_OPENGL
}
Ejemplo n.º 8
0
Archivo: glmenu.c Proyecto: nasa/QuIP
static COMMAND_FUNC( do_new_gl_buffer )
{
	const char *s;
	Data_Obj *dp;
	Platform_Device *pdp;
	Compute_Platform *cdp;
	dimension_t d,w,h;
#ifdef HAVE_OPENGL
	Dimension_Set ds;
	int t;
#endif // HAVE_OPENGL

	s = NAMEOF("name for GL buffer object");
	cdp = pick_platform("platform");
	if( cdp != NULL )
		push_pfdev_context(QSP_ARG  PF_CONTEXT(cdp) );
	pdp = pick_pfdev("device");
	if( cdp != NULL )
		pop_pfdev_context(SINGLE_QSP_ARG);

	w = (int)HOW_MANY("width");
	h = (int)HOW_MANY("height");
	d = (int)HOW_MANY("depth");

	/* what should the depth be??? default to 1 for now... */

	if( pdp == NULL ) return;

	/* Make sure this name isn't already in use... */
	dp = dobj_of(s);
	if( dp != NULL ){
		sprintf(ERROR_STRING,"Data object name '%s' is already in use, can't use for GL buffer object.",s);
		warn(ERROR_STRING);
		return;
	}

#ifdef HAVE_OPENGL
	// BUG need to be able to set the cuda device.
	// Note, however, that we don't need GL buffers on the Tesla...
	//set_data_area(cuda_data_area[0][0]);
	set_data_area( PFDEV_AREA(pdp,PFDEV_GLOBAL_AREA_INDEX) );

	ds.ds_dimension[0]=d;
	ds.ds_dimension[1]=w;
	ds.ds_dimension[2]=h;
	ds.ds_dimension[3]=1;
	ds.ds_dimension[4]=1;
	dp = _make_dp(QSP_ARG  s,&ds,PREC_FOR_CODE(PREC_UBY));
	if( dp == NULL ){
		sprintf(ERROR_STRING,
			"Error creating data_obj header for %s",s);
		error1(ERROR_STRING);
	}

	SET_OBJ_FLAG_BITS(dp, DT_NO_DATA);	/* can't free this data */
	SET_OBJ_FLAG_BITS(dp, DT_GL_BUF);	/* indicate obj is a GL buffer */

	SET_OBJ_DATA_PTR(dp, NULL);
//fprintf(stderr,"do_new_gl_buffer:  allocating gl_info for %s\n",OBJ_NAME(dp));
	SET_OBJ_GL_INFO(dp, (GL_Info *) getbuf( sizeof(GL_Info) ) );
//fprintf(stderr,"do_new_gl_buffer:  DONE allocating gl_info for %s\n",OBJ_NAME(dp));

	glew_check(SINGLE_QSP_ARG);	/* without this, we get a segmentation
			 * violation on glGenBuffers???
			 */

	// We need an extra field in which to store the GL identifier...
	// AND another extra field in which to store the associated texid.

// Why is this ifdef here?  These don't seem to depend
// on libglew???
// Answer:  We need libglew to bring in openGL extensions like glBindBuffer...

//advise("calling glGenBuffers");
//fprintf(stderr,"OBJ_GL_INFO(%s) = 0x%lx\n",OBJ_NAME(dp),(long)OBJ_GL_INFO(dp));
//fprintf(stderr,"OBJ_BUF_ID_P(%s) = 0x%lx\n",OBJ_NAME(dp),(long)OBJ_BUF_ID_P(dp));

	// BUG glGenBuffers seems to require v1.5???
	glGenBuffers(1, OBJ_BUF_ID_P(dp) );	// first arg is # buffers to generate?

//sprintf(ERROR_STRING,"glGenBuffers gave us buf_id = %d",OBJ_BUF_ID(dp));
//advise(ERROR_STRING);
	glBindBuffer(GL_PIXEL_UNPACK_BUFFER,  OBJ_BUF_ID(dp) ); 

	// glBufferData will allocate the memory for the buffer,
	// but won't copy unless the pointer is non-null
	// How do we get the gpu memory space address?
	// That must be with map

	glBufferData(GL_PIXEL_UNPACK_BUFFER,
		OBJ_COMPS(dp) * OBJ_COLS(dp) * OBJ_ROWS(dp), NULL, GL_STREAM_DRAW);  

	/* buffer arg set to 0 unbinds any previously bound buffers...
	 * and restores client memory usage.
	 */
	glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
//#endif // HAVE_LIBGLEW

	glGenTextures(1, OBJ_TEX_ID_P(dp) );		// makes a texture name
fprintf(stderr,"new_gl_buffer:  new texture name is 0x%x\n",OBJ_TEX_ID(dp));
	glBindTexture(GL_TEXTURE_2D, OBJ_TEX_ID(dp) );
	t = gl_pixel_type(dp);
	glTexImage2D(	GL_TEXTURE_2D,
			0,			// level-of-detail - is this the same as miplevel???
			OBJ_COMPS(dp),		// internal format, can also be symbolic constant such as
						// GL_RGBA etc
			OBJ_COLS(dp),		// width - must be 2^n+2 (border) for some n???
			OBJ_ROWS(dp),		// height - must be 2^m+2 (border) for some m???
			0,			// border - must be 0 or 1
			t,			// format of pixel data
			GL_UNSIGNED_BYTE,	// type of pixel data
			NULL			// pixel data - null pointer means
						// allocate but do not copy?
						// - offset into PIXEL_UNPACK_BUFFER??
			);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	// Why was this here?  It would seem to un-bind the target???
	glBindTexture(GL_TEXTURE_2D, 0);
	
	//glFinish();	// necessary or not?

//advise("calling platform-specific buffer registration function");
	if( (*PF_REGBUF_FN(PFDEV_PLATFORM(pdp)))( QSP_ARG  dp ) < 0 ){
		WARN("do_new_gl_buffer:  Error in platform-specific buffer registration!?");
		// BUG? - should clean up here!
	}

	// Leave the buffer mapped by default
	//cutilSafeCall(cudaGLMapBufferObject( &OBJ_DATA_PTR(dp),  OBJ_BUF_ID(dp) ));
//advise("calling platform-specific buffer mapping function");
	if( (*PF_MAPBUF_FN(PFDEV_PLATFORM(pdp)))( QSP_ARG  dp ) < 0 ){
		WARN("do_new_gl_buffer:  Error in platform-specific buffer mapping!?");
		// BUG? - should clean up here!
	}

	SET_OBJ_FLAG_BITS(dp, DT_BUF_MAPPED);
	// propagate change to children and parents
	propagate_flag(dp,DT_BUF_MAPPED);

#else // ! HAVE_OPENGL
	NO_OGL_MSG
#endif // ! HAVE_OPENGL
} /* end do_new_gl_buffer */
Ejemplo n.º 9
0
Archivo: size.c Proyecto: E-LLP/QuIP
static int change_size(QSP_ARG_DECL  Data_Obj *dst_dp,Data_Obj *src_dp )
{
	Dimension_Set ef, *enlargement_factor=&ef;
	Dimension_Set rf, *reduction_factor=&rf;
	Vec_Obj_Args oa1, *oap=&oa1;
	Dimension_Set size_ds, n_ds;
	Dimension_Set *size_dsp=(&size_ds), *n_dsp=(&n_ds);
	Data_Obj *src_ss_dp, *dst_ss_dp;
	dimension_t i,j,k,l,m;
	index_t offsets[N_DIMENSIONS]={0,0,0,0,0};
	incr_t dst_incrs[N_DIMENSIONS], src_incrs[N_DIMENSIONS];
	index_t dst_indices[N_DIMENSIONS]={0,0,0,0,0}, src_indices[N_DIMENSIONS]={0,0,0,0,0};

	/* For simplicity, we don't allow size changes to be combined with conversions */

	if( !dp_same_prec(QSP_ARG  dst_dp,src_dp,"change_size") )
		return(-1);

	for(i=0;i<N_DIMENSIONS;i++){
		if( OBJ_TYPE_DIM(dst_dp,i) > OBJ_TYPE_DIM(src_dp,i) ){
			/* enlargement - subsample the destination */
			SET_DIMENSION(enlargement_factor,i,
				floor( OBJ_TYPE_DIM(dst_dp,i) / OBJ_TYPE_DIM(src_dp,i) ) );
			SET_DIMENSION(reduction_factor,i, 0);

			SET_DIMENSION(size_dsp,i, OBJ_TYPE_DIM(src_dp,i) );
			SET_DIMENSION(n_dsp,i, DIMENSION(enlargement_factor,i) );
			dst_incrs[i] = DIMENSION(n_dsp,i);
			src_incrs[i] = 1;
		} else {
			/* reduction - subsample the source */
			SET_DIMENSION(reduction_factor,i,
				ceil( OBJ_TYPE_DIM(src_dp,i) / OBJ_TYPE_DIM(dst_dp,i) ) );
			SET_DIMENSION(enlargement_factor,i, 0 );

			SET_DIMENSION(size_dsp,i, floor( OBJ_TYPE_DIM(src_dp,i) /
				DIMENSION(reduction_factor,i) ) );
			/* We don't need to do this multiple times, just pick one and do it */
			/*SET_DIMENSION(n_dsp,i, DIMENSION(reduction_factor,i) ); */
			SET_DIMENSION(n_dsp,i, 1);
			src_incrs[i] = DIMENSION(reduction_factor,i);
			dst_incrs[i] = 1;
		}
	}
	/* make the subsamples.
	 * the column increment is expressed in columns, etc.
	 */
	dst_ss_dp=make_subsamp(QSP_ARG  "chngsize_dst_obj",dst_dp,size_dsp,offsets,dst_incrs);
	src_ss_dp=make_subsamp(QSP_ARG  "chngsize_src_obj",src_dp,size_dsp,offsets,src_incrs);

	clear_obj_args(oap);
	SET_OA_DEST(oap,dst_ss_dp);
	SET_OA_SRC_OBJ(oap,0, src_ss_dp);
	SET_OA_ARGSTYPE(oap, REAL_ARGS);
	SET_OA_PFDEV(oap,OBJ_PFDEV(dst_dp));

	for(i=0;i<DIMENSION(n_dsp,4);i++){		/* foreach sequence to copy */
		if( dst_incrs[4] > 1 )
			dst_indices[4]=i;
		else	src_indices[4]=i;
		for(j=0;j<DIMENSION(n_dsp,3);j++){	/* foreach frame to copy */
			if( dst_incrs[3] > 1 )
				dst_indices[3]=j;
			else	src_indices[3]=j;
			for(k=0;k<DIMENSION(n_dsp,2);k++){	/* foreach row */
				if( dst_incrs[2] > 1 )
					dst_indices[2]=k;
				else	src_indices[2]=k;
				for(l=0;l<DIMENSION(n_dsp,1);l++){	/* foreach col */
					if( dst_incrs[1] > 1 )
						dst_indices[1]=l;
					else	src_indices[1]=l;
					for(m=0;m<DIMENSION(n_dsp,0);m++){ /* foreach comp */
						if( dst_incrs[0] > 1 )
							dst_indices[0]=m;
						else	src_indices[0]=m;
						/* relocate the appropriate subsample */
						SET_OBJ_DATA_PTR(dst_ss_dp, multiply_indexed_data(dst_dp,dst_indices) );
						SET_OBJ_DATA_PTR(src_ss_dp, multiply_indexed_data(src_dp,src_indices) );

						// This doesn't check for cuda obj...
						//vmov(oap);
						perf_vfunc(QSP_ARG  FVMOV, oap );
					}
				}
			}
		}
	}
	delvec(QSP_ARG  dst_ss_dp);
	delvec(QSP_ARG  src_ss_dp);

	SET_OBJ_FLAG_BITS(dst_dp, DT_ASSIGNED);

	return(0);
}
Ejemplo n.º 10
0
Archivo: ascmenu.c Proyecto: E-LLP/QuIP
static Data_Obj *insure_ram_obj(QSP_ARG_DECL  Data_Obj *dp)
{
	Data_Obj *tmp_dp;
	char *tname;
	Data_Area *save_ap;
	Data_Obj *c_dp=NULL;

	if( OBJ_IS_RAM(dp) ) return dp;

	// This object lives on a different platform.
	// We create a copy in RAM, and download the data
	// using the platform download function.

	save_ap = curr_ap;
	curr_ap = ram_area_p;

	tname = getbuf( strlen(OBJ_NAME(dp)) + strlen(DNAME_PREFIX) + 1 );
	sprintf(tname,"%s%s",DNAME_PREFIX,OBJ_NAME(dp));
	tmp_dp = dup_obj(QSP_ARG  dp, tname);
	givbuf(tname);
	if( tmp_dp == NO_OBJ ){
		// This can happen if the object is subscripted,
		// as the bracket characters are illegal in names
		return NO_OBJ;
	}

	curr_ap = save_ap;

	// We can't download if the source data is not contiguous...
	//
	// We have a problem with bit precision, because the bits can
	// be non-contiguous when the long words are - any time the number of columns
	// is not evenly divided by the bits-per-word

	if( (! IS_CONTIGUOUS(dp)) && ! HAS_CONTIGUOUS_DATA(dp) ){
		Vec_Obj_Args oa1, *oap=&oa1;

advise("object is not contiguous, and does not have contiguous data...");
longlist(QSP_ARG  dp);
		save_ap = curr_ap;
		curr_ap = OBJ_AREA( dp );

		tname = getbuf( strlen(OBJ_NAME(dp)) + strlen(CNAME_PREFIX) + 1 );
		sprintf(tname,"%s%s",CNAME_PREFIX,OBJ_NAME(dp));
		c_dp = dup_obj(QSP_ARG  dp, tname );
		givbuf(tname);

		curr_ap = save_ap;

		// Now do the move...

		setvarg2(oap,c_dp,dp);
		if( IS_BITMAP(dp) ){
			SET_OA_SBM(oap,dp);
			SET_OA_SRC1(oap,NO_OBJ);
		}

		if( IS_REAL(dp) ) /* BUG case for QUAT too? */
			OA_ARGSTYPE(oap) = REAL_ARGS;
		else if( IS_COMPLEX(dp) ) /* BUG case for QUAT too? */
			OA_ARGSTYPE(oap) = COMPLEX_ARGS;
		else if( IS_QUAT(dp) ) /* BUG case for QUAT too? */
			OA_ARGSTYPE(oap) = QUATERNION_ARGS;
		else
			//ERROR1("CAUTIOUS:  insure_ram_obj:  bad argset type!?");
			assert( AERROR("insure_ram_obj:  bad argset type!?") );

//fprintf(stderr,"insure_ram_obj:  moving remote data to a contiguous object\n");  
		call_vfunc( QSP_ARG  FIND_VEC_FUNC(FVMOV), oap );
//fprintf(stderr,"insure_ram_obj:  DONE moving remote data to a contiguous object\n");  

		dp = c_dp;
	}

	gen_obj_dnload(QSP_ARG  tmp_dp, dp);

	if( c_dp != NO_OBJ )
		delvec(QSP_ARG  c_dp);

	// BUG - when to delete?
	// We try using the VOLATILE flag.  This will work as long as
	// the input object is not VOLATILE!?

	SET_OBJ_FLAG_BITS(tmp_dp, DT_VOLATILE ) ;

	return tmp_dp;
}