diff --git a/include/driver/graphics/DrawCommand.hpp b/include/driver/graphics/DrawCommand.hpp index d135550c..7a887716 100644 --- a/include/driver/graphics/DrawCommand.hpp +++ b/include/driver/graphics/DrawCommand.hpp @@ -2,12 +2,12 @@ #include "common/Exception.hpp" +#include "driver/graphics/StreamBuffer.hpp" + #include "modules/graphics/Shader.tcc" #include "modules/graphics/Texture.tcc" #include "modules/graphics/vertex.hpp" -#include "driver/graphics/StreamBuffer.hpp" - namespace love { struct BatchedDrawCommand diff --git a/include/modules/graphics/Graphics.tcc b/include/modules/graphics/Graphics.tcc index 3f8042b1..ceb47047 100644 --- a/include/modules/graphics/Graphics.tcc +++ b/include/modules/graphics/Graphics.tcc @@ -535,13 +535,7 @@ namespace love return this->states.back().lineJoin; } - void setPointSize(float size) - { - if (size != this->states.back().pointSize) - this->flushBatchedDraws(); - - this->states.back().pointSize = size; - } + virtual void setPointSize(float size) = 0; float getPointSize() const { diff --git a/include/modules/graphics/Texture.tcc b/include/modules/graphics/Texture.tcc index 05cf5877..42ea4537 100644 --- a/include/modules/graphics/Texture.tcc +++ b/include/modules/graphics/Texture.tcc @@ -312,7 +312,7 @@ namespace love * This is ONLY used on 3DS due to memory constraints. * The font textures are already on-device! */ - virtual void setHandleData(void* data) = 0; + virtual void setHandleData(ptrdiff_t data) = 0; virtual void setSamplerState(const SamplerState& state) = 0; diff --git a/include/modules/graphics/vertex.hpp b/include/modules/graphics/vertex.hpp index 4b36766c..82244c15 100644 --- a/include/modules/graphics/vertex.hpp +++ b/include/modules/graphics/vertex.hpp @@ -185,6 +185,7 @@ namespace love XYf_STf_RGBAf, //< 2D position, 2D texture coordinates and 32-bit floating point RGBA color. XYf_STus_RGBAf, //< 2D position, 2D unsigned short texture coordinates and 32-bit floating point RGBA // color. + XYf_RGBAf, XYf_STPf_RGBAf, //< 2D position, 3D texture coordinates and 32-bit floating point RGBA color. }; diff --git a/log.txt b/log.txt new file mode 100644 index 00000000..66482b45 --- /dev/null +++ b/log.txt @@ -0,0 +1,42 @@ +-- Updating Catnip cache +-- Entering /d/lovepotion/build/main.release +[1/6] Building CXX object CMakeFiles/lovepotion.dir/platform/hac/source/driver/display/deko.o +D:/lovepotion/platform/hac/source/driver/display/deko.cpp: In constructor 'love::deko3d::deko3d()': +D:/lovepotion/platform/hac/source/driver/display/deko.cpp:17:20: warning: 'void* memset(void*, int, size_t)' clearing an object of non-trivial type 'struct love::deko3d::Context'; use assignment or value-initialization instead [-Wclass-memaccess] + 17 | std::memset(&this->context, 0, sizeof(this->context)); + | ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In file included from D:/lovepotion/platform/hac/source/driver/display/deko.cpp:1: +D:/lovepotion/platform/hac/include/driver/display/deko.hpp:225:16: note: 'struct love::deko3d::Context' declared here + 225 | struct Context : public ContextBase + | ^~~~~~~ +D:/lovepotion/platform/hac/source/driver/display/deko.cpp: In member function 'virtual void love::deko3d::prepareDraw(love::GraphicsBase*)': +D:/lovepotion/platform/hac/source/driver/display/deko.cpp:158:44: warning: unused parameter 'graphics' [-Wunused-parameter] + 158 | void deko3d::prepareDraw(GraphicsBase* graphics) + | ~~~~~~~~~~~~~~^~~~~~~~ +[2/6] Building CXX object CMakeFiles/lovepotion.dir/source/modules/love/love.o +[3/6] Building CXX object CMakeFiles/lovepotion.dir/source/modules/window/wrap_Window.o +[4/6] Linking CXX executable lovepotion.elf +FAILED: lovepotion.elf lovepotion.lst lovepotion.map /d/lovepotion/build/main.release/lovepotion.lst /d/lovepotion/build/main.release/lovepotion.map +: && /opt/devkitpro/devkitA64/bin/aarch64-none-elf-g++.exe -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -ftls-model=local-exec -ffunction-sections -fdata-sections -D__SWITCH__ -g -O2 -DNDEBUG -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -ftls-model=local-exec -L/opt/devkitpro/libnx/lib -L/opt/devkitpro/portlibs/switch/lib -fPIE -specs=/opt/devkitpro/libnx/switch.specs -Wl,-Map,/d/lovepotion/build/main.release/lovepotion.map CMakeFiles/lovepotion.dir/platform/hac/source/boot.o CMakeFiles/lovepotion.dir/platform/hac/source/common/screen.o CMakeFiles/lovepotion.dir/platform/hac/source/driver/audio/DigitalSound.o CMakeFiles/lovepotion.dir/platform/hac/source/driver/audio/MemoryPool.o CMakeFiles/lovepotion.dir/platform/hac/source/driver/display/deko3d/CIntrusiveTree.o CMakeFiles/lovepotion.dir/platform/hac/source/driver/display/deko3d/CMemPool.o CMakeFiles/lovepotion.dir/platform/hac/source/driver/display/Framebuffer.o CMakeFiles/lovepotion.dir/platform/hac/source/driver/display/deko.o CMakeFiles/lovepotion.dir/platform/hac/source/driver/EventQueue.o CMakeFiles/lovepotion.dir/platform/hac/source/modules/audio/Source.o CMakeFiles/lovepotion.dir/platform/hac/source/modules/graphics/Graphics.o CMakeFiles/lovepotion.dir/platform/hac/source/modules/graphics/Shader.o CMakeFiles/lovepotion.dir/platform/hac/source/modules/joystick/Joystick.o CMakeFiles/lovepotion.dir/platform/hac/source/modules/joystick/JoystickModule.o CMakeFiles/lovepotion.dir/platform/hac/source/modules/keyboard/Keyboard.o CMakeFiles/lovepotion.dir/platform/hac/source/modules/system/System.o CMakeFiles/lovepotion.dir/platform/hac/source/modules/timer/Timer.o CMakeFiles/lovepotion.dir/platform/hac/source/modules/window/Window.o CMakeFiles/lovepotion.dir/source/modules/image/magpie/ASTCHandler.o CMakeFiles/lovepotion.dir/source/modules/image/magpie/ddsHandler.o CMakeFiles/lovepotion.dir/source/modules/image/magpie/JPGHandler.o CMakeFiles/lovepotion.dir/source/modules/image/magpie/KTXHandler.o CMakeFiles/lovepotion.dir/source/modules/image/magpie/PKMHandler.o CMakeFiles/lovepotion.dir/source/modules/image/magpie/PNGHandler.o CMakeFiles/lovepotion.dir/source/modules/font/freetype/Font.o CMakeFiles/lovepotion.dir/source/modules/font/freetype/TrueTypeRasterizer.o CMakeFiles/lovepotion.dir/source/modules/graphics/freetype/Font.o CMakeFiles/lovepotion.dir/source/main.o CMakeFiles/lovepotion.dir/source/common/b64.o CMakeFiles/lovepotion.dir/source/common/Data.o CMakeFiles/lovepotion.dir/source/common/float.o CMakeFiles/lovepotion.dir/source/common/luax.o CMakeFiles/lovepotion.dir/source/common/Matrix.o CMakeFiles/lovepotion.dir/source/common/Message.o CMakeFiles/lovepotion.dir/source/common/Module.o CMakeFiles/lovepotion.dir/source/common/Object.o CMakeFiles/lovepotion.dir/source/common/pixelformat.o CMakeFiles/lovepotion.dir/source/common/Reference.o CMakeFiles/lovepotion.dir/source/common/Stream.o CMakeFiles/lovepotion.dir/source/common/types.o CMakeFiles/lovepotion.dir/source/common/Variant.o CMakeFiles/lovepotion.dir/source/utility/guid.o CMakeFiles/lovepotion.dir/source/modules/audio/Audio.o CMakeFiles/lovepotion.dir/source/modules/audio/Pool.o CMakeFiles/lovepotion.dir/source/modules/audio/Source.o CMakeFiles/lovepotion.dir/source/modules/audio/wrap_Audio.o CMakeFiles/lovepotion.dir/source/modules/audio/wrap_Source.o CMakeFiles/lovepotion.dir/source/modules/data/ByteData.o CMakeFiles/lovepotion.dir/source/modules/data/CompressedData.o CMakeFiles/lovepotion.dir/source/modules/data/DataModule.o CMakeFiles/lovepotion.dir/source/modules/data/DataStream.o CMakeFiles/lovepotion.dir/source/modules/data/DataView.o CMakeFiles/lovepotion.dir/source/modules/data/wrap_ByteData.o CMakeFiles/lovepotion.dir/source/modules/data/wrap_CompressedData.o CMakeFiles/lovepotion.dir/source/modules/data/wrap_Data.o CMakeFiles/lovepotion.dir/source/modules/data/wrap_DataModule.o CMakeFiles/lovepotion.dir/source/modules/data/wrap_DataView.o CMakeFiles/lovepotion.dir/source/modules/event/Event.o CMakeFiles/lovepotion.dir/source/modules/event/wrap_Event.o CMakeFiles/lovepotion.dir/source/modules/filesystem/FileData.o CMakeFiles/lovepotion.dir/source/modules/filesystem/wrap_File.o CMakeFiles/lovepotion.dir/source/modules/filesystem/wrap_FileData.o CMakeFiles/lovepotion.dir/source/modules/filesystem/wrap_Filesystem.o CMakeFiles/lovepotion.dir/source/modules/font/Font.o CMakeFiles/lovepotion.dir/source/modules/font/GlyphData.o CMakeFiles/lovepotion.dir/source/modules/font/Rasterizer.o CMakeFiles/lovepotion.dir/source/modules/font/TextShaper.o CMakeFiles/lovepotion.dir/source/modules/font/GenericShaper.o CMakeFiles/lovepotion.dir/source/modules/font/wrap_Font.o CMakeFiles/lovepotion.dir/source/modules/font/wrap_Rasterizer.o CMakeFiles/lovepotion.dir/source/modules/font/wrap_GlyphData.o CMakeFiles/lovepotion.dir/source/modules/graphics/Buffer.o CMakeFiles/lovepotion.dir/source/modules/graphics/Graphics.o CMakeFiles/lovepotion.dir/source/modules/graphics/FontBase.o CMakeFiles/lovepotion.dir/source/modules/graphics/Mesh.o CMakeFiles/lovepotion.dir/source/modules/graphics/Polyline.o CMakeFiles/lovepotion.dir/source/modules/graphics/wrap_Mesh.o CMakeFiles/lovepotion.dir/source/modules/graphics/TextBatch.o CMakeFiles/lovepotion.dir/source/modules/graphics/renderstate.o CMakeFiles/lovepotion.dir/source/modules/graphics/samplerstate.o CMakeFiles/lovepotion.dir/source/modules/graphics/Shader.o CMakeFiles/lovepotion.dir/source/modules/graphics/Quad.o CMakeFiles/lovepotion.dir/source/modules/graphics/Volatile.o CMakeFiles/lovepotion.dir/source/modules/graphics/vertex.o CMakeFiles/lovepotion.dir/source/modules/graphics/wrap_Graphics.o CMakeFiles/lovepotion.dir/source/modules/graphics/wrap_Texture.o CMakeFiles/lovepotion.dir/source/modules/graphics/wrap_TextBatch.o CMakeFiles/lovepotion.dir/source/modules/graphics/wrap_Font.o CMakeFiles/lovepotion.dir/source/modules/graphics/wrap_Quad.o CMakeFiles/lovepotion.dir/source/modules/graphics/Texture.o CMakeFiles/lovepotion.dir/source/modules/image/CompressedImageData.o CMakeFiles/lovepotion.dir/source/modules/image/CompressedSlice.o CMakeFiles/lovepotion.dir/source/modules/image/FormatHandler.o CMakeFiles/lovepotion.dir/source/modules/image/Image.o CMakeFiles/lovepotion.dir/source/modules/image/ImageData.o CMakeFiles/lovepotion.dir/source/modules/image/ImageDataBase.o CMakeFiles/lovepotion.dir/source/modules/image/wrap_CompressedImageData.o CMakeFiles/lovepotion.dir/source/modules/image/wrap_Image.o CMakeFiles/lovepotion.dir/source/modules/image/wrap_ImageData.o CMakeFiles/lovepotion.dir/source/modules/joystick/JoystickModule.o CMakeFiles/lovepotion.dir/source/modules/joystick/wrap_Joystick.o CMakeFiles/lovepotion.dir/source/modules/joystick/wrap_JoystickModule.o CMakeFiles/lovepotion.dir/source/modules/keyboard/wrap_Keyboard.o CMakeFiles/lovepotion.dir/source/modules/love/love.o CMakeFiles/lovepotion.dir/source/modules/math/BezierCurve.o CMakeFiles/lovepotion.dir/source/modules/math/MathModule.o CMakeFiles/lovepotion.dir/source/modules/math/RandomGenerator.o CMakeFiles/lovepotion.dir/source/modules/math/Transform.o CMakeFiles/lovepotion.dir/source/modules/math/wrap_BezierCurve.o CMakeFiles/lovepotion.dir/source/modules/math/wrap_MathModule.o CMakeFiles/lovepotion.dir/source/modules/math/wrap_RandomGenerator.o CMakeFiles/lovepotion.dir/source/modules/math/wrap_Transform.o CMakeFiles/lovepotion.dir/source/modules/sensor/Sensor.o CMakeFiles/lovepotion.dir/source/modules/sensor/wrap_Sensor.o CMakeFiles/lovepotion.dir/source/modules/sound/Decoder.o CMakeFiles/lovepotion.dir/source/modules/sound/Sound.o CMakeFiles/lovepotion.dir/source/modules/sound/SoundData.o CMakeFiles/lovepotion.dir/source/modules/sound/wrap_Decoder.o CMakeFiles/lovepotion.dir/source/modules/sound/wrap_Sound.o CMakeFiles/lovepotion.dir/source/modules/sound/wrap_SoundData.o CMakeFiles/lovepotion.dir/source/modules/system/wrap_System.o CMakeFiles/lovepotion.dir/source/modules/thread/Channel.o CMakeFiles/lovepotion.dir/source/modules/thread/LuaThread.o CMakeFiles/lovepotion.dir/source/modules/thread/Thread.o CMakeFiles/lovepotion.dir/source/modules/thread/Threadable.o CMakeFiles/lovepotion.dir/source/modules/thread/ThreadModule.o CMakeFiles/lovepotion.dir/source/modules/thread/wrap_Channel.o CMakeFiles/lovepotion.dir/source/modules/thread/wrap_LuaThread.o CMakeFiles/lovepotion.dir/source/modules/thread/wrap_Thread.o CMakeFiles/lovepotion.dir/source/modules/timer/wrap_Timer.o CMakeFiles/lovepotion.dir/source/modules/touch/Touch.o CMakeFiles/lovepotion.dir/source/modules/touch/wrap_Touch.o CMakeFiles/lovepotion.dir/source/modules/window/wrap_Window.o CMakeFiles/lovepotion.dir/source/modules/data/misc/Compressor.o CMakeFiles/lovepotion.dir/source/modules/data/misc/HashFunction.o CMakeFiles/lovepotion.dir/source/modules/filesystem/physfs/File.o CMakeFiles/lovepotion.dir/source/modules/filesystem/physfs/Filesystem.o CMakeFiles/lovepotion.dir/source/modules/sound/lullaby/FLACDecoder.o CMakeFiles/lovepotion.dir/source/modules/sound/lullaby/ModPlugDecoder.o CMakeFiles/lovepotion.dir/source/modules/sound/lullaby/MP3Decoder.o CMakeFiles/lovepotion.dir/source/modules/sound/lullaby/VorbisDecoder.o CMakeFiles/lovepotion.dir/source/modules/sound/lullaby/WaveDecoder.o -o lovepotion.elf -ldeko3d /opt/devkitpro/portlibs/switch/lib/libfreetype.a -lbz2 -lpng -lturbojpeg libddsparse.a liblove_physfs.a libwuff.a libnoise1234.a -lvorbisidec -lz libluabit.a liblua53.a -logg -lmodplug liblua-https.a libluasocket.a /opt/devkitpro/portlibs/switch/lib/liblz4.a /opt/devkitpro/portlibs/switch/lib/libcurl.a /opt/devkitpro/libnx/lib/libnx.a /opt/devkitpro/portlibs/switch/lib/libz.a /opt/devkitpro/libnx/lib/libnx.a /opt/devkitpro/portlibs/switch/lib/libz.a /opt/devkitpro/portlibs/switch/lib/liblua5.1.a /opt/devkitpro/devkitA64/aarch64-none-elf/lib/pic/libm.a -lnx -lm && /bin/sh CMakeFiles/lovepotion.dir/post-build.sh 62f60396062a37ea +C:/msys64/opt/devkitpro/devkitA64/bin/../lib/gcc/aarch64-none-elf/14.2.0/../../../../aarch64-none-elf/bin/ld.exe: CMakeFiles/lovepotion.dir/platform/hac/source/modules/graphics/Graphics.o:(.data.rel.ro._ZTVN4love8GraphicsE[_ZTVN4love8GraphicsE]+0x40): undefined reference to `love::Graphics::newTexture(love::TextureBase::Settings const&, love::TextureBase::Slices const*)' +C:/msys64/opt/devkitpro/devkitA64/bin/../lib/gcc/aarch64-none-elf/14.2.0/../../../../aarch64-none-elf/bin/ld.exe: CMakeFiles/lovepotion.dir/platform/hac/source/modules/graphics/Graphics.o:(.data.rel.ro._ZTVN4love8GraphicsE[_ZTVN4love8GraphicsE]+0x48): undefined reference to `love::Graphics::newFont(love::Rasterizer*)' +C:/msys64/opt/devkitpro/devkitA64/bin/../lib/gcc/aarch64-none-elf/14.2.0/../../../../aarch64-none-elf/bin/ld.exe: CMakeFiles/lovepotion.dir/platform/hac/source/modules/graphics/Graphics.o:(.data.rel.ro._ZTVN4love8GraphicsE[_ZTVN4love8GraphicsE]+0x50): undefined reference to `love::Graphics::newDefaultFont(int, love::Rasterizer::Settings const&)' +C:/msys64/opt/devkitpro/devkitA64/bin/../lib/gcc/aarch64-none-elf/14.2.0/../../../../aarch64-none-elf/bin/ld.exe: CMakeFiles/lovepotion.dir/platform/hac/source/modules/graphics/Graphics.o:(.data.rel.ro._ZTVN4love8GraphicsE[_ZTVN4love8GraphicsE]+0xb0): undefined reference to `love::Graphics::setRenderTargetsInternal(love::GraphicsBase::RenderTargets const&, int, int, bool)' +C:/msys64/opt/devkitpro/devkitA64/bin/../lib/gcc/aarch64-none-elf/14.2.0/../../../../aarch64-none-elf/bin/ld.exe: CMakeFiles/lovepotion.dir/platform/hac/source/modules/graphics/Graphics.o:(.data.rel.ro._ZTVN4love8GraphicsE[_ZTVN4love8GraphicsE]+0xb8): undefined reference to `love::Graphics::isPixelFormatSupported(love::PixelFormat, unsigned int)' +C:/msys64/opt/devkitpro/devkitA64/bin/../lib/gcc/aarch64-none-elf/14.2.0/../../../../aarch64-none-elf/bin/ld.exe: CMakeFiles/lovepotion.dir/source/modules/graphics/wrap_Texture.o: in function `Wrap_Texture::setDepthSampleMode(lua_State*)': +D:/lovepotion/source/modules/graphics/wrap_Texture.cpp:370:(.text._ZN12Wrap_Texture18setDepthSampleModeEP9lua_State+0xf4): undefined reference to `love::Texture::setSamplerState(love::SamplerState const&)' +C:/msys64/opt/devkitpro/devkitA64/bin/../lib/gcc/aarch64-none-elf/14.2.0/../../../../aarch64-none-elf/bin/ld.exe: CMakeFiles/lovepotion.dir/source/modules/graphics/wrap_Texture.o: in function `Wrap_Texture::setWrap(lua_State*)': +D:/lovepotion/source/modules/graphics/wrap_Texture.cpp:261:(.text._ZN12Wrap_Texture7setWrapEP9lua_State+0x1bc): undefined reference to `love::Texture::setSamplerState(love::SamplerState const&)' +C:/msys64/opt/devkitpro/devkitA64/bin/../lib/gcc/aarch64-none-elf/14.2.0/../../../../aarch64-none-elf/bin/ld.exe: CMakeFiles/lovepotion.dir/source/modules/graphics/wrap_Texture.o: in function `Wrap_Texture::setMipmapFilter(lua_State*)': +D:/lovepotion/source/modules/graphics/wrap_Texture.cpp:219:(.text._ZN12Wrap_Texture15setMipmapFilterEP9lua_State+0x7c): undefined reference to `love::Texture::setSamplerState(love::SamplerState const&)' +C:/msys64/opt/devkitpro/devkitA64/bin/../lib/gcc/aarch64-none-elf/14.2.0/../../../../aarch64-none-elf/bin/ld.exe: CMakeFiles/lovepotion.dir/source/modules/graphics/wrap_Texture.o: in function `Wrap_Texture::setFilter(lua_State*)': +D:/lovepotion/source/modules/graphics/wrap_Texture.cpp:175:(.text._ZN12Wrap_Texture9setFilterEP9lua_State+0x170): undefined reference to `love::Texture::setSamplerState(love::SamplerState const&)' +collect2.exe: error: ld returned 1 exit status +ninja: build stopped: subcommand failed. +CMake Error at /opt/devkitpro/cmake/Catnip/Verb-Build.cmake:91 (message): + Failed to build main.release +Call Stack (most recent call first): + /opt/devkitpro/cmake/Catnip/Verb-Build.cmake:102 (__catnip_build) + /opt/devkitpro/cmake/catnip-main.cmake:11 (include) + + diff --git a/platform/cafe/include/modules/graphics/Graphics.hpp b/platform/cafe/include/modules/graphics/Graphics.hpp index 903c4e4e..047cd80a 100644 --- a/platform/cafe/include/modules/graphics/Graphics.hpp +++ b/platform/cafe/include/modules/graphics/Graphics.hpp @@ -34,6 +34,8 @@ namespace love virtual void setBlendState(const BlendState& state) override; + virtual void setPointSize(float size) override; + virtual FontBase* newFont(Rasterizer* data) override; virtual FontBase* newDefaultFont(int size, const Rasterizer::Settings& settings) override; diff --git a/platform/cafe/source/modules/graphics/Graphics.cpp b/platform/cafe/source/modules/graphics/Graphics.cpp index c1419a41..e7f08896 100644 --- a/platform/cafe/source/modules/graphics/Graphics.cpp +++ b/platform/cafe/source/modules/graphics/Graphics.cpp @@ -208,6 +208,14 @@ namespace love state.scissorRect = scissor; } + void Graphics::setPointSize(float size) + { + if (size != this->states.back().pointSize) + this->flushBatchedDraws(); + + this->states.back().pointSize = size; + } + void Graphics::setScissor() { if (this->states.back().scissor) diff --git a/platform/ctr/include/modules/graphics/Graphics.hpp b/platform/ctr/include/modules/graphics/Graphics.hpp index 451af363..dcd7e2f6 100644 --- a/platform/ctr/include/modules/graphics/Graphics.hpp +++ b/platform/ctr/include/modules/graphics/Graphics.hpp @@ -31,6 +31,14 @@ namespace love virtual void setColorMask(ColorChannelMask mask) override; + virtual void setPointSize(float size) override + { + if (size != this->states.back().pointSize) + this->flushBatchedDraws(); + + this->states.back().pointSize = size; + } + virtual void setBlendState(const BlendState& state) override; virtual FontBase* newFont(Rasterizer* data) override; diff --git a/platform/ctr/include/modules/graphics/Texture.hpp b/platform/ctr/include/modules/graphics/Texture.hpp index f519b1a0..c5d60edc 100644 --- a/platform/ctr/include/modules/graphics/Texture.hpp +++ b/platform/ctr/include/modules/graphics/Texture.hpp @@ -32,9 +32,9 @@ namespace love void generateMipmapsInternal() override; - void setHandleData(void* data) override + void setHandleData(ptrdiff_t data) override { - this->texture->data = data; + this->texture->data = (void*)data; } // bool validateDimensions(bool throwException) const; diff --git a/platform/hac/CMakeLists.txt b/platform/hac/CMakeLists.txt index 4d058328..be610d7a 100644 --- a/platform/hac/CMakeLists.txt +++ b/platform/hac/CMakeLists.txt @@ -35,9 +35,12 @@ source/driver/display/deko3d/CIntrusiveTree.cpp source/driver/display/deko3d/CMemPool.cpp source/driver/display/Framebuffer.cpp source/driver/display/deko.cpp +source/driver/graphics/StreamBuffer.cpp source/driver/EventQueue.cpp source/modules/audio/Source.cpp source/modules/graphics/Graphics.cpp +source/modules/graphics/Shader.cpp +source/modules/graphics/Texture.cpp source/modules/joystick/Joystick.cpp source/modules/joystick/JoystickModule.cpp source/modules/keyboard/Keyboard.cpp diff --git a/platform/hac/include/driver/display/deko.hpp b/platform/hac/include/driver/display/deko.hpp index 87dee541..217f3f74 100644 --- a/platform/hac/include/driver/display/deko.hpp +++ b/platform/hac/include/driver/display/deko.hpp @@ -6,11 +6,11 @@ #include "driver/display/Framebuffer.hpp" #include "driver/display/Renderer.tcc" +#include "driver/graphics/BitAlloc.hpp" + #include "driver/display/deko3d/CCmdMemRing.h" -#include "driver/display/deko3d/CCmdVtxRing.h" #include "driver/display/deko3d/CDescriptorSet.h" -#include "modules/graphics/Texture.hpp" #include "modules/graphics/vertex.hpp" /* Enforces GLSL std140/std430 alignment rules for glm types */ @@ -22,6 +22,8 @@ #include #include +#define MAX_OBJECTS 0x400 + namespace love { class deko3d : public RendererBase @@ -68,6 +70,10 @@ namespace love void setVertexWinding(Winding winding); + void setPointSize(float size); + + void setSamplerState(TextureBase* texture, const SamplerState& state); + void prepareDraw(GraphicsBase* graphics); void useProgram(const dk::Shader& vertex, const dk::Shader& fragment); @@ -111,6 +117,13 @@ namespace love } } + void registerTexture(TextureBase* texture, bool registering); + + void ensureInFrame(); + + void drawIndexed(DkPrimitive primitive, uint32_t indexCount, uint32_t indexOffset, + uint32_t instanceCount); + // clang-format off ENUMMAP_DECLARE(BlendOperations, BlendOperation, DkBlendOp, { BLENDOP_ADD, DkBlendOp_Add }, @@ -144,6 +157,58 @@ namespace love { WINDING_CCW, DkFrontFace_CCW }, { WINDING_CW, DkFrontFace_CW } ); + + ENUMMAP_DECLARE(FilterModes, SamplerState::FilterMode, DkFilter, + { SamplerState::FILTER_LINEAR, DkFilter_Linear }, + { SamplerState::FILTER_NEAREST, DkFilter_Nearest } + ); + + ENUMMAP_DECLARE(WrapModes, SamplerState::WrapMode, DkWrapMode, + { SamplerState::WRAP_CLAMP, DkWrapMode_Clamp }, + { SamplerState::WRAP_CLAMP_ZERO, DkWrapMode_ClampToBorder }, + { SamplerState::WRAP_REPEAT, DkWrapMode_Repeat }, + { SamplerState::WRAP_MIRRORED_REPEAT, DkWrapMode_MirroredRepeat } + ); + + ENUMMAP_DECLARE(PixelFormats, PixelFormat, DkImageFormat, + { PIXELFORMAT_R8_UNORM, DkImageFormat_R8_Unorm }, + { PIXELFORMAT_R16_UNORM, DkImageFormat_R16_Unorm }, + { PIXELFORMAT_RG8_UNORM, DkImageFormat_RG8_Unorm }, + { PIXELFORMAT_RGBA8_UNORM, DkImageFormat_RGBA8_Unorm }, + { PIXELFORMAT_RGB565_UNORM, DkImageFormat_RGB565_Unorm }, + { PIXELFORMAT_RGBA8_sRGB, DkImageFormat_RGBA8_Unorm_sRGB }, + { PIXELFORMAT_DXT1_UNORM, DkImageFormat_RGBA_BC1 }, + { PIXELFORMAT_DXT3_UNORM, DkImageFormat_RGBA_BC2 }, + { PIXELFORMAT_DXT5_UNORM, DkImageFormat_RGBA_BC3 }, + { PIXELFORMAT_ETC1_UNORM, DkImageFormat_RGB_ETC2 }, + { PIXELFORMAT_ETC2_RGB_UNORM, DkImageFormat_RGB_ETC2 }, + { PIXELFORMAT_ETC2_RGBA1_UNORM, DkImageFormat_RGBA_ETC2 }, + { PIXELFORMAT_ETC2_RGBA_UNORM, DkImageFormat_RGBA_ETC2 }, + { PIXELFORMAT_BC4_UNORM, DkImageFormat_R_BC4_Unorm }, + { PIXELFORMAT_BC5_UNORM, DkImageFormat_RG_BC5_Unorm }, + { PIXELFORMAT_BC7_UNORM, DkImageFormat_RGBA_BC7_Unorm }, + { PIXELFORMAT_BC7_sRGB, DkImageFormat_RGBA_BC7_Unorm_sRGB }, + { PIXELFORMAT_ASTC_4x4_UNORM, DkImageFormat_RGBA_ASTC_4x4 }, + { PIXELFORMAT_ASTC_5x4_UNORM, DkImageFormat_RGBA_ASTC_5x4 }, + { PIXELFORMAT_ASTC_6x5_UNORM, DkImageFormat_RGBA_ASTC_6x5 }, + { PIXELFORMAT_ASTC_6x6_UNORM, DkImageFormat_RGBA_ASTC_6x6 }, + { PIXELFORMAT_ASTC_8x5_UNORM, DkImageFormat_RGBA_ASTC_8x5 }, + { PIXELFORMAT_ASTC_8x6_UNORM, DkImageFormat_RGBA_ASTC_8x6 }, + { PIXELFORMAT_ASTC_8x8_UNORM, DkImageFormat_RGBA_ASTC_8x8 }, + { PIXELFORMAT_ASTC_10x5_UNORM, DkImageFormat_RGBA_ASTC_10x5 }, + { PIXELFORMAT_ASTC_10x6_UNORM, DkImageFormat_RGBA_ASTC_10x6 }, + { PIXELFORMAT_ASTC_10x8_UNORM, DkImageFormat_RGBA_ASTC_10x8 }, + { PIXELFORMAT_ASTC_10x10_UNORM, DkImageFormat_RGBA_ASTC_10x10 }, + { PIXELFORMAT_ASTC_12x10_UNORM, DkImageFormat_RGBA_ASTC_12x10 }, + { PIXELFORMAT_ASTC_12x12_UNORM, DkImageFormat_RGBA_ASTC_12x12 } + ); + + ENUMMAP_DECLARE(PrimitiveTypes, PrimitiveType, DkPrimitive, + { PRIMITIVE_TRIANGLES, DkPrimitive_Triangles }, + { PRIMITIVE_POINTS, DkPrimitive_Points }, + { PRIMITIVE_TRIANGLE_STRIP, DkPrimitive_TriangleStrip }, + { PRIMITIVE_TRIANGLE_FAN, DkPrimitive_TriangleFan } + ); // clang-format on private: @@ -163,8 +228,6 @@ namespace love static constexpr int COMMAND_SIZE = 0x100000; static constexpr int VERTEX_COMMAND_SIZE = 0x100000; - void ensureInFrame(); - void createFramebuffers(); void destroyFramebuffers(); @@ -174,6 +237,7 @@ namespace love dk::RasterizerState rasterizer; dk::ColorWriteState colorWrite; dk::BlendState blend; + dk::ColorState color; dk::Image* boundFramebuffer; } context; @@ -207,6 +271,10 @@ namespace love CCmdMemRing<2> commands; std::array targets; + + BitwiseAlloc textureHandles; + CDescriptorSet imageSet; + CDescriptorSet samplerSet; }; extern deko3d d3d; diff --git a/platform/hac/include/driver/display/deko3d/bitalloc.hpp b/platform/hac/include/driver/display/deko3d/bitalloc.hpp deleted file mode 100644 index e1853229..00000000 --- a/platform/hac/include/driver/display/deko3d/bitalloc.hpp +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include - -template -class BitwiseAlloc : std::bitset -{ - public: - size_t allocate() - { - size_t index = 0; - while (index < this->size() && this->test(index)) - ++index; - - this->set(index); - return index; - } - - void reset(uint32_t handle) - { - auto index = 0; - - if (this->Find(handle, index)) - this->reset(index); - } - - bool find(uint32_t handle, int& out) - { - size_t index = (handle & ((1U << 20) - 1)); - - if (this->test(index)) - { - out = index; - return true; - } - - out = -1; - return false; - } -}; diff --git a/platform/hac/include/driver/graphics/Attributes.hpp b/platform/hac/include/driver/graphics/Attributes.hpp new file mode 100644 index 00000000..57c93d41 --- /dev/null +++ b/platform/hac/include/driver/graphics/Attributes.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include "common/Color.hpp" + +#include "modules/graphics/vertex.hpp" + +#include +#include +#define DK_HPP_SUPPORT_VECTOR +#include + +namespace love +{ + namespace vertex + { + struct Attributes + { + dk::detail::ArrayProxy attributeState; + dk::detail::ArrayProxy bufferState; + }; + + // clang-format off + /* Primitives */ + constexpr std::array PrimitiveBufferState = { + DkVtxBufferState { sizeof(Vertex), 0 }, + }; + + constexpr std::array PrimitiveAttribState = { + DkVtxAttribState { 0, 0, POSITION_OFFSET, DkVtxAttribSize_2x32, DkVtxAttribType_Float, 0 }, + DkVtxAttribState { 0, 0, COLOR_OFFSET, DkVtxAttribSize_4x32, DkVtxAttribType_Float, 0 } + }; + // clang-format on + + static bool getAttributes(CommonFormat format, Attributes& out) + { + switch (format) + { + case CommonFormat::XYf_RGBAf: + default: + { + out.attributeState = PrimitiveAttribState; + out.bufferState = PrimitiveBufferState; + return true; + } + } + + return false; + } + } // namespace vertex +} // namespace love diff --git a/platform/hac/include/driver/graphics/BitAlloc.hpp b/platform/hac/include/driver/graphics/BitAlloc.hpp new file mode 100644 index 00000000..939af9e0 --- /dev/null +++ b/platform/hac/include/driver/graphics/BitAlloc.hpp @@ -0,0 +1,43 @@ +#pragma once + +#include + +namespace love +{ + template + class BitwiseAlloc : std::bitset + { + public: + size_t allocate() + { + size_t index = 0; + while (index < this->size() && this->test(index)) + ++index; + + this->set(index); + return index; + } + + void reset(uint32_t handle) + { + auto index = 0; + + if (this->find(handle, index)) + this->reset(index); + } + + bool find(uint32_t handle, int& out) + { + size_t index = (handle & ((1U << 20) - 1)); + + if (this->test(index)) + { + out = index; + return true; + } + + out = -1; + return false; + } + }; +} // namespace love diff --git a/platform/hac/include/driver/graphics/StreamBuffer.hpp b/platform/hac/include/driver/graphics/StreamBuffer.hpp index b3a17dff..84fa19bc 100644 --- a/platform/hac/include/driver/graphics/StreamBuffer.hpp +++ b/platform/hac/include/driver/graphics/StreamBuffer.hpp @@ -1,11 +1,10 @@ #pragma once +#include "driver/display/deko.hpp" + #include "driver/graphics/StreamBuffer.tcc" #include "modules/graphics/Volatile.hpp" -#include "driver/display/deko.hpp" -#include "driver/display/deko3d/CMemPool.h" - namespace love { template @@ -17,6 +16,12 @@ namespace love this->sliceSize = (size + DK_CMDMEM_ALIGNMENT - 1) & ~(DK_CMDMEM_ALIGNMENT - 1); } + bool allocate(CMemPool& pool) + { + this->memory = pool.allocate(this->sliceSize, alignof(T)); + return this->memory; + } + StreamBuffer(const StreamBuffer&) = delete; StreamBuffer& operator=(const StreamBuffer&) = delete; @@ -35,6 +40,8 @@ namespace love return info; } + size_t unmap(size_t); + ptrdiff_t getHandle() const { return (ptrdiff_t)this->memory.getGpuAddr(); diff --git a/platform/hac/include/modules/graphics/Graphics.hpp b/platform/hac/include/modules/graphics/Graphics.hpp index ebed0e21..db5d6c60 100644 --- a/platform/hac/include/modules/graphics/Graphics.hpp +++ b/platform/hac/include/modules/graphics/Graphics.hpp @@ -39,6 +39,8 @@ namespace love virtual void setBlendState(const BlendState& state) override; + virtual void setPointSize(float size) override; + virtual FontBase* newFont(Rasterizer* data) override; virtual FontBase* newDefaultFont(int size, const Rasterizer::Settings& settings) override; diff --git a/platform/hac/include/modules/graphics/Texture.hpp b/platform/hac/include/modules/graphics/Texture.hpp index f04c5e70..dbf4d2b2 100644 --- a/platform/hac/include/modules/graphics/Texture.hpp +++ b/platform/hac/include/modules/graphics/Texture.hpp @@ -3,6 +3,7 @@ #include "modules/graphics/Texture.tcc" #include "modules/graphics/Volatile.hpp" +#include "driver/display/deko3d/CMemPool.h" #include namespace love @@ -24,21 +25,38 @@ namespace love ptrdiff_t getSamplerHandle() const override; + dk::ImageDescriptor getDescriptorHandle() + { + return this->descriptor; + } + + dk::SamplerDescriptor getSamplerDescriptorHandle() + { + return this->samplerDescriptor; + } + void setSamplerState(const SamplerState& state) override; void uploadByteData(const void* data, size_t size, int slice, int mipmap, const Rect& rect) override; void generateMipmapsInternal() override; - void setHandleData(void* data) override - {} + void setHandleData(ptrdiff_t data) override + { + this->handle = (DkResHandle)data; + } private: void createTexture(); Slices slices; - DkImage texture; - DkSampler sampler; + dk::Image image; + dk::ImageDescriptor descriptor; + dk::Sampler sampler; + dk::SamplerDescriptor samplerDescriptor; + + DkResHandle handle; + CMemPool::Handle memory; }; } // namespace love diff --git a/platform/hac/source/boot.cpp b/platform/hac/source/boot.cpp index 066be849..c96ab92a 100644 --- a/platform/hac/source/boot.cpp +++ b/platform/hac/source/boot.cpp @@ -16,7 +16,7 @@ namespace love static constexpr std::array services = {{ { "bsd", BIND(socketInitializeDefault), &socketExit }, - { "pl:u", BIND(plInitialize, PlServiceType_User), &plExit }, + { "pl:u", BIND(plInitialize, PlServiceType_User), &plExit }, { "acc:a", BIND(accountInitialize, AccountServiceType_Application), &accountExit }, { "set", BIND(setInitialize), &setExit }, { "set:sys", BIND(setsysInitialize), &setsysExit }, diff --git a/platform/hac/source/driver/display/Framebuffer.cpp b/platform/hac/source/driver/display/Framebuffer.cpp index 452b43d8..8aca4675 100644 --- a/platform/hac/source/driver/display/Framebuffer.cpp +++ b/platform/hac/source/driver/display/Framebuffer.cpp @@ -8,8 +8,7 @@ namespace love Framebuffer::~Framebuffer() {} - void Framebuffer::create(const ScreenInfo& info, dk::Device& device, CMemPool& images, - bool depth) + void Framebuffer::create(const ScreenInfo& info, dk::Device& device, CMemPool& images, bool depth) { const auto flags = depth ? BASE_FLAGS : MAIN_FLAGS; const auto format = depth ? DkImageFormat_Z24S8 : DkImageFormat_RGBA8_Unorm; diff --git a/platform/hac/source/driver/display/deko.cpp b/platform/hac/source/driver/display/deko.cpp index ad7d3c78..12ff633e 100644 --- a/platform/hac/source/driver/display/deko.cpp +++ b/platform/hac/source/driver/display/deko.cpp @@ -1,4 +1,5 @@ #include "driver/display/deko.hpp" +#include "driver/graphics/Attributes.hpp" namespace love { @@ -7,15 +8,13 @@ namespace love device(dk::DeviceMaker {}.setFlags(DkDeviceFlags_DepthMinusOneToOne).create()), mainQueue(dk::QueueMaker { this->device }.setFlags(DkQueueFlags_Graphics).create()), textureQueue(dk::QueueMaker { this->device }.setFlags(DkQueueFlags_Graphics).create()), - commandBuffer(dk::CmdBufMaker { this->device }.create()), swapchain {}, images(CMemPool(this->device, GPU_USE_FLAGS, GPU_POOL_SIZE)), data(CMemPool(this->device, CPU_USE_FLAGS, CPU_POOL_SIZE)), code(CMemPool(this->device, SHADER_USE_FLAGS, SHADER_POOL_SIZE)), - framebufferSlot(-1) - { - std::memset(&this->context, 0, sizeof(this->context)); - } + framebufferSlot(-1), + context {} + {} void deko3d::initialize() { @@ -26,7 +25,14 @@ namespace love this->transform.modelView = glm::mat4(1.0f); this->commands.allocate(this->data, COMMAND_SIZE); + this->commandBuffer = dk::CmdBufMaker { this->device }.create(); + this->createFramebuffers(); + this->ensureInFrame(); + + this->context.rasterizer.setCullMode(DkFace_None); + this->context.rasterizer.setFrontFace(DkFrontFace_CCW); + this->context.color.setBlendEnable(0, true); this->initialized = true; } @@ -79,6 +85,9 @@ namespace love { if (!this->inFrame) { + if (this->framebufferSlot < 0) + this->framebufferSlot = this->mainQueue.acquireImage(this->swapchain); + this->commands.begin(this->commandBuffer); this->inFrame = true; } @@ -86,16 +95,23 @@ namespace love void deko3d::clear(const Color& color) { + if (!this->context.boundFramebuffer) + return; + this->commandBuffer.clearColor(0, DkColorMask_RGBA, color.r, color.g, color.b, color.a); } void deko3d::clearDepthStencil(int depth, uint8_t mask, double stencil) { + if (!this->inFrame) + return; + this->commandBuffer.clearDepthStencil(true, depth, mask, stencil); } dk::Image& deko3d::getInternalBackbuffer() { + this->ensureInFrame(); return this->framebuffers[this->framebufferSlot].getImage(); } @@ -107,12 +123,23 @@ namespace love // clang-format off } + void deko3d::registerTexture(TextureBase* texture, bool registering) + { + if (registering) + { + const auto handle = this->textureHandles.allocate(); + texture->setHandleData(handle); + return; + } + + this->textureHandles.reset((DkResHandle)texture->getHandle()); + } + void deko3d::bindFramebuffer(dk::Image& framebuffer) { if (!this->swapchain) return; - this->ensureInFrame(); bool bindingModified = false; if (this->context.boundFramebuffer != &framebuffer) @@ -133,18 +160,36 @@ namespace love void deko3d::bindBuffer(BufferUsage usage, DkGpuAddr buffer, size_t size) { if (usage == BUFFERUSAGE_VERTEX) - { this->commandBuffer.bindVtxBuffer(0, buffer, size); - return; - } else if (usage == BUFFERUSAGE_INDEX) - { this->commandBuffer.bindIdxBuffer(DkIdxFormat_Uint16, buffer); - } + } + + void deko3d::drawIndexed(DkPrimitive primitive, uint32_t indexCount, uint32_t indexOffset, uint32_t instanceCount) + { + vertex::Attributes attributes {}; + bool success = getAttributes(CommonFormat::XYf_RGBAf, attributes); + + if (!success) + return; + + this->commandBuffer.bindVtxAttribState(attributes.attributeState); + this->commandBuffer.bindVtxBufferState(attributes.bufferState); + + this->commandBuffer.drawIndexed(primitive, indexCount, instanceCount, indexOffset, 0, 0); } void deko3d::prepareDraw(GraphicsBase* graphics) - {} + { + this->commandBuffer.bindRasterizerState(this->context.rasterizer); + this->commandBuffer.bindBlendStates(0, this->context.blend); + + // this->commandBuffer.bindColorState(this->context.color); + + this->commandBuffer.pushConstants(this->uniformBuffer.getGpuAddr(), + this->uniformBuffer.getSize(), 0, TRANSFORM_SIZE, + &this->transform); + } void deko3d::present() { @@ -153,13 +198,16 @@ namespace love if (this->inFrame) { + GraphicsBase::flushBatchedDrawsGlobal(); + GraphicsBase::advanceStreamBuffersGlobal(); + this->mainQueue.submitCommands(this->commands.end(this->commandBuffer)); this->mainQueue.presentImage(this->swapchain, this->framebufferSlot); this->inFrame = false; } - this->framebufferSlot = this->mainQueue.acquireImage(this->swapchain); + this->framebufferSlot = -1; } void deko3d::setVertexWinding(Winding winding) @@ -171,6 +219,11 @@ namespace love this->context.rasterizer.setFrontFace(face); } + void deko3d::setPointSize(float size) + { + this->commandBuffer.setPointSize(size); + } + void deko3d::setCullMode(CullMode mode) { DkFace cullMode; @@ -230,6 +283,47 @@ namespace love this->context.blend.setDstAlphaBlendFactor(destAlpha); } + void deko3d::setSamplerState(TextureBase* texture, const SamplerState&state) + { + auto* sampler = (dk::Sampler*)texture->getSamplerHandle(); + auto index = -1; + + if (!this->textureHandles.find((uint32_t)texture->getHandle(), index)) + index = this->textureHandles.allocate(); + + DkFilter magFilter; + if (!deko3d::getConstant(state.magFilter, magFilter)) + return; + + DkFilter minFilter; + if (!deko3d::getConstant(state.minFilter, minFilter)) + return; + + sampler->setFilter(minFilter, magFilter); + + DkWrapMode wrapU; + if (!deko3d::getConstant(state.wrapU, wrapU)) + return; + + DkWrapMode wrapV; + if (!deko3d::getConstant(state.wrapV, wrapV)) + return; + + DkWrapMode wrapW; + if (!deko3d::getConstant(state.wrapW, wrapW)) + return; + + sampler->setWrapMode(wrapU, wrapV, wrapW); + + // const auto descriptor = ((Texture*)texture)->getDescriptorHandle(); + // this->imageSet.update(this->commandBuffer, index, descriptor); + + // auto samplerDescriptor = ((Texture*)texture)->getSamplerDescriptorHandle(); + // samplerDescriptor.initialize(*sampler); + + // this->samplerSet.update(this->commandBuffer, index, samplerDescriptor); + } + static DkScissor dkScissorFromRect(const Rect& rect) { DkScissor scissor {}; @@ -280,6 +374,9 @@ namespace love _viewport = dkViewportFromRect(viewport); this->commandBuffer.setViewports(0, { _viewport }); + + const auto ortho = glm::ortho(0.0f, (float)viewport.w, (float)viewport.h, 0.0f, -10.0f, 10.0f); + this->transform.projection = ortho; } deko3d d3d; diff --git a/platform/hac/source/driver/graphics/StreamBuffer.cpp b/platform/hac/source/driver/graphics/StreamBuffer.cpp new file mode 100644 index 00000000..ad7f2a89 --- /dev/null +++ b/platform/hac/source/driver/graphics/StreamBuffer.cpp @@ -0,0 +1,20 @@ +#include "driver/display/deko.hpp" + +#include "driver/graphics/StreamBuffer.hpp" + +namespace love +{ + template<> + size_t StreamBuffer::unmap(size_t) + { + d3d.bindBuffer(this->usage, this->memory.getGpuAddr(), this->memory.getSize()); + return this->index; + } + + template<> + size_t StreamBuffer::unmap(size_t) + { + d3d.bindBuffer(this->usage, this->memory.getGpuAddr(), this->memory.getSize()); + return this->index; + } +} // namespace love diff --git a/platform/hac/source/modules/graphics/Graphics.cpp b/platform/hac/source/modules/graphics/Graphics.cpp index 4a19b883..3a30ffa1 100644 --- a/platform/hac/source/modules/graphics/Graphics.cpp +++ b/platform/hac/source/modules/graphics/Graphics.cpp @@ -4,6 +4,8 @@ #include "modules/window/Window.hpp" #include "modules/graphics/Shader.hpp" +#include "modules/graphics/Texture.hpp" +#include "modules/graphics/freetype/Font.hpp" namespace love { @@ -80,7 +82,7 @@ namespace love void Graphics::setActiveScreen() { - // gx2.ensureInFrame(); + d3d.ensureInFrame(); } void Graphics::backbufferChanged(int width, int height, int pixelWidth, int pixelHeight, bool stencil, @@ -120,6 +122,8 @@ namespace love void Graphics::clear(OptionalColor color, OptionalInt stencil, OptionalDouble depth) { + d3d.bindFramebuffer(d3d.getInternalBackbuffer()); + if (color.hasValue) { bool hasIntegerFormat = false; @@ -151,8 +155,6 @@ namespace love gammaCorrectColor(color.value); d3d.clear(color.value); } - - d3d.bindFramebuffer(d3d.getInternalBackbuffer()); } void Graphics::clear(const std::vector& colors, OptionalInt stencil, OptionalDouble depth) @@ -160,6 +162,8 @@ namespace love if (colors.size() == 0 && !stencil.hasValue && !depth.hasValue) return; + d3d.bindFramebuffer(d3d.getInternalBackbuffer()); + int numColors = (int)colors.size(); const auto& targets = this->states.back().renderTargets.colors; @@ -189,8 +193,6 @@ namespace love gammaCorrectColor(value); d3d.clear(value); } - - d3d.bindFramebuffer(d3d.getInternalBackbuffer()); } void Graphics::present(void* screenshotCallback) @@ -235,6 +237,15 @@ namespace love d3d.setScissor(Rect::EMPTY); } + void Graphics::setPointSize(float size) + { + if (size != this->states.back().pointSize) + this->flushBatchedDraws(); + + this->states.back().pointSize = size; + d3d.setPointSize(size); + } + void Graphics::setFrontFaceWinding(Winding winding) { auto& state = this->states.back(); @@ -276,6 +287,57 @@ namespace love this->states.back().blend = state; } + bool Graphics::isPixelFormatSupported(PixelFormat format, uint32_t usage) + { + format = this->getSizedFormat(format); + bool readable = (usage & PIXELFORMATUSAGEFLAGS_SAMPLE) != 0; + + DkImageFormat color; + bool supported = deko3d::getConstant(format, color); + + return readable && supported; + } + + void Graphics::setRenderTargetsInternal(const RenderTargets& targets, int pixelWidth, int pixelHeight, + bool hasSRGBTexture) + { + const auto& state = this->states.back(); + + bool isWindow = targets.getFirstTarget().texture == nullptr; + + if (isWindow) + d3d.bindFramebuffer(d3d.getInternalBackbuffer()); + else + d3d.bindFramebuffer(*(dk::Image*)targets.getFirstTarget().texture->getRenderTargetHandle()); + + d3d.setViewport({ 0, 0, pixelWidth, pixelHeight }); + + if (state.scissor) + d3d.setScissor(state.scissorRect); + } + + TextureBase* Graphics::newTexture(const TextureBase::Settings& settings, const TextureBase::Slices* data) + { + return new Texture(this, settings, data); + } + + FontBase* Graphics::newFont(Rasterizer* data) + { + return new Font(data, this->states.back().defaultSamplerState); + } + + FontBase* Graphics::newDefaultFont(int size, const Rasterizer::Settings& settings) + { + auto* module = Module::getInstance(Module::M_FONT); + + if (module == nullptr) + throw love::Exception("Font module has not been loaded."); + + StrongRef rasterizer = module->newTrueTypeRasterizer(size, settings); + + return this->newFont(rasterizer.get()); + } + bool Graphics::setMode(int width, int height, int pixelWidth, int pixelHeight, bool backBufferStencil, bool backBufferDepth, int msaa) { @@ -290,8 +352,11 @@ namespace love { if (this->batchedDrawState.vertexBuffer == nullptr) { - this->batchedDrawState.indexBuffer = newIndexBuffer(INIT_INDEX_BUFFER_SIZE); + this->batchedDrawState.indexBuffer = newIndexBuffer(INIT_INDEX_BUFFER_SIZE); + this->batchedDrawState.indexBuffer->allocate(d3d.getMemoryPool(deko3d::MEMORYPOOL_DATA)); + this->batchedDrawState.vertexBuffer = newVertexBuffer(INIT_VERTEX_BUFFER_SIZE); + this->batchedDrawState.vertexBuffer->allocate(d3d.getMemoryPool(deko3d::MEMORYPOOL_DATA)); } } catch (love::Exception&) @@ -339,7 +404,13 @@ namespace love } void Graphics::draw(const DrawIndexedCommand& command) - {} + { + d3d.prepareDraw(this); + + DkPrimitive primitive; + bool success = deko3d::getConstant(command.primitiveType, primitive); + d3d.drawIndexed(primitive, command.indexCount, command.indexBufferOffset, command.instanceCount); + } void Graphics::draw(const DrawCommand& command) {} diff --git a/platform/hac/source/modules/graphics/Shader.cpp b/platform/hac/source/modules/graphics/Shader.cpp index af3ca12f..56699f17 100644 --- a/platform/hac/source/modules/graphics/Shader.cpp +++ b/platform/hac/source/modules/graphics/Shader.cpp @@ -1,6 +1,8 @@ #include "modules/graphics/Shader.hpp" #include "driver/display/deko.hpp" +#include "driver/graphics/Attributes.hpp" + #include #define SHADERS_DIR "romfs:/shaders/" @@ -54,13 +56,23 @@ namespace love throw love::Exception("Invalid fragment shader: %s", error.c_str()); } + Shader::~Shader() + { + this->program.vertex.memory.destroy(); + this->program.fragment.memory.destroy(); + } + void Shader::attach() { if (Shader::current != this) { - Shader::current = this; + Graphics::flushBatchedDrawsGlobal(); + d3d.useProgram(this->program.vertex.shader, this->program.fragment.shader); ++shaderSwitches; + + Shader::current = this; + shaderSwitches++; } } @@ -72,6 +84,14 @@ namespace love void Shader::unloadVolatile() {} + void Shader::updateBuiltinUniforms(GraphicsBase* graphics) + {} + + ptrdiff_t Shader::getHandle() const + { + return 0; + } + static bool loadFile(Shader::Stage& stage, const uint8_t* buffer, size_t size, std::string& error) { DkshHeader header {}; diff --git a/platform/hac/source/modules/graphics/Texture.cpp b/platform/hac/source/modules/graphics/Texture.cpp new file mode 100644 index 00000000..3bb2fecc --- /dev/null +++ b/platform/hac/source/modules/graphics/Texture.cpp @@ -0,0 +1,205 @@ +#include "driver/display/deko.hpp" + +#include "modules/graphics/Texture.hpp" + +namespace love +{ + static void dkImageRectFromRect(const Rect& rectangle, DkImageRect& out) + { + out.x = (uint32_t)rectangle.x; + out.y = (uint32_t)rectangle.y; + out.z = (uint32_t)0; + + out.width = (uint32_t)rectangle.w; + out.height = (uint32_t)rectangle.h; + out.depth = (uint32_t)1; + } + + static void updateTextureObject(dk::Image& image, CMemPool::Handle& memory, + dk::ImageDescriptor& descriptor, const Rect& rect, const void* data, + const size_t size, PixelFormat format) + { + DkImageFormat gpuFormat; + if (!deko3d::getConstant(format, gpuFormat)) + throw love::Exception("Invalid image format."); + + auto& pool = d3d.getMemoryPool(deko3d::MEMORYPOOL_DATA); + auto tempMemory = pool.allocate(size, DK_IMAGE_LINEAR_STRIDE_ALIGNMENT); + + if (!tempMemory) + throw love::Exception("Failed to allocate temporary Texture memory."); + + std::memcpy(tempMemory.getCpuAddr(), data, size); + + const auto& device = d3d.getDevice(); + auto tempCommandBuffer = dk::CmdBufMaker { device }.create(); + auto tempCommandMemory = pool.allocate(DK_MEMBLOCK_ALIGNMENT); + + tempCommandBuffer.addMemory(tempCommandMemory.getMemBlock(), tempCommandMemory.getOffset(), + tempCommandMemory.getSize()); + /* set the image layout */ + dk::ImageLayout layout; + dk::ImageLayoutMaker { device } + .setFlags(0) + .setFormat(gpuFormat) + .setDimensions(rect.w, rect.h) + .initialize(layout); + + image.initialize(layout, memory.getMemBlock(), memory.getOffset()); + + dk::ImageView view { image }; + + DkImageRect dkRect {}; + dkImageRectFromRect(rect, dkRect); + + tempCommandBuffer.copyBufferToImage({ tempMemory.getGpuAddr() }, view, dkRect); + + auto& queue = d3d.getQueue(deko3d::QUEUE_TYPE_IMAGES); + queue.submitCommands(tempCommandBuffer.finishList()); + queue.waitIdle(); + + tempCommandMemory.destroy(); + tempMemory.destroy(); + } + + static void createFramebufferObject() + {} + + Texture::Texture(GraphicsBase* graphics, const Settings& settings, const Slices* data) : + TextureBase(graphics, settings, data), + slices(settings.type) + { + if (data != nullptr) + this->slices = *data; + + if (!this->loadVolatile()) + throw love::Exception("Failed to create texture."); + + this->slices.clear(); + } + + Texture::~Texture() + { + this->unloadVolatile(); + } + + bool Texture::loadVolatile() + { + const auto& layout = this->image.getLayout(); + if (layout.getSize() != 0) + return true; + + if (this->parentView.texture != this) + { + Texture* baseTexture = (Texture*)this->parentView.texture; + baseTexture->loadVolatile(); + } + + if (this->isReadable()) + this->createTexture(); + + int64_t memorySize = 0; + + for (int mip = 0; mip < this->getMipmapCount(); mip++) + { + int width = this->getPixelWidth(mip); + int height = this->getPixelHeight(mip); + + const auto faces = (this->textureType == TEXTURE_CUBE) ? 6 : 1; + int slices = this->getDepth(mip) * this->layers * faces; + + memorySize += getPixelFormatSliceSize(this->format, width, height, false) * slices; + } + + this->setGraphicsMemorySize(memorySize); + + return true; + } + + void Texture::unloadVolatile() + { + d3d.registerTexture(this, false); + + if (this->memory) + this->memory.destroy(); + + this->setGraphicsMemorySize(0); + } + + void Texture::createTexture() + { + if (!this->isRenderTarget()) + { + int mipCount = this->getMipmapCount(); + int sliceCount = 1; + + if (this->textureType == TEXTURE_VOLUME) + sliceCount = this->getDepth(); + else if (this->textureType == TEXTURE_2D_ARRAY) + sliceCount = this->layers; + else if (this->textureType == TEXTURE_CUBE) + sliceCount = 6; + + for (int mipmap = 0; mipmap < mipCount; mipmap++) + { + for (int slice = 0; slice < sliceCount; slice++) + { + auto* data = this->slices.get(slice, mipmap); + + if (data != nullptr) + this->uploadImageData(data, mipmap, slice, 0, 0); + } + } + } + + bool hasData = this->slices.get(0, 0) != nullptr; + int clearMips = 1; + + if (isPixelFormatDepthStencil(this->format)) + clearMips = mipmapCount; + + if (this->isRenderTarget()) + { + } + else if (!hasData) + { + for (int mipmap = 0; mipmap < clearMips; mipmap++) + { + } + } + + this->setSamplerState(this->samplerState); + + if (this->slices.getMipmapCount() <= 1 && this->getMipmapsMode() != MIPMAPS_NONE) + this->generateMipmaps(); + } + + void Texture::setSamplerState(const SamplerState& state) + { + this->samplerState = this->validateSamplerState(state); + d3d.setSamplerState(this, this->samplerState); + } + + void Texture::uploadByteData(const void* data, size_t size, int level, int slice, const Rect& rect) + { + updateTextureObject(this->image, this->memory, this->descriptor, rect, data, size, this->format); + } + + void Texture::generateMipmapsInternal() + {} + + ptrdiff_t Texture::getHandle() const + { + return (ptrdiff_t)this->handle; + } + + ptrdiff_t Texture::getRenderTargetHandle() const + { + return (ptrdiff_t)this->handle; + } + + ptrdiff_t Texture::getSamplerHandle() const + { + return (ptrdiff_t)std::addressof(this->sampler); + } +} // namespace love diff --git a/source/modules/font/freetype/Font.cpp b/source/modules/font/freetype/Font.cpp index 4149f873..0975fa90 100644 --- a/source/modules/font/freetype/Font.cpp +++ b/source/modules/font/freetype/Font.cpp @@ -10,17 +10,18 @@ namespace love #if defined(__SWITCH__) ByteData* FontModule::loadSystemFontByType(SystemFontType type = PlSharedFontType_Standard) { - std::unique_ptr data; - plGetSharedFontByType(data.get(), type); + PlFontData data {}; + if (R_FAILED(plGetSharedFontByType(&data, type))) + throw love::Exception("Failed to load Shared Font {:d}", (int)type); std::string_view name {}; FontModule::getConstant(type, name); - if (data == nullptr) + if (data.address == nullptr) throw love::Exception("Error loading system font '{:s}'", name); // create a copy of the data - return new ByteData(data->address, data->size, false); + return new ByteData(data.address, data.size, false); } #elif defined(__WIIU__) ByteData* FontModule::loadSystemFontByType(SystemFontType type = OS_SHAREDDATATYPE_FONT_STANDARD) @@ -45,7 +46,7 @@ namespace love if (FT_Init_FreeType(&this->library) != 0) throw love::Exception("Error initializing FreeType library."); - this->defaultFontData.set(loadSystemFontByType(), Acquire::NO_RETAIN); + // this->defaultFontData.set(loadSystemFontByType(), Acquire::NO_RETAIN); } FontModule::~FontModule()