diff --git a/assets/shaders/test/test.fs.glsl b/assets/shaders/test/test.fs.glsl new file mode 100644 index 0000000..644fedb --- /dev/null +++ b/assets/shaders/test/test.fs.glsl @@ -0,0 +1,15 @@ +#version 450 +#extension GL_GOOGLE_include_directive : enable + +#include "lib/common.glsl" + +IN(0, vec3, normal) +IN(1, vec3, position) +OUT(0, vec4, normal) +OUT(1, vec4, position) + +void main() +{ + out_normal = pack_normal(in_normal); + out_position = vec4(in_position, 1); +} diff --git a/assets/shaders/test/test.json b/assets/shaders/test/test.json new file mode 100644 index 0000000..4a592d7 --- /dev/null +++ b/assets/shaders/test/test.json @@ -0,0 +1,18 @@ +{ + "Inputs": { + "position": { + "Index": 0, + "Type": "float" + }, + "normal": { + "Index": 1, + "Type": "float" + } + }, + "Bindings": { + "Camera": 0, + "Objects": 1, + "Lights": 2, + "Textures": 3 + } +} diff --git a/assets/shaders/test/test.vs.glsl b/assets/shaders/test/test.vs.glsl new file mode 100644 index 0000000..d313500 --- /dev/null +++ b/assets/shaders/test/test.vs.glsl @@ -0,0 +1,35 @@ +#version 450 +#extension GL_GOOGLE_include_directive : enable + +#include "lib/common.glsl" + +CAMERA(0, camera) +STORAGE_BUFFER(1, Object, objects) + +// Attributes +layout (location = 0) in vec3 position; +layout (location = 1) in vec3 normal; + +// Varyings +layout (location = 0) out vec3 normal0; +layout (location = 1) out vec3 position0; + +out gl_PerVertex +{ + vec4 gl_Position; +}; + +void main() +{ + mat4 m = objects.item[gl_InstanceIndex].model; + mat4 mv = camera.View * m; + + // gbuffer view position + position0 = (mv * vec4(position.xyz, 1.0)).xyz; + + // gbuffer view space normal + normal0 = normalize((mv * vec4(normal, 0.0)).xyz); + + // vertex clip space position + gl_Position = camera.Proj * vec4(position0, 1); +} diff --git a/engine/object/player/player.go b/engine/object/player/player.go new file mode 100644 index 0000000..d76e4a1 --- /dev/null +++ b/engine/object/player/player.go @@ -0,0 +1,143 @@ +package player + +import ( + "zworld/engine/object" + "zworld/engine/object/camera" + "zworld/engine/object/light" + "zworld/engine/renderapi/color" + "zworld/plugins/math" + "zworld/plugins/math/quat" + "zworld/plugins/math/vec2" + "zworld/plugins/math/vec3" + "zworld/plugins/system/input/keys" + "zworld/plugins/system/input/mouse" +) + +type Player struct { + object.Object + Camera *camera.Object + Speed float32 + Friction vec3.T + + velocity vec3.T + keys keys.State + mouselook bool +} + +func NewPlayer(position vec3.T, rotation quat.T) *Player { + p := object.Builder(object.New("Player", &Player{ + Camera: object.Builder(camera.NewObject(camera.Args{ + Fov: 58.0, + Near: 0.1, + Far: 500, + Clear: color.Hex("#eddaab"), + })). + Rotation(rotation). + Attach(light.NewPoint(light.PointArgs{ + Range: 20, + Intensity: 2.5, + Color: color.White, + })). + Create(), + Speed: float32(33), + Friction: vec3.New(2, 2, 2), + keys: keys.NewState(), + })). + Position(position). + Create() + return p +} + +func (p *Player) KeyEvent(e keys.Event) { + p.keys.KeyEvent(e) +} + +func (p *Player) Update(scene object.Component, dt float32) { + move := vec3.Zero + moving := false + if p.keys.Down(keys.W) && p.keys.Up(keys.S) { + move.Z += 1.0 + moving = true + } + if p.keys.Down(keys.S) && p.keys.Up(keys.W) { + move.Z -= 1.0 + moving = true + } + if p.keys.Down(keys.A) && p.keys.Up(keys.D) { + move.X -= 1.0 + moving = true + } + if p.keys.Down(keys.D) && p.keys.Up(keys.A) { + move.X += 1.0 + moving = true + } + if p.keys.Down(keys.Q) && p.keys.Up(keys.E) { + move.Y -= 1.0 + moving = true + } + if p.keys.Down(keys.E) && p.keys.Up(keys.Q) { + move.Y += 1.0 + moving = true + } + + if moving { + right := p.Camera.Transform().Right().Scaled(move.X) + up := p.Camera.Transform().Up().Scaled(move.Y) + forward := p.Camera.Transform().Forward().Scaled(move.Z) + + move = right.Add(forward).Add(up) + move.Normalize() + } + move.Scale(p.Speed) + + if p.keys.Shift() { + move.Scale(2) + } + + // apply movement + p.velocity = p.velocity.Add(move.Scaled(dt)) + + // friction + friction := p.velocity.Mul(p.Friction) + p.velocity = p.velocity.Sub(friction.Scaled(dt)) + + // apply movement + step := p.velocity.Scaled(dt) + position := p.Transform().Position() + position = position.Add(step) + p.Transform().SetPosition(position) + + p.Object.Update(scene, dt) +} + +func (p *Player) MouseEvent(e mouse.Event) { + if e.Action() == mouse.Press && e.Button() == mouse.Button2 { + p.mouselook = true + mouse.Lock() + e.Consume() + } + if e.Action() == mouse.Release && e.Button() == mouse.Button2 { + p.mouselook = false + mouse.Show() + e.Consume() + } + + if e.Action() == mouse.Move && p.mouselook { + sensitivity := vec2.New(0.045, 0.04) + delta := e.Delta().Mul(sensitivity) + + eye := p.Camera.Transform().Rotation().Euler() + + xrot := eye.X + delta.Y + yrot := eye.Y + delta.X + + // camera angle limits + xrot = math.Clamp(xrot, -89.9, 89.9) + yrot = math.Mod(yrot, 360) + rot := quat.Euler(xrot, yrot, 0) + + p.Camera.Transform().SetRotation(rot) + + e.Consume() + } +} diff --git a/engine/render/graph/graph.go b/engine/render/graph/graph.go index 7f23e9b..1da6feb 100644 --- a/engine/render/graph/graph.go +++ b/engine/render/graph/graph.go @@ -117,7 +117,6 @@ func (g *graph) Draw(scene object.Object, time, delta float32) { for node := range g.todo { // check if ready if ready(node) { - log.Println(":::draw ", node.Name(), scene.Name()) node.Draw(worker, *args, scene) delete(g.todo, node) progress = true diff --git a/engine/render/pass/basic_material.go b/engine/render/pass/basic_material.go index 3349ef2..dc77caf 100644 --- a/engine/render/pass/basic_material.go +++ b/engine/render/pass/basic_material.go @@ -30,6 +30,9 @@ type BasicMaterial struct { func (m *BasicMaterial) ID() material.ID { return m.id } +func (m *BasicMaterial) SetID(id material.ID) { + m.id = id +} func (m *BasicMaterial) Begin(camera uniform.Camera, lights []light.T) { m.Instance.Descriptors().Camera.Set(camera) diff --git a/engine/renderapi/cache/mesh.go b/engine/renderapi/cache/mesh.go index 9a43d57..8a3e4fa 100644 --- a/engine/renderapi/cache/mesh.go +++ b/engine/renderapi/cache/mesh.go @@ -7,6 +7,11 @@ import ( "github.com/vkngwrapper/core/v2/core1_0" ) +/* +VUID-vkDestroyDevice-device-00378(ERROR / SPEC): msgNum: 1901072314 - Validation Error: [ VUID-vkDestroyDevice-device-00378 ] Object 0: handle = 0x45d6d1000000004c, name = Storage[Object]:1, type = VK_OBJECT_TYPE_DEVICE_MEMOR +Y; | MessageID = 0x71500fba | OBJ ERROR : For VkDevice 0x1aefe8c0600[], VkDeviceMemory 0x45d6d1000000004c[Storage[Object]:1] has not been destroyed. The Vulkan spec states: All child objects created on device must have been d +estroyed prior to destroying device (https://vulkan.lunarg.com/doc/view/1.3.261.1/windows/1.3-extensions/vkspec.html#VUID-vkDestroyDevice-device-00378) +*/ type Mesh interface { Draw(command.Buffer, int) DrawInstanced(buf command.Buffer, startIndex, coount int) diff --git a/engine/renderapi/command/worker.go b/engine/renderapi/command/worker.go index 496dbcd..bbd9286 100644 --- a/engine/renderapi/command/worker.go +++ b/engine/renderapi/command/worker.go @@ -2,6 +2,7 @@ package command import ( "fmt" + "log" "runtime/debug" "zworld/engine/renderapi/device" @@ -36,6 +37,10 @@ type worker struct { } func NewWorker(device device.T, name string, queueFlags core1_0.QueueFlags, queueIndex int) Worker { + if idx := device.GetQueueFamilyIndex(queueFlags); idx != queueIndex { + log.Println("GetQueueFamilyIndex Warning %d:: %d => %d", queueFlags, queueIndex, idx) + queueIndex = idx + } pool := NewPool(device, core1_0.CommandPoolCreateTransient, queueIndex) queue := device.GetQueue(queueIndex, queueFlags) diff --git a/engine/renderapi/descriptor/layout.go b/engine/renderapi/descriptor/layout.go index f460f35..891bfd2 100644 --- a/engine/renderapi/descriptor/layout.go +++ b/engine/renderapi/descriptor/layout.go @@ -6,7 +6,6 @@ import ( "zworld/engine/renderapi/device" "zworld/engine/renderapi/shader" - "github.com/vkngwrapper/core/v2/common" "github.com/vkngwrapper/core/v2/core1_0" "github.com/vkngwrapper/core/v2/driver" "github.com/vkngwrapper/extensions/v2/ext_descriptor_indexing" @@ -73,14 +72,14 @@ func New[S Set](device device.T, set S, shader shader.T) SetLayoutTyped[S] { } } - bindFlagsInfo := ext_descriptor_indexing.DescriptorSetLayoutBindingFlagsCreateInfo{ - BindingFlags: bindFlags, - } + //bindFlagsInfo := ext_descriptor_indexing.DescriptorSetLayoutBindingFlagsCreateInfo{ + //BindingFlags: bindFlags, + //} info := core1_0.DescriptorSetLayoutCreateInfo{ - Flags: createFlags, - Bindings: bindings, - NextOptions: common.NextOptions{Next: bindFlagsInfo}, + Flags: createFlags, + Bindings: bindings, + //NextOptions: common.NextOptions{Next: bindFlagsInfo}, } ptr, _, err := device.Ptr().CreateDescriptorSetLayout(nil, info) diff --git a/engine/renderapi/device/device_help.go b/engine/renderapi/device/device_help.go index 386cdb7..4471eab 100644 --- a/engine/renderapi/device/device_help.go +++ b/engine/renderapi/device/device_help.go @@ -30,12 +30,12 @@ func _QueueCreateInfos(families []*core1_0.QueueFamilyProperties) []core1_0.Devi // todo: what's means the nextoption? func _NextOptions() common.NextOptions { indexingFeatures := ext_descriptor_indexing.PhysicalDeviceDescriptorIndexingFeatures{ - ShaderSampledImageArrayNonUniformIndexing: true, - RuntimeDescriptorArray: true, - DescriptorBindingPartiallyBound: true, - DescriptorBindingVariableDescriptorCount: true, - DescriptorBindingUpdateUnusedWhilePending: true, - DescriptorBindingUniformBufferUpdateAfterBind: true, + ShaderSampledImageArrayNonUniformIndexing: true, + RuntimeDescriptorArray: true, + DescriptorBindingPartiallyBound: true, + DescriptorBindingVariableDescriptorCount: true, + DescriptorBindingUpdateUnusedWhilePending: true, + //DescriptorBindingUniformBufferUpdateAfterBind: true, DescriptorBindingSampledImageUpdateAfterBind: true, DescriptorBindingStorageBufferUpdateAfterBind: true, DescriptorBindingStorageTexelBufferUpdateAfterBind: true, diff --git a/engine/renderapi/vulkan/backend.go b/engine/renderapi/vulkan/backend.go index 0233cc9..a84b0e8 100644 --- a/engine/renderapi/vulkan/backend.go +++ b/engine/renderapi/vulkan/backend.go @@ -49,13 +49,13 @@ func New(appName string, deviceIndex int) App { } // transfer worker - transfer := command.NewWorker(device, "xfer", core1_0.QueueTransfer|core1_0.QueueGraphics, 0) + transfer := command.NewWorker(device, "xfer", core1_0.QueueTransfer|core1_0.QueueGraphics, 1) // per frame graphics workers workerCount := 1 // frames workers := make([]command.Worker, workerCount) for i := range workers { - workers[i] = command.NewWorker(device, fmt.Sprintf("frame%d", i), core1_0.QueueGraphics, i+1) + workers[i] = command.NewWorker(device, fmt.Sprintf("frame%d", i), core1_0.QueueGraphics, 0) } // init caches diff --git a/engine/renderapi/vulkan/instance/instance.go b/engine/renderapi/vulkan/instance/instance.go index 49e2b3f..b9bf7b1 100644 --- a/engine/renderapi/vulkan/instance/instance.go +++ b/engine/renderapi/vulkan/instance/instance.go @@ -32,7 +32,7 @@ func New(appName string) T { ApplicationVersion: common.CreateVersion(0, 1, 0), EngineName: engineName, EngineVersion: common.CreateVersion(0, 2, 1), - EnabledLayerNames: _EnabledLayerNames(), + EnabledLayerNames: _EnabledLayerNames(loader), EnabledExtensionNames: _EnabledExtensionNames(loader), }) if err != nil { diff --git a/engine/renderapi/vulkan/instance/instance_help.go b/engine/renderapi/vulkan/instance/instance_help.go index b2399b0..fc79e50 100644 --- a/engine/renderapi/vulkan/instance/instance_help.go +++ b/engine/renderapi/vulkan/instance/instance_help.go @@ -19,7 +19,7 @@ var ( } layers = []string{ "VK_LAYER_KHRONOS_validation", - //"VK_LAYER_LUNARG_api_dump", + "VK_LAYER_LUNARG_api_dump", } engineName = "goworld" ) @@ -38,6 +38,17 @@ func _EnabledExtensionNames(loader *core.VulkanLoader) []string { extensions = _extensions return _extensions } -func _EnabledLayerNames() []string { +func _EnabledLayerNames(loader *core.VulkanLoader) []string { + avaliableLayers, _, _ := loader.AvailableLayers() + var _layers []string + for _, lay := range layers { + _, hasExt := avaliableLayers[lay] + if !hasExt { + log.Printf("cann't support layer: %s", lay) + continue + } + _layers = append(_layers, lay) + } + layers = _layers return layers } diff --git a/game/main.go b/game/main.go index 1f5e367..9d9a6d7 100644 --- a/game/main.go +++ b/game/main.go @@ -2,12 +2,27 @@ package main import ( "zworld/engine" + "zworld/engine/object" + "zworld/engine/object/player" + "zworld/plugins/geometry/cube" + "zworld/plugins/math/quat" + "zworld/plugins/math/vec3" + "zworld/test/tgraph" ) func main() { engine.Run(engine.Args{ - Width: 1600, - Height: 1200, - Title: "zworld", + Width: 720, + Height: 640, + Title: "zworld", + Renderer: tgraph.Renderer, + }, func(scene object.Object) { + object.Builder(cube.NewObject(cube.Args{})). + Position(vec3.New(14, 14, 14)). + Parent(scene). + Create() + + player := player.NewPlayer(vec3.New(-8, 24, -8), quat.Euler(30, 45, 0)) + object.Attach(scene, player) }) } diff --git a/go.mod b/go.mod index ba67d72..4de58be 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/go-logr/logr v1.3.0 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/google/go-cmp v0.6.0 // indirect - github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect + github.com/google/pprof v0.0.0-20230728192033-2ba5b33183c6 // indirect github.com/google/uuid v1.3.0 // indirect github.com/pkg/errors v0.9.1 // indirect golang.org/x/net v0.20.0 // indirect diff --git a/go.sum b/go.sum index 31f7e7d..91778c5 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,5 @@ github.com/CannibalVox/cgoparam v1.1.0 h1:6UDDhOpT06csFE2vkcanXsIJmebMc9o+6Vzhvi4i0wY= github.com/CannibalVox/cgoparam v1.1.0/go.mod h1:9LDFLuHVgE+IIBDd1QFN3dPqmGQN9bS6H+NPizMv2fA= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -22,11 +19,12 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20230728192033-2ba5b33183c6 h1:ZgoomqkdjGbQ3+qQXCkvYMCDvGDNg2k5JJDjjdTB6jY= +github.com/google/pprof v0.0.0-20230728192033-2ba5b33183c6/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/johanhenriksson/goworld v0.0.0-20231109170831-124f97e005f9 h1:WVzeeZIPUeMJYejUcjdmgY/1HZUS4FFlBLR6B5HfpEE= +github.com/johanhenriksson/goworld v0.0.0-20231109170831-124f97e005f9/go.mod h1:NoZ3PxKykryuY2mLnZpUqLEw252H4iPHKizHDh230RI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -61,7 +59,6 @@ golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8= golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= diff --git a/log/error/VkPresentInfoKHR.txt b/log/error/VkPresentInfoKHR.txt new file mode 100644 index 0000000..18e814a --- /dev/null +++ b/log/error/VkPresentInfoKHR.txt @@ -0,0 +1,33 @@ +Thread 7, Frame 1: +vkWaitForFences(device, fenceCount, pFences, waitAll, timeout) returns VkResult VK_SUCCESS (0): + device: VkDevice = 0000017DFB263730 + fenceCount: uint32_t = 1 + pFences: const VkFence* = 0000002F943FF630 +VUID-VkPresentInfoKHR-pImageIndices-01430(ERROR / SPEC): msgNum: 1219306694 - Validation Error: [ VUID-VkPresentInfoKHR-pImageIndices-01430 ] Object 0: handle = 0x17dfd8b9ad0, name = frame0:0:17dfd8b9ad0, type = VK_OBJECT_TYP +E_QUEUE; | MessageID = 0x48ad24c6 | vkQueuePresentKHR(): pSwapchains[0] images passed to present must be in layout VK_IMAGE_LAYOUT_PRESENT_SRC_KHR or VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR but is in VK_IMAGE_LAYOUT_UNDEFINED. The + Vulkan spec states: Each element of pImageIndices must be the index of a presentable image acquired from the swapchain specified by the corresponding element of the pSwapchains array, and the presented image subresource must + be in the VK_IMAGE_LAYOUT_PRESENT_SRC_KHR or VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR layout at the time the operation is executed on a VkDevice (https://vulkan.lunarg.com/doc/view/1.3.261.1/windows/1.3-extensions/vkspec.html#VUID +-VkPresentInfoKHR-pImageIndices-01430) + Objects: 1 + [0] 0x17dfd8b9ad0, type: 4, name: frame0:0:17dfd8b9ad0 + pFences[0]: const VkFence = 0000017DFA4D8460 + waitAll: VkBool32 = 1 + timeout: uint64_t = 3600000000000 + +Thread 3, Frame 1: +vkQueuePresentKHR(queue, pPresentInfo) returns VkResult VK_SUCCESS (0): + queue: VkQueue = 0000017DFD8B9AD0 + pPresentInfo: const VkPresentInfoKHR* = 00000568D00E0EC0: + sType: VkStructureType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR (1000001001) + pNext: const void* = NULL + waitSemaphoreCount: uint32_t = 1 + pWaitSemaphores: const VkSemaphore* = 00000568D0090240 + pWaitSemaphores[0]: const VkSemaphore = 0000017DFDE29F00 + swapchainCount: uint32_t = 1 + pSwapchains: const VkSwapchainKHR* = 00000568D0090248 + pSwapchains[0]: const VkSwapchainKHR = 0000017DFDE11C40 + pImageIndices: const uint32_t* = 00000568D0090250 + pImageIndices[0]: const uint32_t = 1 + pResults: VkResult* = 00000568D0090258 + pResults[0]: VkResult = VK_SUCCESS (0) + diff --git a/log/error/vkCreateDescriptorSetLayout.txt b/log/error/vkCreateDescriptorSetLayout.txt new file mode 100644 index 0000000..fa24de3 --- /dev/null +++ b/log/error/vkCreateDescriptorSetLayout.txt @@ -0,0 +1,46 @@ +-VkDescriptorSetLayoutCreateInfo-pNext-pNext(ERROR / SPEC): msgNum: 729054019 - Validation Error: [ VUID-VkDescriptorSetLayoutCreateInfo-pNext-pNext ] Object 0: handle = 0x1990747ed20, type = VK_OBJECT_TYPE_INSTANCE; | Me +ssageID = 0x2b747b43 | vkCreateDescriptorSetLayout: Includes a pNext pointer (pCreateInfo->pNext) to a VkStructureType (VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO), but its parent extension VK_EXT_descr +iptor_indexing has not been enabled. The Vulkan spec states: Each pNext member of any structure (including this one) in the pNext chain must be either NULL or a pointer to a valid instance of VkDescriptorSetLayoutBindingFlags +CreateInfo or VkMutableDescriptorTypeCreateInfoEXT (https://vulkan.lunarg.com/doc/view/1.3.261.1/windows/1.3-extensions/vkspec.html#VUID-VkDescriptorSetLayoutCreateInfo-pNext-pNext) + Objects: 1 + [0] 0x1990747ed20, type: 1, name: NULL +Thread 0, Frame 0: +vkCreateDescriptorSetLayout(device, pCreateInfo, pAllocator, pSetLayout) returns VkResult VK_SUCCESS (0): + device: VkDevice = 000001994FE041C0 + pCreateInfo: const VkDescriptorSetLayoutCreateInfo* = 00000079C01FF870: + sType: VkStructureType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO (32) + pNext: const void* = VkDescriptorSetLayoutBindingFlagsCreateInfo + flags: VkDescriptorSetLayoutCreateFlags = 0 + bindingCount: uint32_t = 2 + pBindings: const VkDescriptorSetLayoutBinding* = 000002C1AC6FA9C8 + pBindings[0]: const VkDescriptorSetLayoutBinding = 000002C1AC6FA9C8: + binding: uint32_t = 0 + descriptorType: VkDescriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER (6) + descriptorCount: uint32_t = 1 + stageFlags: VkShaderStageFlags = 2147483647 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | VK_SHADER_STAGE_GEOMETRY_B +IT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_ALL | VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_MISS_BIT_KHR | V +K_SHADER_STAGE_INTERSECTION_BIT_KHR | VK_SHADER_STAGE_CALLABLE_BIT_KHR | VK_SHADER_STAGE_TASK_BIT_EXT | VK_SHADER_STAGE_MESH_BIT_EXT | VK_SHADER_STAGE_SUBPASS_SHADING_BIT_HUAWEI | VK_SHADER_STAGE_CLUSTER_CULLING_BIT_HUAWEI) + pImmutableSamplers: const VkSampler* = UNUSED + pBindings[1]: const VkDescriptorSetLayoutBinding = 000002C1AC6FA9E0: + binding: uint32_t = 1 + descriptorType: VkDescriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER (7) + descriptorCount: uint32_t = 1 + stageFlags: VkShaderStageFlags = 2147483647 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | VK_SHADER_STAGE_GEOMETRY_B +IT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_ALL | VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_MISS_BIT_KHR | V +K_SHADER_STAGE_INTERSECTION_BIT_KHR | VK_SHADER_STAGE_CALLABLE_BIT_KHR | VK_SHADER_STAGE_TASK_BIT_EXT | VK_SHADER_STAGE_MESH_BIT_EXT | VK_SHADER_STAGE_SUBPASS_SHADING_BIT_HUAWEI | VK_SHADER_STAGE_CLUSTER_CULLING_BIT_HUAWEI) + pImmutableSamplers: const VkSampler* = UNUSED + pNext: VkDescriptorSetLayoutBindingFlagsCreateInfo = 000002C1AC6EF620: + sType: VkStructureType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO (1000161000) + pNext: const void* = NULL + bindingCount: uint32_t = 2 + pBindingFlags: const VkDescriptorBindingFlags* = 000002C1AC791F38 + pBindingFlags[0]: const VkDescriptorBindingFlags = 0 + pBindingFlags[1]: const VkDescriptorBindingFlags = 0 + pAllocator: const VkAllocationCallbacks* = NULL + pSetLayout: VkDescriptorSetLayout* = 000001994FE11E80 + +2024-01-18T09:19:34+08:00 error layer=debugger could not resolve parametric type of set +2024-01-18T09:19:34+08:00 error layer=debugger could not resolve parametric type of ~r0 +2024-01-18T09:19:34+08:00 error layer=debugger could not resolve parametric type of set +2024-01-18T09:19:34+08:00 error layer=debugger could not resolve parametric type of ~r0 + diff --git a/test/tgraph/mat_cache.go b/test/tgraph/mat_cache.go new file mode 100644 index 0000000..cbe33d1 --- /dev/null +++ b/test/tgraph/mat_cache.go @@ -0,0 +1,90 @@ +package tgraph + +import ( + "github.com/vkngwrapper/core/v2/core1_0" + "zworld/engine/render/uniform" + "zworld/engine/renderapi/cache" + "zworld/engine/renderapi/descriptor" + "zworld/engine/renderapi/material" + "zworld/engine/renderapi/renderpass" + "zworld/engine/renderapi/shader" + "zworld/engine/renderapi/vertex" + "zworld/engine/renderapi/vulkan" +) + +type MatCache struct { + app vulkan.App + pass renderpass.T + frames int +} + +func NewMaterialCache(app vulkan.App, pass renderpass.T, frames int) MaterialCache { + return cache.New[*material.Def, []Material](&MatCache{ + app: app, + pass: pass, + frames: frames, + }) +} + +func (m *MatCache) Name() string { return "DepthMaterials" } + +func (m *MatCache) Instantiate(def *material.Def, callback func([]Material)) { + if def == nil { + def = &material.Def{} + } + + desc := &BasicDescriptors{ + Camera: &descriptor.Uniform[uniform.Camera]{ + Stages: core1_0.StageAll, + }, + Objects: &descriptor.Storage[uniform.Object]{ + Stages: core1_0.StageAll, + Size: 2000, + }, + } + + // read vertex pointers from vertex format + pointers := vertex.ParsePointers(def.VertexFormat) + + // fetch shader from cache + shader := m.app.Shaders().Fetch(shader.NewRef("depth")) + + // create material + mat := material.New( + m.app.Device(), + material.Args{ + Shader: shader, + Pass: m.pass, + Subpass: MainSubpass, + Pointers: pointers, + CullMode: vertex.CullBack, + DepthTest: true, + DepthWrite: true, + DepthFunc: core1_0.CompareOpLess, + DepthClamp: def.DepthClamp, + Primitive: def.Primitive, + }, + desc) + + instances := make([]Material, m.frames) + for i := range instances { + instance := mat.Instantiate(m.app.Pool()) + bm := &BasicMaterial{ + //id: def.Hash(), + Instance: instance, + Objects: NewObjectBuffer(desc.Objects.Size), + Meshes: m.app.Meshes(), + } + bm.SetID(def.Hash()) + instances[i] = bm + } + + callback(instances) +} + +func (m *MatCache) Destroy() { +} + +func (m *MatCache) Delete(mat []Material) { + mat[0].Destroy() +} diff --git a/test/tgraph/pass.go b/test/tgraph/pass.go new file mode 100644 index 0000000..7af0563 --- /dev/null +++ b/test/tgraph/pass.go @@ -0,0 +1,102 @@ +package tgraph + +import ( + "github.com/vkngwrapper/core/v2/core1_0" + "zworld/engine/object" + "zworld/engine/object/mesh" + "zworld/engine/renderapi" + "zworld/engine/renderapi/command" + "zworld/engine/renderapi/framebuffer" + "zworld/engine/renderapi/renderpass" + "zworld/engine/renderapi/renderpass/attachment" + "zworld/engine/renderapi/vulkan" +) + +type Pass struct { + app vulkan.App + pass renderpass.T + gbuffer GeometryBuffer + fbuf framebuffer.Array + + materials MaterialCache + meshQuery *object.Query[mesh.Mesh] +} + +func NewPass(app vulkan.App, target vulkan.Target, gbuffer GeometryBuffer) *Pass { + pass := renderpass.New(app.Device(), renderpass.Args{ + Name: "Pass", + ColorAttachments: []attachment.Color{ + { + Name: NormalsAttachment, + LoadOp: core1_0.AttachmentLoadOpClear, + StoreOp: core1_0.AttachmentStoreOpStore, + FinalLayout: core1_0.ImageLayoutShaderReadOnlyOptimal, + + Image: attachment.FromImageArray(gbuffer.Normal()), + }, + { + Name: PositionAttachment, + LoadOp: core1_0.AttachmentLoadOpClear, + StoreOp: core1_0.AttachmentStoreOpStore, + FinalLayout: core1_0.ImageLayoutShaderReadOnlyOptimal, + + Image: attachment.FromImageArray(gbuffer.Position()), + }, + }, + DepthAttachment: &attachment.Depth{ + LoadOp: core1_0.AttachmentLoadOpClear, + StencilLoadOp: core1_0.AttachmentLoadOpClear, + StoreOp: core1_0.AttachmentStoreOpStore, + FinalLayout: core1_0.ImageLayoutShaderReadOnlyOptimal, + ClearDepth: 1, + + Image: attachment.FromImageArray(target.Surfaces()), + }, + Subpasses: []renderpass.Subpass{ + { + Name: MainSubpass, + Depth: true, + + ColorAttachments: []attachment.Name{NormalsAttachment, PositionAttachment}, + }, + }, + }) + fbuf, err := framebuffer.NewArray(target.Frames(), app.Device(), "forward", target.Width(), target.Height(), pass) + if err != nil { + panic(err) + } + return &Pass{ + gbuffer: gbuffer, + fbuf: fbuf, + app: app, + pass: pass, + materials: NewMaterialCache(app, pass, gbuffer.Frames()), + meshQuery: object.NewQuery[mesh.Mesh](), + } +} + +func (p *Pass) Record(cmds command.Recorder, args renderapi.Args, scene object.Component) { + opaque := p.meshQuery. + Reset(). + Collect(scene) + + cmds.Record(func(cmd command.Buffer) { + cmd.CmdBeginRenderPass(p.pass, p.fbuf[args.Frame]) + }) + + cam := CameraFromArgs(args) + groups := MaterialGroups(p.materials, args.Frame, opaque) + groups.Draw(cmds, cam, nil) + + cmds.Record(func(cmd command.Buffer) { + cmd.CmdEndRenderPass() + }) +} + +func (p *Pass) Name() string { + return "Pass" +} + +func (p *Pass) Destroy() { + p.pass.Destroy() +} diff --git a/test/tgraph/renderer.go b/test/tgraph/renderer.go new file mode 100644 index 0000000..033d391 --- /dev/null +++ b/test/tgraph/renderer.go @@ -0,0 +1,26 @@ +package tgraph + +import ( + "zworld/engine/render/graph" + "zworld/engine/render/pass" + "zworld/engine/renderapi/vulkan" +) + +func Renderer(app vulkan.App, target vulkan.Target) graph.T { + return graph.New(app, target, func(g graph.T, output vulkan.Target) []graph.Resource { + size := output.Size() + // allocate main depth buffer + depth := vulkan.NewDepthTarget(app.Device(), "main-depth", size) + // create geometry buffer + gbuffer, err := pass.NewGbuffer(app.Device(), size) + if err != nil { + panic(err) + } + // depth pre-pass + g.Node(NewPass(app, depth, gbuffer)) + return []graph.Resource{ + depth, + gbuffer, + } + }) +} diff --git a/test/tgraph/type.go b/test/tgraph/type.go new file mode 100644 index 0000000..d200e9c --- /dev/null +++ b/test/tgraph/type.go @@ -0,0 +1,26 @@ +package tgraph + +import ( + "zworld/engine/render/pass" +) + +type ( + GeometryBuffer = pass.GeometryBuffer + MaterialCache = pass.MaterialCache + + Material = pass.Material + BasicMaterial = pass.BasicMaterial + BasicDescriptors = pass.BasicDescriptors +) + +var ( + NormalsAttachment = pass.NormalsAttachment + PositionAttachment = pass.PositionAttachment + + MainSubpass = pass.MainSubpass + + CameraFromArgs = pass.CameraFromArgs + MaterialGroups = pass.MaterialGroups + + NewObjectBuffer = pass.NewObjectBuffer +)