static int rmUploadClut(GSCLUT *clut) { if (clut->VramClut && clut->VramClut != GSKIT_ALLOC_ERROR) // already uploaded return 1; u32 size; u32 w, h; if (!rmClutSize(clut, &size, &w, &h)) return 0; size = (-GS_VRAM_BLOCKSIZE_256)&(size+GS_VRAM_BLOCKSIZE_256-1); // too large to fit VRAM with the currently allocated space? if(gsGlobal->CurrentPointer + size >= __VRAM_SIZE) { if (size >= __VRAM_SIZE) { // Only log this if the allocation is too large itself LOG("RENDERMAN Requested clut allocation is bigger than VRAM!\n"); // We won't allocate this, it's too large clut->VramClut = GSKIT_ALLOC_ERROR; return 0; } rmFlush(); } clut->VramClut = gsGlobal->CurrentPointer; gsGlobal->CurrentPointer += size; rmAppendUploadedCLUTs(clut); SyncDCache(clut->Clut, (u8*)(clut->Clut)+size); gsKit_texture_send_inline(gsGlobal, clut->Clut, w, h, clut->VramClut, clut->ClutPSM, 1, GS_CLUT_PALLETE); return 1; }
static int rmUploadTexture(GSTEXTURE* txt) { // For clut based textures... if (txt->Clut) { // upload CLUT first if (!rmUploadClut((GSCLUT *)txt->Clut)) return 0; // copy the new VramClut txt->VramClut = ((GSCLUT*)txt->Clut)->VramClut; } u32 size = gsKit_texture_size(txt->Width, txt->Height, txt->PSM); // alignment of the allocation size = (-GS_VRAM_BLOCKSIZE_256)&(size+GS_VRAM_BLOCKSIZE_256-1); // too large to fit VRAM with the currently allocated space? if(gsGlobal->CurrentPointer + size >= __VRAM_SIZE) { if (size >= __VRAM_SIZE) { // Only log this if the allocation is too large itself LOG("RENDERMAN Requested texture allocation is bigger than VRAM!\n"); // We won't allocate this, it's too large txt->Vram = GSKIT_ALLOC_ERROR; return 0; } rmFlush(); // Should not flush CLUT away. If this happenned we have to reupload if (txt->Clut) { if (!rmUploadClut((GSCLUT *)txt->Clut)) return 0; txt->VramClut = ((GSCLUT*)txt->Clut)->VramClut; } // only could fit CLUT but not the pixmap with it! if(gsGlobal->CurrentPointer + size >= __VRAM_SIZE) return 0; } txt->Vram = gsGlobal->CurrentPointer; gsGlobal->CurrentPointer += size; rmAppendUploadedTextures(txt); // We can't do gsKit_texture_upload since it'd assume txt->Clut is the CLUT table directly // whereas we're using it as a pointer to our structure containg clut data gsKit_setup_tbw(txt); SyncDCache(txt->Mem, (u8*)(txt->Mem)+size); gsKit_texture_send_inline(gsGlobal, txt->Mem, txt->Width, txt->Height, txt->Vram, txt->PSM, txt->TBW, txt->Clut ? GS_CLUT_TEXTURE : GS_CLUT_NONE); return 1; }
int main(void) { GSGLOBAL *gsGlobal = gsKit_init_global(); //GS_MODE_VGA_640_60 GSTEXTURE Sprite; u64 White = GS_SETREG_RGBAQ(0xFF,0xFF,0xFF,0x00,0x00); #ifdef HAVE_LIBPNG u64 TexCol = GS_SETREG_RGBAQ(0x80,0x80,0x80,0x80,0x00); #endif gsGlobal->PSM = GS_PSM_CT24; gsGlobal->PSMZ = GS_PSMZ_16S; // gsGlobal->DoubleBuffering = GS_SETTING_OFF; // gsGlobal->ZBuffering = GS_SETTING_OFF; dmaKit_init(D_CTRL_RELE_OFF,D_CTRL_MFD_OFF, D_CTRL_STS_UNSPEC, D_CTRL_STD_OFF, D_CTRL_RCYC_8, 1 << DMA_CHANNEL_GIF); // Initialize the DMAC dmaKit_chan_init(DMA_CHANNEL_GIF); gsGlobal->PrimAlphaEnable = GS_SETTING_ON; gsKit_init_screen(gsGlobal); Sprite.Delayed = GS_SETTING_ON; #ifdef HAVE_LIBPNG if(gsKit_texture_png(gsGlobal, &Sprite, "host:texstream.png") < 0) { printf("Loading Failed!\n"); } #endif Sprite.Vram = gsKit_vram_alloc(gsGlobal, gsKit_texture_size(Sprite.Width, Sprite.Height, Sprite.PSM), GSKIT_ALLOC_USERBUFFER); gsKit_mode_switch(gsGlobal, GS_ONESHOT); while(1) { gsKit_clear(gsGlobal, White); gsKit_texture_send_inline(gsGlobal, Sprite.Mem, Sprite.Width, Sprite.Height, Sprite.Vram, Sprite.PSM, Sprite.TBW, GS_CLUT_NONE); gsKit_set_primalpha(gsGlobal, GS_SETREG_ALPHA(0,1,0,1,0), 0); gsKit_set_test(gsGlobal, GS_ATEST_OFF); #ifdef HAVE_LIBPNG gsKit_prim_sprite_texture(gsGlobal, &Sprite, 310.0f, // X1 50.0f, // Y2 0.0f, // U1 0.0f, // V1 Sprite.Width + 310.0f, // X2 Sprite.Height + 50.0f, // Y2 Sprite.Width, // U2 Sprite.Height, // V2 3, TexCol); #endif gsKit_set_test(gsGlobal, GS_ATEST_ON); gsKit_set_primalpha(gsGlobal, GS_BLEND_BACK2FRONT, 0); gsKit_sync_flip(gsGlobal); gsKit_queue_exec(gsGlobal); } return 0; }