Created
March 12, 2022 05:53
-
-
Save F0bes/70b2e8c7fc508e914121b257678f99fe to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Tests MTBA with MXL 0 and MMIN 0 | |
// (MTBA still works with these set to 0) | |
#include "defs.h" | |
#include <kernel.h> | |
#include <tamtypes.h> | |
#include <stdio.h> | |
#include <gif_tags.h> | |
#include <gs_gp.h> | |
#include <gs_psm.h> | |
#include <dma.h> | |
#include <dma_tags.h> | |
#include <draw.h> | |
#include <graph.h> | |
#include <packet.h> | |
#include <stdlib.h> | |
#include <fcntl.h> | |
#include "clut.c" | |
#include "tex4_1.c" | |
#include "tex4_2.c" | |
#include "tex4_3.c" | |
#include "tex4_4.c" | |
const u32 WIDTH = 640; | |
const u32 HEIGHT = 480; | |
const s32 FRAME_PSM = GS_PSM_32; | |
#undef GS_SET_MIPTBP1 | |
#define GS_SET_MIPTBP1(TBA1, TBW1, TBA2, TBW2, TBA3, TBW3) \ | |
(u64)((TBA1)&0x00003FFF) << 0 | (u64)((TBW1)&0x0000003F) << 14 | \ | |
(u64)((TBA2)&0x00003FFF) << 20 | (u64)((TBW2)&0x0000003F) << 34 | \ | |
(u64)((TBA3)&0x00003FFF) << 40 | (u64)((TBW3)&0x0000003F) << 54 | |
#define GS_SETREG_TEST(ate, atst, aref, afail, date, datm, zte, ztst) \ | |
((u64)(ate) | ((u64)(atst) << 1) | \ | |
((u64)(aref) << 4) | ((u64)(afail) << 12) | \ | |
((u64)(date) << 14) | ((u64)(datm) << 15) | \ | |
((u64)(zte) << 16) | ((u64)(ztst) << 17)) | |
qword_t *draw_texture_transfer(qword_t *q, void *src, int width, int height, int psm, int dest, int dest_width, u32 dx, u32 dy); | |
int download_from_gs(u32 address, u32 format, const char *fname, int psm_size, int width, int height) | |
{ | |
u32 destBuffer[width * height]; | |
static union | |
{ | |
u32 value_u32[4]; | |
u128 value; | |
} enable_path3 ALIGNED(16) = { | |
{VIF1_MSKPATH3(0), VIF1_NOP, VIF1_NOP, VIF1_NOP}}; | |
u32 prev_imr; | |
u32 prev_chcr; | |
u32 dmaChain[20 * 2] ALIGNED(16); | |
u32 i = 0; // Used to index through the chain | |
u32 *pdma32 = (u32 *)&dmaChain; | |
u64 *pdma64 = (u64 *)(pdma32 + 4); | |
// Set up VIF packet | |
pdma32[i++] = VIF1_NOP; | |
pdma32[i++] = VIF1_MSKPATH3(0x8000); | |
pdma32[i++] = VIF1_FLUSHA; | |
pdma32[i++] = VIF1_DIRECT(6); | |
// Set up our GS packet | |
i = 0; | |
pdma64[i++] = GIFTAG(5, 1, 0, 0, 0, 1); | |
pdma64[i++] = GIF_AD; | |
// pdma64[i++] = GSBITBLTBUF_SET(address / 64, width / 64, format, 0, 0, 0); | |
pdma64[i++] = GSBITBLTBUF_SET(address / 64, width < 64 ? 1 : width / 64, format, 0, 0, 0); | |
pdma64[i++] = GSBITBLTBUF; | |
pdma64[i++] = GSTRXPOS_SET(0, 0, 0, 0, 0); // SSAX, SSAY, DSAX, DSAY, DIR | |
pdma64[i++] = GSTRXPOS; | |
pdma64[i++] = GSTRXREG_SET(width, height); // RRW, RRh | |
pdma64[i++] = GSTRXREG; | |
pdma64[i++] = 0; | |
pdma64[i++] = GSFINISH; | |
pdma64[i++] = GSTRXDIR_SET(1); // XDIR | |
pdma64[i++] = GSTRXDIR; | |
prev_imr = GsPutIMR(GsGetIMR() | 0x0200); | |
prev_chcr = *D1_CHCR; | |
if ((*D1_CHCR & 0x0100) != 0) | |
return 0; | |
// Finish event | |
*GS_CSR = CSR_FINISH; | |
// DMA crap | |
FlushCache(0); | |
printf("DMA stuff\n"); | |
*D1_QWC = 0x7; | |
*D1_MADR = (u32)pdma32; | |
*D1_CHCR = 0x101; | |
asm __volatile__("sync.l\n"); | |
// check if DMA is complete (STR=0) | |
printf("Waiting for DMA channel completion\n"); | |
while (*D1_CHCR & 0x0100) | |
; | |
printf("Waiting for GS_CSR\n"); | |
while ((*GS_CSR & CSR_FINISH) == 0) | |
; | |
printf("Waiting for the vif fifo to empty\n"); | |
// Wait for viffifo to become empty | |
while ((*VIF1_STAT & (0x1f000000))) | |
; | |
// Reverse busdir and transfer image to host | |
*VIF1_STAT = VIF1_STAT_FDR; | |
*GS_BUSDIR = (u64)0x00000001; | |
FlushCache(0); | |
u32 trans_size = ((width * height * psm_size) / 0x100); | |
printf("Download the frame in 2 transfers of qwc 0x%x\n", trans_size); | |
*D1_QWC = trans_size; | |
*D1_MADR = (u32)destBuffer; | |
*D1_CHCR = 0x100; | |
asm __volatile__(" sync.l\n"); | |
// check if DMA is complete (STR=0) | |
while (*D1_CHCR & 0x0100) | |
; | |
*D1_QWC = trans_size; | |
*D1_CHCR = 0x100; | |
asm __volatile__(" sync.l\n"); | |
// Wait for viffifo to become empty | |
while ((*VIF1_STAT & (0x1f000000))) | |
; | |
// check if DMA is complete (STR=0) | |
while (*D1_CHCR & 0x0100) | |
; | |
*D1_CHCR = prev_chcr; | |
asm __volatile__(" sync.l\n"); | |
*VIF1_STAT = 0; | |
*GS_BUSDIR = (u64)0; | |
// Put back prew imr and set finish event | |
GsPutIMR(prev_imr); | |
*GS_CSR = CSR_FINISH; | |
// Enable path3 again | |
*VIF1_FIFO = enable_path3.value; | |
/* | |
Write out to a file | |
*/ | |
FILE *f = fopen(fname, "w+"); | |
if ((u32)f < 0) | |
{ | |
printf("??? couldn't open file, trying usb\n"); | |
} | |
printf("File should be size %d\n", (psm_size / 8) * width * height); | |
fwrite(destBuffer, psm_size / 8, width * height, f); | |
fclose(f); | |
return 0; | |
} | |
int main(void) | |
{ | |
(*(volatile u_int *)0x10003000) = 1; | |
/* | |
Initialize graph | |
*/ | |
framebuffer_t fb; | |
fb.width = WIDTH; | |
fb.height = HEIGHT; | |
fb.psm = FRAME_PSM; | |
fb.mask = 0x00000000; | |
fb.address = graph_vram_allocate(fb.width, fb.height, fb.psm, GRAPH_ALIGN_PAGE); | |
zbuffer_t zb; | |
zb.enable = 1; | |
zb.zsm = GS_ZBUF_32; | |
zb.address = graph_vram_allocate(fb.width, fb.height, zb.zsm, GRAPH_ALIGN_PAGE); | |
zb.mask = 0; | |
zb.method = ZTEST_METHOD_ALLPASS; | |
graph_initialize(fb.address, fb.width, fb.height, fb.psm, 0, 0); | |
dma_channel_initialize(DMA_CHANNEL_GIF, NULL, 0); | |
dma_channel_fast_waits(DMA_CHANNEL_GIF); | |
/* | |
Init drawing stuff | |
*/ | |
packet_t *packet = packet_init(100, PACKET_NORMAL); | |
qword_t *q = packet->data; | |
q = draw_setup_environment(q, 0, &fb, &zb); | |
q = draw_primitive_xyoffset(q, 0, 0, 0); | |
q = draw_enable_tests(q, 0, &zb); | |
q = draw_finish(q); | |
dma_channel_send_normal(DMA_CHANNEL_GIF, packet->data, q - packet->data, 0, 0); | |
draw_wait_finish(); | |
/* | |
Upload texture | |
*/ | |
q = packet->data; | |
FlushCache(0); | |
int clutAddress = graph_vram_allocate(16, 16, GS_PSM_32, GRAPH_ALIGN_BLOCK); | |
q = draw_texture_transfer(q, &clut[0], 16, 16, GS_PSM_32, clutAddress, 64); | |
q = draw_texture_flush(q); | |
dma_channel_send_chain(DMA_CHANNEL_GIF, packet->data, q - packet->data, 0, 0); | |
dma_wait_fast(); | |
q = packet->data; | |
/*int texAddress32 = graph_vram_allocate(32, 32, GS_PSM_4, GRAPH_ALIGN_BLOCK); | |
int texAddress16 = graph_vram_allocate(16, 16, GS_PSM_4, GRAPH_ALIGN_BLOCK); | |
int texAddress8 = graph_vram_allocate(8, 8, GS_PSM_4, GRAPH_ALIGN_BLOCK); | |
int texAddress4 = graph_vram_allocate(4, 4, GS_PSM_4, GRAPH_ALIGN_BLOCK);*/ | |
int texAddress32 = graph_vram_allocate(32, 32, GS_PSM_4, GRAPH_ALIGN_BLOCK); | |
int texAddress16 = texAddress32 + 0x80; | |
int texAddress8 = texAddress16 + 0x40; | |
int texAddress4 =texAddress8 + 0x40; | |
printf("%x,%x,%x,%x\n", texAddress32, texAddress16, texAddress8, texAddress4); | |
q = draw_texture_transfer(q, (void *)tex4_1, 32, 32, GS_PSM_4, texAddress32, 64); | |
q = draw_texture_transfer(q, (void *)tex4_2, 16, 16, GS_PSM_4, texAddress16, 64); | |
q = draw_texture_transfer(q, (void *)tex4_3, 8, 8, GS_PSM_4, texAddress8, 64); | |
q = draw_texture_transfer(q, (void *)tex4_4, 4, 8, GS_PSM_4, texAddress4, 64); | |
//q = draw_texture_transfer(q, (void *)tex4_4, 4, 4, GS_PSM_4, texAddress32, 64); | |
q = draw_texture_flush(q); | |
dma_channel_send_chain(DMA_CHANNEL_GIF, packet->data, q - packet->data, 0, 0); | |
dma_wait_fast(); | |
/* | |
Now draw something | |
*/ | |
int frame = 0; | |
while (1) | |
{ | |
q = packet->data; | |
// Draw a full screen sprite | |
PACK_GIFTAG(q, GIF_SET_TAG(1, 1, GIF_PRE_ENABLE, GIF_PRIM_SPRITE, GIF_FLG_PACKED, 7), | |
GIF_REG_AD | (GIF_REG_AD << 4) | (GIF_REG_AD << 8) | (GIF_REG_AD << 12) | (GIF_REG_RGBAQ << 16) | (GIF_REG_XYZ2 << 20) | (GIF_REG_XYZ2 << 24)); | |
q++; | |
q->dw[0] = GS_SET_TEX1(1, 3, 0, 2, 1, 0, 0); // MXL 0 | |
q->dw[1] = GS_REG_TEX1; | |
q++; | |
q->dw[0] = GS_SET_MIPTBP1(texAddress16 / 64, 1, texAddress8 / 64, 1, texAddress4 / 64, 1); // MXL 3 | |
q->dw[1] = GS_REG_NOP; | |
q++; | |
q->dw[0] = GS_SET_TEX0(texAddress32 / 64, 1, GS_PSM_4, 5, 5, 0, 1, clutAddress / 64, GS_PSM_32, 0, 0, 1); | |
q->dw[1] = GS_REG_TEX0; | |
q++; | |
q->dw[0] = GS_SET_TEST(0, 0, 0, 0, 0, 0, 1, 1); | |
q->dw[1] = GS_REG_TEST; | |
q++; | |
// RGBAQ | |
q->dw[0] = (u64)((0x33) | ((u64)0x33 << 32)); | |
q->dw[1] = (u64)((0x33) | ((u64)0 << 32)); | |
q++; | |
// XYZ2 | |
q->dw[0] = (u64)((((0 << 4)) | (((u64)(0 << 4)) << 32))); | |
q->dw[1] = (u64)(0); | |
q++; | |
// XYZ2 | |
q->dw[0] = (u64)((((640 << 4)) | (((u64)(480 << 4)) << 32))); | |
q->dw[1] = (u64)(0); | |
q++; | |
q = draw_finish(q); | |
dma_channel_send_normal(DMA_CHANNEL_GIF, packet->data, q - packet->data, 0, 0); | |
draw_wait_finish(); | |
frame++; | |
if (!(frame % 1000)) | |
{ | |
printf("1000Frames\n"); | |
// allows me to reset ps2link | |
} | |
q = packet->data; | |
PACK_GIFTAG(q, GIF_SET_TAG(4, 1, GIF_PRE_ENABLE, GIF_SET_PRIM(GIF_PRIM_SPRITE, 0, 1, 0, 0, 0, 0, 0, 0), GIF_FLG_PACKED, 6), | |
GIF_REG_AD | (GIF_REG_ST << 4) | (GIF_REG_RGBAQ << 8) | (GIF_REG_XYZ2 << 12) | (GIF_REG_ST << 16) | (GIF_REG_XYZ2 << 20)); | |
q++; | |
{ // 128X128 | |
// TEST1 | |
q->dw[0] = GS_SET_TEX1(1, 3, 0, 2, 1, 0, 0); | |
q->dw[1] = GS_REG_TEX1; | |
q++; | |
// UV | |
q->dw[0] = GIF_SET_ST(0 << 4, 0 << 4); | |
q->dw[1] = 0x3f800000; | |
q++; | |
// RGBAQ (Q will default to 1.0f on new tag) | |
q->dw[0] = (u64)((0) | ((u64)0xcc << 32)); | |
q->dw[1] = (u64)((0xcc) | ((u64)0xFF << 32)); | |
q++; | |
// XYZ2 | |
q->dw[0] = (u64)((((0 << 4)) | (((u64)(0 << 4)) << 32))); | |
q->dw[1] = (u64)(0x1000); | |
q++; | |
// UV | |
q->dw[0] = GIF_SET_ST(0x3f800000, 0x3f800000); | |
q->dw[1] = 0x3f800000; | |
q++; | |
// XYZ2 | |
q->dw[0] = (u64)(((128 << 4)) | (((u64)(128 << 4)) << 32)); | |
q->dw[1] = (u64)(0x1000); | |
q++; | |
} | |
{ // 64X64 | |
// TEST1 | |
q->dw[0] = GS_SET_TEX1(1, 3, 0, 2, 1, 0, 1 << 4); | |
q->dw[1] = GS_REG_TEX1; | |
q++; | |
// UV | |
q->dw[0] = GIF_SET_ST(0 << 4, 0 << 4); | |
q->dw[1] = 0x3f800000; | |
q++; | |
// RGBAQ (Q will default to 1.0f on new tag) | |
q->dw[0] = (u64)((0) | ((u64)0xcc << 32)); | |
q->dw[1] = (u64)((0xcc) | ((u64)0xFF << 32)); | |
q++; | |
// XYZ2 | |
q->dw[0] = (u64)((((128 << 4)) | (((u64)(0 << 4)) << 32))); | |
q->dw[1] = (u64)(0x1000); | |
q++; | |
// UV | |
q->dw[0] = GIF_SET_ST(0x3f800000, 0x3f800000); | |
q->dw[1] = 0x3f800000; | |
q++; | |
// XYZ2 | |
q->dw[0] = (u64)(((256 << 4)) | (((u64)(128 << 4)) << 32)); | |
q->dw[1] = (u64)(0x1000); | |
q++; | |
} | |
{ // 32X32 | |
// TEST1 | |
q->dw[0] = GS_SET_TEX1(1, 3, 0, 2, 1, 0, 2 << 4); | |
q->dw[1] = GS_REG_TEX1; | |
q++; | |
// UV | |
q->dw[0] = GIF_SET_ST(0 << 4, 0 << 4); | |
q->dw[1] = 0x3f800000; | |
q++; | |
// RGBAQ (Q will default to 1.0f on new tag) | |
q->dw[0] = (u64)((0) | ((u64)0xcc << 32)); | |
q->dw[1] = (u64)((0xcc) | ((u64)0xFF << 32)); | |
q++; | |
// XYZ2 | |
q->dw[0] = (u64)((((256 << 4)) | (((u64)(0 << 4)) << 32))); | |
q->dw[1] = (u64)(0x1000); | |
q++; | |
// UV | |
q->dw[0] = GIF_SET_ST(0x3f800000, 0x3f800000); | |
q->dw[1] = 0x3f800000; | |
q++; | |
// XYZ2 | |
q->dw[0] = (u64)(((386 << 4)) | (((u64)(128 << 4)) << 32)); | |
q->dw[1] = (u64)(0x1000); | |
q++; | |
} | |
{ // 16X16 | |
// TEST1 | |
q->dw[0] = GS_SET_TEX1(1, 3, 0, 2, 1, 0, 3 << 4); | |
q->dw[1] = GS_REG_TEX1; | |
q++; | |
// UV | |
q->dw[0] = GIF_SET_ST(0 << 4, 0 << 4); | |
q->dw[1] = 0x3f800000; | |
q++; | |
// RGBAQ (Q will default to 1.0f on new tag) | |
q->dw[0] = (u64)((0) | ((u64)0xcc << 32)); | |
q->dw[1] = (u64)((0xcc) | ((u64)0xFF << 32)); | |
q++; | |
// XYZ2 | |
q->dw[0] = (u64)((((386 << 4)) | (((u64)(0 << 4)) << 32))); | |
q->dw[1] = (u64)(0x1000); | |
q++; | |
// UV | |
q->dw[0] = GIF_SET_ST(0x3f800000, 0x3f800000); | |
q->dw[1] = 0x3f800000; | |
q++; | |
// XYZ2 | |
q->dw[0] = (u64)(((512 << 4)) | (((u64)(128 << 4)) << 32)); | |
q->dw[1] = (u64)(0x1000); | |
q++; | |
} | |
q = draw_finish(q); | |
dma_channel_send_normal(DMA_CHANNEL_GIF, packet->data, q - packet->data, 0, 0); | |
// Wait until the drawing is finished. | |
draw_wait_finish(); | |
{ | |
/* q = packet->data; | |
PACK_GIFTAG(q, GIF_SET_TAG(1, 1, GIF_PRE_DISABLE, GIF_PRIM_SPRITE, GIF_FLG_PACKED, 3), | |
GIF_REG_AD | (GIF_REG_AD << 4) | (GIF_REG_AD << 8)); | |
q++; | |
q->dw[0] = GS_SET_TEX1(1, 3, 0, 2, 1, 0, 0); | |
q->dw[1] = GS_REG_TEX1; | |
q++; | |
q->dw[0] = GS_SET_MIPTBP1(0,1,0,1,0,1); | |
q->dw[1] = GS_REG_MIPTBP1; | |
q++; | |
q->dw[0] = GS_SET_TEX0(texAddress128 / 64, 2, GS_PSM_24, 7, 7, 0, 1, 0, 0, 0, 0, 0); | |
q->dw[1] = GS_REG_TEX0; | |
q++; | |
q = draw_finish(q); | |
dma_channel_send_normal(DMA_CHANNEL_GIF, packet->data, q - packet->data, 0, 0); | |
draw_wait_finish();*/ | |
} | |
q = packet->data; | |
PACK_GIFTAG(q, GIF_SET_TAG(4, 1, GIF_PRE_ENABLE, GIF_SET_PRIM(GIF_PRIM_SPRITE, 0, 1, 0, 0, 0, 0, 0, 0), GIF_FLG_PACKED, 6), | |
GIF_REG_AD | (GIF_REG_ST << 4) | (GIF_REG_RGBAQ << 8) | (GIF_REG_XYZ2 << 12) | (GIF_REG_ST << 16) | (GIF_REG_XYZ2 << 20)); | |
q++; | |
{ // 128X128 | |
// TEST1 | |
q->dw[0] = GS_SET_TEX1(1, 3, 0, 2, 1, 0, 0); | |
q->dw[1] = GS_REG_TEX1; | |
q++; | |
// UV | |
q->dw[0] = GIF_SET_ST(0 << 4, 0 << 4); | |
q->dw[1] = 0x3f800000; | |
q++; | |
// RGBAQ (Q will default to 1.0f on new tag) | |
q->dw[0] = (u64)((0) | ((u64)0xcc << 32)); | |
q->dw[1] = (u64)((0xcc) | ((u64)0xFF << 32)); | |
q++; | |
// XYZ2 | |
q->dw[0] = (u64)((((0 << 4)) | (((u64)(128 << 4)) << 32))); | |
q->dw[1] = (u64)(0x1000); | |
q++; | |
// UV | |
q->dw[0] = GIF_SET_ST(0x3f800000, 0x3f800000); | |
q->dw[1] = 0x3f800000; | |
q++; | |
// XYZ2 | |
q->dw[0] = (u64)(((128 << 4)) | (((u64)(256 << 4)) << 32)); | |
q->dw[1] = (u64)(0x1000); | |
q++; | |
} | |
{ // 64X64 | |
// TEST1 | |
q->dw[0] = GS_SET_TEX1(1, 3, 0, 2, 1, 0, 1 << 4); | |
q->dw[1] = GS_REG_TEX1; | |
q++; | |
// UV | |
q->dw[0] = GIF_SET_ST(0 << 4, 0 << 4); | |
q->dw[1] = 0x3f800000; | |
q++; | |
// RGBAQ (Q will default to 1.0f on new tag) | |
q->dw[0] = (u64)((0) | ((u64)0xcc << 32)); | |
q->dw[1] = (u64)((0xcc) | ((u64)0xFF << 32)); | |
q++; | |
// XYZ2 | |
q->dw[0] = (u64)((((128 << 4)) | (((u64)(128 << 4)) << 32))); | |
q->dw[1] = (u64)(0x1000); | |
q++; | |
// UV | |
q->dw[0] = GIF_SET_ST(0x3f800000, 0x3f800000); | |
q->dw[1] = 0x3f800000; | |
q++; | |
// XYZ2 | |
q->dw[0] = (u64)(((256 << 4)) | (((u64)(256 << 4)) << 32)); | |
q->dw[1] = (u64)(0x1000); | |
q++; | |
} | |
{ // 32X32 | |
// TEST1 | |
q->dw[0] = GS_SET_TEX1(1, 3, 0, 2, 1, 0, 2 << 4); | |
q->dw[1] = GS_REG_TEX1; | |
q++; | |
// UV | |
q->dw[0] = GIF_SET_ST(0 << 4, 0 << 4); | |
q->dw[1] = 0x3f800000; | |
q++; | |
// RGBAQ (Q will default to 1.0f on new tag) | |
q->dw[0] = (u64)((0) | ((u64)0xcc << 32)); | |
q->dw[1] = (u64)((0xcc) | ((u64)0xFF << 32)); | |
q++; | |
// XYZ2 | |
q->dw[0] = (u64)((((256 << 4)) | (((u64)(128 << 4)) << 32))); | |
q->dw[1] = (u64)(0x1000); | |
q++; | |
// UV | |
q->dw[0] = GIF_SET_ST(0x3f800000, 0x3f800000); | |
q->dw[1] = 0x3f800000; | |
q++; | |
// XYZ2 | |
q->dw[0] = (u64)(((386 << 4)) | (((u64)(256 << 4)) << 32)); | |
q->dw[1] = (u64)(0x1000); | |
q++; | |
} | |
{ // 16X16 | |
// TEST1 | |
q->dw[0] = GS_SET_TEX1(1, 3, 0, 2, 1, 0, 3 << 4); | |
q->dw[1] = GS_REG_TEX1; | |
q++; | |
// UV | |
q->dw[0] = GIF_SET_ST(0 << 4, 0 << 4); | |
q->dw[1] = 0x3f800000; | |
q++; | |
// RGBAQ (Q will default to 1.0f on new tag) | |
q->dw[0] = (u64)((0) | ((u64)0xcc << 32)); | |
q->dw[1] = (u64)((0xcc) | ((u64)0xFF << 32)); | |
q++; | |
// XYZ2 | |
q->dw[0] = (u64)((((386 << 4)) | (((u64)(128 << 4)) << 32))); | |
q->dw[1] = (u64)(0x1000); | |
q++; | |
// UV | |
q->dw[0] = GIF_SET_ST(0x3f800000, 0x3f800000); | |
q->dw[1] = 0x3f800000; | |
q++; | |
// XYZ2 | |
q->dw[0] = (u64)(((512 << 4)) | (((u64)(256 << 4)) << 32)); | |
q->dw[1] = (u64)(0x1000); | |
q++; | |
} | |
q = draw_finish(q); | |
dma_channel_send_normal(DMA_CHANNEL_GIF, packet->data, q - packet->data, 0, 0); | |
// Wait until the drawing is finished. | |
draw_wait_finish(); | |
/* Flat shaded triangle, for testing | |
q = packet->data; | |
PACK_GIFTAG(q, GIF_SET_TAG(1, 1, GIF_PRE_ENABLE, GIF_PRIM_TRIANGLE, GIF_FLG_PACKED, 5), | |
GIF_REG_AD | (GIF_REG_RGBAQ << 4) | (GIF_REG_XYZ2 << 8) | (GIF_REG_XYZ2 << 12) | (GIF_REG_XYZ2 << 16)); | |
q++; | |
// TEST1 | |
q->dw[0] = GS_SET_TEST(0, 0, 0, 0, 0, 0, 1, 1); | |
q->dw[1] = GS_REG_TEST; | |
q++; | |
// RGBAQ (Q will default to 1.0f on new tag) | |
q->dw[0] = (u64)((0) | ((u64)0xcc << 32)); | |
q->dw[1] = (u64)((0xcc) | ((u64)0xFF << 32)); | |
q++; | |
// XYZ2 | |
q->dw[0] = (u64)((((200 << 4)) | (((u64)(100 << 4)) << 32))); | |
q->dw[1] = (u64)(0x1000); | |
q++; | |
// XYZ2 | |
q->dw[0] = (u64)(((100 << 4)) | (((u64)(200 << 4)) << 32)); | |
q->dw[1] = (u64)(0x1000); | |
q++; | |
// XYZ2 | |
q->dw[0] = (u64)(((200 << 4)) | (((u64)(200 << 4)) << 32)); | |
q->dw[1] = (u64)(0x1000); | |
q++; | |
q = draw_finish(q); | |
dma_channel_send_normal(DMA_CHANNEL_GIF, packet->data, q - packet->data, 0, 0); | |
// Wait until the drawing is finished. | |
draw_wait_finish(); | |
*/ | |
// Now initiate vsync. | |
graph_wait_vsync(); | |
} | |
download_from_gs(fb.address, GS_PSM_32, "framebuffer.raw", 32, WIDTH, HEIGHT); | |
SleepThread(); | |
} | |
qword_t *draw_texture_transfer(qword_t *q, void *src, int width, int height, int psm, int dest, int dest_width, u32 dx, u32 dy) | |
{ | |
int i; | |
int remaining; | |
int qwords = 0; | |
switch (psm) | |
{ | |
case GS_PSM_8: | |
{ | |
qwords = (width * height) >> 4; | |
break; | |
} | |
case GS_PSM_32: | |
case GS_PSM_24: | |
{ | |
qwords = (width * height) >> 2; | |
break; | |
} | |
case GS_PSM_4: | |
{ | |
qwords = (width * height) >> 5; | |
break; | |
} | |
case GS_PSM_16: | |
case GS_PSM_16S: | |
{ | |
qwords = (width * height) >> 3; | |
break; | |
} | |
default: | |
{ | |
switch (psm) | |
{ | |
case GS_PSM_8H: | |
{ | |
qwords = (width * height) >> 4; | |
break; | |
} | |
case GS_PSMZ_32: | |
case GS_PSMZ_24: | |
{ | |
qwords = (width * height) >> 2; | |
break; | |
} | |
case GS_PSMZ_16: | |
case GS_PSMZ_16S: | |
{ | |
qwords = (width * height) >> 3; | |
break; | |
} | |
case GS_PSM_4HL: | |
case GS_PSM_4HH: | |
{ | |
qwords = (width * height) >> 5; | |
break; | |
} | |
} | |
break; | |
} | |
} | |
// Determine number of iterations based on the number of qwords | |
// that can be handled per dmatag | |
i = qwords / GIF_BLOCK_SIZE; | |
// Now calculate the remaining image data left over | |
remaining = qwords % GIF_BLOCK_SIZE; | |
// Setup the transfer | |
DMATAG_CNT(q, 5, 0, 0, 0); | |
q++; | |
PACK_GIFTAG(q, GIF_SET_TAG(4, 0, 0, 0, GIF_FLG_PACKED, 1), GIF_REG_AD); | |
q++; | |
PACK_GIFTAG(q, GS_SET_BITBLTBUF(0, 0, 0, dest >> 6, dest_width >> 6, psm), GS_REG_BITBLTBUF); | |
q++; | |
PACK_GIFTAG(q, GS_SET_TRXPOS(0, 0, dx, dy, 0), GS_REG_TRXPOS); | |
q++; | |
PACK_GIFTAG(q, GS_SET_TRXREG(width, height), GS_REG_TRXREG); | |
q++; | |
PACK_GIFTAG(q, GS_SET_TRXDIR(0), GS_REG_TRXDIR); | |
q++; | |
while (i-- > 0) | |
{ | |
// Setup image data dma chain | |
DMATAG_CNT(q, 1, 0, 0, 0); | |
q++; | |
PACK_GIFTAG(q, GIF_SET_TAG(GIF_BLOCK_SIZE, 0, 0, 0, 2, 0), 0); | |
q++; | |
DMATAG_REF(q, GIF_BLOCK_SIZE, (unsigned int)src, 0, 0, 0); | |
q++; | |
// Now increment the address by the number of qwords in bytes | |
src = (void *)src + (GIF_BLOCK_SIZE * 16); | |
} | |
if (remaining) | |
{ | |
// Setup remaining image data dma chain | |
DMATAG_CNT(q, 1, 0, 0, 0); | |
q++; | |
PACK_GIFTAG(q, GIF_SET_TAG(remaining, 0, 0, 0, 2, 0), 0); | |
q++; | |
DMATAG_REF(q, remaining, (unsigned int)src, 0, 0, 0); | |
q++; | |
} | |
return q; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment