Skip to content

Commit

Permalink
cellGcmSetDrawIndexArray offset
Browse files Browse the repository at this point in the history
  • Loading branch information
elad335 committed Jan 5, 2021
1 parent e7309f8 commit 26055c7
Show file tree
Hide file tree
Showing 7 changed files with 399 additions and 0 deletions.
1 change: 1 addition & 0 deletions rsx_tests/cellGcmSetDrawIndexArray offset/expected.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sample finished.
20 changes: 20 additions & 0 deletions rsx_tests/cellGcmSetDrawIndexArray offset/mainfp.cg
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
struct v2fConnector
{
float2 texCoord : TEXCOORD0;
};

struct f2fConnector
{
float4 COL : COLOR;
};

f2fConnector main
(
v2fConnector v2f,
uniform texobj2D texture
)
{
f2fConnector f2f;
f2f.COL = tex2D( texture, v2f.texCoord );
return f2f;
}
Binary file not shown.
359 changes: 359 additions & 0 deletions rsx_tests/cellGcmSetDrawIndexArray offset/mainrsxcrap.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,359 @@
#include <stdio.h>
#include <stdlib.h>

#include <sys/types.h>
#include <sys/process.h>
#include <sys/synchronization.h>
#include <sys/prx.h>

#include <sysutil/sysutil_sysparam.h>
#include <sysutil/sysutil_syscache.h>
#include <cell/sysmodule.h>
#include <sys/ppu_thread.h>
#include <sys/timer.h>
#include <sys/memory.h>
#include <sys/event.h>
#include <sys/syscall.h>
#include <memory>
#include <string.h>

#include "../rsx_header.h"

#define SYS_APP_HOME "/app_home"

#define VP_PROGRAM SYS_APP_HOME "/mainvp.vpo"
#define FP_PROGRAM SYS_APP_HOME "/mainfp.fpo"

// Set priority and stack size for the primary PPU thread.
// Priority : 1000
// Stack : 64KB
SYS_PROCESS_PARAM(1000, 0x10000)

static sys_memory_t mem_id;
static sys_addr_t addr;

//shader static data
static char *vpFile = NULL;
static CellCgbProgram vp;
static CellCgbVertexProgramConfiguration vpConf;
static const void *vpUcode = NULL;

static char *fpFile = NULL;
static CellCgbProgram fp;
static CellCgbFragmentProgramConfiguration fpConf;

static void *vucode, *fucode;
static u32 fpUcodeSize, vpUcodeSize;

static inline void LoadModules()
{
int ret = cellSysmoduleLoadModule( CELL_SYSMODULE_GCM_SYS );
ret |= cellSysmoduleLoadModule( CELL_SYSMODULE_FS );
ret |= cellSysmoduleLoadModule( CELL_SYSMODULE_RESC );
ENSURE_OK(ret != CELL_OK && ret != CELL_SYSMODULE_ERROR_DUPLICATED);
}

static rsxCommandCompiler c;
static CellGcmContextData& Gcm = c.c;

// CellGcmContextCallback
int GcmCallback(struct CellGcmContextData *, uint32_t){}

namespace loc
{
enum
{
video = 0,
fragment,
vertex,
varray,
color1,

__enum_max,
};
};

void* gLocations[static_cast<size_t>(loc::__enum_max)] =
{
ptr_cast(0xC0200000), // Video
ptr_cast(0xC0900000), // FP shader
NULL, // VP shader
ptr_cast(0xC0A00000), // Vertex array 1
ptr_cast(0xC0D00000), // Color buffer 1

};

struct Vertex4D{float i[4];};
static Vertex4D Varray[1] =
{
{.1, .2, .3, .4}
};


#define CELL_GCM_FUNCTION_MACROS
#include "cell/gcm/gcm_function_macros.h"
#include "cell/gcm/gcm_methods.h"
#define CELL_GCM_THIS thisContext
#define CELL_GCM_CURRENT CELL_GCM_THIS->current
#define CELL_GCM_END CELL_GCM_THIS->end
#define CELL_GCM_CALLBACK CELL_GCM_THIS->callback

