static int is_good_for_inner(Data_Obj *dp,const char *func_name) { int retval=1; //#ifdef CAUTIOUS // if( dp == NO_OBJ ){ // NWARN("CAUTIOUS: is_good_for_inner passed null object pointer!?"); // return(0); // } //#endif /* CAUTIOUS */ assert( dp != NO_OBJ ); if( OBJ_COMPS(dp) > 1 ){ sprintf(DEFAULT_ERROR_STRING,"%s: object %s has %d components (should be 1)", func_name,OBJ_NAME(dp),OBJ_COMPS(dp)); NWARN(DEFAULT_ERROR_STRING); retval=0; } if( OBJ_MACH_PREC(dp) != PREC_SP && OBJ_MACH_PREC(dp) != PREC_DP ){ sprintf(DEFAULT_ERROR_STRING,"%s: object %s has machine prec %s (should be float or double)", func_name,OBJ_NAME(dp),OBJ_MACH_PREC_NAME(dp) ); NWARN(DEFAULT_ERROR_STRING); retval=0; } return(retval); }
int get_framerate_strings( QSP_ARG_DECL Data_Obj *str_dp, PGR_Cam *pgcp ) { // Could check format of object here... // Should be string table with enough entries to hold the modes // Should the strings be rows or multidim pixels? int i, n; if( OBJ_COLS(str_dp) < pgcp->pc_framerates.num ){ sprintf(ERROR_STRING,"String object %s has too few columns (%ld) to hold %d framerates", OBJ_NAME(str_dp),(long)OBJ_COLS(str_dp),pgcp->pc_framerates.num); WARN(ERROR_STRING); n = OBJ_COLS(str_dp); } else { n=pgcp->pc_framerates.num; } for(i=0;i<n;i++){ const char *src; char *dst; src = name_for_framerate(pgcp->pc_framerates.framerates[i]); dst = OBJ_DATA_PTR(str_dp); dst += i * OBJ_PXL_INC(str_dp); if( strlen(src)+1 > OBJ_COMPS(str_dp) ){ sprintf(ERROR_STRING,"String object %s has too few components (%ld) to hold framerate string \"%s\"", OBJ_NAME(str_dp),(long)OBJ_COMPS(str_dp),src); WARN(ERROR_STRING); } else { strcpy(dst,src); } } return n; }
void compute_histo(QSP_ARG_DECL Data_Obj *histo_dp,Data_Obj *data_dp,double bin_width,double min_limit) { dimension_t i,j,k; float num; float *histbuf; incr_t index; dimension_t n_bins; int n_under=0, n_over=0; INSIST_RAM_OBJ(histo_dp,compute_histo); INSIST_RAM_OBJ(data_dp,compute_histo); if( OBJ_PREC(histo_dp) != PREC_SP ){ WARN("histogram precision must be float"); return; } if( OBJ_COMPS(histo_dp) != 1 ){ WARN("histogram data must be real"); return; } if( OBJ_ROWS(histo_dp) > 1 || OBJ_FRAMES(histo_dp) > 1 ){ WARN("only using first row of histogram image"); } if( OBJ_COMPS(data_dp) != 1 ){ WARN("input data must be real"); return; } switch( OBJ_PREC(data_dp) ){ case PREC_SP: HISTOGRAM(float) break; case PREC_DP: HISTOGRAM(double) break; case PREC_UBY: HISTOGRAM(u_char) break; case PREC_BY: HISTOGRAM(char) break; case PREC_UIN: HISTOGRAM(u_short) break; case PREC_IN: HISTOGRAM(short) break; case PREC_UDI: HISTOGRAM(u_long) break; case PREC_DI: HISTOGRAM(long) break; default: NWARN("unhandled source precision in histogram"); return; } if( (n_under > 0) || (n_over > 0) ){ sprintf(ERROR_STRING, "Histogram for %s had %d underflows and %d overflows", OBJ_NAME(data_dp),n_under,n_over); advise(ERROR_STRING); } }
FIO_DP_TO_FT_FUNC(wav,Wav_Header) { /* num_frame set when when write request given */ /* BUG questionable cast */ hd_p->wh_n_channels = (short) OBJ_COMPS(dp); switch( OBJ_MACH_PREC(dp) ){ case PREC_UBY: hd_p->wh_bits_per_sample = 8; break; case PREC_IN: hd_p->wh_bits_per_sample = 16; break; default: sprintf(ERROR_STRING, "dp_to_wav: vector %s has unsupported source precision %s", OBJ_NAME(dp),PREC_NAME(OBJ_MACH_PREC_PTR(dp))); warn(ERROR_STRING); return(-1); break; } hd_p->wh_datasize = OBJ_N_TYPE_ELTS(dp) * PREC_SIZE( OBJ_MACH_PREC_PTR(dp) ); hd_p->wh_chunksize = 36 + hd_p->wh_datasize; /* BUG dp's don't have a way to carry around the sample rate with them??? */ /* So we assume that the current sample rate is the one that corresponds * to this object BUG */ hd_p->wh_samp_rate = (*samp_rate_func)(); hd_p->wh_blk_align = hd_p->wh_n_channels * hd_p->wh_bits_per_sample / 8; hd_p->wh_bytes_per_sec = hd_p->wh_blk_align * hd_p->wh_samp_rate; return 0; }
void dobj_iterate(Data_Obj *dp,void (*func)(Data_Obj *,index_t)) { dimension_t comp,col,row,frm,seq; /* offsets for sequence, frame, row, pixel, component */ dimension_t s_os, f_os, r_os, p_os, c_os; s_os=0; for(seq=0;seq<OBJ_SEQS(dp);seq++){ f_os = s_os; for(frm=0;frm<OBJ_FRAMES(dp);frm++){ r_os = f_os; for(row=0;row<OBJ_ROWS(dp);row++){ p_os = r_os; for(col=0;col<OBJ_COLS(dp);col++){ c_os = p_os; for(comp=0;comp<OBJ_COMPS(dp);comp++){ (*func)(dp,c_os); c_os += OBJ_COMP_INC(dp); } p_os += OBJ_PXL_INC(dp); } r_os += OBJ_ROW_INC(dp); } f_os += OBJ_FRM_INC(dp); } s_os += OBJ_SEQ_INC(dp); } }
static void fb_load(QSP_ARG_DECL Data_Obj *dp,int x, int y) { #ifdef HAVE_FB_DEV dimension_t i,j; /* char *p,*q; */ /* BUG probably a lot faster if we cast to long! */ long *p,*q; u_long bytes_per_row, words_per_row; /* BUG assume dp is the right kind of object */ if( ! IS_CONTIGUOUS(dp) ){ sprintf(ERROR_STRING,"fb_load: object %s must be contiguous", OBJ_NAME(dp)); WARN(ERROR_STRING); return; } INSURE_FB("fb_load"); p=(long *)OBJ_DATA_PTR(dp); q=(long *)OBJ_DATA_PTR(curr_fbip->fbi_dp); bytes_per_row = OBJ_COLS(dp) * OBJ_COMPS(dp); words_per_row = bytes_per_row / sizeof(long); for(i=0;i<OBJ_ROWS(dp);i++){ /* BUG we need to correct the row ptr if dp is narrower than the display */ for(j=0;j<words_per_row;j++) *q++ = *p++; } #endif /* HAVE_FB_DEV */ }
static void fb_save(QSP_ARG_DECL Data_Obj *dp,int x, int y) { #ifdef HAVE_FB_DEV dimension_t i,j,k; char *p,*q; /* BUG assume dp is the right kind of object */ if( ! IS_CONTIGUOUS(dp) ){ sprintf(ERROR_STRING,"fb_save: object %s must be contiguous", OBJ_NAME(dp)); WARN(ERROR_STRING); return; } INSURE_FB("fb_save"); p=(char *)OBJ_DATA_PTR(dp); q=(char *)OBJ_DATA_PTR(curr_fbip->fbi_dp); /* BUG this byte-at-a-time copy is horribly inefficient */ for(i=0;i<OBJ_ROWS(dp);i++) for(j=0;j<OBJ_COLS(dp);j++) for(k=0;k<OBJ_COMPS(dp);k++) *p++ = *q++; #endif /* HAVE_FB_DEV */ }
int get_camera_names( QSP_ARG_DECL Data_Obj *str_dp ) { // Could check format of object here... // Should be string table with enough entries to hold the modes // Should the strings be rows or multidim pixels? List *lp; Node *np; PGR_Cam *pgcp; int i, n; lp = pgc_list(); if( lp == NULL ){ WARN("No cameras!?"); return 0; } n=eltcount(lp); if( OBJ_COLS(str_dp) < n ){ sprintf(ERROR_STRING,"String object %s has too few columns (%ld) to hold %d camera names", OBJ_NAME(str_dp),(long)OBJ_COLS(str_dp),n); WARN(ERROR_STRING); n = OBJ_COLS(str_dp); } np=QLIST_HEAD(lp); i=0; while(np!=NULL){ char *dst; pgcp = (PGR_Cam *) NODE_DATA(np); dst = OBJ_DATA_PTR(str_dp); dst += i * OBJ_PXL_INC(str_dp); if( strlen(pgcp->pc_name)+1 > OBJ_COMPS(str_dp) ){ sprintf(ERROR_STRING,"String object %s has too few components (%ld) to hold camera name \"%s\"", OBJ_NAME(str_dp),(long)OBJ_COMPS(str_dp),pgcp->pc_name); WARN(ERROR_STRING); } else { strcpy(dst,pgcp->pc_name); } i++; if( i>=n ) np=NULL; else np = NODE_NEXT(np); } return i; }
//int _wav_to_dp(QSP_ARG_DECL Data_Obj *dp,Wav_Header *hd_p) FIO_FT_TO_DP_FUNC(wav,Wav_Header) { Precision * prec_p; dimension_t total_samples, samples_per_channel; switch( hd_p->wh_bits_per_sample ){ case 8: prec_p=PREC_FOR_CODE(PREC_UBY); break; case 16: prec_p=PREC_FOR_CODE(PREC_IN); break; default: sprintf(ERROR_STRING, "wav_to_dp: unexpected # of bits per sample %d", hd_p->wh_bits_per_sample); warn(ERROR_STRING); return(-1); } SET_OBJ_PREC_PTR(dp, prec_p); SET_OBJ_COMPS(dp, hd_p->wh_n_channels ); total_samples = (dimension_t) (hd_p->wh_datasize / PREC_SIZE( prec_p )); samples_per_channel = total_samples / OBJ_COMPS(dp); SET_OBJ_COLS(dp, samples_per_channel); SET_OBJ_ROWS(dp, 1); SET_OBJ_FRAMES(dp, 1); SET_OBJ_SEQS(dp, 1); SET_OBJ_COMP_INC(dp, 1); SET_OBJ_PXL_INC(dp, 1); SET_OBJ_ROW_INC(dp, 1); SET_OBJ_FRM_INC(dp, 1); SET_OBJ_SEQ_INC(dp, 1); SET_OBJ_PARENT(dp, NULL); SET_OBJ_CHILDREN(dp, NULL); SET_OBJ_AREA(dp, ram_area_p); /* the default */ /* dp->dt_data = hd_p->image; */ /* where do we allocate data??? */ SET_OBJ_N_TYPE_ELTS(dp, OBJ_COMPS(dp) * OBJ_COLS(dp) * OBJ_ROWS(dp) * OBJ_FRAMES(dp) * OBJ_SEQS(dp) ); auto_shape_flags(OBJ_SHAPE(dp)); return 0; }
static int bad_plot_vec(QSP_ARG_DECL Data_Obj *dp,dimension_t n_comps_expected,const char *funcname) { if( dp==NO_OBJ ) return 1; if( OBJ_PREC(dp) != PREC_SP ) { sprintf(ERROR_STRING, "%s: data vector %s (%s) should have float precision", funcname, OBJ_NAME(dp),OBJ_MACH_PREC_NAME(dp)); WARN(ERROR_STRING); return 1; } if( OBJ_COMPS(dp) != n_comps_expected ) { sprintf(ERROR_STRING,"%s: data vector %s (%d) should have %d components", funcname,OBJ_NAME(dp),OBJ_COMPS(dp),n_comps_expected); WARN(ERROR_STRING); return 1; } return 0; }
static void prepare_image_for_mapping(Data_Obj *dp) { #ifdef HAVE_OPENGL int t; cudaError_t e; // unmap buffer before using w/ GL if( BUF_IS_MAPPED(dp) ){ e = cudaGLUnmapBufferObject( OBJ_BUF_ID(dp) ); if( e != cudaSuccess ){ describe_cuda_driver_error2("update_cuda_viewer", "cudaGLUnmapBufferObject",e); NERROR1("failed to unmap buffer object"); } 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_cuda_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)); #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 }
void set_texture_image(QSP_ARG_DECL Data_Obj *dp) { int code,prec; /*glDepthFunc(GL_LEQUAL); glPixelStorei(GL_UNPACK_ALIGNMENT,1);*/ if(OBJ_COMPS(dp)==1) code=GL_LUMINANCE; else if( OBJ_COMPS(dp) == 3 ) code=GL_RGB; else { sprintf(ERROR_STRING, "set_texture_image: Object %s has type dimension %d, expected 1 or 3", OBJ_NAME(dp),OBJ_COMPS(dp)); warn(ERROR_STRING); return; } if( OBJ_PREC(dp) == PREC_SP ) prec=GL_FLOAT; else if( OBJ_PREC(dp) == PREC_UBY ) prec=GL_UNSIGNED_BYTE; else { sprintf(ERROR_STRING,"set_texture_image: Object %s has precision %s, expected %s or %s", OBJ_NAME(dp),PREC_NAME(OBJ_PREC_PTR(dp)), NAME_FOR_PREC_CODE(PREC_SP),NAME_FOR_PREC_CODE(PREC_UBY)); warn(ERROR_STRING); return; } if( debug & gl_debug ) advise("glTexImage2D"); glTexImage2D(GL_TEXTURE_2D, 0, OBJ_COMPS(dp), OBJ_COLS(dp), OBJ_ROWS(dp), 0, code, prec, OBJ_DATA_PTR(dp)); if( debug & gl_debug ) advise("glTexParameterf (4)"); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); if( debug & gl_debug ) advise("glTexEnv"); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); /*glEnable(GL_TEXTURE_2D); glShadeModel(GL_FLAT);*/ }
static COMMAND_FUNC( do_read_str ) { Data_Obj *dp; const char *s; dp=PICK_OBJ(""); s=NAMEOF("string"); if( dp == NO_OBJ ) return; INSIST_RAM_OBJ(dp,"read_string") #ifdef QUIP_DEBUG //if( debug ) dptrace(dp); #endif /* QUIP_DEBUG */ if( ! IS_STRING(dp) ){ sprintf(ERROR_STRING,"do_read_str: object %s (%s) does not have string precision", OBJ_NAME(dp),OBJ_PREC_NAME(dp)); WARN(ERROR_STRING); return; } if( (strlen(s)+1) > OBJ_COMPS(dp) ){ sprintf(ERROR_STRING, "Type dimension (%d) of string object %s is too small for string of length %d", OBJ_COMPS(dp),OBJ_NAME(dp),(int)strlen(s)); WARN(ERROR_STRING); return; } if( ! IS_CONTIGUOUS(dp) ){ sprintf(ERROR_STRING,"Sorry, object %s must be contiguous for string reading", OBJ_NAME(dp)); WARN(ERROR_STRING); return; } strcpy((char *)OBJ_DATA_PTR(dp),s); }
int get_video_mode_strings( QSP_ARG_DECL Data_Obj *str_dp, PGR_Cam *pgcp ) { // Could check format of object here... // Should be string table with enough entries to hold the modes // Should the strings be rows or multidim pixels? int i, n; if( OBJ_COLS(str_dp) < pgcp->pc_video_modes.num ){ sprintf(ERROR_STRING,"String object %s has too few columns (%ld) to hold %d modes", OBJ_NAME(str_dp),(long)OBJ_COLS(str_dp),pgcp->pc_video_modes.num); WARN(ERROR_STRING); n = OBJ_COLS(str_dp); } else { n=pgcp->pc_video_modes.num; } for(i=0;i<n;i++){ int k; const char *src; char *dst; k=index_of_video_mode(pgcp->pc_video_modes.modes[i]); src = all_video_modes[k].nvm_name; dst = OBJ_DATA_PTR(str_dp); dst += i * OBJ_PXL_INC(str_dp); if( strlen(src)+1 > OBJ_COMPS(str_dp) ){ sprintf(ERROR_STRING,"String object %s has too few components (%ld) to hold mode string \"%s\"", OBJ_NAME(str_dp),(long)OBJ_COMPS(str_dp),src); WARN(ERROR_STRING); } else { strcpy(dst,src); } } set_script_var_from_int("n_video_modes",n); return n; }
int good_polh_vector(QSP_ARG_DECL Data_Obj *dp) { int n_expected_words; /* The polhemus can output floats, but we'll assume it's all short here... */ if( dp == NULL ) return(0); if( OBJ_PREC(dp) != PREC_IN && OBJ_PREC(dp) != PREC_UIN ) { sprintf(ERROR_STRING, "Object %s has %s precision, should be %s or %s for polhemus data", OBJ_NAME(dp), OBJ_PREC_NAME(dp), NAME_FOR_PREC_CODE(PREC_IN), NAME_FOR_PREC_CODE(PREC_UIN) ); warn(ERROR_STRING); return(0); } if( n_active_stations == 2 ) n_expected_words = station_info[0].sd_multi_prf.rf_n_words + station_info[1].sd_multi_prf.rf_n_words; else n_expected_words = station_info[curr_station_idx].sd_multi_prf.rf_n_words ; if( OBJ_COMPS(dp) != n_expected_words ) { sprintf(ERROR_STRING, "Object %s has bad type dimensions (%d), should be %d", OBJ_NAME(dp), OBJ_COMPS(dp), n_expected_words); warn(ERROR_STRING); return(0); } if( !IS_CONTIGUOUS(dp) ) { sprintf(ERROR_STRING, "good_polh_vector: Object %s must be contiguous", OBJ_NAME(dp)); warn(ERROR_STRING); return(0); } return(1); }
int _gl_pixel_type(QSP_ARG_DECL Data_Obj *dp) { int t; switch(OBJ_COMPS(dp)){ case 1: t = GL_LUMINANCE; break; /* 2 is allowable, but what do we do with it? */ case 3: t = GL_BGR; break; case 4: t = GL_BGRA; break; default: t=0; // quiet compiler error1("bad pixel depth!?"); break; } return(t); }
static COMMAND_FUNC( mksubsequence ) { const char *obj_name; Data_Obj *dp, *newdp; index_t offsets[N_DIMENSIONS]; Dimension_Set ds1, *dsp=(&ds1); long x_offset, y_offset, t_offset; long nr,nc,nf; obj_name=NAMEOF("name for subsequence"); dp=pick_obj(PARENT_PROMPT); nc = (long) how_many("number of columns"); nr = (long) how_many("number of rows"); nf = (long) how_many("number of frames"); x_offset=(long) how_many("x offset"); y_offset=(long) how_many("y offset"); t_offset=(long) how_many("t offset"); if( dp==NULL ) return; INSIST_POSITIVE_DIM(nc,"column","mksubsequence"); INSIST_POSITIVE_DIM(nr,"row","mksubsequence"); INSIST_POSITIVE_DIM(nf,"frame","mksubsequence"); INSIST_NONNEGATIVE(x_offset,"x offset","mksubsequence"); INSIST_NONNEGATIVE(y_offset,"y offset","mksubsequence"); INSIST_NONNEGATIVE(t_offset,"t offset","mksubsequence"); offsets[0]=0; offsets[1]=(index_t)x_offset; offsets[2]=(index_t)y_offset; offsets[3]=(index_t)t_offset; offsets[4]=0; SET_DIMENSION(dsp,0,OBJ_COMPS(dp)); SET_DIMENSION(dsp,1,nc); SET_DIMENSION(dsp,2,nr); SET_DIMENSION(dsp,3,nf); SET_DIMENSION(dsp,4,1); newdp=mk_subseq(obj_name,dp,offsets,dsp); if( newdp == NULL ) warn("couldn't create subimage"); }
void _dpair_iterate(QSP_ARG_DECL Data_Obj *dp1,Data_Obj *dp2,void (*func)(QSP_ARG_DECL Data_Obj *,index_t,Data_Obj *,index_t)) { dimension_t comp,col,row,frm,seq; /* offsets for sequence, frame, row, pixel, component */ dimension_t s_os1, f_os1, r_os1, p_os1, c_os1; dimension_t s_os2, f_os2, r_os2, p_os2, c_os2; s_os1=0; s_os2=0; for(seq=0;seq<OBJ_SEQS(dp1);seq++){ f_os1 = s_os1; f_os2 = s_os2; for(frm=0;frm<OBJ_FRAMES(dp1);frm++){ r_os1 = f_os1; r_os2 = f_os2; for(row=0;row<OBJ_ROWS(dp1);row++){ p_os1 = r_os1; p_os2 = r_os2; for(col=0;col<OBJ_COLS(dp1);col++){ c_os1 = p_os1; c_os2 = p_os2; for(comp=0;comp<OBJ_COMPS(dp1);comp++){ (*func)(QSP_ARG dp1,c_os1,dp2,c_os2); c_os1 += OBJ_COMP_INC(dp1); c_os2 += OBJ_COMP_INC(dp2); } p_os1 += OBJ_PXL_INC(dp1); p_os2 += OBJ_PXL_INC(dp2); } r_os1 += OBJ_ROW_INC(dp1); r_os2 += OBJ_ROW_INC(dp2); } f_os1 += OBJ_FRM_INC(dp1); f_os2 += OBJ_FRM_INC(dp2); } s_os1 += OBJ_SEQ_INC(dp1); s_os2 += OBJ_SEQ_INC(dp2); } }
// This function allows us to do a different mapping of the image... static void map_cuda_viewer(QSP_ARG_DECL Cuda_Viewer *cvp, Data_Obj *img_dp, Data_Obj *coord_dp) { if( OBJ_PREC(coord_dp) != PREC_SP ){ sprintf(ERROR_STRING, "map_cuda_viewer: coord object %s must have %s precision!?", OBJ_NAME(coord_dp),PREC_NAME(OBJ_PREC_PTR(coord_dp))); WARN(ERROR_STRING); return; } if( ! IS_CONTIGUOUS(coord_dp) ){ sprintf(ERROR_STRING, "map_cuda_viewer: coord object %s must be contiguous!?", OBJ_NAME(coord_dp)); WARN(ERROR_STRING); return; } if( OBJ_COMPS(coord_dp) != 2 ){ sprintf(ERROR_STRING, "map_cuda_viewer: coord object %s must have 2 components!?", OBJ_NAME(coord_dp)); WARN(ERROR_STRING); return; } if( OBJ_COLS(coord_dp) != 2 ){ sprintf(ERROR_STRING, "map_cuda_viewer: coord object %s must have 2 columns!?", OBJ_NAME(coord_dp)); WARN(ERROR_STRING); return; } if( OBJ_ROWS(coord_dp) != 2 ){ sprintf(ERROR_STRING, "map_cuda_viewer: coord object %s must have 2 rows!?", OBJ_NAME(coord_dp)); WARN(ERROR_STRING); return; } #ifdef HAVE_OPENGL float *f; prepare_image_for_mapping(img_dp); f=(float *)OBJ_DATA_PTR(coord_dp); glBegin(GL_QUADS); fprintf(stderr,"first vertex at %f, %f (normally -1, -1)\n",f[0],f[1]); glTexCoord2f(0, 1); glVertex2f( f[0], f[1] ); // -1, -1 fprintf(stderr,"second vertex at %f, %f (normally -1, 1)\n",f[4],f[5]); glTexCoord2f(0, 0); glVertex2f( f[4], f[5] ); // -1, 1 fprintf(stderr,"third vertex at %f, %f (normally 1, 1)\n",f[6],f[7]); glTexCoord2f(1, 0); glVertex2f( f[6], f[7] ); // 1, 1 fprintf(stderr,"fourth vertex at %f, %f (normally 1, -1)\n",f[2],f[3]); glTexCoord2f(1, 1); glVertex2f( f[2], f[3] ); // 1, -1 glEnd(); glBindTexture(GL_TEXTURE_2D, 0); cuda_display_finish(QSP_ARG img_dp); #else // ! HAVE_OPENGL NO_OGL_MSG #endif // ! HAVE_OPENGL }
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 */
static void test_parport(void) { int n,s; Data_Obj *dp; u_long *lp; FB_Info *fbip; pthread_attr_t attr1; VBoard_Info vbi1; PPort_Info ppti1; u_long l; pthread_attr_init(&attr1); /* initialize to default values */ pthread_attr_setinheritsched(&attr1,PTHREAD_INHERIT_SCHED); fbip = pick_fbi("frame buffer for VSYNC"); dp = pick_obj("data vector for latencies"); if( fbip == NULL || dp == NULL ) return; INSIST_RAM_OBJ(dp,"test_parport") if( OBJ_PREC(dp) != PREC_UDI ){ sprintf(ERROR_STRING,"latency vector %s (%s) should have precision %s", OBJ_NAME(dp),PREC_NAME(OBJ_PREC_PTR(dp)), NAME_FOR_PREC_CODE(PREC_UDI)); WARN(ERROR_STRING); return; } if( OBJ_COMPS(dp) != 2 ){ sprintf(ERROR_STRING,"latency vector %s (%d) should have 2 components", OBJ_NAME(dp),OBJ_COMPS(dp)); WARN(ERROR_STRING); return; } if( ! IS_CONTIGUOUS(dp) ){ sprintf(ERROR_STRING,"latency vector %s should be contiguous",OBJ_NAME(dp)); WARN(ERROR_STRING); return; } n = OBJ_N_MACH_ELTS(dp)/2; lp = (u_long *) OBJ_DATA_PTR(dp); vbi1.vbi_fbip = fbip; vbi1.vbi_buf = lp; vbi1.vbi_count = n; vbi1.vbi_inc = 2; #ifdef THREAD_SAFE_QUERY vbi1.vbi_qsp = THIS_QSP; #endif // THREAD_SAFE_QUERY lp ++; if( the_ppp == NULL ){ the_ppp=open_parport(NULL); /* use default */ if( the_ppp == NULL ) return; } ppti1.ppti_ppp = the_ppp; ppti1.ppti_buf = lp; ppti1.ppti_count = n; ppti1.ppti_inc = 2; tvp = NULL; /* force re-zero */ s=read_til_transition(the_ppp,8); if( s==0 ) s=read_til_transition(the_ppp,8); /* should now be in the one state */ /* this is the end of the (negative) pulse */ l = delta_usecs(); /* zero the clock */ pthread_create(&vboard_thr,&attr1,vboard_daemon,&vbi1); pthread_create(&pport_thr,&attr1,pport_logger,&ppti1); /* should wait for threads here... */ if( pthread_join(vboard_thr,NULL) != 0 ){ perror("pthread_join"); WARN("error joining video board thread"); } if( pthread_join(pport_thr,NULL) != 0 ){ perror("pthread_join"); WARN("error joining parallel port thread"); } }
int xform_chk(Data_Obj *dpto,Data_Obj *dpfr,Data_Obj *xform) { if( dpto==NO_OBJ || dpfr==NO_OBJ || xform==NO_OBJ ) return(-1); if( !IS_IMAGE(xform) ){ sprintf(DEFAULT_ERROR_STRING, "xform_chk: transformation %s must be a matrix (image)", OBJ_NAME(xform)); NWARN(DEFAULT_ERROR_STRING); return(-1); } if( OBJ_COMPS(xform) != 1 ){ sprintf(DEFAULT_ERROR_STRING, "xform_chk: transform matrix %s must have single-component elements",OBJ_NAME(xform)); NWARN(DEFAULT_ERROR_STRING); return(-1); } if( OBJ_COMPS(dpto) != OBJ_ROWS(xform) ){ sprintf(DEFAULT_ERROR_STRING, "xform_chk: target %s component dimension (%d) must match # rows of xform %s (%d)", OBJ_NAME(dpto),OBJ_COMPS(dpto),OBJ_NAME(xform),OBJ_ROWS(xform)); NWARN(DEFAULT_ERROR_STRING); return(-1); } if( OBJ_COMPS(dpfr) != OBJ_COLS(xform) ){ sprintf(DEFAULT_ERROR_STRING, "xform_chk: source %s component dimension (%d) must match # columns of xform %s (%d)", OBJ_NAME(dpto),OBJ_COMPS(dpto),OBJ_NAME(xform),OBJ_ROWS(xform)); NWARN(DEFAULT_ERROR_STRING); return(-1); } if( OBJ_N_TYPE_ELTS(dpto)/OBJ_COMPS(dpto) != OBJ_N_TYPE_ELTS(dpfr)/OBJ_COMPS(dpfr) ){ sprintf(DEFAULT_ERROR_STRING, "xform_chk: target %s (%d/%d) and source %s (%d/%d) must have same # of elements", OBJ_NAME(dpto),OBJ_N_TYPE_ELTS(dpto),OBJ_COMPS(dpto), OBJ_NAME(dpfr),OBJ_N_TYPE_ELTS(dpfr),OBJ_COMPS(dpfr)); NWARN(DEFAULT_ERROR_STRING); return(-1); } /* BUG these contiguity requirements may no longer be necessary... */ if( !is_contiguous(DEFAULT_QSP_ARG dpto) ){ sprintf(DEFAULT_ERROR_STRING, "xform_chk: xform target %s must be contiguous",OBJ_NAME(dpto)); NWARN(DEFAULT_ERROR_STRING); return(-1); } if( !is_contiguous(DEFAULT_QSP_ARG dpfr) ){ sprintf(DEFAULT_ERROR_STRING, "xform_chk: xform source %s must be contiguous",OBJ_NAME(dpfr)); NWARN(DEFAULT_ERROR_STRING); return(-1); } if( !is_contiguous(DEFAULT_QSP_ARG xform) ){ sprintf(DEFAULT_ERROR_STRING, "xform_chk: xform %s must be contiguous",OBJ_NAME(xform)); NWARN(DEFAULT_ERROR_STRING); return(-1); } return(0); } // end xform_chk
void inner(QSP_ARG_DECL Data_Obj *dpto,Data_Obj *dpfr1,Data_Obj *dpfr2) { //dimension_t _n; /* dot prod len */ dimension_t i,j; Vec_Obj_Args oa1, *oap=&oa1; //Dimension_Set sizes={{1,1,1,1,1}}; Dimension_Set *sizes; index_t dst_indices[N_DIMENSIONS]={0,0,0,0,0}; index_t src1_indices[N_DIMENSIONS]={0,0,0,0,0}; index_t src2_indices[N_DIMENSIONS]={0,0,0,0,0}; Data_Obj *col_dp; sizes=NEW_DIMSET; for(i=0;i<N_DIMENSIONS;i++) SET_DIMENSION(sizes,i,1); #ifdef CAUTIOUS clear_obj_args(oap); #endif /* CAUTIOUS */ /* The types and precisions should be whatever is allowed by vdot, * which is float, double, real and complex... */ if( ! is_good_for_inner(dpto,"inner") ) return; if( ! is_good_for_inner(dpfr1,"inner") ) return; if( ! is_good_for_inner(dpfr2,"inner") ) return; /* we need to make sure that the types and precisions MATCH! */ if( ! prec_and_type_match(dpto,dpfr1,"inner") ) return; if( ! prec_and_type_match(dpto,dpfr2,"inner") ) return; if( OBJ_ROWS(dpto) != OBJ_ROWS(dpfr1) ){ sprintf(DEFAULT_ERROR_STRING, "inner: dpto %s (%d) and first operand %s (%d) must have same # rows", OBJ_NAME(dpto),OBJ_ROWS(dpto),OBJ_NAME(dpfr1),OBJ_ROWS(dpfr1)); NWARN(DEFAULT_ERROR_STRING); return; } if( OBJ_COLS(dpto) != OBJ_COLS(dpfr2) ){ sprintf(DEFAULT_ERROR_STRING, "inner: target %s (%d) and second operand %s (%d) must have same # columns", OBJ_NAME(dpto),OBJ_COLS(dpto),OBJ_NAME(dpfr2),OBJ_COLS(dpfr2)); NWARN(DEFAULT_ERROR_STRING); return; } if( OBJ_COLS(dpfr1) != OBJ_ROWS(dpfr2) ){ sprintf(DEFAULT_ERROR_STRING, "inner: # cols of operand %s (%d) must match # rows of operand %s (%d)", OBJ_NAME(dpfr1),OBJ_COLS(dpfr1),OBJ_NAME(dpfr2),OBJ_ROWS(dpfr2)); NWARN(DEFAULT_ERROR_STRING); return; } //_n=OBJ_COLS(dpfr1); /* the length of each dot product we will compute */ if( IS_COMPLEX(dpto) ) SET_OA_ARGSTYPE(oap,COMPLEX_ARGS); else SET_OA_ARGSTYPE(oap,REAL_ARGS); /* vdot things it's inputs have the same shape, so if we are taking the inner * product of a column vector with a row vector, we have to transpose one of * the inputs... */ if( OBJ_ROWS(dpfr1) > 1 ) SET_OA_SRC1(oap,d_subscript(QSP_ARG dpfr1,0) ); /* subscript first row */ else SET_OA_SRC1(oap,dpfr1); /* object is a row */ if( OBJ_COLS(dpto) > 1 ) col_dp=c_subscript(QSP_ARG dpfr2,0); else col_dp=dpfr2; SET_OA_DEST(oap,mk_subimg(QSP_ARG dpto,0,0,"target pixel",1,1) ); //[sizes setDimensionAtIndex : 1 withValue : OBJ_ROWS(col_dp) ]; SET_DIMENSION(sizes,1,OBJ_ROWS(col_dp)); SET_DIMENSION(sizes,0,OBJ_COMPS(col_dp)); SET_OA_SRC2(oap,make_equivalence(QSP_ARG "_transposed_column", col_dp,sizes,OBJ_PREC_PTR(col_dp)) ); for(i=0;i<OBJ_ROWS(dpto);i++){ src1_indices[2]=i; SET_OBJ_DATA_PTR( OA_SRC1(oap), multiply_indexed_data(dpfr1,src1_indices) ); for(j=0;j<OBJ_COLS(dpto);j++){ dst_indices[2]=i; /* k_th component */ dst_indices[1]=j; /* k_th component */ SET_OBJ_DATA_PTR( OA_DEST(oap), multiply_indexed_data(dpto,dst_indices) ); src2_indices[1]=j; SET_OBJ_DATA_PTR( OA_SRC2(oap), multiply_indexed_data(dpfr2,src2_indices) ); vdot(QSP_ARG oap); } } delvec(QSP_ARG OA_SRC2(oap) ); /* "_transposed_column" */ if( OA_SRC1(oap) != dpfr1 ) delvec(QSP_ARG OA_SRC1(oap) ); if( col_dp != dpfr2 ) delvec(QSP_ARG col_dp); delvec(QSP_ARG OA_DEST(oap) ); }
void multivariate_histo(QSP_ARG_DECL Data_Obj *histo_dp,Data_Obj *data_dp,float *width_array,float *min_array) { dimension_t n_dimensions; dimension_t i,j,k; unsigned int l; float *fbase, *fptr, *f; float *histbuf; incr_t index[MAX_DIMENSIONS]; int n_bins[MAX_DIMENSIONS]; int n_under[MAX_DIMENSIONS], n_over[MAX_DIMENSIONS]; INSIST_RAM_OBJ(histo_dp,compute_histo); INSIST_RAM_OBJ(data_dp,compute_histo); if( OBJ_PREC(histo_dp) != PREC_SP ){ NWARN("2D histogram precision must be float"); return; } if( OBJ_COMPS(histo_dp) != 1 ){ NWARN("2D histogram data must be real"); return; } if( OBJ_PXL_INC(histo_dp) != 1 ){ NWARN("2D histogram data must be contiguous"); return; } n_dimensions = OBJ_COMPS(data_dp); if( n_dimensions > MAX_DIMENSIONS ){ NWARN("Too many 2D histogram dimensions"); return; } if( OBJ_PREC(data_dp) != PREC_SP ){ NWARN("2D data precision must be float"); return; } fbase = (float *) OBJ_DATA_PTR(data_dp); for(l=0;l<n_dimensions;l++){ n_over[l]=0; n_under[l]=0; n_bins[l] = OBJ_TYPE_DIM(histo_dp,l+1); } histbuf = (float *) OBJ_DATA_PTR(histo_dp); zero_dimension(histo_dp,(float *)OBJ_DATA_PTR(histo_dp),n_dimensions,0L); for(l=0;l<MAX_DIMENSIONS;l++) index[l]=0; for(i=0;i<OBJ_FRAMES(data_dp);i++){ fptr = fbase; for(j=0;j<OBJ_ROWS(data_dp);j++){ f=fptr; for(k=0;k<OBJ_COLS(data_dp);k++){ float num[MAX_DIMENSIONS]; for(l=0;l<n_dimensions;l++){ num[l] = f[l]; /* assume cinc=1 */ num[l] -= min_array[l]; num[l] /= width_array[l]; num[l] += 0.5; index[l] = (incr_t)num[l]; /* cast to int */ if( index[l] < 0 ){ index[l]=0; n_under[l]++; } else if( index[l] >= n_bins[l] ){ index[l] = n_bins[l]-1; n_over[l]++; } } histbuf[ index[0] + index[1] * OBJ_ROW_INC(histo_dp) + index[2] * OBJ_FRM_INC(histo_dp) ] += 1.0; f += OBJ_PXL_INC(data_dp); } fptr += OBJ_ROW_INC(data_dp); } fbase += OBJ_FRM_INC(data_dp); } for(l=0;l<n_dimensions;l++){ if( (n_under[l] > 0) || (n_over[l] > 0) ){ sprintf(ERROR_STRING, "Histogram for %s had %d underflows and %d overflows in dimension %d", OBJ_NAME(data_dp),n_under[l],n_over[l],l); advise(ERROR_STRING); } } }
void vinterp(QSP_ARG_DECL Data_Obj *target,Data_Obj *source,Data_Obj *control) { float *to, *fr, *c; dimension_t i; int32_t n_to_interpolate=0; float *interp_dest; int32_t start_index=(-1); assert( target != NULL ); assert( source != NULL ); assert( control != NULL ); INSIST_RAM_OBJ(target,vinterp) INSIST_RAM_OBJ(source,vinterp) INSIST_RAM_OBJ(control,vinterp) if( not_prec(target,PREC_SP) ) return; if( not_prec(source,PREC_SP) ) return; if( not_prec(control,PREC_SP) ) return; if( !dp_same_size(target,source,"vinterp") ){ warn("vinterp: target/source length mismatch"); return; } if( !dp_same_size(target,control,"vinterp") ){ warn("vinterp: target/control length mismatch"); return; } if( OBJ_COMPS(source) != 1 || OBJ_COMPS(target) != 1 ){ warn("vinterp: component dimensions must be 1"); return; } /* could check that they are all vectors... */ to=(float *)OBJ_DATA_PTR(target); fr=(float *)OBJ_DATA_PTR(source); c=(float *)OBJ_DATA_PTR(control); interp_dest=to; for(i=0;i<OBJ_COLS(target);i++){ if( *c == 1.0 ){ /* copy data */ if( n_to_interpolate > 0 ){ /* end of gap? */ int j; float start_val, end_val; end_val = get_end_val(source,control,i); /* if we haven't seen any good values yet, * just fill in with the first good value. */ if( start_index < 0 ) start_val=end_val; /* * Otherwise, use a starting value which * is an average of the last N good values... */ else start_val = get_start_val(source,control,start_index); #ifdef DEBUG if( debug ){ sprintf(ERROR_STRING, "vinterp: %d values at index %d (start_i = %d), start = %f end = %f", n_to_interpolate,i,start_index,start_val,end_val); advise(ERROR_STRING); } #endif /* DEBUG */ for(j=0;j<n_to_interpolate;j++){ float factor; factor=((float)j+1)/((float)n_to_interpolate+1); *interp_dest = factor*end_val + (1-factor)*start_val; interp_dest += OBJ_PXL_INC(target); } } *to = *fr; start_index = i; /* always the last good one seen */ n_to_interpolate=0; } else { /* control is 0 */ if( n_to_interpolate == 0 ) /* remember start */ interp_dest = to; n_to_interpolate++; } to += OBJ_PXL_INC(target); c += OBJ_PXL_INC(control); fr += OBJ_PXL_INC(source); } if( n_to_interpolate > 0 ){ /* fill in at end? */ float fill_val; int j; if( start_index < 0 ){ warn("vinterp: no valid data!?"); fill_val=0.0; } else fill_val = get_start_val(source,control,start_index); for(j=0;j<n_to_interpolate;j++){ *interp_dest = fill_val; interp_dest += OBJ_PXL_INC(target); } } }
// 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 }
static void _ocl_offset_data(QSP_ARG_DECL Data_Obj *dp, index_t offset) { #ifndef USE_OPENCL_SUBREGION /* The original code used subBuffers, but overlapping subregions * don't work... * So instead we use a common memory buffer, but keep track * of the starting offset (in elements). This offset has * to be passed to the kernels. */ //fprintf(stderr,"ocl_offset_data: obj %s, offset = %d\n",OBJ_NAME(dp),offset); //fprintf(stderr,"\tparent obj %s, parent offset = %d\n",OBJ_NAME(OBJ_PARENT(dp)), //OBJ_OFFSET(OBJ_PARENT(dp))); if( IS_COMPLEX(dp) ){ assert( (offset & 1) == 0 ); offset /= 2; //fprintf(stderr,"Adjusted offset (%d) for complex object %s\n",offset,OBJ_NAME(dp)); } else if( IS_QUAT(dp) ){ assert( (offset & 3) == 0 ); offset /= 4; } SET_OBJ_DATA_PTR(dp,OBJ_DATA_PTR(OBJ_PARENT(dp))); SET_OBJ_OFFSET( dp, OBJ_OFFSET(OBJ_PARENT(dp)) + offset ); #else // USE_OPENCL_SUBREGION cl_mem buf; cl_mem parent_buf; cl_buffer_region reg; cl_int status; int extra_offset; parent_buf = find_parent_buf(OBJ_PARENT(dp),&extra_offset); assert( parent_buf != NULL ); reg.origin = (offset+extra_offset) * ELEMENT_SIZE(dp); // No - the region has to be big enough for all of the elements. // The safest thing is to include everything from the start // of the subregion to the end of the parent. Note that this // cannot handle negative increments!? // reg.size = OBJ_N_MACH_ELTS(dp) * ELEMENT_SIZE(dp); // p p p p p p p // p p c c c p p // p p p p p p p // p p c c c p p reg.size = OBJ_SEQ_INC(dp)*(OBJ_SEQS(dp)-1) + OBJ_FRM_INC(dp)*(OBJ_FRAMES(dp)-1) + OBJ_ROW_INC(dp)*(OBJ_ROWS(dp)-1) + OBJ_PXL_INC(dp)*(OBJ_COLS(dp)-1) + OBJ_COMP_INC(dp)*(OBJ_COMPS(dp)-1) + 1; reg.size *= ELEMENT_SIZE(dp); //fprintf(stderr,"requesting subregion of %ld bytes at offset %ld\n", //reg.size,reg.origin); buf = clCreateSubBuffer ( parent_buf, CL_MEM_READ_WRITE, CL_BUFFER_CREATE_TYPE_REGION, ®, &status); if( status != CL_SUCCESS ){ report_ocl_error(status, "clCreateSubBuffer"); SET_OBJ_DATA_PTR(dp,OBJ_DATA_PTR(OBJ_PARENT(dp))); } else { SET_OBJ_DATA_PTR(dp,buf); } // BUG - Because this object doesn't "own" the data, the sub-buffer // won't be released when the object is destroyed, a possible memory // leak... // We need to add a special case, or make data releasing a // platform-specific function... #endif // USE_OPENCL_SUBREGION }
static void fb_open(QSP_ARG_DECL const char *fb_name) { #ifdef HAVE_FB_DEV Dimension_Set dimset; FB_Info *fbip; long nbytes; fbip = new_fbi(QSP_ARG fb_name); if( fbip == NO_FBI ) return; fbip->fbi_fd = open(fb_name,O_RDWR); if( fbip->fbi_fd < 0 ){ perror(fb_name); sprintf(ERROR_STRING,"couldn't open device %s",fb_name); WARN(ERROR_STRING); /* BUG? - do we need any more cleanup? */ del_fbi(QSP_ARG fbip); return; } if (ioctl(fbip->fbi_fd,FBIOGET_VSCREENINFO, &fbip->fbi_var_info)<0) { perror("ioctl error getting variable screeninfo"); return; } /* see if the vbl sync flags are set... */ if (ioctl(fbip->fbi_fd,FBIOGET_FSCREENINFO, &fbip->fbi_fix_info)<0) { perror("ioctl error getting fixed screeninfo"); return; } SET_DS_COMPS(&dimset, fbip->fbi_var_info.bits_per_pixel/8 ); SET_DS_COLS(&dimset, fbip->fbi_var_info.xres_virtual ); SET_DS_ROWS(&dimset, fbip->fbi_var_info.yres_virtual ); SET_DS_FRAMES(&dimset, 1 ); SET_DS_SEQS(&dimset, 1 ); fbip->fbi_dp = _make_dp(QSP_ARG fb_name,&dimset,PREC_FOR_CODE(PREC_UBY)); if( fbip->fbi_dp == NO_OBJ ){ sprintf(ERROR_STRING,"Unable to create data object structure for %s",fb_name); WARN(ERROR_STRING); close(fbip->fbi_fd); del_fbi(QSP_ARG fbip); return; } nbytes = OBJ_ROWS(fbip->fbi_dp) * OBJ_COLS(fbip->fbi_dp) * OBJ_COMPS(fbip->fbi_dp); sprintf(ERROR_STRING,"mapping frame buffer device, %ld (0x%lx) bytes (%ld Mb)",nbytes,nbytes,nbytes/(1024*1024)); advise(ERROR_STRING); if( (OBJ_DATA_PTR(fbip->fbi_dp)=mmap(0,nbytes,PROT_READ|PROT_WRITE,MAP_SHARED,fbip->fbi_fd,0)) == MAP_FAILED ){ perror("mmap /dev/fb"); close(fbip->fbi_fd); fbip->fbi_fd = -1; del_fbi(QSP_ARG fbip); return; } curr_fbip = fbip; #else /* ! HAVE_FB_DEV */ WARN("No frame buffer device present at config time!?"); #endif /* ! HAVE_FB_DEV */ }