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;
}