void SetDrawIndexArray(CELL_GCM_ARGS(uint8_t mode,
uint32_t count, uint8_t type, uint8_t location, uint32_t indicies))
{
uint32_t startOffset;
uint32_t startIndex;
uint32_t misalignedIndexCount;

startOffset = indicies;

// need to compute the number of indexes from starting
// address to next 128-byte alignment

// type == 32
if(type == CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32)
misalignedIndexCount = (((startOffset + 127) & ~127) - startOffset) >> 2;
// type == 16
else
misalignedIndexCount = (((startOffset + 127) & ~127) - startOffset) >> 1;

CELL_GCM_RESERVE(7);

CELL_GCM_METHOD_INVALIDATE_VERTEX_FILE(CELL_GCM_CURRENT);

// begin
CELL_GCM_METHOD_SET_INDEX_ARRAY_OFFSET_FORMAT(CELL_GCM_CURRENT,
CELL_GCM_COMMAND_CAST(location), startOffset, CELL_GCM_COMMAND_CAST(type));
CELL_GCM_METHOD_SET_BEGIN_END(CELL_GCM_CURRENT,
CELL_GCM_COMMAND_CAST(mode));

startIndex = 0;
// starting address of first index is not 128 byte aligned
// send the mis-aligned indices thus aligning the rest to 128 byte boundary
if (misalignedIndexCount && (misalignedIndexCount < count))
{
uint32_t tmp = misalignedIndexCount-1;
CELL_GCM_RESERVE(2);
CELL_GCM_METHOD_DRAW_INDEX_ARRAY(CELL_GCM_CURRENT, startIndex,tmp);
count -= misalignedIndexCount;
startIndex += misalignedIndexCount;
}

// avoid writing more then 2047(0x7ff) words per inc method (hw limit)
CELL_GCM_ASSERT(count && (count <= 0xfffff)); // hw limit
while(count > 0x7FF00)
{
CELL_GCM_RESERVE(1+CELL_GCM_MAX_METHOD_COUNT);

count -= 0x7ff00;
CELL_GCM_CURRENT[0] = CELL_GCM_METHOD_NI(CELL_GCM_NV4097_DRAW_INDEX_ARRAY, CELL_GCM_MAX_METHOD_COUNT);
CELL_GCM_CURRENT += 1;
for (uint32_t lcount = CELL_GCM_MAX_METHOD_COUNT; lcount; --lcount)
{
CELL_GCM_CURRENT[0] = CELL_GCM_ENDIAN_SWAP(0xFF000000 | startIndex);
CELL_GCM_CURRENT += 1;
startIndex += 0x100;
}
}

// round up count to 256(0x100) counts
uint32_t mcount = (count + 0xff)>>8;

CELL_GCM_RESERVE(1+mcount);

// [startIndex, startIndex+0xff] range in DRAW_INDEX_ARRAY
CELL_GCM_CURRENT[0] = CELL_GCM_METHOD_NI(CELL_GCM_NV4097_DRAW_INDEX_ARRAY, mcount);
CELL_GCM_CURRENT += 1;
while(count > 0x100)
{
count -= 0x100;
CELL_GCM_CURRENT[0] = CELL_GCM_ENDIAN_SWAP(0xFF000000 | startIndex);
CELL_GCM_CURRENT += 1;
startIndex += 0x100;
}

// remainder indices
if(count)
{
--count;
CELL_GCM_CURRENT[0] = CELL_GCM_ENDIAN_SWAP((count << 24) | startIndex);
CELL_GCM_CURRENT += 1;
}

CELL_GCM_RESERVE(2);
CELL_GCM_METHOD_SET_BEGIN_END(CELL_GCM_CURRENT, 0);

CELL_GCM_DEBUG_FINISH(CELL_GCM_THIS);
}
int main() {

LoadModules();
sys_memory_allocate(0x1000000, 0x400, &addr);

ENSURE_OK(cellGcmInit(1<<16, 0x100000, ptr_cast(addr)));
GcmMapEaIoAddress(addr + (1<<20), 1<<20, 15<<20);

u8 id; cellGcmGetCurrentDisplayBufferId(&id);
cellGcmSetDisplayBuffer(id, 2<<20, 1280*4, 1280, 720);
cellGcmGetOffsetTable(&offsetTable);

const CellGcmDisplayInfo* disp_info = cellGcmGetDisplayInfo();
CellGcmControl* ctrl = cellGcmGetControlRegister();

// Wait for RSX to complete previous operation
wait_for_fifo(ctrl);

// Place a jump into io address 1mb
*OffsetToAddr(ctrl->get) = (1<<20) | RSX_METHOD_NEW_JUMP_CMD;
sys_timer_usleep(40);

// Load Shaders binaries and configs
{
u32 size = readFile(VP_PROGRAM,&vpFile);
ENSURE_NVAL(size, 0);

ENSURE_OK(cellCgbRead(vpFile, size, &vp));

//retrieve the vertex hardware configuration
cellCgbGetVertexConfiguration(&vp,&vpConf);

vpUcodeSize = cellCgbGetUCodeSize(&vp);

memcpy(gLocations[loc::vertex] = ptr_cast(addr + (1<<15)), cellCgbGetUCode(&vp), vpUcodeSize);
}

{
u32 size = readFile(FP_PROGRAM,&fpFile);
ENSURE_NVAL(size, 0);

ENSURE_OK(cellCgbRead(fpFile, size, &fp));

//retrieve the fragment program configuration
cellCgbGetFragmentConfiguration(&fp,&fpConf);

fpUcodeSize = cellCgbGetUCodeSize(&fp);

memcpy(gLocations[loc::fragment], cellCgbGetUCode(&fp), fpUcodeSize);
}

struct VertexData3D { float i[6];};

#define MINX -0.9f
#define MINY -0.9f
#define MAXX 0.9f
#define MAXY 0.9f
VertexData3D vertices[4] = {
// vertex tex coord
{ MINX,MINY,0.f,0, 0.f, 0.f },
{ MAXX,MINY,0.f,0, 1.f, 0.f },
{ MINX,MAXY,0.f,0, 0.f, 1.f },
{ MAXX,MAXY,0.f,0, 1.f, 1.f }
};
#undef MINX
#undef MINY
#undef MAXX
#undef MAXY

// Initial vertex array
memcpy(gLocations[loc::varray], &vertices, sizeof(VertexData3D) * 4);

cellGcmSetupContextData(&Gcm, ptr_caste(addr + (1<<20), u32), 0x10000, GcmCallback);
gcmLabel start = c.newLabel();

static const u32 colorOffset = 0x400000;
static const u32 depthOffset = 0x140000;

CellGcmSurface surface;
surface.type = CELL_GCM_SURFACE_PITCH;
surface.antialias = CELL_GCM_SURFACE_CENTER_1;
surface.colorFormat = CELL_GCM_SURFACE_X8R8G8B8_O8R8G8B8;
surface.colorTarget = CELL_GCM_SURFACE_TARGET_0;
for (u32 i = 0, pitch = cellGcmGetTiledPitchSize(1280*4); i < 4; i++)
{
surface.colorLocation[i] = CELL_GCM_LOCATION_MAIN;
surface.colorOffset[i] = colorOffset;
surface.colorPitch[i] = pitch;
}
surface.depthFormat = CELL_GCM_SURFACE_Z16;
surface.depthLocation = CELL_GCM_LOCATION_MAIN;
surface.depthOffset = depthOffset;
surface.depthPitch = 1280*2;
surface.width = 1280;
surface.height = 720;
surface.x = 0;
surface.y = 0;
cellGcmSetSurface(&Gcm, &surface);

// Texture cache
cellGcmSetInvalidateTextureCache(&Gcm, CELL_GCM_INVALIDATE_TEXTURE);

cellGcmSetTextureControl(&Gcm, 0, CELL_GCM_TRUE, 12, 12, CELL_GCM_TEXTURE_MAX_ANISO_1);

cellGcmSetTextureAddress( &Gcm, 0,
CELL_GCM_TEXTURE_CLAMP_TO_EDGE,
CELL_GCM_TEXTURE_CLAMP_TO_EDGE,
CELL_GCM_TEXTURE_CLAMP_TO_EDGE,
CELL_GCM_TEXTURE_UNSIGNED_REMAP_NORMAL,
CELL_GCM_TEXTURE_ZFUNC_LESS, 0);
cellGcmSetTextureFilter( &Gcm, 0, 0,
CELL_GCM_TEXTURE_NEAREST,
CELL_GCM_TEXTURE_NEAREST, CELL_GCM_TEXTURE_CONVOLUTION_QUINCUNX);

cellGcmSetVertexDataBase(&Gcm, 0, 0xFFFFF);

CellGcmTexture tex;
tex.location = CELL_GCM_LOCATION_MAIN;
tex.format = CELL_GCM_TEXTURE_A8R8G8B8 | CELL_GCM_TEXTURE_NR| CELL_GCM_TEXTURE_LN;
tex.dimension = CELL_GCM_TEXTURE_DIMENSION_2;
tex.pitch = 1280*4;
tex.height = 720;
tex.width = 720;
tex.offset = 1<<31;
tex.depth = 1;
tex.cubemap = CELL_GCM_FALSE;
tex.mipmap = 1;
tex.remap = CELL_GCM_TEXTURE_REMAP_REMAP << 14 |
CELL_GCM_TEXTURE_REMAP_REMAP << 12 |
CELL_GCM_TEXTURE_REMAP_REMAP << 10 |
CELL_GCM_TEXTURE_REMAP_REMAP << 8 |
CELL_GCM_TEXTURE_REMAP_FROM_B << 6 |
CELL_GCM_TEXTURE_REMAP_FROM_G << 4 |
CELL_GCM_TEXTURE_REMAP_FROM_R << 2 |
CELL_GCM_TEXTURE_REMAP_FROM_A;

cellGcmSetTexture(&Gcm, 0, &tex);

// State setting
cellGcmSetDepthFunc(&Gcm, CELL_GCM_ALWAYS);
cellGcmSetDepthTestEnable( &Gcm, CELL_GCM_TRUE );
cellGcmSetShadeMode(&Gcm, CELL_GCM_SMOOTH);

cellGcmSetVertexProgramLoad(&Gcm, &vpConf, gLocations[loc::vertex]);
fpConf.offset = 0x00900000;
cellGcmSetFragmentProgramLoad(&Gcm, &fpConf);
cellGcmSetVertexDataArray(&Gcm, 0 /*??*/, 0, sizeof(VertexData3D), 2,
CELL_GCM_VERTEX_F, CELL_GCM_LOCATION_LOCAL,
0x0A00000u );
cellGcmSetVertexDataArray(&Gcm, 1 /*??*/, 0, sizeof(VertexData3D), 2,
CELL_GCM_VERTEX_F, CELL_GCM_LOCATION_LOCAL,
0x0A00000u + (sizeof(float) * 4) );

SetDrawIndexArray(&Gcm, CELL_GCM_PRIMITIVE_TRIANGLE_STRIP, 4,CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32,CELL_GCM_LOCATION_LOCAL,0xE1900000);
ptr_caste(0xc1900000, u32)[0] = 0;
ptr_caste(0xc1900000, u32)[1] = 1;
ptr_caste(0xc1900000, u32)[2] = 2;
ptr_caste(0xc1900000, u32)[3] = 3;

cellGcmSetFlip(&Gcm, id);
cellGcmSetReferenceCommand(&Gcm, 2);
c.jmp(start);

c.flush();
sys_timer_usleep(100);

while (load_vol(ctrl->ref) != 2) sys_timer_usleep(1000);

printf("sample finished.\n");

return 0;
}
Binary file not shown.

0 comments on commit 26055c7

Please sign in to comment.