diff --git a/nx/include/switch.h b/nx/include/switch.h index ae6ebf07..f7b8aabd 100644 --- a/nx/include/switch.h +++ b/nx/include/switch.h @@ -69,6 +69,7 @@ extern "C" { #include "switch/nvidia/gpu/error_notifier.h" #include "switch/nvidia/gpu/gpu.h" #include "switch/nvidia/cmds/common.h" +#include "switch/nvidia/cmds/3d.h" #include "switch/runtime/env.h" diff --git a/nx/include/switch/nvidia/cmds/3d.h b/nx/include/switch/nvidia/cmds/3d.h index cc319000..498976b6 100644 --- a/nx/include/switch/nvidia/cmds/3d.h +++ b/nx/include/switch/nvidia/cmds/3d.h @@ -1,3 +1,18 @@ enum { - NvReg3D_MultisampleEnable = 0x54d + NvReg3D_ClearColor = 0x360, + NvReg3D_ScreenScissorHorizontal = 0x3fd, + NvReg3D_ScreenScissorVertical = 0x3fe, + NvReg3D_RenderTargetControl = 0x487, + NvReg3D_RenderTargetNAddr = 0x200, + NvReg3D_RenderTargetNHorizontal = 0x202, + NvReg3D_RenderTargetNVertical = 0x203, + NvReg3D_RenderTargetNFormat = 0x204, + NvReg3D_RenderTargetNTileMode = 0x205, + NvReg3D_RenderTargetNArrayMode = 0x206, + NvReg3D_RenderTargetNLayerStride = 0x207, + NvReg3D_RenderTargetNBaseLayer = 0x208, + NvReg3D_MultisampleEnable = 0x54d, + NvReg3D_ClearBufferTrigger = 0x674, }; + +void nvCmdsClearColor(NvCmdList* cmds, float colors[4]); diff --git a/nx/include/switch/nvidia/gpu/cmd_list.h b/nx/include/switch/nvidia/gpu/cmd_list.h index 427b32fd..d13bfe7c 100644 --- a/nx/include/switch/nvidia/gpu/cmd_list.h +++ b/nx/include/switch/nvidia/gpu/cmd_list.h @@ -29,3 +29,8 @@ u32* nvCmdListInsert(NvCmdList* c, size_t num_cmds); #define NvIncrOnce(subc, reg, ...) \ (0xA0000000 | ((reg) | ((subc) << 13) | ((sizeof((u32[]) { __VA_ARGS__ })) << 16))), __VA_ARGS__ + +static inline u32 f2i(float f) { + #pragma GCC diagnostic ignored "-Wstrict-aliasing" + return *(u32*) &f; +} diff --git a/nx/source/nvidia/cmds/3d.c b/nx/source/nvidia/cmds/3d.c index 94b77fe7..9d8b541c 100644 --- a/nx/source/nvidia/cmds/3d.c +++ b/nx/source/nvidia/cmds/3d.c @@ -1,2 +1,32 @@ #include +#include +void nvCmdsClearBuffer( + NvCmdList* cmds, NvBuffer* buf, u32 width, u32 height, float colors[4]) +{ + NvCmd(cmds, NvIncr(0, NvReg3D_ClearColor, + f2i(colors[0]), f2i(colors[1]), f2i(colors[2]), f2i(colors[3]))); + NvCmd(cmds, NvIncr(0, NvReg3D_ScreenScissorHorizontal, + 0 | (0x100 << 16), 0 | (0x100 << 16))); + NvCmd(cmds, NvImm(0, NvReg3D_RenderTargetControl, 1)); // bit0 probably enables RT #0 + + iova_t gpu_addr = nvBufferGetGpuAddr(buf); + NvCmd(cmds, NvIncr(NvReg3D_RenderTargetNAddr + 0x10*0, + gpu_addr >> 32, gpu_addr, + width, height, + 0xfe /* Format */, + 0x1000 /* TileMode */, + 1 /* ArrayMode */, + 0 /* Stride */, + 0 /* BaseLayer */ + )); + int z; + for (z=0; z<32; z++) + NvCmd(cmds, NvImm(0, NvReg3D_ClearBufferTrigger, 0x3c | (z << 10))); + /* + TODO: + IMMED_NVC0(push, NVC0_3D(ZETA_ENABLE), 0); + IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), 0); + */ + +}