all repos — mgba @ 7930c5a350fc21b233cc9cfdab058de1da79619a

mGBA Game Boy Advance Emulator

3DS: Port to using citro3D
Jeffrey Pfau jeffrey@endrift.com
Wed, 27 Jul 2016 01:04:52 -0700
commit

7930c5a350fc21b233cc9cfdab058de1da79619a

parent

2f3c4982bd774a944817e7c3c12ef92e55fb454f

M CHANGESCHANGES

@@ -23,6 +23,7 @@ - Qt: Simplify OpenGL context creation

- Debugger: Support register and memory writes via GDB stub - GBA Audio: Force audio DMAs to not increment destination - Qt: Thread startup improvements + - 3DS: Port to using citro3D 0.4.1: (2016-07-11) Bugfixes:
M src/platform/3ds/CMakeLists.txtsrc/platform/3ds/CMakeLists.txt

@@ -13,7 +13,7 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-format" PARENT_SCOPE)

set(OS_DEFINES COLOR_16_BIT COLOR_5_6_5 IOAPI_NO_64) include_directories(${CMAKE_CURRENT_BINARY_DIR}) -list(APPEND OS_LIB ctru) +list(APPEND OS_LIB citro3d ctru) file(GLOB OS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/3ds-*.c ${CMAKE_CURRENT_SOURCE_DIR}/ctru-heap.c ${CMAKE_CURRENT_SOURCE_DIR}/socket.c) set(OS_SRC ${OS_SRC} PARENT_SCOPE) set(OS_LIB ${OS_LIB} PARENT_SCOPE)

@@ -31,9 +31,12 @@

