From bf4ddae73d052b3825ea2bb98d78ad8474bda531 Mon Sep 17 00:00:00 2001 From: James Benton Date: Wed, 10 May 2017 17:32:37 +0100 Subject: [PATCH] Add gx2 triangle hello world. Shader assembled using the latte-assembler tool in decaf-emu repo. --- samples/CMakeLists.txt | 3 +- samples/gx2/CMakeLists.txt | 4 ++ samples/gx2/content/pos_col_shader.gsh | Bin 0 -> 1386 bytes samples/gx2/content/pos_col_shader.psh | 9 +++ samples/gx2/content/pos_col_shader.vsh | 22 ++++++ samples/gx2/triangle/CMakeLists.txt | 14 ++++ samples/gx2/triangle/src/main.c | 92 +++++++++++++++++++++++++ samples/helloworld/src/main.c | 30 +++----- 8 files changed, 154 insertions(+), 20 deletions(-) create mode 100644 samples/gx2/CMakeLists.txt create mode 100644 samples/gx2/content/pos_col_shader.gsh create mode 100644 samples/gx2/content/pos_col_shader.psh create mode 100644 samples/gx2/content/pos_col_shader.vsh create mode 100644 samples/gx2/triangle/CMakeLists.txt create mode 100644 samples/gx2/triangle/src/main.c diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 459a68ce..1b85c9ee 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -1,5 +1,6 @@ cmake_minimum_required(VERSION 3.2) -project(wut-samples) +project(samples) add_subdirectory(helloworld) add_subdirectory(pong) +add_subdirectory(gx2) diff --git a/samples/gx2/CMakeLists.txt b/samples/gx2/CMakeLists.txt new file mode 100644 index 00000000..e5854f10 --- /dev/null +++ b/samples/gx2/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.2) +project(samples-gx2) + +add_subdirectory(triangle) diff --git a/samples/gx2/content/pos_col_shader.gsh b/samples/gx2/content/pos_col_shader.gsh new file mode 100644 index 0000000000000000000000000000000000000000..e1c4694b3c0e61fdd9b43842f5253339ed5cfafa GIT binary patch literal 1386 zcmZ=yt1x0m!0z$gK#)_~|{OuLW(W(fh+fJ_AeW*|EaOU$uC zeTNj%4V*R#j0_!Y3{w~mFaT)<5wHm(fWQ(yY{2jVrT~-_$pj1#Sa<K1PT|&q$-Ogbyroz$F|2 De)CrP literal 0 HcmV?d00001 diff --git a/samples/gx2/content/pos_col_shader.psh b/samples/gx2/content/pos_col_shader.psh new file mode 100644 index 00000000..d23c6c7e --- /dev/null +++ b/samples/gx2/content/pos_col_shader.psh @@ -0,0 +1,9 @@ +; $MODE = "UniformRegister" +; $SQ_PGM_RESOURCES_PS.NUM_GPRS = 1 +; $SPI_PS_IN_CONTROL_0.NUM_INTERP = 1 +; $NUM_SPI_PS_INPUT_CNTL = 1 +; $SPI_PS_INPUT_CNTL[0].SEMANTIC = 0 +; $SPI_PS_INPUT_CNTL[0].DEFAULT_VAL = 1 + +00 EXP_DONE: PIX0, R0.xyzw +END_OF_PROGRAM diff --git a/samples/gx2/content/pos_col_shader.vsh b/samples/gx2/content/pos_col_shader.vsh new file mode 100644 index 00000000..cfe36108 --- /dev/null +++ b/samples/gx2/content/pos_col_shader.vsh @@ -0,0 +1,22 @@ +; $MODE = "UniformRegister" +; $ATTRIB_VARS[0].name = "aColour" +; $ATTRIB_VARS[0].type = "Float4" +; $ATTRIB_VARS[0].location = 0 +; $ATTRIB_VARS[1].name = "aPosition" +; $ATTRIB_VARS[1].type = "Float4" +; $ATTRIB_VARS[1].location = 1 +; $SQ_PGM_RESOURCES_VS.NUM_GPRS = 3 +; $SQ_PGM_RESOURCES_VS.STACK_SIZE = 1 +; $NUM_SPI_VS_OUT_ID = 1 +; $SPI_VS_OUT_ID[0].SEMANTIC_0 = 0 +; $SQ_VTX_SEMANTIC_CLEAR.CLEAR = 0xFFFFFFFC +; $NUM_SQ_VTX_SEMANTIC = 2 +; $SQ_VTX_SEMANTIC[0].SEMANTIC_ID = 0 +; $SQ_VTX_SEMANTIC[1].SEMANTIC_ID = 1 +; $VGT_VERTEX_REUSE_BLOCK_CNTL.VTX_REUSE_DEPTH = 14 +; $VGT_HOS_REUSE_DEPTH.REUSE_DEPTH = 16 + +00 CALL_FS NO_BARRIER +01 EXP_DONE: POS0, R2.xyzw +02 EXP_DONE: PARAM0, R1.xyzw NO_BARRIER +END_OF_PROGRAM diff --git a/samples/gx2/triangle/CMakeLists.txt b/samples/gx2/triangle/CMakeLists.txt new file mode 100644 index 00000000..8ef4b233 --- /dev/null +++ b/samples/gx2/triangle/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.2) +project(samples-gx2-triangle) + +file(GLOB_RECURSE SOURCE_FILES src/*.c) +file(GLOB_RECURSE HEADER_FILES src/*.h) + +add_rpx_lite(triangle ${SOURCE_FILES} ${HEADER_FILES}) +target_link_libraries(triangle + whb + coreinit + defaultheap + gx2 + gfd + proc_ui) diff --git a/samples/gx2/triangle/src/main.c b/samples/gx2/triangle/src/main.c new file mode 100644 index 00000000..a762b584 --- /dev/null +++ b/samples/gx2/triangle/src/main.c @@ -0,0 +1,92 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const float sPositionData[] = +{ + 0.0f, -0.5f, 0.0f, + -0.5f, 0.5f, 0.0f, + 0.5f, 0.5f, 0.0f +}; + +static const float sColourData[] = +{ + 1.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 1.0f +}; + +int main(int argc, char **argv) +{ + GX2RBuffer positionBuffer = { 0 }; + GX2RBuffer colourBuffer = { 0 }; + WHBGfxShaderGroup group = { 0 }; + void *buffer = NULL; + char *gshFileData = NULL; + + WHBProcInit(); + WHBGfxInit(); + + gshFileData = WHBReadWholeFile("pos_col_shader.gsh", NULL); + + if (!WHBGfxLoadGFDShaderGroup(&group, 0, gshFileData)) { + return -1; + } + + WHBGfxInitShaderAttribute(&group, "aPosition", 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32_32); + WHBGfxInitShaderAttribute(&group, "aColour", 1, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32_32); + WHBGfxInitFetchShader(&group); + + WHBFreeWholeFile(gshFileData); + gshFileData = NULL; + + positionBuffer.flags = GX2R_RESOURCE_BIND_VERTEX_BUFFER | GX2R_RESOURCE_USAGE_CPU_WRITE | GX2R_RESOURCE_USAGE_GPU_READ; + positionBuffer.elemSize = 4 * 3; + positionBuffer.elemCount = 3; + GX2RCreateBuffer(&positionBuffer); + buffer = GX2RLockBufferEx(&positionBuffer, 0); + memcpy(buffer, sPositionData, 4 * 3 * 3); + GX2RUnlockBufferEx(&positionBuffer, 0); + + colourBuffer.flags = GX2R_RESOURCE_BIND_VERTEX_BUFFER | GX2R_RESOURCE_USAGE_CPU_WRITE | GX2R_RESOURCE_USAGE_GPU_READ; + colourBuffer.elemSize = 4 * 3; + colourBuffer.elemCount = 3; + GX2RCreateBuffer(&colourBuffer); + buffer = GX2RLockBufferEx(&colourBuffer, 0); + memcpy(buffer, sColourData, 4 * 3 * 3); + GX2RUnlockBufferEx(&colourBuffer, 0); + + while(WHBProcIsRunning()) { + WHBGfxBeginRender(); + + WHBGfxBeginRenderTV(); + GX2SetFetchShader(&group.fetchShader); + GX2SetVertexShader(group.vertexShader); + GX2SetPixelShader(group.pixelShader); + GX2RSetAttributeBuffer(&positionBuffer, 0, positionBuffer.elemSize, 0); + GX2RSetAttributeBuffer(&colourBuffer, 1, colourBuffer.elemSize, 0); + GX2DrawEx(GX2_PRIMITIVE_MODE_TRIANGLES, 3, 0, 1); + WHBGfxFinishRenderTV(); + + WHBGfxBeginRenderDRC(); + GX2SetFetchShader(&group.fetchShader); + GX2SetVertexShader(group.vertexShader); + GX2SetPixelShader(group.pixelShader); + GX2RSetAttributeBuffer(&positionBuffer, 0, positionBuffer.elemSize, 0); + GX2RSetAttributeBuffer(&colourBuffer, 1, colourBuffer.elemSize, 0); + GX2DrawEx(GX2_PRIMITIVE_MODE_TRIANGLES, 3, 0, 1); + WHBGfxFinishRenderDRC(); + + WHBGfxFinishRender(); + } + + WHBGfxShutdown(); + WHBProcShutdown(); + return 0; +} diff --git a/samples/helloworld/src/main.c b/samples/helloworld/src/main.c index 22be22ed..86271869 100644 --- a/samples/helloworld/src/main.c +++ b/samples/helloworld/src/main.c @@ -7,36 +7,28 @@ bool isAppRunning = true; -void +static void SaveCallback() { OSSavesDone_ReadyToRelease(); // Required } -bool +static bool AppRunning() { - if(!OSIsMainCore()) - { + if (!OSIsMainCore()) { ProcUISubProcessMessages(true); - } - else - { + } else { ProcUIStatus status = ProcUIProcessMessages(true); - - if(status == PROCUI_STATUS_EXITING) - { + + if (status == PROCUI_STATUS_EXITING) { // Being closed, deinit, free, and prepare to exit isAppRunning = false; ProcUIShutdown(); - } - else if(status == PROCUI_STATUS_RELEASE_FOREGROUND) - { + } else if (status == PROCUI_STATUS_RELEASE_FOREGROUND) { // Free up MEM1 to next foreground app, deinit screen, etc. ProcUIDrawDoneRelease(); - } - else if(status == PROCUI_STATUS_IN_FOREGROUND) - { + } else if(status == PROCUI_STATUS_IN_FOREGROUND) { // Executed while app is in foreground } } @@ -44,7 +36,7 @@ AppRunning() return isAppRunning; } -int +static int CoreEntryPoint(int argc, const char **argv) { OSReport("Hello world from %s", argv[0]); @@ -82,11 +74,11 @@ main(int argc, char **argv) OSReport("Core 0 thread returned %d", resultCore0); OSReport("Core 2 thread returned %d", resultCore2); - + // Sends messages for ProcUI to release foreground, exit // and launch into the system menu immediately. SYSLaunchMenu(); - + while(AppRunning()); return 0; }