Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
106 commits
Select commit Hold shift + click to select a range
ef9d0b6
Unrestricted Ghengin monad to wrap linear Renderer
alt-romes Dec 21, 2025
6d146d1
Rename examples to examples/core
alt-romes Dec 21, 2025
f2103d2
refact: Core.Render.Property to avoid Ur in input
alt-romes Dec 21, 2025
0846b0a
Revert "refact: Core.Render.Property to avoid Ur in input"
alt-romes Dec 21, 2025
f75977a
clean: mesh2MatKey and drop old comments
alt-romes Dec 21, 2025
f81b062
planets: Only regen terrain when terrain settings change
alt-romes Dec 21, 2025
974d388
WIP on Ghengin monad
alt-romes Dec 21, 2025
d37016d
Use backpack for dear-imgui module and provide vulkan instance
alt-romes Dec 22, 2025
744f1dc
WIP ghengin
alt-romes Dec 22, 2025
aebd06b
More progress on Ghengin monad
alt-romes Dec 23, 2025
a5ac336
WIP ghengin planets using ghengin full
alt-romes Dec 25, 2025
d04ce2d
Rename ghengin/planets
alt-romes Dec 26, 2025
ebe5729
refact: Make shouldCloseWindow return Ur Bool
alt-romes Dec 26, 2025
6a07684
WIP
alt-romes Dec 27, 2025
7a9d1b0
Simulation sketch
alt-romes Dec 27, 2025
65bf685
Sampler filter and addrmode datatypes
alt-romes Dec 30, 2025
c3774aa
Cleaning up and use more of FIR's power and vulkan code
alt-romes Dec 30, 2025
8271df0
Cleanup createGraphicsPipeline a bit
alt-romes Dec 30, 2025
b31029c
Drop a few outdated comments
alt-romes Jan 2, 2026
79ac02b
Use Std430 for Storage Buffers
alt-romes Jan 2, 2026
4d4fbcd
Drop outdated and obsolete Core.Shader.Canonical
alt-romes Jan 2, 2026
cf40f28
Cleanups around Instance.createInstance
alt-romes Jan 4, 2026
5e2e1fb
Clean up Devices and Windows
alt-romes Jan 4, 2026
b853182
Clean up Swapchain
alt-romes Jan 4, 2026
eb9550c
tweaks Core.Prelude
alt-romes Jan 4, 2026
48f858a
Fix swapchain module
alt-romes Jan 4, 2026
20b742e
Get Vulkan.Renderer.Context, inspired by fir-examples, to compile
alt-romes Jan 4, 2026
f0dba34
ghengin-vulkan: Improve Vulkan.Context namespace
alt-romes Jan 4, 2026
58c4307
Refactor Image.hs
alt-romes Jan 4, 2026
79a5f51
Start putting it together
alt-romes Jan 4, 2026
e8db7b5
fixup! Refactor Image.hs
alt-romes Jan 4, 2026
b621231
Pruning progress
alt-romes Jan 13, 2026
3dac242
Add FIR.Vulkan.Attachment
alt-romes Jan 17, 2026
0edcc18
Continue refactor: depth attachment
alt-romes Jan 19, 2026
4b2f75f
tweaks, destroyVkContext
alt-romes Jan 19, 2026
ea1444a
WIP
alt-romes Jan 22, 2026
eae232c
Comment a lot of things and create fences and sems
alt-romes Feb 8, 2026
5aab6f0
FIR.Vulkan.Resource wip
alt-romes Feb 8, 2026
ff9787a
Vulkan commands updated for dynamic rendering
alt-romes Feb 8, 2026
dc5d86d
Progress in compiling Renderer.hs
alt-romes Feb 8, 2026
ad2637f
Frame index Finite, delete RenderPass
alt-romes Feb 8, 2026
5e189f7
more clean up of RenderPass
alt-romes Feb 8, 2026
c6c3ee4
Progress
alt-romes Feb 8, 2026
8b948fc
New frame, present at the end
alt-romes Feb 9, 2026
89fe5f5
tweaking sigs
alt-romes Feb 9, 2026
a99b58b
Update Command.hsig
alt-romes Feb 9, 2026
ebf57dc
RenderPassCmdM -> RenderCmdM
alt-romes Feb 9, 2026
775fd27
BufferUsageFlags abstract
alt-romes Feb 9, 2026
675a8d8
fixup! RenderPassCmdM -> RenderCmdM
alt-romes Feb 9, 2026
1df581f
Add todo
alt-romes Feb 10, 2026
2b9e298
Kill backpack
alt-romes Feb 10, 2026
7313d90
Kill vulkan dependency from ghengin-core
alt-romes Feb 10, 2026
6086e6b
Kill Render.Packet module
alt-romes Feb 11, 2026
49575fe
Kill dependency on vulkan
alt-romes Feb 11, 2026
53b0f35
Use type state for CommandBuffer
alt-romes Feb 11, 2026
65c9cb5
Tweaks
alt-romes Feb 11, 2026
a0ee419
Use GHC 9.14 in shell.nix
alt-romes Feb 13, 2026
530dddb
Update cabal.project for GHC 9.14
alt-romes Feb 13, 2026
484e679
Upgrade to 9.14
alt-romes Feb 13, 2026
a86292c
Somehow manage to compile aliased command pools and buffers
alt-romes Feb 14, 2026
e93e632
It's insane that this compiles
alt-romes Feb 14, 2026
494ef19
Revert "It's insane that this compiles"
alt-romes Feb 14, 2026
aaa28b3
Revert "Somehow manage to compile aliased command pools and buffers"
alt-romes Feb 14, 2026
06d66f8
Yeah, this is a much better way to do it than using untyped cmdbuffer…
alt-romes Feb 14, 2026
aedae19
Use Maybe Command buffer rather than Either ()
alt-romes Feb 14, 2026
f1399a5
Dropping renderpass from example
alt-romes Feb 17, 2026
4d5d33a
Accumulate free actions while recording command buffer which must be …
alt-romes Feb 24, 2026
63a02c0
tweak shell.nix
alt-romes Feb 25, 2026
ae31140
Progressing
alt-romes Mar 6, 2026
f9f27d4
Tweaks and progress
alt-romes Mar 7, 2026
3425911
Clean up all boot files and split DescriptorSet module in 3
alt-romes Mar 7, 2026
97ec136
Get a whole lot more to compile
alt-romes Mar 7, 2026
5072d27
Further fixes and simplifications
alt-romes Mar 7, 2026
23f6a11
Fix Cmd recording capturing things, re-implement textures, more tasks
alt-romes Mar 7, 2026
9f25484
A few more great tweaks
alt-romes Mar 7, 2026
171b94e
Next: swapchainImageViews, beginRendering
alt-romes Mar 8, 2026
65fdfb2
Allocate swapchainImageViews for swapchain images
alt-romes Apr 3, 2026
1693895
Fix all examples to new API
alt-romes May 26, 2026
5771e41
Lift Vec2/Vec3 is now upstreamed
alt-romes May 26, 2026
5e2f2a1
tweaks
alt-romes May 26, 2026
b995c61
wip RenderingInfo, next up I'll just have to construct an alias and u…
alt-romes May 27, 2026
af6730d
Thread swapchain and depth image views to dynamic rendering info
alt-romes May 27, 2026
5d73104
Finally: submit command buffer graphics
alt-romes May 28, 2026
d41c126
fix newframe bug in all examples
alt-romes May 28, 2026
9990067
Depth Clear value should be 0, not 1, for reverse Z buffer
alt-romes May 28, 2026
1ad9ca0
TODO: 2 frames in flight
alt-romes May 28, 2026
9f69e7e
wait for device idle before terminating
alt-romes May 29, 2026
b28b19a
waitDeviceIdle before freeing user resources too.
alt-romes May 29, 2026
18868ab
Compile unrestricted lib:ghengin
alt-romes May 31, 2026
9c9d842
newGhenginFrame
alt-romes May 31, 2026
22fa50d
more Ghengin.Monad things
alt-romes May 31, 2026
b980d5b
demo with ghengin.monad works
alt-romes May 31, 2026
b177763
simplify runGameLoop signature
alt-romes May 31, 2026
81e5cfc
little cleanup
alt-romes May 31, 2026
8231897
clean ups
alt-romes Jun 1, 2026
c236d83
fix: ImGui was frozen when using runGhengin
alt-romes Jun 1, 2026
2ba4ce6
make Planet.hs a sublibrary for the examples
alt-romes Jun 1, 2026
ad316ba
2 random planets
alt-romes Jun 1, 2026
e94f35a
wip: refactoring into n-body problem
alt-romes Jun 1, 2026
33bcbae
Make editAt*Key functions allow the edit function to return value
alt-romes Jun 2, 2026
0287e51
call ImGui.withNewFrame automatically in runGameLoop if enabled
alt-romes Jun 2, 2026
f2b50b7
ImGui.render must happen before renderDrawData (can't be at the end o…
alt-romes Jun 2, 2026
275e8d4
repro for bug and tweak demo
alt-romes Jun 2, 2026
f291811
Kill Vulkan.Linear
alt-romes Jun 18, 2026
6f81002
Clean up Vulkan.Renderer.Sampler
alt-romes Jun 21, 2026
3986474
FIR.Resource; Textures more general v. good
alt-romes Jun 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion TODO
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
[ ] Perhaps use more efficient list-like type by default for creating meshes
[ ] Dear imgui specific render pipeline
[x] Custom descriptor set #0 through Render Pipeline constructors + edit function similar to Materials
[ ] Untangle World {-# SOURCE #-} imports by creating another module for it
[x] Untangle World {-# SOURCE #-} imports by creating another module for it
[ ] Hex map tutorial series https://catlikecoding.com/unity/tutorials/hex-map/
[x] Compatible mesh constraint with working planets example
[x] Get rid of VertexArray altogether (use Storable Vector directly)?
Expand Down
23 changes: 22 additions & 1 deletion cabal.project
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
packages:
./examples/
./examples/core/
./examples/ghengin/
./ghengin-core/
./linear-utils/
./ghengin/
Expand All @@ -18,6 +19,8 @@ packages:
-- package *
-- profiling-detail: late

multi-repl: True

package dear-imgui
flags: +glfw +vulkan -sdl -opengl3

Expand All @@ -26,12 +29,19 @@ package fir

constraints:
linear-generics>0.2.2,
ghc-tcplugins-extra>=0.5,
ghc-typelits-natnormalise>=0.9.3,
ghc-typelits-knownnat>=0.8.2,
QuickCheck>=2.15

allow-newer:
base,
containers,
time,
template-haskell,
filepath,
text,
ghc-tcplugins-extra:*,
fir:*,
linear-base:*,
dear-imgui:*,
Expand All @@ -40,13 +50,24 @@ allow-newer:
linear-apecs:*,
typelits-witnesses:*

source-repository-package
type: git
location: https://github.com/sheaf/ghc-tcplugins-extra
tag: 6842eb467dde87cf6249828011f4c9d717f7f2b0

source-repository-package
type: git
location: https://github.com/sheaf/ghc-tcplugins-extra
tag: 6842eb467dde87cf6249828011f4c9d717f7f2b0

source-repository-package
type: git
location: https://github.com/alt-romes/reference-counting.git

source-repository-package
type: git
location: https://gitlab.com/rodrigo.m.mesquita/fir.git
tag: bba6cbec065d5493bc915d5e810c1f649d46300f
-- location: https://gitlab.com/sheaf/fir.git

-----------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,39 +23,39 @@ import Shaders
-- https://www.saschawillems.de/blog/2016/08/13/vulkan-tutorial-on-rendering-a-fullscreen-quad-without-buffers/
--------------------------------------------------------------------------------

gameLoop :: Alias RenderPass ⊸ RenderQueue () ⊸ Renderer (RenderQueue ())
gameLoop rp rq = Linear.do
should_close <- shouldCloseWindow
if should_close then Alias.forget rp >> return rq else Linear.do
gameLoop :: RenderQueue () ⊸ Renderer (RenderQueue ())
gameLoop rq = Linear.do
Ur should_close <- shouldCloseWindow
if should_close then return rq else Linear.do
pollWindowEvents

(rp, rq) <- renderWith $ Linear.do
rq <- newFrame \frameIndex imageIndex ->
renderWith frameIndex imageIndex $ \rinfo -> Linear.do
Ur extent <- lift getRenderExtent
let viewport = viewportFromExtent extent
scissor = scissorFromExtent extent

(rp1, rp2) <- lift (Alias.share rp)
beginRendering rinfo $ Linear.do
setViewport viewport
setScissor scissor

Ur extent <- lift getRenderExtent

renderPassCmd extent rp1 $ Linear.do
rq <- renderQueueCmd rq

rq <- renderQueueCmd rq
draw 3 1

draw 3
return rq

return (rp2, rq)

gameLoop rp rq
gameLoop rq

main :: Prelude.IO ()
main = do
withLinearIO $
runRenderer (width, height) Linear.do

(rp1, rp2) <- Alias.share =<< createSimpleRenderPass

pipeline <- makeRenderPipelineWith defaultGraphicsPipelineSettings{cullMode=CullBack} rp1 shaderPipelineSimple GHNil
pipeline <- makeRenderPipelineWith defaultGraphicsPipelineSettings{cullMode=CullBack} shaderPipelineSimple GHNil
(rq, Ur pkey) <- pure (insertPipeline pipeline LMon.mempty)

rq <- gameLoop rp2 rq
rq <- gameLoop rq

freeRenderQueue rq

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,39 +23,39 @@ import Shaders
-- https://www.saschawillems.de/blog/2016/08/13/vulkan-tutorial-on-rendering-a-fullscreen-quad-without-buffers/
--------------------------------------------------------------------------------

gameLoop :: Alias RenderPass ⊸ RenderQueue () ⊸ Renderer (RenderQueue ())
gameLoop rp rq = Linear.do
should_close <- shouldCloseWindow
if should_close then Alias.forget rp >> return rq else Linear.do
gameLoop :: RenderQueue () ⊸ Renderer (RenderQueue ())
gameLoop rq = Linear.do
Ur should_close <- shouldCloseWindow
if should_close then return rq else Linear.do
pollWindowEvents

(rp, rq) <- renderWith $ Linear.do
rq <- newFrame \frameIndex imageIndex ->
renderWith frameIndex imageIndex $ \rinfo -> Linear.do
Ur extent <- lift getRenderExtent
let viewport = viewportFromExtent extent
scissor = scissorFromExtent extent

(rp1, rp2) <- lift (Alias.share rp)
beginRendering rinfo $ Linear.do
setViewport viewport
setScissor scissor

Ur extent <- lift getRenderExtent

renderPassCmd extent rp1 $ Linear.do
rq <- renderQueueCmd rq

rq <- renderQueueCmd rq
draw 3 1

draw 3
return rq

return (rp2, rq)

gameLoop rp rq
gameLoop rq

main :: Prelude.IO ()
main = do
withLinearIO $
runRenderer (width, height) Linear.do

(rp1, rp2) <- Alias.share =<< createSimpleRenderPass

pipeline <- makeRenderPipelineWith defaultGraphicsPipelineSettings{cullMode=CullFront} rp1 shaderPipelineSimple GHNil
pipeline <- makeRenderPipelineWith defaultGraphicsPipelineSettings{cullMode=CullFront} shaderPipelineSimple GHNil
(rq, Ur pkey) <- pure (insertPipeline pipeline LMon.mempty)

rq <- gameLoop rp2 rq
rq <- gameLoop rq

freeRenderQueue rq

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import Ghengin.Core.Mesh
import Ghengin.Core.Mesh.Vertex
import Ghengin.Core.Prelude as Linear
import Ghengin.Core.Render
import Ghengin.Core.Render.Packet
import Ghengin.Core.Render.Pipeline
import Ghengin.Core.Render.Property
import Ghengin.Core.Render.Queue
Expand Down
File renamed without changes.
44 changes: 22 additions & 22 deletions examples/dear-imgui/Main.hs → examples/core/dear-imgui/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -23,49 +23,49 @@ import qualified Ghengin.DearImGui.Vulkan as ImGui
-- https://www.saschawillems.de/blog/2016/08/13/vulkan-tutorial-on-rendering-a-fullscreen-quad-without-buffers/
--------------------------------------------------------------------------------

gameLoop :: Alias RenderPass ⊸ RenderQueue () ⊸ Renderer (RenderQueue ())
gameLoop rp rq = Linear.do
should_close <- shouldCloseWindow
if should_close then Alias.forget rp >> return rq else Linear.do
gameLoop :: RenderQueue () ⊸ Renderer (RenderQueue ())
gameLoop rq = Linear.do
Ur should_close <- shouldCloseWindow
if should_close then return rq else Linear.do
pollWindowEvents

-- Prepare Imgui data
ImGui.withNewFrame $ do
ImGui.withNewFrame $ liftSystemIO $ do

ImGui.showDemoWindow

(rp, rq) <- renderWith $ Linear.do
rq <- newFrame \frameIndex imageIndex ->
renderWith frameIndex imageIndex $ \rinfo -> Linear.do
Ur extent <- lift getRenderExtent
let viewport = viewportFromExtent extent
scissor = scissorFromExtent extent

(rp1, rp2) <- lift (Alias.share rp)
beginRendering rinfo $ Linear.do
setViewport viewport
setScissor scissor

Ur extent <- lift getRenderExtent

renderPassCmd extent rp1 $ Linear.do
rq <- renderQueueCmd rq
draw 3 1

rq <- renderQueueCmd rq
draw 3
-- Render Imgui data!
ImGui.renderDrawData

-- Render Imgui data!
ImGui.renderDrawData
return rq

return (rp2, rq)

gameLoop rp rq
gameLoop rq

main :: Prelude.IO ()
main = do
withLinearIO $
runRenderer (width, height) Linear.do

(rp1, rp2) <- Alias.share =<< createSimpleRenderPass

-- Init imgui
(rp1, imctx) <- Alias.useM rp1 ImGui.initImGui
imctx <- ImGui.initImGui

pipeline <- makeRenderPipelineWith defaultGraphicsPipelineSettings{cullMode=CullFront} rp1 shaderPipelineSimple GHNil
pipeline <- makeRenderPipelineWith defaultGraphicsPipelineSettings{cullMode=CullFront} shaderPipelineSimple GHNil
(rq, Ur pkey) <- pure (insertPipeline pipeline LMon.mempty)

rq <- gameLoop rp2 rq
rq <- gameLoop rq

freeRenderQueue rq
-- Then destroy it
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import Ghengin.Core.Mesh.Vertex
import Ghengin.Core.Material
import Ghengin.Core.Prelude as Linear
import Ghengin.Core.Render
import Ghengin.Core.Render.Packet
import Ghengin.Core.Render.Pipeline
import Ghengin.Core.Render.Property
import Ghengin.Core.Render.Queue
Expand All @@ -44,7 +43,7 @@ import Common

gameLoop :: forall (_s :: FIR.PipelineInfo). Vec2 -> PipelineKey _s PipelineProps -> RenderQueue () ⊸ Renderer (RenderQueue ())
gameLoop (WithVec2 previousPosX previousPosY) pkey rq = Linear.do
should_close <- shouldCloseWindow
Ur should_close <- shouldCloseWindow
if should_close then return rq else Linear.do
pollWindowEvents

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import Ghengin.Core.Mesh.Vertex
import Ghengin.Core.Material
import Ghengin.Core.Prelude as Linear
import Ghengin.Core.Render
import Ghengin.Core.Render.Packet
import Ghengin.Core.Render.Pipeline
import Ghengin.Core.Render.Property
import Ghengin.Core.Render.Queue
Expand Down Expand Up @@ -69,16 +68,16 @@ makeMainPipeline = makeRenderPipeline (shaderPipeline WINDOW_SIZE)

gameLoop :: forall (_s :: FIR.PipelineInfo). Vec2 -> PipelineKey _s '[MousePos] -> RenderQueue () ⊸ Core (RenderQueue ())
gameLoop (WithVec2 previousPosX previousPosY) pkey rq = Linear.do
should_close <- (shouldCloseWindow ↑)
Ur should_close <- shouldCloseWindow
if should_close then return rq else Linear.do
(pollWindowEvents ↑)
pollWindowEvents

Ur (double2Float -> newPosX, double2Float -> newPosY) <- (getMousePos ↑)
Ur (double2Float -> newPosX, double2Float -> newPosY) <- getMousePos
liftSystemIO $ print (newPosX, newPosY)

let pos = vec2 (0.5 * (previousPosX + newPosX)) (0.5 * (previousPosY + newPosY))

rq' <- (editPipeline pkey rq (propertyAt @0 (\(Ur _) -> pure $ Ur $ MousePos pos)) ↑)
rq' <- editPipeline pkey rq (propertyAt @0 (\(Ur _) -> pure $ Ur $ MousePos pos))

rq'' <- render rq'

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -72,33 +72,32 @@ icosahedronIndices

gameLoop :: PipelineKey _ '[Camera "view" "proj"] -- ^ rq key to camera
-> MeshKey _ _ _ _ '[] -- ^ rq key to cube mesh
-> Alias RenderPass
⊸ RenderQueue ()
-> RenderQueue ()
⊸ Renderer (RenderQueue ())
gameLoop ckey mkey rp rq = Linear.do
should_close <- shouldCloseWindow
if should_close then Alias.forget rp >> return rq else Linear.do
gameLoop ckey mkey rq = Linear.do
Ur should_close <- shouldCloseWindow
if should_close then return rq else Linear.do
pollWindowEvents

(rp, rq) <- render rp rq
rq <- newFrame \frameIndex imageIndex ->
render frameIndex imageIndex rq

gameLoop ckey mkey rp rq
gameLoop ckey mkey rq

main :: Prelude.IO ()
main =
main =
withLinearIO $
runRenderer (640, 480) Linear.do
(rp1, rp2) <- Alias.share =<< createSimpleRenderPass

pipeline :: RenderPipeline π ps <- makeRenderPipeline rp1 shaderPipeline (StaticBinding (Ur (cameraLookAt @"view" @"proj" (vec3 0 0 0) (vec3 0 0 1) (640, 480))) :## GHNil)
pipeline :: RenderPipeline π ps <- makeRenderPipeline shaderPipeline (StaticBinding (Ur (cameraLookAt @"view" @"proj" (vec3 0 0 0) (vec3 0 0 1) (640, 480))) :## GHNil)
(emptyMat, pipeline) <- material GHNil pipeline
(mesh :: IcosahedronMesh, pipeline) <- createMeshWithIxs pipeline GHNil icosahedronVerts icosahedronIndices

(rq, Ur pkey) <- pure (insertPipeline @π @ps pipeline LMon.mempty)
(rq, Ur mkey) <- pure (insertMaterial @π @ps pkey emptyMat rq)
(rq, Ur mshkey) <- pure (insertMesh @π @ps mkey mesh rq)

rq <- gameLoop pkey mshkey rp2 rq
rq <- gameLoop pkey mshkey rq

freeRenderQueue rq

Expand Down
Loading