list(APPEND GUI_SRC ${CMAKE_CURRENT_BINARY_DIR}/icons.c ${CMAKE_CURRENT_BINARY_DIR}/font.c - ${CMAKE_CURRENT_BINARY_DIR}/uishader.c - ${CMAKE_CURRENT_BINARY_DIR}/uishader.h - ${CMAKE_CURRENT_BINARY_DIR}/uishader.shbin.h + ${CMAKE_CURRENT_BINARY_DIR}/uishader_g.c + ${CMAKE_CURRENT_BINARY_DIR}/uishader_g.h + ${CMAKE_CURRENT_BINARY_DIR}/uishader_g.shbin.h + ${CMAKE_CURRENT_BINARY_DIR}/uishader_v.c + ${CMAKE_CURRENT_BINARY_DIR}/uishader_v.h + ${CMAKE_CURRENT_BINARY_DIR}/uishader_v.shbin.h ${CMAKE_CURRENT_SOURCE_DIR}/gui-font.c ${CMAKE_CURRENT_SOURCE_DIR}/ctr-gpu.c

@@ -42,10 +45,14 @@

set_source_files_properties( ${CMAKE_CURRENT_BINARY_DIR}/icons.c ${CMAKE_CURRENT_BINARY_DIR}/font.c - ${CMAKE_CURRENT_BINARY_DIR}/uishader.c - ${CMAKE_CURRENT_BINARY_DIR}/uishader.h - ${CMAKE_CURRENT_BINARY_DIR}/uishader.shbin.h + ${CMAKE_CURRENT_BINARY_DIR}/uishader_g.c + ${CMAKE_CURRENT_BINARY_DIR}/uishader_g.h + ${CMAKE_CURRENT_BINARY_DIR}/uishader_g.shbin.h + ${CMAKE_CURRENT_BINARY_DIR}/uishader_v.c + ${CMAKE_CURRENT_BINARY_DIR}/uishader_v.h + ${CMAKE_CURRENT_BINARY_DIR}/uishader_v.shbin.h PROPERTIES GENERATED ON) + add_executable(${BINARY_NAME}.elf ${GUI_SRC} main.c) set_target_properties(${BINARY_NAME}.elf PROPERTIES COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}") target_link_libraries(${BINARY_NAME}.elf ${BINARY_NAME} ${M_LIBRARY} ${OS_LIB})

@@ -67,20 +74,36 @@ COMMAND ${RAW2C} ${CMAKE_SOURCE_DIR}/src/platform/3ds/icons.raw

DEPENDS ${CMAKE_SOURCE_DIR}/src/platform/3ds/icons.raw) add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/uishader.shbin ${CMAKE_CURRENT_BINARY_DIR}/uishader.shbin.h - MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/uishader.vsh + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/uishader_g.shbin ${CMAKE_CURRENT_BINARY_DIR}/uishader_g.shbin.h + MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/uishader.g.pica + COMMAND ${PICASSO} + -o ${CMAKE_CURRENT_BINARY_DIR}/uishader_g.shbin + -h ${CMAKE_CURRENT_BINARY_DIR}/uishader_g.shbin.h + ${CMAKE_CURRENT_SOURCE_DIR}/uishader.g.pica + COMMENT "picasso uishader.g.pica") + +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/uishader_g.c ${CMAKE_CURRENT_BINARY_DIR}/uishader_g.h + MAIN_DEPENDENCY ${CMAKE_CURRENT_BINARY_DIR}/uishader_g.shbin + COMMAND ${RAW2C} ${CMAKE_CURRENT_BINARY_DIR}/uishader_g.shbin + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "raw2c uishader.g.shbin") + +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/uishader_v.shbin ${CMAKE_CURRENT_BINARY_DIR}/uishader_v.shbin.h + MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/uishader.v.pica COMMAND ${PICASSO} - -o ${CMAKE_CURRENT_BINARY_DIR}/uishader.shbin - -h ${CMAKE_CURRENT_BINARY_DIR}/uishader.shbin.h - ${CMAKE_CURRENT_SOURCE_DIR}/uishader.vsh - COMMENT "picasso uishader.vsh") + -o ${CMAKE_CURRENT_BINARY_DIR}/uishader_v.shbin + -h ${CMAKE_CURRENT_BINARY_DIR}/uishader_v.shbin.h + ${CMAKE_CURRENT_SOURCE_DIR}/uishader.v.pica + COMMENT "picasso uishader.v.pica") add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/uishader.c ${CMAKE_CURRENT_BINARY_DIR}/uishader.h - MAIN_DEPENDENCY ${CMAKE_CURRENT_BINARY_DIR}/uishader.shbin - COMMAND ${RAW2C} ${CMAKE_CURRENT_BINARY_DIR}/uishader.shbin + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/uishader_v.c ${CMAKE_CURRENT_BINARY_DIR}/uishader_v.h + MAIN_DEPENDENCY ${CMAKE_CURRENT_BINARY_DIR}/uishader_v.shbin + COMMAND ${RAW2C} ${CMAKE_CURRENT_BINARY_DIR}/uishader_v.shbin WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "raw2c uishader.shbin") + COMMENT "raw2c uishader.v.shbin") add_custom_target(${BINARY_NAME}.3dsx ALL ${3DSXTOOL} ${BINARY_NAME}.elf ${BINARY_NAME}.3dsx --smdh=${BINARY_NAME}.smdh
M src/platform/3ds/ctr-gpu.csrc/platform/3ds/ctr-gpu.c

@@ -1,4 +1,5 @@

/* Copyright (c) 2015 Yuri Kunde Schlesner + * Copyright (c) 2016 Jeffrey Pfau * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this

@@ -13,348 +14,132 @@ #include <stdio.h>

#include "ctr-gpu.h" -#include "uishader.h" -#include "uishader.shbin.h" +#include "uishader_v.h" +#include "uishader_v.shbin.h" +#include "uishader_g.h" +#include "uishader_g.shbin.h" struct ctrUIVertex { - s16 x,y; - s16 u,v; + short x, y; + short w, h; + short u, v; + short uw, vh; u32 abgr; }; -#define VRAM_BASE 0x18000000u - #define MAX_NUM_QUADS 1024 -#define COMMAND_LIST_LENGTH (16 * 1024) -// Each quad requires 4 vertices and 2*3 indices for the two triangles used to draw it -#define VERTEX_INDEX_BUFFER_SIZE (MAX_NUM_QUADS * (4 * sizeof(struct ctrUIVertex) + 6 * sizeof(u16))) +#define VERTEX_BUFFER_SIZE MAX_NUM_QUADS * sizeof(struct ctrUIVertex) static struct ctrUIVertex* ctrVertexBuffer = NULL; -static u16* ctrIndexBuffer = NULL; static u16 ctrNumQuads = 0; -static void* gpuColorBuffer[2] = { NULL, NULL }; -static u32* gpuCommandList = NULL; -static void* screenTexture = NULL; +static C3D_Tex* activeTexture = NULL; static shaderProgram_s gpuShader; -static DVLB_s* passthroughShader = NULL; - -static int pendingEvents = 0; - -static const struct ctrTexture* activeTexture = NULL; +static DVLB_s* vertexShader = NULL; +static DVLB_s* geometryShader = NULL; -void ctrClearPending(int events) { - int toClear = events & pendingEvents; - if (toClear & (1 << GSPGPU_EVENT_PSC0)) { - gspWaitForPSC0(); +bool ctrInitGpu() { + // Load vertex shader binary + vertexShader = DVLB_ParseFile((u32*) uishader_v, uishader_v_size); + if (vertexShader == NULL) { + return false; } - if (toClear & (1 << GSPGPU_EVENT_PPF)) { - gspWaitForPPF(); - } - pendingEvents ^= toClear; -} -// Replacements for the limiting GPU_SetViewport function in ctrulib -static void _GPU_SetFramebuffer(intptr_t colorBuffer, intptr_t depthBuffer, u16 w, u16 h) { - u32 buf[4]; - - // Unknown - GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_FLUSH, 0x00000001); - GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_INVALIDATE, 0x00000001); - - // Set depth/color buffer address and dimensions - buf[0] = depthBuffer >> 3; - buf[1] = colorBuffer >> 3; - buf[2] = (0x01) << 24 | ((h-1) & 0xFFF) << 12 | (w & 0xFFF) << 0; - GPUCMD_AddIncrementalWrites(GPUREG_DEPTHBUFFER_LOC, buf, 3); - GPUCMD_AddWrite(GPUREG_RENDERBUF_DIM, buf[2]); - - // Set depth/color buffer pixel format - GPUCMD_AddWrite(GPUREG_DEPTHBUFFER_FORMAT, 3 /* D248S */ ); - GPUCMD_AddWrite(GPUREG_COLORBUFFER_FORMAT, 0 /* RGBA8 */ << 16 | 2 /* Unknown */); - GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_BLOCK32, 0); // Unknown - - // Enable color/depth buffers - buf[0] = colorBuffer != 0 ? 0xF : 0x0; - buf[1] = buf[0]; - buf[2] = depthBuffer != 0 ? 0x2 : 0x0; - buf[3] = buf[2]; - GPUCMD_AddIncrementalWrites(GPUREG_COLORBUFFER_READ, buf, 4); -} - -static void _GPU_SetViewportEx(u16 x, u16 y, u16 w, u16 h) { - u32 buf[4]; - - buf[0] = f32tof24(w / 2.0f); - buf[1] = f32tof31(2.0f / w) << 1; - buf[2] = f32tof24(h / 2.0f); - buf[3] = f32tof31(2.0f / h) << 1; - GPUCMD_AddIncrementalWrites(GPUREG_VIEWPORT_WIDTH, buf, 4); - - GPUCMD_AddWrite(GPUREG_VIEWPORT_XY, (y & 0xFFFF) << 16 | (x & 0xFFFF) << 0); - - buf[0] = 0; - buf[1] = 0; - buf[2] = ((h-1) & 0xFFFF) << 16 | ((w-1) & 0xFFFF) << 0; - GPUCMD_AddIncrementalWrites(GPUREG_SCISSORTEST_MODE, buf, 3); -} - -static void _setDummyTexEnv(int id) { - GPU_SetTexEnv(id, - GPU_TEVSOURCES(GPU_PREVIOUS, 0, 0), - GPU_TEVSOURCES(GPU_PREVIOUS, 0, 0), - GPU_TEVOPERANDS(0, 0, 0), - GPU_TEVOPERANDS(0, 0, 0), - GPU_REPLACE, - GPU_REPLACE, - 0x00000000); -} - -Result ctrInitGpu() { - Result res = -1; - - // Allocate buffers - gpuColorBuffer[0] = vramAlloc(400 * 240 * 4); - gpuColorBuffer[1] = vramAlloc(320 * 240 * 4); - gpuCommandList = linearAlloc(COMMAND_LIST_LENGTH * sizeof(u32)); - ctrVertexBuffer = linearAlloc(VERTEX_INDEX_BUFFER_SIZE); - if (gpuColorBuffer[0] == NULL || gpuColorBuffer[1] == NULL || gpuCommandList == NULL || ctrVertexBuffer == NULL) { - res = -1; - goto error_allocs; - } - // Both buffers share the same allocation, index buffer follows the vertex buffer - ctrIndexBuffer = (u16*)(ctrVertexBuffer + (4 * MAX_NUM_QUADS)); - - // Load vertex shader binary - passthroughShader = DVLB_ParseFile((u32*)uishader, uishader_size); - if (passthroughShader == NULL) { - res = -1; - goto error_dvlb; + // Load geometry shader binary + geometryShader = DVLB_ParseFile((u32*) uishader_g, uishader_g_size); + if (geometryShader == NULL) { + return false; } // Create shader shaderProgramInit(&gpuShader); - res = shaderProgramSetVsh(&gpuShader, &passthroughShader->DVLE[0]); + Result res = shaderProgramSetVsh(&gpuShader, &vertexShader->DVLE[0]); if (res < 0) { - goto error_shader; + return false; } - - // Initialize the GPU in ctrulib and assign the command buffer to accept submission of commands - GPU_Init(NULL); - GPUCMD_SetBuffer(gpuCommandList, COMMAND_LIST_LENGTH, 0); - - return 0; - -error_shader: - shaderProgramFree(&gpuShader); - -error_dvlb: - if (passthroughShader != NULL) { - DVLB_Free(passthroughShader); - passthroughShader = NULL; + res = shaderProgramSetGsh(&gpuShader, &geometryShader->DVLE[0], 3); + if (res < 0) { + return false; } + C3D_BindProgram(&gpuShader); -error_allocs: - if (ctrVertexBuffer != NULL) { - linearFree(ctrVertexBuffer); - ctrVertexBuffer = NULL; - ctrIndexBuffer = NULL; + // Allocate buffers + ctrVertexBuffer = linearAlloc(VERTEX_BUFFER_SIZE); + if (ctrVertexBuffer == NULL) { + return false; } - if (gpuCommandList != NULL) { - GPUCMD_SetBuffer(NULL, 0, 0); - linearFree(gpuCommandList); - gpuCommandList = NULL; - } + // Set up TexEnv and other parameters + C3D_TexEnv* env = C3D_GetTexEnv(0); + C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, 0); + C3D_TexEnvOp(env, C3D_Both, 0, 0, 0); + C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE); - if (gpuColorBuffer[0] != NULL) { - vramFree(gpuColorBuffer[0]); - gpuColorBuffer[0] = NULL; - } + C3D_CullFace(GPU_CULL_NONE); + C3D_DepthTest(false, GPU_ALWAYS, GPU_WRITE_ALL); + C3D_AlphaBlend(GPU_BLEND_ADD, GPU_BLEND_ADD, GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA); + C3D_AlphaTest(false, GPU_ALWAYS, 0); + C3D_BlendingColor(0); - if (gpuColorBuffer[1] != NULL) { - vramFree(gpuColorBuffer[1]); - gpuColorBuffer[1] = NULL; - } - return res; -} + C3D_AttrInfo* attrInfo = C3D_GetAttrInfo(); + AttrInfo_Init(attrInfo); + AttrInfo_AddLoader(attrInfo, 0, GPU_SHORT, 4); // in_pos + AttrInfo_AddLoader(attrInfo, 1, GPU_SHORT, 4); // in_tc0 + AttrInfo_AddLoader(attrInfo, 2, GPU_UNSIGNED_BYTE, 4); // in_col -void ctrDeinitGpu() { - shaderProgramFree(&gpuShader); + C3D_BufInfo* bufInfo = C3D_GetBufInfo(); + BufInfo_Init(bufInfo); + BufInfo_Add(bufInfo, ctrVertexBuffer, sizeof(struct ctrUIVertex), 3, 0x210); - DVLB_Free(passthroughShader); - passthroughShader = NULL; - - linearFree(screenTexture); - screenTexture = NULL; - - linearFree(ctrVertexBuffer); - ctrVertexBuffer = NULL; - ctrIndexBuffer = NULL; - - GPUCMD_SetBuffer(NULL, 0, 0); - linearFree(gpuCommandList); - gpuCommandList = NULL; - - vramFree(gpuColorBuffer[0]); - gpuColorBuffer[0] = NULL; - - vramFree(gpuColorBuffer[1]); - gpuColorBuffer[1] = NULL; + return true; } -void ctrGpuBeginFrame(int screen) { - if (screen > 1) { - return; +void ctrDeinitGpu() { + if (ctrVertexBuffer) { + linearFree(ctrVertexBuffer); + ctrVertexBuffer = NULL; } - int fw; - if (screen == 0) { - fw = 400; - } else { - fw = 320; - } - - _GPU_SetFramebuffer(osConvertVirtToPhys(gpuColorBuffer[screen]), 0, 240, fw); -} - -void ctrGpuBeginDrawing(void) { - shaderProgramUse(&gpuShader); - - // Disable depth and stencil testing - GPU_SetDepthTestAndWriteMask(false, GPU_ALWAYS, GPU_WRITE_COLOR); - GPU_SetStencilTest(false, GPU_ALWAYS, 0, 0xFF, 0); - GPU_SetStencilOp(GPU_STENCIL_KEEP, GPU_STENCIL_KEEP, GPU_STENCIL_KEEP); - GPU_DepthMap(-1.0f, 0.0f); - - // Enable alpha blending - GPU_SetAlphaBlending( - GPU_BLEND_ADD, GPU_BLEND_ADD, // Operation RGB, Alpha - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, // Color src, dst - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA); // Alpha src, dst - GPU_SetBlendingColor(0, 0, 0, 0); - - // Disable alpha testing - GPU_SetAlphaTest(false, GPU_ALWAYS, 0); - - // Unknown - GPUCMD_AddMaskedWrite(GPUREG_EARLYDEPTH_TEST1, 0x1, 0); - GPUCMD_AddWrite(GPUREG_EARLYDEPTH_TEST2, 0); + shaderProgramFree(&gpuShader); - GPU_SetTexEnv(0, - GPU_TEVSOURCES(GPU_TEXTURE0, GPU_PRIMARY_COLOR, 0), // RGB - GPU_TEVSOURCES(GPU_TEXTURE0, GPU_PRIMARY_COLOR, 0), // Alpha - GPU_TEVOPERANDS(0, 0, 0), // RGB - GPU_TEVOPERANDS(0, 0, 0), // Alpha - GPU_MODULATE, GPU_MODULATE, // Operation RGB, Alpha - 0x00000000); // Constant color - _setDummyTexEnv(1); - _setDummyTexEnv(2); - _setDummyTexEnv(3); - _setDummyTexEnv(4); - _setDummyTexEnv(5); - - // Configure vertex attribute format - u32 bufferOffsets[] = { osConvertVirtToPhys(ctrVertexBuffer) - VRAM_BASE }; - u64 arrayTargetAttributes[] = { 0x210 }; - u8 numAttributesInArray[] = { 3 }; - GPU_SetAttributeBuffers( - 3, // Number of attributes - (u32*)VRAM_BASE, // Base address - GPU_ATTRIBFMT(0, 2, GPU_SHORT) | // Attribute format - GPU_ATTRIBFMT(1, 2, GPU_SHORT) | - GPU_ATTRIBFMT(2, 4, GPU_UNSIGNED_BYTE), - 0xFF8, // Non-fixed vertex inputs - 0x210, // Vertex shader input map - 1, // Use 1 vertex array - bufferOffsets, arrayTargetAttributes, numAttributesInArray); -} - -void ctrGpuEndFrame(int screen, void* outputFramebuffer, int w, int h) { - if (screen > 1) { - return; + if (vertexShader) { + DVLB_Free(vertexShader); + vertexShader = NULL; } - int fw; - if (screen == 0) { - fw = 400; - } else { - fw = 320; + if (geometryShader) { + DVLB_Free(geometryShader); + geometryShader = NULL; } - - ctrFlushBatch(); - - void* colorBuffer = (u8*)gpuColorBuffer[screen] + ((fw - w) * 240 * 4); - - const u32 GX_CROP_INPUT_LINES = (1 << 2); - - ctrClearPending(1 << GSPGPU_EVENT_PSC0); - ctrClearPending(1 << GSPGPU_EVENT_PPF); - - GX_DisplayTransfer( - colorBuffer, GX_BUFFER_DIM(240, fw), - outputFramebuffer, GX_BUFFER_DIM(h, w), - GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | - GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) | - GX_CROP_INPUT_LINES); - pendingEvents |= (1 << GSPGPU_EVENT_PPF); -} - -void ctrGpuEndDrawing(void) { - ctrClearPending(1 << GSPGPU_EVENT_PPF); - gfxSwapBuffersGpu(); - gspWaitForEvent(GSPGPU_EVENT_VBlank0, false); - - void* gpuColorBuffer0End = (char*)gpuColorBuffer[0] + 240 * 400 * 4; - void* gpuColorBuffer1End = (char*)gpuColorBuffer[1] + 240 * 320 * 4; - GX_MemoryFill( - gpuColorBuffer[0], 0x00000000, gpuColorBuffer0End, GX_FILL_32BIT_DEPTH | GX_FILL_TRIGGER, - gpuColorBuffer[1], 0x00000000, gpuColorBuffer1End, GX_FILL_32BIT_DEPTH | GX_FILL_TRIGGER); - pendingEvents |= 1 << GSPGPU_EVENT_PSC0; } void ctrSetViewportSize(s16 w, s16 h) { - // Set up projection matrix mapping (0,0) to the top-left and (w,h) to the - // bottom-right, taking into account the 3DS' screens' portrait - // orientation. - float projectionMtx[4 * 4] = { - // Rows are in the order w z y x, because ctrulib - 1.0f, 0.0f, -2.0f / h, 0.0f, - 1.0f, 0.0f, 0.0f, -2.0f / w, - -0.5f, 0.0f, 0.0f, 0.0f, - 1.0f, 0.0f, 0.0f, 0.0f, - }; - - GPU_SetFloatUniform(GPU_VERTEX_SHADER, VSH_FVEC_projectionMtx, (u32*)&projectionMtx, 4); - _GPU_SetViewportEx(0, 0, h, w); + C3D_SetViewport(0, 0, h, w); + C3D_Mtx projectionMtx; + Mtx_OrthoTilt(&projectionMtx, 0.0, w, h, 0.0, 0.0, 1.0); + C3D_FVUnifMtx4x4(GPU_GEOMETRY_SHADER, GSH_FVEC_projectionMtx, &projectionMtx); } -void ctrActivateTexture(const struct ctrTexture* texture) { - if (activeTexture == texture) { +void ctrActivateTexture(C3D_Tex* texture) { + if (texture == activeTexture) { return; } - - ctrFlushBatch(); + if (activeTexture) { + ctrFlushBatch(); + } - GPU_SetTextureEnable(GPU_TEXUNIT0); - GPU_SetTexture( - GPU_TEXUNIT0, (u32*)osConvertVirtToPhys(texture->data), - texture->width, texture->height, - GPU_TEXTURE_MAG_FILTER(texture->filter) | GPU_TEXTURE_MIN_FILTER(texture->filter) | - GPU_TEXTURE_WRAP_S(GPU_CLAMP_TO_BORDER) | GPU_TEXTURE_WRAP_T(GPU_CLAMP_TO_BORDER), - texture->format); - GPU_SetTextureBorderColor(GPU_TEXUNIT0, 0x00000000); + C3D_TexBind(0, texture); + activeTexture = texture; - float textureMtx[2 * 4] = { - // Rows are in the order w z y x, because ctrulib - 0.0f, 0.0f, 0.0f, 1.0f / texture->width, - 0.0f, 0.0f, 1.0f / texture->height, 0.0f, + C3D_Mtx textureMtx = { + .m = { + // Rows are in the order w z y x, because ctrulib + 0.0f, 0.0f, 0.0f, 1.0f / activeTexture->width, + 0.0f, 0.0f, 1.0f / activeTexture->height, 0.0f + } }; - - GPU_SetFloatUniform(GPU_VERTEX_SHADER, VSH_FVEC_textureMtx, (u32*)&textureMtx, 2); - - activeTexture = texture; + C3D_FVUnifMtx2x4(GPU_GEOMETRY_SHADER, GSH_FVEC_textureMtx, &textureMtx); } void ctrAddRectScaled(u32 color, s16 x, s16 y, s16 w, s16 h, s16 u, s16 v, s16 uw, s16 vh) {

