Hi, I wanted to know when i alloc a dma buffer like in r300_textmem or r200_textmem (same) and then when i do bitblt_multi i should see the component of a 32bits rgba texture wrapped ?
Or does the way the texture is specified in text1.c do the swap for me ? Because right now i see the correct picture. Does X use another way to send texture ? I attach the r300_demo i use to send texture via dma. Revealent code are between : /*********/ /*********/ Code that matter /*********/ /*********/ As r300_demo.c is becoming a little bit messy :) thx for your help, Jerome Glisse
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <math.h> #include "xf86drm.h" #include "radeon_common.h" #include "radeon_reg.h" #include "r300_reg.h" #include "global.h" #include "cmdline.h" /* this is just a 256x256 RGBA picture */ #include "tex1.c" #if BYTE_ORDER == BIG_ENDIAN #define SWAP16(A) ((((unsigned short)(A) & 0xff00) >> 8) | \ (((unsigned short)(A) & 0x00ff) << 8)) #define SWAP32(A) ((((CARD32)(A) & 0xff000000) >> 24) | \ (((CARD32)(A) & 0x00ff0000) >> 8) | \ (((CARD32)(A) & 0x0000ff00) << 8) | \ (((CARD32)(A) & 0x000000ff) << 24)) #else #define SWAP16(A) (A) #define SWAP32(A) (A) #endif struct gengetopt_args_info args_info; #define RADEON_TIMEOUT 2000000 /* Fall out of wait loops after this count */ int drmFD=-1; drmContext context; drmDMAReq dma; drmBufMapPtr BufMapPtr=NULL; #define DMA_COUNT 3 #define DMA_SIZE 64000 #define TEXT_DMA_COUNT 1 #define TEXT_DMA_SIZE 264000 int indices[DMA_COUNT]; int sizes[DMA_COUNT]; int text_indices[TEXT_DMA_COUNT]; int text_sizes[TEXT_DMA_COUNT]; #define INDIRECT 0 int indirect_start=0, indirect_end=0,indirect_idx=-1,indirect_size=0; CARD32 *indirect; /**********************************************************************************/ /**********************************************************************************/ int text_dma_start=0, text_dma_end=0,text_dma_idx=-1, text_dma_size=0; CARD32 *text_dmaptr; CARD32 gart_buffer_offset; /**********************************************************************************/ /**********************************************************************************/ #include "r300_lib.h" ADAPTOR adaptor; R300_PIPELINE pipeline; /* DRM driver does not reprogram MC controller by default. Thus all these can start at 0. I put depth and zmask at offsets that are inside visible framebuffer so I can see what is happening */ unsigned int display_base=0x0, zmask_offset=1920*4*700; int display_width=800; void xf86InstallSIGIOHandler(void) { fprintf(stderr,"I should not be called !!!\n"); exit(-1); } void xf86RemoveSIGIOHandler(void) { fprintf(stderr,"I should not be called !!!\n"); exit(-1); } void print_versions(void) { drmVersionPtr v; v=drmGetVersion(drmFD); fprintf(stderr,"driver \"%s\" version %d.%d.%d\n",v->name,v->version_major,v->version_minor,v->version_patchlevel); fprintf(stderr,"driver description \"%s\"\n",v->desc); fprintf(stderr,"AGPVendorID: %04x AGPDeviceId: %04x\n", drmAgpVendorId(drmFD), drmAgpDeviceId(drmFD)); fprintf(stderr,"BusID: \"%s\"\n", drmGetBusid(drmFD)); } void *registers=NULL, *agp_space=NULL, *framebuffer=NULL; unsigned long agp_physical=0x0; unsigned short get_short(CARD32 address) { unsigned short *p; p=(unsigned short *)(registers+address); return SWAP16(*p); } CARD32 get_int(CARD32 address) { CARD32 *p; p=(CARD32 *)(registers+address); return SWAP32(*p); } void GetMaps(void) { int i,r; drmHandle offset; drmSize size; drmMapType type; drmMapFlags flags; drmHandle handle; int mtrr; char *typename; agp_physical=drmAgpBase(drmFD); fprintf(stderr,"AGP base: 0x%08x\n", (unsigned int)agp_physical); fprintf(stderr,"Map Offset Size Type Handle Mtrr\n"); for(i=0; !drmGetMap(drmFD, i, &offset, &size, &type, &flags, &handle, &mtrr); i++){ switch(type){ case DRM_FRAME_BUFFER: typename = "FB"; if((r=drmMap(drmFD, offset, size, &framebuffer))<0) drmError(r, __func__); break; case DRM_REGISTERS: typename = "REG"; if((r=drmMap(drmFD, offset, size, ®isters))<0) drmError(r, __func__); break; case DRM_SHM: typename = "SHM"; break; case DRM_AGP: typename = "AGP"; if(offset==agp_physical){ if((r=drmMap(drmFD, offset, size, &agp_space))<0) drmError(r, __func__); } break; case DRM_SCATTER_GATHER: typename = "SG"; break; default: typename = "???"; break; } fprintf(stderr,"%2d 0x%08lx %8d KB %3.3s 0x%08lx ", i, offset, size/1024, typename, handle); if(mtrr < 0 ) fprintf(stderr," none\n"); else fprintf(stderr,"%4d\n", mtrr); } #if BYTE_ORDER == BIG_ENDIAN agp_physical=(((get_int(RADEON_MC_AGP_LOCATION))& 0x0ffffU) << 16); #endif } void GetBufs(void) { int i,r; dma.context = context; dma.send_count = 0; dma.request_count = DMA_COUNT; dma.request_size = DMA_SIZE; dma.request_list = indices; dma.request_sizes = sizes; dma.flags = DRM_DMA_WAIT; for(i=0;i<RADEON_TIMEOUT;i++){ drmGetLock(drmFD, context, DRM_LOCK_READY); if((r=drmDMA(drmFD, &dma))!=EBUSY){ drmUnlock(drmFD,context); if(!r)break; drmError(r, __func__); exit(-1); } fprintf(stderr,"drmDMA()=EBUSY, trying again\n"); drmUnlock(drmFD,context); } printf("Buffers:\n"); for(i=0;i<dma.granted_count;i++){ printf("%5d: index = %d, size = %d\n", i, dma.request_list[i], dma.request_sizes[i]); } indirect_idx=indices[INDIRECT]; indirect_size=sizes[INDIRECT]; /**********************************************************************************/ /**********************************************************************************/ dma.context = context; dma.send_count = 0; dma.request_count = TEXT_DMA_COUNT; dma.request_size = TEXT_DMA_SIZE; dma.request_list = text_indices; dma.request_sizes = text_sizes; dma.flags = DRM_DMA_WAIT; for(i=0;i<RADEON_TIMEOUT;i++){ drmGetLock(drmFD, context, DRM_LOCK_READY); if((r=drmDMA(drmFD, &dma))!=EBUSY){ drmUnlock(drmFD,context); if(!r)break; drmError(r, __func__); exit(-1); } fprintf(stderr,"drmDMA()=EBUSY, trying again\n"); drmUnlock(drmFD,context); } printf("Text Buffers:\n"); for(i=0;i<dma.granted_count;i++){ printf("%5d: index = %d, size = %d\n", i, dma.request_list[i], dma.request_sizes[i]); } text_dma_idx=text_indices[INDIRECT]; text_dma_size=text_sizes[INDIRECT]; struct drm_radeon_getparam gp; gp.param = RADEON_PARAM_GART_BUFFER_OFFSET; gp.value = &gart_buffer_offset; int ret = drmCommandWriteRead(drmFD, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); if(ret) { fprintf(stderr, "(RADEON_PARAM_GART_BUFFER_OFFSET) error: %d\n", ret); } fprintf(stderr, "(RADEON_PARAM_GART_BUFFER_OFFSET): 0x%08x\n", gart_buffer_offset); /**********************************************************************************/ /**********************************************************************************/ } void FlushIndirect(void) { drmRadeonIndirect indirect; int r; while(indirect_end & 0x3c){ e32(RADEON_CP_PACKET2); /* fill up to multiple of 16 dwords */ } if(indirect_end & 0x3){ fprintf(stderr,"indirect_end & 0x3\n"); return; /* does not end on dword boundary */ } if(indirect_start==indirect_end){ fprintf(stderr,"indirect empty\n"); return; } if(indirect_end>=indirect_size){ fprintf(stderr,"indirect out of bounds\n"); return; } fprintf(stderr,"flushing indirect buffer with %d dwords\n", (indirect_end-indirect_start)/4); indirect.idx = indirect_idx; indirect.start = indirect_start; indirect.end = indirect_end; indirect.discard = 0; drmGetLock(drmFD,context,DRM_LOCK_READY); r=drmCommandWriteRead(drmFD, DRM_RADEON_INDIRECT, &indirect, sizeof(drmRadeonIndirect)); drmUnlock(drmFD,context); if(r<0){ drmError(r, __func__); } indirect_start=indirect_end; } void read_registers(void) { if(registers==NULL){ fprintf(stderr,"No register map found\n"); exit(-1); } fprintf(stderr,"VendorID: %04x DeviceID: %04x\n", get_short(RADEON_VENDOR_ID), get_short(RADEON_DEVICE_ID)); if(get_short(RADEON_VENDOR_ID)!=0x1002){ fprintf(stderr,"VendorID is not 0x1002, aborting\n"); exit(-1); } adaptor.chip=0; if(args_info.R300_given)adaptor=FOUR_PIPE_ADAPTOR; if(args_info.RV350_given)adaptor=TWO_PIPE_ADAPTOR; if(adaptor.chip==0){ /* chip type unknown, try to determine automatically */ switch(get_short(RADEON_DEVICE_ID)){ case 0x4144: case 0x4145: case 0x4146: case 0x4147: /* these are not strictly speaking Mobility, but they have the same number of pipes */ case 0x4150: /* Sapphire Radeon 9600 pro, RV350 AP */ case 0x4151: case 0x4152: case 0x4153: /* Radeon 9550 */ case 0x4154: case 0x4156: case 0x4e50: /* Mobility M10 */ adaptor=TWO_PIPE_ADAPTOR; break; case 0x4e44: /* AIW 9700 */ case 0x4e45: case 0x4e46: case 0x4e47: case 0x4e48: /* R350 - Radeon 9800 */ case 0x4e49: /* R350 - Radeon 9800 */ adaptor=FOUR_PIPE_ADAPTOR; break; default: fprintf(stderr, "Unknown device id: 0x%04x, aborting\n", get_short(RADEON_DEVICE_ID)); exit(-1); } } display_width=(get_int(RADEON_CRTC_PITCH) & 0x3ff)*8; display_base=get_int(RADEON_DISPLAY_BASE_ADDR); fprintf(stderr,"display_width=%d\n", display_width); fprintf(stderr,"display_base=0x%08x\n", display_base); } void EmitBITBLT(void) { int srcx,srcy,dstx,dsty,w,h,color_fmt,src_pitch,src_offset,dst_pitch,dst_offset; srcx=0; srcy=0; dstx=500; dsty=500; w=200; h=150; src_pitch=display_width*4; dst_pitch=display_width*4; src_offset=0; dst_offset=0; color_fmt=6; e32(RADEON_CP_PACKET3_CNTL_BITBLT_MULTI | (5 << 16)); e32(RADEON_GMC_SRC_PITCH_OFFSET_CNTL | RADEON_GMC_DST_PITCH_OFFSET_CNTL | RADEON_GMC_BRUSH_NONE | (color_fmt << 8) | RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP3_S | RADEON_DP_SRC_SOURCE_MEMORY | RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS ); e32(((src_pitch/64)<<22) | (src_offset >> 10)); e32(((dst_pitch/64)<<22) | (dst_offset >> 10)); e32((srcx << 16) | srcy); e32((dstx << 16) | dsty); /* dst */ e32((w << 16) | h); } /* play with color space argument here */ #define COLORSPACE (6<<5) /* ARGB */ void test_triangles(void) { init_3d(&adaptor); set_viewport(320.0, 888.0, -240.0, 262.0, 0.5, 0.5); set_scissors(0, 0, 2647, 1941); set_cliprect(0, 0, 0, 2647,1941); set_cliprect(1, 0, 0, 2647,1941); set_cliprect(2, 0, 0, 2647,1941); set_cliprect(3, 0, 0, 2647,1941); if(args_info.clear_color_arg)clear_color_buffer(&adaptor, 0.0, 0.0); clear_depth_buffer(&adaptor, 0.0, 0.0); init_flat_primitive(&adaptor); set_quad0(1.0,1.0,1.0,1.0); set_init21(0.0,1.0); /* rainbow triangle */ start_primitive(R300_VAP_VF_CNTL__PRIM_TRIANGLES); emit_flat_vertex(1.0,0.0,0.0, 1.0,0.0,0.0); emit_flat_vertex(0.0,1.0,0.0, 0.0,1.0,0.0); emit_flat_vertex(0.0,0.0,1.0, 0.0,0.0,1.0); end_primitive(); /* black triangle */ start_primitive(R300_VAP_VF_CNTL__PRIM_TRIANGLES); emit_flat_vertex(-1.1,-1.1,0.0, 0.0,0.0,0.0); emit_flat_vertex(-1.1,0.3,0.0, 0.0,0.0,0.0); emit_flat_vertex(0.3,-1.1,0.0, 0.0,0.0,0.0); end_primitive(); /* white triangle */ start_primitive(R300_VAP_VF_CNTL__PRIM_TRIANGLES); emit_flat_vertex(-1.0,-1.0,0.0, 1.0,1.0,1.0); emit_flat_vertex(-1.0,0.0,0.0, 1.0,1.0,1.0); emit_flat_vertex(0.0,-1.0,0.0, 1.0,1.0,1.0); end_primitive(); end_3d(); } void test_tex_bitblt(void) { /**********************************************************************************/ /**********************************************************************************/ /**********************************************************************************/ /**********************************************************************************/ unsigned int srcx,srcy,dstx,dsty,w,h,color_fmt,src_pitch,src_offset,dst_pitch,dst_offset; /* copy picture into beginning of AGP space */ if(agp_space==NULL){ fprintf(stderr,"AGP/GART space not found... Yeeeks !\n"); exit(-1); } //memcpy(agp_space, texture1.pixel_data, texture1.width*texture1.height*texture1.bytes_per_pixel); memcpy(text_dmaptr + text_dma_start, texture1.pixel_data, texture1.width*texture1.height*texture1.bytes_per_pixel/2); srcx=0; srcy=0; dstx=200; dsty=200; w=texture1.width; h=texture1.height; src_pitch=texture1.width*4; dst_pitch=display_width*4; //src_offset=agp_physical; src_offset= ((unsigned int)gart_buffer_offset) + ((unsigned int)text_dmaptr) - ((unsigned int)BufMapPtr->list[0].address) + text_dma_start; fprintf(stderr,"AGP space : 0x%08x\n",(unsigned int)agp_space); fprintf(stderr,"AGP physical : 0x%08x\n",(unsigned int)agp_physical); fprintf(stderr,"TEXT DMA src offset : 0x%08x\n",(unsigned int)src_offset); dst_offset=0; color_fmt=6; e32(RADEON_CP_PACKET3_CNTL_BITBLT_MULTI | (5 << 16)); e32(RADEON_GMC_SRC_PITCH_OFFSET_CNTL | RADEON_GMC_DST_PITCH_OFFSET_CNTL | RADEON_GMC_BRUSH_NONE | (color_fmt << 8) | RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP3_S | RADEON_DP_SRC_SOURCE_MEMORY | RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS ); e32(((src_pitch/64)<<22) | (src_offset >> 10)); e32(((dst_pitch/64)<<22) | (dst_offset >> 10)); e32((srcx << 16) | srcy); e32((dstx << 16) | dsty); /* dst */ e32((w << 16) | h); /**********************************************************************************/ /**********************************************************************************/ /**********************************************************************************/ /**********************************************************************************/ } void test_tex_triangles(void) { /* copy picture into beginning of AGP space */ if(agp_space==NULL){ fprintf(stderr,"AGP/GART space not found... Yeeeks !\n"); exit(-1); } memcpy(agp_space, texture1.pixel_data, texture1.width*texture1.height*texture1.bytes_per_pixel); init_3d(&adaptor); set_viewport(200.0, 888.0, -240.0, 262.0, 0.5, 0.5); set_scissors(0, 0, 2600, 1900); set_cliprect(0, 0, 0, 2647,1941); set_cliprect(1, 0, 0, 2647,1941); set_cliprect(2, 0, 0, 2647,1941); set_cliprect(3, 0, 0, 2647,1941); if(args_info.clear_color_arg)clear_color_buffer(&adaptor, 0.0, 0.0); clear_depth_buffer(&adaptor, 0.0, 0.0); SINGLE_TEXTURE_PIPELINE.texture_unit[0].offset=agp_physical; //SINGLE_TEXTURE_PIPELINE.texture_unit[0].format=R300_EASY_TX_FORMAT(X,Y,Z,W, R8G8B8A8); init_textured_primitive(&adaptor); program_pipeline(&SINGLE_TEXTURE_PIPELINE); start_primitive(R300_VAP_VF_CNTL__PRIM_TRIANGLES); emit_textured_vertex(-2.0,-1.0,0.0, 0.0,0.0); emit_textured_vertex(1.0,-1.0,2.0, 1.0,0.0); emit_textured_vertex(1.0,1.0, 1.0, 1.0,1.0); emit_textured_vertex(-2.0,1.0,1.0, 0.0,1.0); emit_textured_vertex(-2.0,-1.0,0.0, 0.0,0.0); emit_textured_vertex(1.0,1.0,1.0, 1.0,1.0); end_primitive(); end_3d(); } void test_vb_triangles(void) { AOS_DATA vb_arrays[2]; int i; float a[300]; /* vertex coordinates */ for(i=0;i<150;i++)a[i]=-1.0+(2.0*rand())/RAND_MAX; /* color components */ for(i=150;i<300;i++)a[i]=(2.0*rand())/RAND_MAX; memcpy(agp_space, a, 300*4); /* setup array of structures data */ /* xyz */ vb_arrays[0].element_size=3; vb_arrays[0].stride=3; vb_arrays[0].offset=agp_physical; vb_arrays[0].format=AOS_FORMAT_FLOAT_COLOR; vb_arrays[0].ncomponents=3; vb_arrays[0].reg=REG_COORDS; /* color */ vb_arrays[1].element_size=3; vb_arrays[1].stride=3; vb_arrays[1].offset=agp_physical+150*4; vb_arrays[1].format=AOS_FORMAT_FLOAT; vb_arrays[1].ncomponents=3; vb_arrays[1].reg=REG_COLOR0; init_3d(&adaptor); set_viewport(320.0, 888.0, -240.0, 262.0, 0.5, 0.5); set_scissors(0, 0, 2647, 1941); set_cliprect(0, 0, 0, 2647,1941); set_cliprect(1, 0, 0, 2647,1941); set_cliprect(2, 0, 0, 2647,1941); set_cliprect(3, 0, 0, 2647,1941); if(args_info.clear_color_arg)clear_color_buffer(&adaptor, 0.0, 0.0); clear_depth_buffer(&adaptor, 0.0, 0.0); init_flat_primitive(&adaptor); set_quad0(1.0,1.0,1.0,1.0); set_init21(0.0,1.0); reg_start(R300_RE_OCCLUSION_CNTL, 0); e32(R300_OCCLUSION_ON); setup_AOS(vb_arrays, 2); fire_AOS(27, R300_VAP_VF_CNTL__PRIM_TRIANGLES); end_3d(); } #define EB_N_ELEMENTS 300 void test_eb_triangles(void) { AOS_DATA vb_arrays[2]; int i; float a[EB_N_ELEMENTS*6]; unsigned short int b[EB_N_ELEMENTS]; /* vertex coordinates */ for(i=0;i<EB_N_ELEMENTS*3;i++)a[i]=-1.0+(2.0*rand())/RAND_MAX; /* color components */ for(i=EB_N_ELEMENTS*3;i<EB_N_ELEMENTS*6;i++)a[i]=(2.0*rand())/RAND_MAX; for(i=0;i<EB_N_ELEMENTS;i++) b[i]=i; memcpy(agp_space, a, EB_N_ELEMENTS*6*4); memcpy(agp_space+EB_N_ELEMENTS*6*4, b, EB_N_ELEMENTS*2); /* setup array of structures data */ /* xyz */ vb_arrays[0].element_size=3; vb_arrays[0].stride=3; vb_arrays[0].offset=agp_physical; vb_arrays[0].format=AOS_FORMAT_FLOAT_COLOR; vb_arrays[0].ncomponents=3; vb_arrays[0].reg=REG_COORDS; /* color */ vb_arrays[1].element_size=3; vb_arrays[1].stride=3; vb_arrays[1].offset=agp_physical+EB_N_ELEMENTS*3*4; vb_arrays[1].format=AOS_FORMAT_FLOAT; vb_arrays[1].ncomponents=3; vb_arrays[1].reg=REG_COLOR0; init_3d(&adaptor); set_viewport(320.0, 888.0, -240.0, 262.0, 0.5, 0.5); set_scissors(0, 0, 2647, 1941); set_cliprect(0, 0, 0, 2647,1941); set_cliprect(1, 0, 0, 2647,1941); set_cliprect(2, 0, 0, 2647,1941); set_cliprect(3, 0, 0, 2647,1941); if(args_info.clear_color_arg)clear_color_buffer(&adaptor, 0.0, 0.0); clear_depth_buffer(&adaptor, 0.0, 0.0); init_flat_primitive(&adaptor); set_quad0(1.0,1.0,1.0,1.0); set_init21(0.0,1.0); reg_start(R300_RE_OCCLUSION_CNTL, 0); e32(R300_OCCLUSION_ON); setup_AOS(vb_arrays, 2); fire_EB(agp_physical+EB_N_ELEMENTS*6*4, EB_N_ELEMENTS, R300_VAP_VF_CNTL__PRIM_TRIANGLES); end_3d(); } void test_immd_triangles(void) { int i; AOS_DATA vb_arrays[2]; /* setup array of structures data */ /* Note: immediate vertex data includes all coordinates. To save bandwidth use either VBUF or state-based vertex generation */ /* xyz */ vb_arrays[0].element_size=4; vb_arrays[0].stride=4; vb_arrays[0].offset=0; /* Not used */ vb_arrays[0].format=AOS_FORMAT_FLOAT; vb_arrays[0].ncomponents=4; vb_arrays[0].reg=REG_COORDS; /* color */ vb_arrays[1].element_size=4; vb_arrays[1].stride=4; vb_arrays[1].offset=0; /* Not used */ vb_arrays[1].format=AOS_FORMAT_FLOAT_COLOR; vb_arrays[1].ncomponents=4; vb_arrays[1].reg=REG_COLOR0; init_3d(&adaptor); set_viewport(320.0, 888.0, -240.0, 262.0, 0.5, 0.5); set_scissors(0, 0, 2647, 1941); set_cliprect(0, 0, 0, 2647,1941); set_cliprect(1, 0, 0, 2647,1941); set_cliprect(2, 0, 0, 2647,1941); set_cliprect(3, 0, 0, 2647,1941); if(args_info.clear_color_arg)clear_color_buffer(&adaptor, 0.0, 0.0); clear_depth_buffer(&adaptor, 0.0, 0.0); init_flat_primitive(&adaptor); set_quad0(1.0,1.0,1.0,1.0); set_init21(0.0,1.0); reg_start(R300_RE_OCCLUSION_CNTL, 0); e32(R300_OCCLUSION_ON); /* We need LOAD_VBPNTR to setup AOS_ATTR fields.. the offsets are irrelevant */ setup_AOS(vb_arrays, 2); start_immediate_packet(6, R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP, 8); for(i=0;i<6;i++){ /* I don't know how to tell the engine (and whether it is possible) that I don't want to send all the components.. This is likely what state-based input is for */ /* coordinates */ efloat(-1.0+(2.0*rand())/RAND_MAX); efloat(-1.0+(2.0*rand())/RAND_MAX); efloat(-1.0+(2.0*rand())/RAND_MAX); efloat(-1.0+(2.0*rand())/RAND_MAX); /* colors */ efloat((1.0*rand())/RAND_MAX); efloat((1.0*rand())/RAND_MAX); efloat((1.0*rand())/RAND_MAX); efloat((1.0*rand())/RAND_MAX); } end_3d(); } void test_idx_triangles(void) { AOS_DATA vb_arrays[2]; int i; float a[300]; /* vertex coordinates */ for(i=0;i<150;i++)a[i]=-1.0+(2.0*rand())/RAND_MAX; /* color components */ for(i=150;i<300;i++)a[i]=(2.0*rand())/RAND_MAX; memcpy(agp_space, a, 300*4); /* setup array of structures data */ /* xyz */ vb_arrays[0].element_size=3; vb_arrays[0].stride=3; vb_arrays[0].offset=agp_physical; vb_arrays[0].format=AOS_FORMAT_FLOAT_COLOR; vb_arrays[0].ncomponents=3; vb_arrays[0].reg=REG_COORDS; /* color */ vb_arrays[1].element_size=3; vb_arrays[1].stride=3; vb_arrays[1].offset=agp_physical+150*4; vb_arrays[1].format=AOS_FORMAT_FLOAT; vb_arrays[1].ncomponents=3; vb_arrays[1].reg=REG_COLOR0; init_3d(&adaptor); set_viewport(320.0, 888.0, -240.0, 262.0, 0.5, 0.5); set_scissors(0, 0, 2647, 1941); set_cliprect(0, 0, 0, 2647,1941); set_cliprect(1, 0, 0, 2647,1941); set_cliprect(2, 0, 0, 2647,1941); set_cliprect(3, 0, 0, 2647,1941); if(args_info.clear_color_arg)clear_color_buffer(&adaptor, 0.0, 0.0); clear_depth_buffer(&adaptor, 0.0, 0.0); init_flat_primitive(&adaptor); set_quad0(1.0,1.0,1.0,1.0); set_init21(0.0,1.0); reg_start(R300_RE_OCCLUSION_CNTL, 0); e32(R300_OCCLUSION_ON); setup_AOS(vb_arrays, 2); start_index32_packet(27, R300_VAP_VF_CNTL__PRIM_TRIANGLES); /* should be the same output as when we do fire_AOS */ for(i=0;i<27;i++)e32(i); end_3d(); } void test_tex_immd_triangles(void) { AOS_DATA vb_arrays[3]; int i; /* setup array of structures data */ /* Note: immediate vertex data includes all coordinates. To save bandwidth use either VBUF or state-based vertex generation */ /* xyz */ vb_arrays[0].element_size=4; vb_arrays[0].stride=4; vb_arrays[0].offset=0; /* Not used */ vb_arrays[0].format=AOS_FORMAT_FLOAT; vb_arrays[0].ncomponents=4; vb_arrays[0].reg=REG_COORDS; /* color */ vb_arrays[1].element_size=4; vb_arrays[1].stride=4; vb_arrays[1].offset=0; /* Not used */ vb_arrays[1].format=AOS_FORMAT_FLOAT_COLOR; vb_arrays[1].ncomponents=4; vb_arrays[1].reg=REG_COLOR0; /* texture */ vb_arrays[2].element_size=4; vb_arrays[2].stride=4; vb_arrays[2].offset=0; /* Not used */ vb_arrays[2].format=AOS_FORMAT_FLOAT; vb_arrays[2].ncomponents=4; vb_arrays[2].reg=REG_TEX0; /* copy picture into beginning of AGP space */ if(agp_space==NULL){ fprintf(stderr,"AGP/GART space not found... Yeeeks !\n"); exit(-1); } memcpy(agp_space, texture1.pixel_data, texture1.width*texture1.height*texture1.bytes_per_pixel); SINGLE_TEXTURE_PIPELINE.texture_unit[0].offset=agp_physical; init_3d(&adaptor); set_viewport(200.0, 888.0, -240.0, 262.0, 0.5, 0.5); set_scissors(0, 0, 2600, 1900); set_cliprect(0, 0, 0, 2647,1941); set_cliprect(1, 0, 0, 2647,1941); set_cliprect(2, 0, 0, 2647,1941); set_cliprect(3, 0, 0, 2647,1941); if(args_info.clear_color_arg)clear_color_buffer(&adaptor, 0.0, 0.0); clear_depth_buffer(&adaptor, 0.0, 0.0); init_textured_primitive(&adaptor); program_pipeline(&SINGLE_TEXTURE_PIPELINE); /* We need LOAD_VBPNTR to setup AOS_ATTR fields.. the offsets are irrelevant */ setup_AOS(vb_arrays, 3); start_immediate_packet(6, R300_VAP_VF_CNTL__PRIM_TRIANGLES, 12); for(i=0;i<6;i++){ /* I don't know how to tell the engine (and whether it is possible) that I don't want to send all the components.. This is likely what state-based input is for */ /* coordinates */ efloat(-1.0+(2.0*rand())/RAND_MAX); efloat(-1.0+(2.0*rand())/RAND_MAX); efloat(-1.0+(2.0*rand())/RAND_MAX); efloat(-1.0+(2.0*rand())/RAND_MAX); /* colors */ efloat((1.0*rand())/RAND_MAX); efloat((1.0*rand())/RAND_MAX); efloat((1.0*rand())/RAND_MAX); efloat((1.0*rand())/RAND_MAX); /* texture coordinates */ efloat((1.0*rand())/RAND_MAX); efloat((1.0*rand())/RAND_MAX); efloat((1.0*rand())/RAND_MAX); efloat((1.0*rand())/RAND_MAX); } end_3d(); } void float_demo1(void) { int i; float *p; /*generate data in the beginning of AGP space */ if(agp_space==NULL){ fprintf(stderr,"AGP/GART space not found... Yeeeks !\n"); exit(-1); } p=(float *)agp_space; for(i=0;i<256*256*4;i++){ p[i]=i/4.0; p[i]=i/(4.0*256.0*256.0); } init_3d(&adaptor); #if 0 set_viewport(500.0, 500.0, -500.0, 500.0, 0.5, 0.5); #endif set_viewport(320.0, 888.0, -240.0, 262.0, 0.5, 0.5); set_scissors(0, 0, 2600, 1900); set_cliprect(0, 0, 0, 2647,1941); set_cliprect(1, 0, 0, 2647,1941); set_cliprect(2, 0, 0, 2647,1941); set_cliprect(3, 0, 0, 2647,1941); SINGLE_TEXTURE_PIPELINE.write_z_value=0; SINGLE_TEXTURE_PIPELINE.z_test=R300_Z_TEST_ALWAYS; SINGLE_TEXTURE_PIPELINE.texture_unit[0].format=R300_EASY_TX_FORMAT(Y,Y,Y,ONE,FL_I32); SINGLE_TEXTURE_PIPELINE.texture_unit[0].format=R300_EASY_TX_FORMAT(Z,Y,X,W,FL_R32G32B32A32); SINGLE_TEXTURE_PIPELINE.texture_unit[0].offset=agp_physical; fprintf(stderr, "Using texture format %08x\n", SINGLE_TEXTURE_PIPELINE.texture_unit[0].format); init_textured_primitive(&adaptor); program_pipeline(&SINGLE_TEXTURE_PIPELINE); start_primitive(R300_VAP_VF_CNTL__PRIM_TRIANGLES); emit_textured_vertex(-1.0,-1.0,0.0, 0.0,0.0); emit_textured_vertex(1.0,-1.0,0.0, 1.0,0.0); emit_textured_vertex(1.0,1.0, 0.0, 1.0,1.0); emit_textured_vertex(-1.0,1.0,0.0, 0.0,1.0); emit_textured_vertex(-1.0,-1.0,0.0, 0.0,0.0); emit_textured_vertex(1.0,1.0, 0.0, 1.0,1.0); end_primitive(); end_3d(); } int main(int argc, char *argv[]) { int r,i; if(cmdline_parser(argc, argv, &args_info))exit(-1); CHECKPOINT drmFD=drmOpen("radeon", args_info.bus_id_arg); if(drmFD<0){ drmError(drmFD, __func__ ); fprintf(stderr, "Check that BusId is correct. You can find the correct BusId in /var/log/Xorg.0.log\n"); fprintf(stderr, "You can also try setting the environment variable LIBGL_DEBUG to \"verbose\" to see what libdrm is trying to do.\n"); exit(-1); } print_versions(); if((r=drmCreateContext(drmFD, &context))){ drmError(r, __func__); fprintf(stderr, "Could not create context, aborting\n"); exit(-1); } fprintf(stderr,"Context %d\n",context); #if 0 if((r = drmSwitchToContext(drmFD, context))){ drmError(r, __func__); exit(-1); } #endif GetMaps(); GetBufs(); fprintf(stderr,"Mapping buffers:\n"); BufMapPtr=drmMapBufs(drmFD); if(BufMapPtr==NULL){ drmError(r, __func__); fprintf(stderr, "Could not map buffers, aborting\n"); exit(-1); } fprintf(stderr,"\tidx\tsize\tused\taddress\n"); for(i=0;i<BufMapPtr->count;i++){ fprintf(stderr,"\t%d\t%d\t%d\t%p", BufMapPtr->list[i].idx, BufMapPtr->list[i].total, BufMapPtr->list[i].used, BufMapPtr->list[i].address); if(BufMapPtr->list[i].idx==indirect_idx){ fprintf(stderr,"\tINDIRECT"); indirect=BufMapPtr->list[i].address; indirect_start=BufMapPtr->list[i].used; indirect_end=indirect_start; } if(BufMapPtr->list[i].idx==text_dma_idx){ fprintf(stderr,"\tTEXT INDIRECT"); text_dmaptr=BufMapPtr->list[i].address; text_dma_start=BufMapPtr->list[i].used; text_dma_end=text_dma_start; } fprintf(stderr,"\n"); } /* setup ADAPTOR structure */ read_registers(); adaptor.color_offset[0]=display_base; adaptor.color_pitch[0]=(display_width | (0xc0<<16)); adaptor.depth_offset=display_width*4*500; adaptor.depth_pitch=display_width | (0x2 << 16); print_adaptor(&adaptor); if(args_info.diag_given){ /* exit quietly.. */ exit(0); } fprintf(stderr,"Last chance to hit ^C\n"); system("sync"); sleep(1); /* Give people chance to hit Ctrl-C */ /* play around with indirect buffer here */ if(args_info.bitblt_given){ EmitBITBLT(); } if(args_info.triangles_given){ test_triangles(); } if(args_info.tex_bitblt_given){ test_tex_bitblt(); } if(args_info.tex_triangles_given){ test_tex_triangles(); } if(args_info.vb_triangles_given){ test_vb_triangles(); } if(args_info.eb_triangles_given){ test_eb_triangles(); } if(args_info.immd_triangles_given){ test_immd_triangles(); } if(args_info.idx_triangles_given){ test_idx_triangles(); } if(args_info.tex_immd_triangles_given){ test_tex_immd_triangles(); } if(args_info.float_demo1_given){ float_demo1(); } FlushIndirect(); /* free stuff */ drmFreeBufs(drmFD,dma.granted_count,indices); drmFreeBufs(drmFD,dma.granted_count,text_indices); if((r=drmDestroyContext(drmFD, context))){ drmError(r, __func__); exit(-1); } drmClose(drmFD); CHECKPOINT return 0; }