@@ -362,38 +147,22 @@ if (ctrNumQuads == MAX_NUM_QUADS) {

ctrFlushBatch(); } - u16 index = ctrNumQuads * 4; - struct ctrUIVertex* vtx = &ctrVertexBuffer[index]; - vtx->x = x; vtx->y = y; - vtx->u = u; vtx->v = v; + struct ctrUIVertex* vtx = &ctrVertexBuffer[ctrNumQuads]; + vtx->x = x; + vtx->y = y; + vtx->w = w; + vtx->h = h; + vtx->u = u; + vtx->v = v; + vtx->uw = uw; + vtx->vh = vh; vtx->abgr = color; - vtx++; - vtx->x = x + w; vtx->y = y; - vtx->u = u + uw; vtx->v = v; - vtx->abgr = color; - vtx++; - - vtx->x = x; vtx->y = y + h; - vtx->u = u; vtx->v = v + vh; - vtx->abgr = color; - vtx++; - - vtx->x = x + w; vtx->y = y + h; - vtx->u = u + uw; vtx->v = v + vh; - vtx->abgr = color; - - u16* i = &ctrIndexBuffer[ctrNumQuads * 6]; - i[0] = index + 0; i[1] = index + 1; i[2] = index + 2; - i[3] = index + 2; i[4] = index + 1; i[5] = index + 3; - - ctrNumQuads += 1; + ++ctrNumQuads; } void ctrAddRect(u32 color, s16 x, s16 y, s16 u, s16 v, s16 w, s16 h) { - ctrAddRectScaled(color, - x, y, w, h, - u, v, w, h); + ctrAddRectScaled(color, x, y, w, h, u, v, w, h); } void ctrFlushBatch(void) {

@@ -401,19 +170,9 @@ if (ctrNumQuads == 0) {

return; } - ctrClearPending((1 << GSPGPU_EVENT_PSC0)); - - GSPGPU_FlushDataCache(ctrVertexBuffer, VERTEX_INDEX_BUFFER_SIZE); - GPU_DrawElements(GPU_GEOMETRY_PRIM, (u32*)(osConvertVirtToPhys(ctrIndexBuffer) - VRAM_BASE), ctrNumQuads * 6); - - GPU_FinishDrawing(); - GPUCMD_Finalize(); - GSPGPU_FlushDataCache((u8*)gpuCommandList, COMMAND_LIST_LENGTH * sizeof(u32)); - GPUCMD_FlushAndRun(); - - gspWaitForP3D(); - - GPUCMD_SetBufferOffset(0); + GSPGPU_FlushDataCache(ctrVertexBuffer, VERTEX_BUFFER_SIZE); + C3D_DrawArrays(GPU_GEOMETRY_PRIM, 0, ctrNumQuads); + C3D_Flush(); ctrNumQuads = 0; }
M src/platform/3ds/ctr-gpu.hsrc/platform/3ds/ctr-gpu.h

@@ -1,4 +1,5 @@

/* Copyright (c) 2015 Yuri Kunde Schlesner + * Copyright (c) 2016 Jeffrey Pfau * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this

@@ -8,34 +9,14 @@ #ifndef GUI_GPU_H

#define GUI_GPU_H #include <3ds.h> - -struct ctrTexture { - void* data; - u32 format; - u32 filter; - u16 width; - u16 height; -}; +#include <citro3d.h> -static inline void ctrTexture_Init(struct ctrTexture* tex) { - tex->data = NULL; - tex->format = GPU_RGB565; - tex->filter = GPU_NEAREST; - tex->width = 0; - tex->height = 0; -} - -Result ctrInitGpu(void); +bool ctrInitGpu(void); void ctrDeinitGpu(void); -void ctrGpuBeginDrawing(void); -void ctrGpuBeginFrame(int screen); -void ctrGpuEndFrame(int screen, void* outputFramebuffer, int w, int h); -void ctrGpuEndDrawing(void); - void ctrSetViewportSize(s16 w, s16 h); -void ctrActivateTexture(const struct ctrTexture* texture); +void ctrActivateTexture(C3D_Tex* texture); void ctrAddRectScaled(u32 color, s16 x, s16 y, s16 w, s16 h, s16 u, s16 v, s16 uw, s16 vh); void ctrAddRect(u32 color, s16 x, s16 y, s16 u, s16 v, s16 w, s16 h); void ctrFlushBatch(void);
M src/platform/3ds/gui-font.csrc/platform/3ds/gui-font.c

@@ -7,17 +7,18 @@ #include "util/gui/font.h"

#include "util/gui/font-metrics.h" #include "util/png-io.h" #include "util/vfs.h" -#include "platform/3ds/ctr-gpu.h" #include "icons.h" #include "font.h" + +#include "ctr-gpu.h" #define CELL_HEIGHT 16 #define CELL_WIDTH 16 #define GLYPH_HEIGHT 12 struct GUIFont { - struct ctrTexture texture; - struct ctrTexture icons; + C3D_Tex texture; + C3D_Tex icons; }; struct GUIFont* GUIFontCreate(void) {

@@ -26,23 +27,16 @@ if (!guiFont) {

return 0; } - struct ctrTexture* tex = &guiFont->texture; - ctrTexture_Init(tex); - tex->data = vramAlloc(256 * 128 * 2); - tex->format = GPU_RGBA5551; - tex->width = 256; - tex->height = 128; + C3D_Tex* tex = &guiFont->texture; + C3D_TexInitVRAM(tex, 256, 128, GPU_RGBA5551); GSPGPU_FlushDataCache(font, font_size); GX_RequestDma((u32*) font, tex->data, font_size); gspWaitForDMA(); tex = &guiFont->icons; - ctrTexture_Init(tex); - tex->data = vramAlloc(256 * 64 * 2); - tex->format = GPU_RGBA5551; - tex->width = 256; - tex->height = 64; + C3D_TexInitVRAM(tex, 256, 64, GPU_RGBA5551); + GSPGPU_FlushDataCache(icons, icons_size); GX_RequestDma((u32*) icons, tex->data, icons_size);

@@ -52,8 +46,8 @@ return guiFont;

} void GUIFontDestroy(struct GUIFont* font) { - vramFree(font->texture.data); - vramFree(font->icons.data); + C3D_TexDelete(&font->texture); + C3D_TexDelete(&font->icons); free(font); }
M src/platform/3ds/main.csrc/platform/3ds/main.c

@@ -61,39 +61,39 @@ static struct mAVStream stream;

static int16_t* audioLeft = 0; static int16_t* audioRight = 0; static size_t audioPos = 0; -static struct ctrTexture gbaOutputTexture; -static int guiDrawn; -static int screenCleanup; +static C3D_Tex outputTexture; static ndspWaveBuf dspBuffer[DSP_BUFFERS]; static int bufferId = 0; +static C3D_RenderBuf bottomScreen; +static C3D_RenderBuf topScreen; + static aptHookCookie cookie; -enum { - GUI_ACTIVE = 1, - GUI_THIS_FRAME = 2, -}; +extern bool allocateRomBuffer(void); -enum { - SCREEN_CLEANUP_TOP_1 = 1, - SCREEN_CLEANUP_TOP_2 = 2, - SCREEN_CLEANUP_TOP = SCREEN_CLEANUP_TOP_1 | SCREEN_CLEANUP_TOP_2, - SCREEN_CLEANUP_BOTTOM_1 = 4, - SCREEN_CLEANUP_BOTTOM_2 = 8, - SCREEN_CLEANUP_BOTTOM = SCREEN_CLEANUP_BOTTOM_1 | SCREEN_CLEANUP_BOTTOM_2, -}; +static bool _initGpu(void) { + if (!C3D_Init(C3D_DEFAULT_CMDBUF_SIZE)) { + return false; + } -extern bool allocateRomBuffer(void); + if (!C3D_RenderBufInit(&topScreen, 240, 400, GPU_RB_RGB8, 0) || !C3D_RenderBufInit(&bottomScreen, 240, 320, GPU_RB_RGB8, 0)) { + return false; + } + + return ctrInitGpu(); +} static void _cleanup(void) { + ctrDeinitGpu(); + if (outputBuffer) { linearFree(outputBuffer); } - if (gbaOutputTexture.data) { - ctrDeinitGpu(); - vramFree(gbaOutputTexture.data); - } + C3D_RenderBufDelete(&topScreen); + C3D_RenderBufDelete(&bottomScreen); + C3D_Fini(); gfxExit();

@@ -173,52 +173,15 @@

static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* right); static void _drawStart(void) { - ctrGpuBeginDrawing(); - if (screenMode < SM_PA_TOP || (guiDrawn & GUI_ACTIVE)) { - ctrGpuBeginFrame(GFX_BOTTOM); - ctrSetViewportSize(320, 240); - } else { - ctrGpuBeginFrame(GFX_TOP); - ctrSetViewportSize(400, 240); - } - guiDrawn &= ~GUI_THIS_FRAME; + C3D_RenderBufClear(&bottomScreen); + C3D_RenderBufClear(&topScreen); } static void _drawEnd(void) { - int screen = screenMode < SM_PA_TOP ? GFX_BOTTOM : GFX_TOP; - u16 width = 0, height = 0; - - void* outputFramebuffer = gfxGetFramebuffer(screen, GFX_LEFT, &height, &width); - ctrGpuEndFrame(screen, outputFramebuffer, width, height); - - if (screen != GFX_BOTTOM) { - if (guiDrawn & (GUI_THIS_FRAME | GUI_ACTIVE)) { - void* outputFramebuffer = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, &height, &width); - ctrGpuEndFrame(GFX_BOTTOM, outputFramebuffer, width, height); - } else if (screenCleanup & SCREEN_CLEANUP_BOTTOM) { - ctrGpuBeginFrame(GFX_BOTTOM); - if (screenCleanup & SCREEN_CLEANUP_BOTTOM_1) { - screenCleanup &= ~SCREEN_CLEANUP_BOTTOM_1; - } else if (screenCleanup & SCREEN_CLEANUP_BOTTOM_2) { - screenCleanup &= ~SCREEN_CLEANUP_BOTTOM_2; - } - void* outputFramebuffer = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, &height, &width); - ctrGpuEndFrame(GFX_BOTTOM, outputFramebuffer, width, height); - } - } - - if ((screenCleanup & SCREEN_CLEANUP_TOP) && screen != GFX_TOP) { - ctrGpuBeginFrame(GFX_TOP); - if (screenCleanup & SCREEN_CLEANUP_TOP_1) { - screenCleanup &= ~SCREEN_CLEANUP_TOP_1; - } else if (screenCleanup & SCREEN_CLEANUP_TOP_2) { - screenCleanup &= ~SCREEN_CLEANUP_TOP_2; - } - void* outputFramebuffer = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, &height, &width); - ctrGpuEndFrame(GFX_TOP, outputFramebuffer, width, height); - } - - ctrGpuEndDrawing(); + C3D_RenderBufTransfer(&topScreen, (u32*) gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8)); + C3D_RenderBufTransfer(&bottomScreen, (u32*) gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL), GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8)); + gfxSwapBuffersGpu(); + gspWaitForEvent(GSPGPU_EVENT_VBlank0, false); } static int _batteryState(void) {

@@ -237,20 +200,17 @@ return state | charge;

} static void _guiPrepare(void) { - guiDrawn = GUI_ACTIVE | GUI_THIS_FRAME; int screen = screenMode < SM_PA_TOP ? GFX_BOTTOM : GFX_TOP; if (screen == GFX_BOTTOM) { return; } - ctrFlushBatch(); - ctrGpuBeginFrame(GFX_BOTTOM); + C3D_RenderBufBind(&bottomScreen); ctrSetViewportSize(320, 240); } static void _guiFinish(void) { - guiDrawn &= ~GUI_ACTIVE; - screenCleanup |= SCREEN_CLEANUP_BOTTOM; + ctrFlushBatch(); } static void _setup(struct mGUIRunner* runner) {

@@ -322,7 +282,6 @@ }

unsigned mode; if (mCoreConfigGetUIntValue(&runner->core->config, "screenMode", &mode) && mode != screenMode) { screenMode = mode; - screenCleanup |= SCREEN_CLEANUP_BOTTOM | SCREEN_CLEANUP_TOP; } }

@@ -358,6 +317,15 @@ }

} static void _drawTex(struct mCore* core, bool faded) { + if (screenMode < SM_PA_TOP) { + C3D_RenderBufBind(&bottomScreen); + ctrSetViewportSize(320, 240); + } else { + C3D_RenderBufBind(&topScreen); + ctrSetViewportSize(400, 240); + } + ctrActivateTexture(&outputTexture); + u32 color = faded ? 0x3FFFFFFF : 0xFFFFFFFF; int screen_w = screenMode < SM_PA_TOP ? 320 : 400;

@@ -408,15 +376,16 @@ int x = (screen_w - w) / 2;

int y = (screen_h - h) / 2; ctrAddRectScaled(color, x, y, w, h, 0, 0, corew, coreh); + ctrFlushBatch(); } static void _drawFrame(struct mGUIRunner* runner, bool faded) { UNUSED(runner); - struct ctrTexture* tex = &gbaOutputTexture; + C3D_Tex* tex = &outputTexture; GSPGPU_FlushDataCache(outputBuffer, 256 * VIDEO_VERTICAL_PIXELS * 2); - GX_DisplayTransfer( + C3D_SafeDisplayTransfer( outputBuffer, GX_BUFFER_DIM(256, VIDEO_VERTICAL_PIXELS), tex->data, GX_BUFFER_DIM(256, 256), GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB565) |

@@ -429,14 +398,13 @@ blip_clear(runner->core->getAudioChannel(runner->core, 1));

} gspWaitForPPF(); - ctrActivateTexture(tex); _drawTex(runner->core, faded); } static void _drawScreenshot(struct mGUIRunner* runner, const uint32_t* pixels, bool faded) { UNUSED(runner); - struct ctrTexture* tex = &gbaOutputTexture; + C3D_Tex* tex = &outputTexture; u16* newPixels = linearMemAlign(256 * VIDEO_VERTICAL_PIXELS * sizeof(u32), 0x100);

@@ -454,7 +422,7 @@ memset(&newPixels[y * 256 + VIDEO_HORIZONTAL_PIXELS], 0, (256 - VIDEO_HORIZONTAL_PIXELS) * sizeof(u32));

} GSPGPU_FlushDataCache(newPixels, 256 * VIDEO_VERTICAL_PIXELS * sizeof(u32)); - GX_DisplayTransfer( + C3D_SafeDisplayTransfer( (u32*) newPixels, GX_BUFFER_DIM(256, VIDEO_VERTICAL_PIXELS), tex->data, GX_BUFFER_DIM(256, 256), GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB565) |

@@ -463,7 +431,6 @@ GX_TRANSFER_OUT_TILED(1) | GX_TRANSFER_FLIP_VERT(1));

gspWaitForPPF(); linearFree(newPixels); - ctrActivateTexture(tex); _drawTex(runner->core, faded); }

@@ -479,9 +446,11 @@ }

static void _incrementScreenMode(struct mGUIRunner* runner) { UNUSED(runner); - screenCleanup |= SCREEN_CLEANUP_TOP | SCREEN_CLEANUP_BOTTOM; screenMode = (screenMode + 1) % SM_MAX; mCoreConfigSetUIntValue(&runner->core->config, "screenMode", screenMode); + + C3D_RenderBufClear(&bottomScreen); + C3D_RenderBufClear(&topScreen); } static uint32_t _pollInput(void) {

@@ -636,39 +605,29 @@ audioLeft = linearMemAlign(AUDIO_SAMPLE_BUFFER * sizeof(int16_t), 0x80);

audioRight = linearMemAlign(AUDIO_SAMPLE_BUFFER * sizeof(int16_t), 0x80); } - gfxInit(GSP_BGR8_OES, GSP_BGR8_OES, false); + gfxInit(GSP_BGR8_OES, GSP_BGR8_OES, true); - if (ctrInitGpu() < 0) { - gbaOutputTexture.data = 0; + if (!_initGpu()) { + outputTexture.data = 0; _cleanup(); return 1; } - ctrTexture_Init(&gbaOutputTexture); - gbaOutputTexture.format = GPU_RGB565; - gbaOutputTexture.filter = GPU_LINEAR; - gbaOutputTexture.width = 256; - gbaOutputTexture.height = 256; - gbaOutputTexture.data = vramAlloc(256 * 256 * 2); - void* outputTextureEnd = (u8*)gbaOutputTexture.data + 256 * 256 * 2; - - if (!gbaOutputTexture.data) { + if (!C3D_TexInitVRAM(&outputTexture, 256, 256, GPU_RGB565)) { _cleanup(); return 1; } + C3D_TexSetWrap(&outputTexture, GPU_CLAMP_TO_EDGE, GPU_CLAMP_TO_EDGE); + C3D_TexSetFilter(&outputTexture, GPU_LINEAR, GPU_LINEAR); + void* outputTextureEnd = (u8*)outputTexture.data + 256 * 256 * 2; // Zero texture data to make sure no garbage around the border interferes with filtering GX_MemoryFill( - gbaOutputTexture.data, 0x0000, outputTextureEnd, GX_FILL_16BIT_DEPTH | GX_FILL_TRIGGER, + outputTexture.data, 0x0000, outputTextureEnd, GX_FILL_16BIT_DEPTH | GX_FILL_TRIGGER, NULL, 0, NULL, 0); gspWaitForPSC0(); - sdmcArchive = (FS_Archive) { - ARCHIVE_SDMC, - (FS_Path) { PATH_EMPTY, 1, "" }, - 0 - }; - FSUSER_OpenArchive(&sdmcArchive); + FSUSER_OpenArchive(&sdmcArchive, ARCHIVE_SDMC, fsMakePath(PATH_EMPTY, "")); struct GUIFont* font = GUIFontCreate();
A src/platform/3ds/uishader.g.pica

@@ -0,0 +1,96 @@

+; Copyright (c) 2015 Yuri Kunde Schlesner +; Copyright (c) 2016 Jeffrey Pfau +; +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, You can obtain one at http://mozilla.org/MPL/2.0/. + +; Uniforms +.fvec projectionMtx[4] +.fvec textureMtx[2] + +; Constants +.constf consts1(0.0, 1.0, -0.5, -1.0) + +; Outputs : here only position and color +.out out_pos position +.out out_tc0 texcoord0 +.out out_col color + +; Inputs : here we have only vertices +.alias in_pos v0 +.alias in_tc0 v1 +.alias in_col v2 + +.gsh +.proc main + ; Set up the vertex endpoints + mov r0.xy, in_pos.xy + mov r0.zw, consts1.zy + add r1.xy, r0.xy, in_pos.zw + + dp4 r2.x, projectionMtx[0], r0 + dp4 r2.y, projectionMtx[1], r0 + dp4 r2.z, projectionMtx[2], r0 + dp4 r2.w, projectionMtx[3], r0 + + dp4 r3.x, projectionMtx[0], r1 + dp4 r3.y, projectionMtx[1], r1 + dp4 r3.z, projectionMtx[2], r1 + dp4 r3.w, projectionMtx[3], r1 + + ; Set up the texture endpoints + mov r0.xy, in_tc0.xy + mov r0.zw, consts1.xy + add r1.xy, r0.xy, in_tc0.zw + + dp4 r4.x, textureMtx[0], r0 + dp4 r4.y, textureMtx[1], r0 + mov r4.zw, consts1.xy + + dp4 r5.x, textureMtx[0], r1 + dp4 r5.y, textureMtx[1], r1 + mov r5.zw, consts1.xy + + ; Emit top-left + setemit 0 + mov out_pos.xyzw, r2.xyzw + mov out_tc0.xyzw, r4.xyzw + mov out_col, in_col + emit + + ; Emit bottom-left + setemit 1 + mov out_pos.x, r2.x + mov out_pos.y, r3.y + mov out_pos.z, consts1.z + mov out_pos.w, consts1.y + mov out_tc0.x, r5.x + mov out_tc0.y, r4.y + mov out_tc0.z, consts1.x + mov out_tc0.w, consts1.y + mov out_col, in_col + emit + + ; Emit bottom-right + setemit 2, prim + mov out_pos.xyzw, r3.xyzw + mov out_tc0.xyzw, r5.xyzw + mov out_col, in_col + emit + + ; Emit top-right + setemit 1, prim inv + mov out_pos.x, r3.x + mov out_pos.y, r2.y + mov out_pos.z, consts1.z + mov out_pos.w, consts1.y + mov out_tc0.x, r4.x + mov out_tc0.y, r5.y + mov out_tc0.z, consts1.x + mov out_tc0.w, consts1.y + mov out_col, in_col + emit + + end +.end
A src/platform/3ds/uishader.v.pica

@@ -0,0 +1,35 @@

+; Copyright (c) 2015 Yuri Kunde Schlesner +; Copyright (c) 2016 Jeffrey Pfau + +; +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, You can obtain one at http://mozilla.org/MPL/2.0/. + +; uishader.vsh - Simply multiplies input position and texcoords with +; corresponding matrices before outputting + +; Uniforms + +; Constants +.constf consts1(0.0, 1.0, 0.0039215686, -1.0) + +; Outputs +.out out_pos position +.out out_tc0 texcoord0 +.out out_col color + +; Inputs +.alias in_pos v0 +.alias in_tc0 v1 +.alias in_col v2 + +.proc main + mov out_pos, in_pos + mov out_tc0, in_tc0 + + ; Normalize color by multiplying by 1 / 255 + mul out_col, consts1.z, in_col + + end +.end
D src/platform/3ds/uishader.vsh

@@ -1,41 +0,0 @@

-; Copyright (c) 2015 Yuri Kunde Schlesner -; -; This Source Code Form is subject to the terms of the Mozilla Public -; License, v. 2.0. If a copy of the MPL was not distributed with this -; file, You can obtain one at http://mozilla.org/MPL/2.0/. - -; uishader.vsh - Simply multiplies input position and texcoords with -; corresponding matrices before outputting - -; Uniforms -.fvec projectionMtx[4] -.fvec textureMtx[2] - -; Constants -.constf consts1(0.0, 1.0, 0.0039215686, 0.0) - -; Outputs : here only position and color -.out out_pos position -.out out_tc0 texcoord0 -.out out_col color - -; Inputs : here we have only vertices -.alias in_pos v0 -.alias in_tc0 v1 -.alias in_col v2 - -.proc main - dp4 out_pos.x, projectionMtx[0], in_pos - dp4 out_pos.y, projectionMtx[1], in_pos - dp4 out_pos.z, projectionMtx[2], in_pos - dp4 out_pos.w, projectionMtx[3], in_pos - - dp4 out_tc0.x, textureMtx[0], in_tc0 - dp4 out_tc0.y, textureMtx[1], in_tc0 - mov out_tc0.zw, consts1.xxxy - - ; Normalize color by multiplying by 1 / 255 - mul out_col, consts1.z, in_col - - end -.end