diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 0000000..fa46a58 --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,24 @@ +name: Check Build +on: + pull_request: + branches: ['*'] + push: + branches: ['*'] +jobs: + build: + name: Build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: gradle/wrapper-validation-action@v1 + - uses: actions/setup-java@v3 + with: + distribution: 'zulu' + java-version: '17' + - uses: actions/cache@v3 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + - run: ./gradlew build --stacktrace --no-daemon diff --git a/.gitignore b/.gitignore index 3c37caf..3055880 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,10 @@ *.ipr *.iws +# VS Code +.vscode/ +bin/ + # IntelliJ out/ # mpeltonen/sbt-idea plugin diff --git a/build.gradle b/build.gradle index d243f20..214eadd 100644 --- a/build.gradle +++ b/build.gradle @@ -44,6 +44,8 @@ dependencies { modRuntimeOnly 'org.anarres:jcpp:1.4.14' modRuntimeOnly 'io.github.douira:glsl-transformer:2.0.0-pre13' + modRuntimeOnly 'net.java.dev.jna:jna:5.9.0' + implementation("com.github.FiguraMC.LuaJ:luaj-core:3.0.6-figura") implementation("com.github.FiguraMC.LuaJ:luaj-jse:3.0.6-figura") diff --git a/gradle.properties b/gradle.properties index ab1029b..4a98384 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ # Done to increase the memory available to gradle. -org.gradle.jvmargs=-Xmx1G +org.gradle.jvmargs=-Xmx4G # Fabric Properties # check these on https://modmuss50.me/fabric.html minecraft_version=1.20.1 @@ -9,7 +9,7 @@ loader_version=0.14.21 #Fabric api fabric_version=0.84.0+1.20.1 # Mod Properties -mod_version=0.0.2-pre-alpha +mod_version=0.0.3-pre-alpha maven_group=me.cortex archives_base_name=vulkanite diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..c1962a7 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 874fcb1..0c85a1f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip +networkTimeout=10000 +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..3a163de --- /dev/null +++ b/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" \ No newline at end of file diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..93e3f59 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/main/java/me/cortex/vulkanite/acceleration/AccelerationBlasBuilder.java b/src/main/java/me/cortex/vulkanite/acceleration/AccelerationBlasBuilder.java index 3bffc5e..3f84bfb 100644 --- a/src/main/java/me/cortex/vulkanite/acceleration/AccelerationBlasBuilder.java +++ b/src/main/java/me/cortex/vulkanite/acceleration/AccelerationBlasBuilder.java @@ -34,13 +34,13 @@ import static org.lwjgl.vulkan.KHRAccelerationStructure.*; import static org.lwjgl.vulkan.KHRBufferDeviceAddress.VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR; import static org.lwjgl.vulkan.VK10.*; -import static org.lwjgl.vulkan.VK12.VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; +import static org.lwjgl.vulkan.VK12.*; public class AccelerationBlasBuilder { private final VContext context; private record BLASTriangleData(int quadCount, NativeBuffer geometry, int geometryFlags) {} - private record BLASBuildJob(List geometries, RenderSection section, long time, List gpuVertexGeometry) {} - public record BLASBuildResult(VAccelerationStructure structure, RenderSection section, long time, List gpuVertexGeometry) {} + private record BLASBuildJob(List geometries, JobPassThroughData data) {} + public record BLASBuildResult(VAccelerationStructure structure, JobPassThroughData data) {} public record BLASBatchResult(List results, VSemaphore semaphore) { } private final Thread worker; private final int asyncQueue; @@ -130,7 +130,12 @@ private void run() { int indexType = SharedQuadVkIndexBuffer.TYPE; //TODO: also need to store the buffer so it can be freed later (after blas build the vertex data can be freed as blas is self contained) - var buf = context.memory.createBufferGlobal(geometry.geometry.getLength(), VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); + var buf = context.memory.createBuffer(geometry.geometry.getLength(), + VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT + | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR + | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + 0, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); long ptr = buf.map(); MemoryUtil.memCopy(MemoryUtil.memAddress(geometry.geometry.getDirectBuffer()), ptr, geometry.geometry.getLength()); buf.unmap(); @@ -191,7 +196,7 @@ private void run() { var scratch = context.memory.createBuffer(buildSizesInfo.buildScratchSize(), VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 256); + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 256, 0); bi.scratchData(VkDeviceOrHostAddressKHR.calloc(stack).deviceAddress(scratch.deviceAddress())); bi.dstAccelerationStructure(structure.structure); @@ -289,7 +294,7 @@ private void run() { compactedAS[idx] = as; var job = jobs.get(idx); - results.add(new BLASBuildResult(as, job.section, job.time, job.gpuVertexGeometry)); + results.add(new BLASBuildResult(as, job.data)); } vkCmdPipelineBarrier(cmd.buffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, null, null, null); @@ -346,8 +351,13 @@ public void enqueue(List batch) { buildData.add(new BLASTriangleData(entry.getValue().quadCount(), entry.getValue().data(), flag)); var geometry = cbr.getMesh(entry.getKey()); - - var buff = context.memory.createBufferGlobal(geometry.getVertexData().getLength(), VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); + if (geometry.getVertexData().getLength() == 0) { + throw new IllegalStateException(); + } + var buff = context.memory.createBuffer(geometry.getVertexData().getLength(), + VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + 0, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); long ptr = buff.map(); MemoryUtil.memCopy(MemoryUtil.memAddress(geometry.getVertexData().getDirectBuffer()), ptr, geometry.getVertexData().getLength()); buff.unmap(); @@ -355,7 +365,7 @@ public void enqueue(List batch) { geometryBuffers.add(buff); } - jobs.add(new BLASBuildJob(buildData, cbr.render, cbr.buildTime, geometryBuffers)); + jobs.add(new BLASBuildJob(buildData, new JobPassThroughData(cbr.render, cbr.buildTime, geometryBuffers))); } if (jobs.isEmpty()) { diff --git a/src/main/java/me/cortex/vulkanite/acceleration/AccelerationTLASManager.java b/src/main/java/me/cortex/vulkanite/acceleration/AccelerationTLASManager.java index ad3cf66..648c101 100644 --- a/src/main/java/me/cortex/vulkanite/acceleration/AccelerationTLASManager.java +++ b/src/main/java/me/cortex/vulkanite/acceleration/AccelerationTLASManager.java @@ -149,7 +149,7 @@ public void buildTLAS(VSemaphore semIn, VSemaphore semOut, VSemaphore[] blocking // get automatically freed since we using vma dont have to worry about performance _too_ much i think VBuffer scratchBuffer = context.memory.createBuffer(buildSizesInfo.buildScratchSize(), VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 256); + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 256, 0); buildInfo.dstAccelerationStructure(tlas.structure) .scratchData(VkDeviceOrHostAddressKHR.calloc(stack) @@ -230,7 +230,12 @@ public TLASGeometryManager() { //TODO: make the instances buffer, gpu permenent then stream updates instead of uploading per frame public void setGeometryUpdateMemory(VCmdBuff cmd, VFence fence, VkAccelerationStructureGeometryKHR struct) { long size = (long) VkAccelerationStructureInstanceKHR.SIZEOF * count; - VBuffer data = context.memory.createBufferGlobal(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_HEAP_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); + VBuffer data = context.memory.createBuffer(size, + VK_BUFFER_USAGE_TRANSFER_DST_BIT + | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR + | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, + VK_MEMORY_HEAP_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + 0, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); long ptr = data.map(); MemoryUtil.memCopy(this.instances.address(0), ptr, size); data.unmap(); @@ -316,7 +321,10 @@ public void setGeometryUpdateMemory(VCmdBuff cmd, VFence fence, VkAccelerationSt if (ref != null) { context.sync.addCallback(fence, ref::free); } - geometryReferenceBuffer = context.memory.createBufferGlobal(8L *arena.maxIndex, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_HEAP_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); + geometryReferenceBuffer = context.memory.createBuffer(8L * arena.maxIndex, + VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, + VK_MEMORY_HEAP_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + 0, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); long ptr = geometryReferenceBuffer.map(); MemoryUtil.memCopy(arrayRef, ptr, 8L * arena.maxIndex); geometryReferenceBuffer.unmap(); @@ -340,7 +348,8 @@ private Holder(int id, RenderSection section) { Map tmp = new HashMap<>(); public void update(AccelerationBlasBuilder.BLASBuildResult result) { - var holder = tmp.computeIfAbsent(result.section().getPosition(), a -> new Holder(alloc(), result.section())); + var data = result.data(); + var holder = tmp.computeIfAbsent(data.section().getPosition(), a -> new Holder(alloc(), data.section())); if (holder.structure != null) { structuresToRelease.add(holder.structure); } @@ -350,7 +359,7 @@ public void update(AccelerationBlasBuilder.BLASBuildResult result) { arena.free(holder.geometryIndex, holder.geometryBuffers.size()); holder.geometryBuffers.forEach(buffer -> Vulkanite.INSTANCE.addSyncedCallback(buffer::free)); } - holder.geometryBuffers = result.gpuVertexGeometry(); + holder.geometryBuffers = data.geometryBuffers(); holder.geometryIndex = arena.allocate(holder.geometryBuffers.size()); for (int i = 0; i < holder.geometryBuffers.size(); i++) { diff --git a/src/main/java/me/cortex/vulkanite/acceleration/JobPassThroughData.java b/src/main/java/me/cortex/vulkanite/acceleration/JobPassThroughData.java new file mode 100644 index 0000000..d54d4c2 --- /dev/null +++ b/src/main/java/me/cortex/vulkanite/acceleration/JobPassThroughData.java @@ -0,0 +1,10 @@ +package me.cortex.vulkanite.acceleration; + +import me.cortex.vulkanite.lib.memory.VBuffer; +import me.jellysquid.mods.sodium.client.render.chunk.RenderSection; + +import java.util.List; + +public record JobPassThroughData(RenderSection section, long time, List geometryBuffers) { + +} diff --git a/src/main/java/me/cortex/vulkanite/acceleration/SharedQuadVkIndexBuffer.java b/src/main/java/me/cortex/vulkanite/acceleration/SharedQuadVkIndexBuffer.java index 4bc741f..c62c864 100644 --- a/src/main/java/me/cortex/vulkanite/acceleration/SharedQuadVkIndexBuffer.java +++ b/src/main/java/me/cortex/vulkanite/acceleration/SharedQuadVkIndexBuffer.java @@ -37,7 +37,12 @@ private static void makeNewIndexBuffer(VContext context, int quadCount) { ByteBuffer buffer = genQuadIdxs(quadCount); //TODO: dont harcode VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR and VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT - indexBuffer = context.memory.createBufferGlobal(buffer.remaining(), VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_HEAP_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); + indexBuffer = context.memory.createBuffer(buffer.remaining(), + VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT + | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR + | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, + VK_MEMORY_HEAP_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + 0, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); //TODO: GET RID OF VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT from the allocation and replace this with a proper uploading/copy system since VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT slows it down alot long ptr = indexBuffer.map(); diff --git a/src/main/java/me/cortex/vulkanite/client/Test.java b/src/main/java/me/cortex/vulkanite/client/Test.java index 28412cc..2fee9ee 100644 --- a/src/main/java/me/cortex/vulkanite/client/Test.java +++ b/src/main/java/me/cortex/vulkanite/client/Test.java @@ -4,6 +4,7 @@ import me.cortex.vulkanite.lib.base.initalizer.VInitializer; import me.cortex.vulkanite.lib.descriptors.DescriptorSetLayoutBuilder; import me.cortex.vulkanite.lib.pipeline.*; +import me.cortex.vulkanite.lib.shader.VShader; import org.lwjgl.glfw.GLFWErrorCallback; import org.lwjgl.glfw.GLFWVidMode; import org.lwjgl.opengl.GL; @@ -116,7 +117,8 @@ public static void main(String[] args) throws IOException { var pool = context.cmd.createSingleUsePool(); pool.createCommandBuffer(); - var mem = context.memory.createBufferGlobal(1024, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, 0, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); + var mem = context.memory.createBuffer(1024, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, 0, + 0, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); mem.map(); mem.unmap(); mem.flush(); diff --git a/src/main/java/me/cortex/vulkanite/client/Vulkanite.java b/src/main/java/me/cortex/vulkanite/client/Vulkanite.java index 740b28b..ada32b7 100644 --- a/src/main/java/me/cortex/vulkanite/client/Vulkanite.java +++ b/src/main/java/me/cortex/vulkanite/client/Vulkanite.java @@ -7,8 +7,10 @@ import me.cortex.vulkanite.lib.base.initalizer.VInitializer; import me.jellysquid.mods.sodium.client.render.chunk.RenderSection; import me.jellysquid.mods.sodium.client.render.chunk.compile.ChunkBuildOutput; +import net.minecraft.util.Util; import org.lwjgl.vulkan.*; +import java.util.ArrayList; import java.util.List; import static org.lwjgl.vulkan.EXTDebugUtils.VK_EXT_DEBUG_UTILS_EXTENSION_NAME; @@ -19,12 +21,15 @@ import static org.lwjgl.vulkan.KHRBufferDeviceAddress.VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME; import static org.lwjgl.vulkan.KHRDeferredHostOperations.VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME; import static org.lwjgl.vulkan.KHRExternalFenceCapabilities.VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME; +import static org.lwjgl.vulkan.KHRExternalFenceFd.VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME; import static org.lwjgl.vulkan.KHRExternalFenceWin32.VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME; import static org.lwjgl.vulkan.KHRExternalMemory.VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME; import static org.lwjgl.vulkan.KHRExternalMemoryCapabilities.VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME; +import static org.lwjgl.vulkan.KHRExternalMemoryFd.VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME; import static org.lwjgl.vulkan.KHRExternalMemoryWin32.VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME; import static org.lwjgl.vulkan.KHRExternalSemaphore.VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME; import static org.lwjgl.vulkan.KHRExternalSemaphoreCapabilities.VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME; +import static org.lwjgl.vulkan.KHRExternalSemaphoreFd.VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME; import static org.lwjgl.vulkan.KHRExternalSemaphoreWin32.VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME; import static org.lwjgl.vulkan.KHRGetMemoryRequirements2.VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME; import static org.lwjgl.vulkan.KHRGetPhysicalDeviceProperties2.VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; @@ -34,7 +39,10 @@ import static org.lwjgl.vulkan.KHRSpirv14.VK_KHR_SPIRV_1_4_EXTENSION_NAME; public class Vulkanite { + public static final boolean IS_WINDOWS = Util.getOperatingSystem() == Util.OperatingSystem.WINDOWS; + public static boolean MEMORY_LEAK_TRACING = true; + public static boolean IS_ENABLED = true; public static final Vulkanite INSTANCE = new Vulkanite(); @@ -102,50 +110,45 @@ private static VContext createVulkanContext() { //This copies whatever gpu the opengl context is on init.findPhysicalDevice();//glGetString(GL_RENDERER).split("/")[0] - init.createDevice(List.of( - VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, - VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME, - VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME, - VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, - VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, - VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME, - VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, - VK_KHR_SPIRV_1_4_EXTENSION_NAME, - VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, - VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, - - //VK_KHR_RAY_QUERY_EXTENSION_NAME, - - VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, - VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, - - VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME, - - VK_KHR_16BIT_STORAGE_EXTENSION_NAME, - VK_KHR_8BIT_STORAGE_EXTENSION_NAME - ), + List extensions = new ArrayList<>(List.of( + VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, + VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, + VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME, + VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, + VK_KHR_SPIRV_1_4_EXTENSION_NAME, + VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, + + //VK_KHR_RAY_QUERY_EXTENSION_NAME, + + VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, + VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, + + VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME + )); + if (IS_WINDOWS) { + extensions.addAll(List.of(VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, + VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME, + VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME)); + } else { + extensions.addAll(List.of(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, + VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, + VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME)); + } + init.createDevice(extensions, List.of(), new float[]{1.0f, 0.9f}, features -> features.shaderInt16(true).shaderInt64(true).multiDrawIndirect(true), List.of( stack-> VkPhysicalDeviceAccelerationStructureFeaturesKHR.calloc(stack) - .sType$Default() - .accelerationStructure(true), + .sType$Default(), stack-> VkPhysicalDeviceRayTracingPipelineFeaturesKHR.calloc(stack) - .sType$Default() - .rayTracingPipeline(true) - .rayTracingPipelineTraceRaysIndirect(true), + .sType$Default(), - stack-> VkPhysicalDevice16BitStorageFeatures.calloc(stack) - .sType$Default() - .storageBuffer16BitAccess(true), + stack-> VkPhysicalDeviceVulkan11Features.calloc(stack) + .sType$Default(), stack-> VkPhysicalDeviceVulkan12Features.calloc(stack) .sType$Default() - .storageBuffer8BitAccess(true) - .shaderInt8(true) - .bufferDeviceAddress(true) - .descriptorIndexing(true) )); return init.createContext(); diff --git a/src/main/java/me/cortex/vulkanite/client/rendering/VulkanPipeline.java b/src/main/java/me/cortex/vulkanite/client/rendering/VulkanPipeline.java index 92211dc..f4eb5cc 100644 --- a/src/main/java/me/cortex/vulkanite/client/rendering/VulkanPipeline.java +++ b/src/main/java/me/cortex/vulkanite/client/rendering/VulkanPipeline.java @@ -19,11 +19,9 @@ import me.cortex.vulkanite.lib.other.sync.VSemaphore; import me.cortex.vulkanite.lib.pipeline.RaytracePipelineBuilder; import me.cortex.vulkanite.lib.pipeline.VRaytracePipeline; -import me.cortex.vulkanite.lib.pipeline.VShader; import net.coderbot.iris.texture.pbr.PBRTextureHolder; import net.coderbot.iris.texture.pbr.PBRTextureManager; import net.coderbot.iris.uniforms.CapturedRenderingState; -import net.coderbot.iris.uniforms.CommonUniforms; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.Camera; import net.minecraft.client.render.CameraSubmersionType; @@ -33,29 +31,21 @@ import org.joml.Matrix4f; import org.joml.Vector3f; import org.joml.Vector4f; -import org.lwjgl.system.MemoryStack; import org.lwjgl.system.MemoryUtil; import org.lwjgl.vulkan.*; -import java.io.File; import java.nio.ByteBuffer; -import java.nio.LongBuffer; -import java.nio.file.Files; -import static me.cortex.vulkanite.lib.other.VUtil._CHECK_; import static net.coderbot.iris.uniforms.CelestialUniforms.getSunAngle; import static net.coderbot.iris.uniforms.CelestialUniforms.isDay; import static org.lwjgl.opengl.EXTSemaphore.GL_LAYOUT_GENERAL_EXT; -import static org.lwjgl.opengl.EXTSemaphore.glSignalSemaphoreEXT; import static org.lwjgl.opengl.GL11C.glFinish; import static org.lwjgl.opengl.GL11C.glFlush; import static org.lwjgl.system.MemoryStack.stackPush; import static org.lwjgl.util.vma.Vma.VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT; import static org.lwjgl.vulkan.KHRAccelerationStructure.VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR; import static org.lwjgl.vulkan.KHRRayTracingPipeline.*; -import static org.lwjgl.vulkan.KHRRayTracingPipeline.VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR; import static org.lwjgl.vulkan.VK10.*; -import static org.lwjgl.vulkan.VK10.VK_SHADER_STAGE_ALL; public class VulkanPipeline { private final VContext ctx; @@ -73,6 +63,9 @@ public class VulkanPipeline { private final SharedImageViewTracker blockAtlasNormalView; private final SharedImageViewTracker blockAtlasSpecularView; + private final VImage placeholderImage; + private final VImageView placeholderImageView; + private int fidx; public VulkanPipeline(VContext ctx, AccelerationManager accelerationManager, RaytracingShaderSet[] passes) { @@ -96,6 +89,22 @@ public VulkanPipeline(VContext ctx, AccelerationManager accelerationManager, Ray PBRTextureHolder holder = PBRTextureManager.INSTANCE.getOrLoadHolder(blockAtlas.getGlId());//((TextureAtlasExtension)blockAtlas).getPBRHolder() return ((IVGImage)holder.getSpecularTexture()).getVGImage(); }); + this.placeholderImage = ctx.memory.creatImage2D(1, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + this.placeholderImageView = new VImageView(ctx, placeholderImage); + + try (var stack = stackPush()) { + var cmd = singleUsePool.createCommandBuffer(); + cmd.begin(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + + var barriers = VkImageMemoryBarrier.calloc(1, stack); + applyImageBarrier(barriers.get(0), placeholderImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_MEMORY_READ_BIT); + vkCmdPipelineBarrier(cmd.buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, null, null, barriers); + cmd.end(); + + ctx.cmd.submit(0, VkSubmitInfo.calloc(stack).sType$Default().pCommandBuffers(stack.pointers(cmd))); + + Vulkanite.INSTANCE.addSyncedCallback(cmd::enqueueFree); + } } this.sampler = new VSampler(ctx, a->a.magFilter(VK_FILTER_NEAREST) @@ -173,7 +182,10 @@ public void renderPostShadows(VGImage outImg, Camera camera) { var out = ctx.sync.createSharedBinarySemaphore(); VBuffer uboBuffer; { - uboBuffer = ctx.memory.createBufferGlobal(1024, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); + uboBuffer = ctx.memory.createBuffer(1024, + VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + 0, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); long ptr = uboBuffer.map(); MemoryUtil.memSet(ptr, 0, 1024); { @@ -220,7 +232,7 @@ public void renderPostShadows(VGImage outImg, Camera camera) { long desc = descriptors.get(fidx); - new DescriptorUpdateBuilder(ctx, 7) + new DescriptorUpdateBuilder(ctx, 7, placeholderImageView) .set(desc) .uniform(0, uboBuffer) .acceleration(1, tlas) @@ -299,6 +311,8 @@ public void destory() { blockAtlasView.free(); blockAtlasNormalView.free(); blockAtlasSpecularView.free(); + placeholderImageView.free(); + placeholderImage.free(); sampler.free(); } diff --git a/src/main/java/me/cortex/vulkanite/compat/RaytracingShaderSet.java b/src/main/java/me/cortex/vulkanite/compat/RaytracingShaderSet.java index d38bc02..11f7a7a 100644 --- a/src/main/java/me/cortex/vulkanite/compat/RaytracingShaderSet.java +++ b/src/main/java/me/cortex/vulkanite/compat/RaytracingShaderSet.java @@ -2,11 +2,9 @@ import me.cortex.vulkanite.lib.base.VContext; import me.cortex.vulkanite.lib.pipeline.RaytracePipelineBuilder; -import me.cortex.vulkanite.lib.pipeline.ShaderModule; -import me.cortex.vulkanite.lib.pipeline.VShader; +import me.cortex.vulkanite.lib.shader.ShaderModule; +import me.cortex.vulkanite.lib.shader.VShader; -import java.io.File; -import java.nio.file.Files; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/me/cortex/vulkanite/lib/base/initalizer/VInitializer.java b/src/main/java/me/cortex/vulkanite/lib/base/initalizer/VInitializer.java index 571e8b7..75a9e6a 100644 --- a/src/main/java/me/cortex/vulkanite/lib/base/initalizer/VInitializer.java +++ b/src/main/java/me/cortex/vulkanite/lib/base/initalizer/VInitializer.java @@ -19,6 +19,7 @@ import static org.lwjgl.system.MemoryStack.stackPush; import static org.lwjgl.system.MemoryUtil.memUTF8; import static org.lwjgl.vulkan.VK10.*; +import static org.lwjgl.vulkan.VK11.*; public class VInitializer { private final VkInstance instance; @@ -91,8 +92,12 @@ public void createDevice(List extensions, List layers, float[] q } long chain = createInfo.address(); + var deviceProperties2 = VkPhysicalDeviceFeatures2.calloc(stack).sType$Default(); for (var applicator : applicators) { - long next = applicator.apply(stack).address(); + Struct feature = applicator.apply(stack); + deviceProperties2.pNext(feature.address()); + vkGetPhysicalDeviceFeatures2(physicalDevice, deviceProperties2); + long next = feature.address(); MemoryUtil.memPutAddress(chain+8, next); chain = next; } diff --git a/src/main/java/me/cortex/vulkanite/lib/descriptors/DescriptorUpdateBuilder.java b/src/main/java/me/cortex/vulkanite/lib/descriptors/DescriptorUpdateBuilder.java index 1418c8f..9891332 100644 --- a/src/main/java/me/cortex/vulkanite/lib/descriptors/DescriptorUpdateBuilder.java +++ b/src/main/java/me/cortex/vulkanite/lib/descriptors/DescriptorUpdateBuilder.java @@ -18,10 +18,21 @@ public class DescriptorUpdateBuilder { private final VContext ctx; private final MemoryStack stack; private final VkWriteDescriptorSet.Buffer updates; + private final VImageView placeholderImageView; public DescriptorUpdateBuilder(VContext ctx, int maxUpdates) { + this(ctx, maxUpdates, null); + } + + public DescriptorUpdateBuilder(VContext ctx, int maxUpdates, VImageView placeholderImageView) { this.ctx = ctx; this.stack = MemoryStack.stackPush(); this.updates = VkWriteDescriptorSet.calloc(maxUpdates, stack); + this.placeholderImageView = placeholderImageView; + } + + private long viewOrPlaceholder(VImageView v) { + if (v == null && placeholderImageView == null) return 0; + return v == null ? placeholderImageView.view : v.view; } private long set; @@ -99,7 +110,7 @@ public DescriptorUpdateBuilder imageStore(int binding, int layout, VImageView vi .pImageInfo(VkDescriptorImageInfo .calloc(1, stack) .imageLayout(layout) - .imageView(view.view)); + .imageView(viewOrPlaceholder(view))); return this; } @@ -117,7 +128,7 @@ public DescriptorUpdateBuilder imageSampler(int binding, int layout, VImageView .pImageInfo(VkDescriptorImageInfo .calloc(1, stack) .imageLayout(layout) - .imageView(view==null?0:view.view) + .imageView(viewOrPlaceholder(view)) .sampler(sampler.sampler)); return this; } diff --git a/src/main/java/me/cortex/vulkanite/lib/memory/HandleDescriptorManger.java b/src/main/java/me/cortex/vulkanite/lib/memory/HandleDescriptorManger.java new file mode 100644 index 0000000..7d71aec --- /dev/null +++ b/src/main/java/me/cortex/vulkanite/lib/memory/HandleDescriptorManger.java @@ -0,0 +1,38 @@ +package me.cortex.vulkanite.lib.memory; + +import com.sun.jna.Pointer; +import com.sun.jna.platform.linux.LibC; +import com.sun.jna.platform.win32.Kernel32; +import com.sun.jna.platform.win32.WinNT; +import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap; +import me.cortex.vulkanite.client.Vulkanite; + +public class HandleDescriptorManger { + private static final Long2IntOpenHashMap USED_HANDLE_DESCRIPTORS = new Long2IntOpenHashMap(); + public static void add(long handleDescriptor) { + synchronized (USED_HANDLE_DESCRIPTORS) { + USED_HANDLE_DESCRIPTORS.addTo(handleDescriptor, 1); + } + } + + public static void close(long handleDescriptor) { + synchronized (USED_HANDLE_DESCRIPTORS) { + int val = USED_HANDLE_DESCRIPTORS.addTo(handleDescriptor, -1); + if (val <= 0) { + throw new IllegalStateException(); + } + if (val == 1) { + USED_HANDLE_DESCRIPTORS.remove(handleDescriptor); + if (Vulkanite.IS_WINDOWS) { + if (!Kernel32.INSTANCE.CloseHandle(new WinNT.HANDLE(new Pointer(handleDescriptor)))) { + throw new IllegalStateException(); + } + } else { + //if (LibC.INSTANCE.close((int) handleDescriptor) != 0) { + // throw new IllegalStateException(); + //} + } + } + } + } +} diff --git a/src/main/java/me/cortex/vulkanite/lib/memory/MemoryManager.java b/src/main/java/me/cortex/vulkanite/lib/memory/MemoryManager.java index cc42dc4..55bfac9 100644 --- a/src/main/java/me/cortex/vulkanite/lib/memory/MemoryManager.java +++ b/src/main/java/me/cortex/vulkanite/lib/memory/MemoryManager.java @@ -1,32 +1,41 @@ package me.cortex.vulkanite.lib.memory; +import com.sun.jna.Pointer; +import com.sun.jna.platform.linux.LibC; +import com.sun.jna.platform.win32.Kernel32; +import com.sun.jna.platform.win32.WinNT; +import me.cortex.vulkanite.client.Vulkanite; import org.lwjgl.PointerBuffer; import org.lwjgl.util.vma.VmaAllocationCreateInfo; import org.lwjgl.vulkan.*; +import java.nio.IntBuffer; import java.nio.LongBuffer; import static me.cortex.vulkanite.lib.other.VUtil._CHECK_; import static me.cortex.vulkanite.lib.other.VUtil._CHECK_GL_ERROR_; import static org.lwjgl.opengl.ARBDirectStateAccess.*; import static org.lwjgl.opengl.EXTMemoryObject.*; +import static org.lwjgl.opengl.EXTMemoryObjectFD.GL_HANDLE_TYPE_OPAQUE_FD_EXT; +import static org.lwjgl.opengl.EXTMemoryObjectFD.glImportMemoryFdEXT; import static org.lwjgl.opengl.EXTMemoryObjectWin32.glImportMemoryWin32HandleEXT; import static org.lwjgl.opengl.EXTSemaphoreWin32.GL_HANDLE_TYPE_OPAQUE_WIN32_EXT; import static org.lwjgl.opengl.GL11C.*; import static org.lwjgl.system.MemoryStack.stackPush; -import static org.lwjgl.util.vma.Vma.VMA_MEMORY_USAGE_AUTO; +import static org.lwjgl.util.vma.Vma.*; import static org.lwjgl.vulkan.KHRAccelerationStructure.VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR; import static org.lwjgl.vulkan.KHRAccelerationStructure.vkCreateAccelerationStructureKHR; -import static org.lwjgl.vulkan.KHRBufferDeviceAddress.VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR; +import static org.lwjgl.vulkan.KHRExternalMemoryFd.vkGetMemoryFdKHR; import static org.lwjgl.vulkan.KHRExternalMemoryWin32.vkGetMemoryWin32HandleKHR; import static org.lwjgl.vulkan.VK10.*; +import static org.lwjgl.vulkan.VK11.VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT; import static org.lwjgl.vulkan.VK11.VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT; public class MemoryManager { + private static final int EXTERNAL_MEMORY_HANDLE_TYPE = Vulkanite.IS_WINDOWS?VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT:VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT; private final VkDevice device; private final VmaAllocator allocator; private final VmaAllocator.MemoryPool shared; - private final VmaAllocator.MemoryPool nonshared; private final boolean hasDeviceAddresses; //VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR //TODO: FIXME: i think the vma allocator must be allocated with VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT, or at least the pools should @@ -38,11 +47,10 @@ public MemoryManager(VkDevice device, boolean hasDeviceAddresses) { // memory manager should never be created more than once per application, so it should bo ok shared = allocator.createPool(VkExportMemoryAllocateInfo.calloc() .sType$Default() - .handleTypes(VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT)); - nonshared = allocator.createPool(); + .handleTypes(EXTERNAL_MEMORY_HANDLE_TYPE)); } - private void importMemoryWin32(int memoryObject, VmaAllocator.Allocation allocation) { + private long importMemoryWin32(int memoryObject, VmaAllocator.Allocation allocation) { try (var stack = stackPush()) { PointerBuffer pb = stack.callocPointer(1); _CHECK_(vkGetMemoryWin32HandleKHR(device, VkMemoryGetWin32HandleInfoKHR.calloc(stack) @@ -52,13 +60,37 @@ private void importMemoryWin32(int memoryObject, VmaAllocator.Allocation allocat long handle = pb.get(0); if (handle == 0) throw new IllegalStateException(); + HandleDescriptorManger.add(handle); //TODO: fixme: the `alloc.ai.size() + alloc.ai.offset()` is an extreamly ugly hack // it is ment to extend over the entire size of vkMemoryObject, but im not sure how to obtain it glImportMemoryWin32HandleEXT(memoryObject, allocation.ai.size() + allocation.ai.offset(), GL_HANDLE_TYPE_OPAQUE_WIN32_EXT, handle); + return handle; } } + private int importMemoryFd(int memoryObject, VmaAllocator.Allocation allocation) { + try (var stack = stackPush()) { + IntBuffer pb = stack.callocInt(1); + _CHECK_(vkGetMemoryFdKHR(device, VkMemoryGetFdInfoKHR.calloc(stack) + .sType$Default() + .memory(allocation.ai.deviceMemory()) + .handleType(VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT), pb)); + int descriptor = pb.get(0); + if (descriptor == 0) + throw new IllegalStateException(); + HandleDescriptorManger.add(descriptor); + + //TODO: fixme: the `alloc.ai.size() + alloc.ai.offset()` is an extreamly ugly hack + // it is ment to extend over the entire size of vkMemoryObject, but im not sure how to obtain it + glImportMemoryFdEXT(memoryObject, allocation.ai.size() + allocation.ai.offset(), GL_HANDLE_TYPE_OPAQUE_FD_EXT, descriptor); + return descriptor; + } + } + private long importMemory(int memoryObject, VmaAllocator.Allocation allocation) { + return Vulkanite.IS_WINDOWS?importMemoryWin32(memoryObject,allocation):importMemoryFd(memoryObject,allocation); + } + //TODO: there is a better way to do shared memory, a vk memory object from vma should be put into a single memory object // then the memory object should be reused multiple times, this is the corrent and more efficent way // that is, since `alloc.ai.deviceMemory()` is shared by multiple allocations, they can also share a single memory object @@ -74,19 +106,22 @@ public VGBuffer createSharedBuffer(long size, int usage, int properties, int ali .usage(usage) .pNext(VkExternalMemoryBufferCreateInfo.calloc(stack) .sType$Default() - .handleTypes(VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT)), + .handleTypes(EXTERNAL_MEMORY_HANDLE_TYPE)), + // VERY IMPORTANT: create dedicated allocation so underlying memory object is only used by this buffer, + // thus only imported once. VmaAllocationCreateInfo.calloc(stack) .usage(VMA_MEMORY_USAGE_AUTO) - .requiredFlags(properties), + .requiredFlags(properties) + .flags(VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT), alignment); int memoryObject = glCreateMemoryObjectsEXT(); - importMemoryWin32(memoryObject, alloc); + long handle = importMemory(memoryObject, alloc); int glId = glCreateBuffers(); glNamedBufferStorageMemEXT(glId, size, memoryObject, alloc.ai.offset()); _CHECK_GL_ERROR_(); - return new VGBuffer(alloc, glId, memoryObject); + return new VGBuffer(alloc, glId, memoryObject, handle); } } @@ -98,7 +133,7 @@ public VGImage createSharedImage(int width, int height, int mipLevels, int vkFor .usage(usage) .pNext(VkExternalMemoryImageCreateInfo.calloc(stack) .sType$Default() - .handleTypes(VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT)) + .handleTypes(EXTERNAL_MEMORY_HANDLE_TYPE)) .format(vkFormat) .imageType(VK_IMAGE_TYPE_2D) .mipLevels(mipLevels) @@ -111,10 +146,11 @@ public VGImage createSharedImage(int width, int height, int mipLevels, int vkFor var alloc = shared.alloc(createInfo, VmaAllocationCreateInfo.calloc(stack) .usage(VMA_MEMORY_USAGE_AUTO) - .requiredFlags(properties)); + .requiredFlags(properties) + .flags(VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT)); int memoryObject = glCreateMemoryObjectsEXT(); - importMemoryWin32(memoryObject, alloc); + long handle = importMemory(memoryObject, alloc); int glId = glCreateTextures(GL_TEXTURE_2D); @@ -125,11 +161,15 @@ public VGImage createSharedImage(int width, int height, int mipLevels, int vkFor glTextureParameteri(glId, GL_TEXTURE_WRAP_T, GL_REPEAT); _CHECK_GL_ERROR_(); - return new VGImage(alloc, width, height, mipLevels, vkFormat, glFormat, glId, memoryObject); + return new VGImage(alloc, width, height, mipLevels, vkFormat, glFormat, glId, memoryObject, handle); } } - public VBuffer createBufferGlobal(long size, int usage, int properties, int vmaFlags) { + public VBuffer createBuffer(long size, int usage, int properties) { + return createBuffer(size, usage, properties, 0L, 0); + } + + public VBuffer createBuffer(long size, int usage, int properties, long alignment, int vmaFlags) { try (var stack = stackPush()) { var alloc = allocator.alloc(0, VkBufferCreateInfo .calloc(stack) @@ -138,34 +178,35 @@ public VBuffer createBufferGlobal(long size, int usage, int properties, int vmaF .usage(usage), VmaAllocationCreateInfo.calloc(stack) .usage(VMA_MEMORY_USAGE_AUTO) - .requiredFlags(properties) - .flags(vmaFlags)); + .requiredFlags(properties), + alignment); return new VBuffer(alloc); } } - public VBuffer createBuffer(long size, int usage, int properties) { - return createBuffer(size, usage, properties, 0L); - } - - public VBuffer createBuffer(long size, int usage, int properties, long alignment) { + public VImage creatImage2D(int width, int height, int mipLevels, int vkFormat, int usage, int properties) { try (var stack = stackPush()) { - var alloc = nonshared.alloc(VkBufferCreateInfo - .calloc(stack) - .sType$Default() - .size(size) - .usage(usage), + var alloc = allocator.alloc(0, VkImageCreateInfo + .calloc(stack) + .sType$Default() + .format(vkFormat) + .imageType(VK_IMAGE_TYPE_2D) + .tiling(VK_IMAGE_TILING_OPTIMAL) + .samples(VK_SAMPLE_COUNT_1_BIT) + .initialLayout(VK_IMAGE_LAYOUT_UNDEFINED) + .arrayLayers(1) + .mipLevels(mipLevels) + .extent(e -> e.width(width).height(height).depth(1)) + .usage(usage), VmaAllocationCreateInfo.calloc(stack) .usage(VMA_MEMORY_USAGE_AUTO) - .requiredFlags(properties), - alignment); - return new VBuffer(alloc); + .requiredFlags(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)); + return new VImage(alloc, width, height, mipLevels, vkFormat); } } - public VAccelerationStructure createAcceleration(long size, int alignment, int usage, int type) { - var buffer = createBuffer(size, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | usage, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, alignment); + var buffer = createBuffer(size, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | usage, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, alignment, 0); try (var stack = stackPush()) { LongBuffer pAccelerationStructure = stack.mallocLong(1); _CHECK_(vkCreateAccelerationStructureKHR(device, VkAccelerationStructureCreateInfoKHR diff --git a/src/main/java/me/cortex/vulkanite/lib/memory/VGBuffer.java b/src/main/java/me/cortex/vulkanite/lib/memory/VGBuffer.java index 18f882c..46dd3d6 100644 --- a/src/main/java/me/cortex/vulkanite/lib/memory/VGBuffer.java +++ b/src/main/java/me/cortex/vulkanite/lib/memory/VGBuffer.java @@ -1,27 +1,25 @@ package me.cortex.vulkanite.lib.memory; -import me.cortex.vulkanite.client.Vulkanite; - import static me.cortex.vulkanite.lib.other.VUtil._CHECK_GL_ERROR_; import static org.lwjgl.opengl.ARBDirectStateAccess.glCreateBuffers; import static org.lwjgl.opengl.EXTMemoryObject.glDeleteMemoryObjectsEXT; -import static org.lwjgl.opengl.GL11C.glFinish; import static org.lwjgl.opengl.GL15C.glDeleteBuffers; import static org.lwjgl.opengl.GL15C.glGenBuffers; public class VGBuffer extends VBuffer { public final int glId; private final int glMemObj; - VGBuffer(VmaAllocator.BufferAllocation allocation, int glId, int glMemObj) { + private final long handle; + VGBuffer(VmaAllocator.BufferAllocation allocation, int glId, int glMemObj, long handle) { super(allocation); this.glId = glId; this.glMemObj = glMemObj; + this.handle = handle; } @Override public void free() { - glFinish(); - Vulkanite.INSTANCE.getCtx().cmd.waitQueueIdle(0); + HandleDescriptorManger.close(handle); glDeleteBuffers(glId); glDeleteMemoryObjectsEXT(glMemObj); _CHECK_GL_ERROR_(); diff --git a/src/main/java/me/cortex/vulkanite/lib/memory/VGImage.java b/src/main/java/me/cortex/vulkanite/lib/memory/VGImage.java index 67fb23d..781449e 100644 --- a/src/main/java/me/cortex/vulkanite/lib/memory/VGImage.java +++ b/src/main/java/me/cortex/vulkanite/lib/memory/VGImage.java @@ -3,20 +3,24 @@ import static me.cortex.vulkanite.lib.other.VUtil._CHECK_GL_ERROR_; import static org.lwjgl.opengl.EXTMemoryObject.glDeleteMemoryObjectsEXT; import static org.lwjgl.opengl.GL11C.glDeleteTextures; -import static org.lwjgl.opengl.GL15C.glDeleteBuffers; public class VGImage extends VImage { public final int glId; private final int glMemObj; public final int glFormat; - VGImage(VmaAllocator.ImageAllocation allocation, int width, int height, int mipLayers, int format, int glFormat, int glId, int glMemObj) { + private final long handle; + + VGImage(VmaAllocator.ImageAllocation allocation, int width, int height, int mipLayers, int format, int glFormat, int glId, int glMemObj, long handle) { super(allocation, width, height, mipLayers, format); this.glId = glId; this.glMemObj = glMemObj; this.glFormat = glFormat; + this.handle = handle; } public void free() { + HandleDescriptorManger.close(handle); + glDeleteTextures(glId); glDeleteMemoryObjectsEXT(glMemObj); _CHECK_GL_ERROR_(); diff --git a/src/main/java/me/cortex/vulkanite/lib/memory/VImage.java b/src/main/java/me/cortex/vulkanite/lib/memory/VImage.java index 5bf80f1..dccbec1 100644 --- a/src/main/java/me/cortex/vulkanite/lib/memory/VImage.java +++ b/src/main/java/me/cortex/vulkanite/lib/memory/VImage.java @@ -3,7 +3,7 @@ import java.lang.ref.Cleaner; public class VImage { - private VmaAllocator.ImageAllocation allocation; + protected VmaAllocator.ImageAllocation allocation; public final int width; public final int height; public final int mipLayers; diff --git a/src/main/java/me/cortex/vulkanite/lib/memory/VmaAllocator.java b/src/main/java/me/cortex/vulkanite/lib/memory/VmaAllocator.java index 546a123..4dfed64 100644 --- a/src/main/java/me/cortex/vulkanite/lib/memory/VmaAllocator.java +++ b/src/main/java/me/cortex/vulkanite/lib/memory/VmaAllocator.java @@ -16,9 +16,9 @@ import static me.cortex.vulkanite.lib.other.VUtil._CHECK_; import static org.lwjgl.system.MemoryStack.stackPush; import static org.lwjgl.util.vma.Vma.*; -import static org.lwjgl.vulkan.KHRBufferDeviceAddress.vkGetBufferDeviceAddressKHR; import static org.lwjgl.vulkan.VK10.*; -import static org.lwjgl.vulkan.VK12.VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; +import static org.lwjgl.vulkan.VK12.*; +import static org.lwjgl.vulkan.VK11.VK_API_VERSION_1_1; //TODO: make multiple pools for allocations public class VmaAllocator { @@ -36,6 +36,7 @@ public VmaAllocator(VkDevice device, boolean enableDeviceAddresses) { .pVulkanFunctions(VmaVulkanFunctions .calloc(stack) .set(device.getPhysicalDevice().getInstance(), device)) + .vulkanApiVersion(VK_API_VERSION_1_2) .flags(enableDeviceAddresses?VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT:0); /* @@ -165,7 +166,7 @@ public BufferAllocation(long buffer, long allocation, VmaAllocationInfo info, bo this.buffer = buffer; if (hasDeviceAddresses && hasDeviceAddress) { try (MemoryStack stack = stackPush()) { - deviceAddress = vkGetBufferDeviceAddressKHR(device, VkBufferDeviceAddressInfo + deviceAddress = vkGetBufferDeviceAddress(device, VkBufferDeviceAddressInfo .calloc(stack) .sType$Default() .buffer(buffer)); diff --git a/src/main/java/me/cortex/vulkanite/lib/other/sync/SyncManager.java b/src/main/java/me/cortex/vulkanite/lib/other/sync/SyncManager.java index 9dc7f27..8ce7816 100644 --- a/src/main/java/me/cortex/vulkanite/lib/other/sync/SyncManager.java +++ b/src/main/java/me/cortex/vulkanite/lib/other/sync/SyncManager.java @@ -1,8 +1,11 @@ package me.cortex.vulkanite.lib.other.sync; +import me.cortex.vulkanite.client.Vulkanite; +import me.cortex.vulkanite.lib.memory.HandleDescriptorManger; import org.lwjgl.PointerBuffer; import org.lwjgl.vulkan.*; +import java.nio.IntBuffer; import java.nio.LongBuffer; import java.util.HashMap; import java.util.LinkedList; @@ -10,15 +13,20 @@ import java.util.Map; import static me.cortex.vulkanite.lib.other.VUtil._CHECK_; +import static org.lwjgl.opengl.EXTMemoryObjectFD.GL_HANDLE_TYPE_OPAQUE_FD_EXT; +import static org.lwjgl.opengl.EXTMemoryObjectFD.glImportMemoryFdEXT; import static org.lwjgl.opengl.EXTSemaphore.glGenSemaphoresEXT; import static org.lwjgl.opengl.EXTSemaphore.glIsSemaphoreEXT; +import static org.lwjgl.opengl.EXTSemaphoreFD.glImportSemaphoreFdEXT; import static org.lwjgl.opengl.EXTSemaphoreWin32.GL_HANDLE_TYPE_OPAQUE_WIN32_EXT; import static org.lwjgl.opengl.EXTSemaphoreWin32.glImportSemaphoreWin32HandleEXT; import static org.lwjgl.opengl.GL11C.glGetError; import static org.lwjgl.opengl.KHRRobustness.GL_NO_ERROR; import static org.lwjgl.system.MemoryStack.stackPush; +import static org.lwjgl.vulkan.KHRExternalSemaphoreFd.vkGetSemaphoreFdKHR; import static org.lwjgl.vulkan.KHRExternalSemaphoreWin32.vkGetSemaphoreWin32HandleKHR; import static org.lwjgl.vulkan.VK10.*; +import static org.lwjgl.vulkan.VK11.VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT; import static org.lwjgl.vulkan.VK11.VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT; //TODO: the sync manager (probably rename) manages all sync operations @@ -26,6 +34,7 @@ // use this to add a cleanup system for e.g. single use command buffers is a good example, the fences themselves // semaphores, scratch/temp buffers etc public class SyncManager { + private static final int EXTERNAL_SEMAPHORE_TYPE = Vulkanite.IS_WINDOWS?VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT; private final VkDevice device; public SyncManager(VkDevice device) { this.device = device; @@ -39,7 +48,7 @@ public VFence createFence() { } } - public VGSemaphore createSharedBinarySemaphore() { + private VGSemaphore createSharedBinarySemaphoreWin32() { try (var stack = stackPush()) { LongBuffer res = stack.callocLong(1); _CHECK_(vkCreateSemaphore(device, @@ -47,21 +56,23 @@ public VGSemaphore createSharedBinarySemaphore() { .sType$Default() .pNext(VkExportSemaphoreCreateInfo.calloc(stack) .sType$Default() - .handleTypes(VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT)), + .handleTypes(EXTERNAL_SEMAPHORE_TYPE)), null, res)); long semaphore = res.get(0); PointerBuffer pb = stack.callocPointer(1); _CHECK_(vkGetSemaphoreWin32HandleKHR(device, VkSemaphoreGetWin32HandleInfoKHR.calloc(stack) - .sType$Default() - .semaphore(semaphore) - .handleType(VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT), + .sType$Default() + .semaphore(semaphore) + .handleType(EXTERNAL_SEMAPHORE_TYPE), pb)); if (pb.get(0)== 0) { throw new IllegalStateException(); } + HandleDescriptorManger.add(pb.get(0)); + int glSemaphore = glGenSemaphoresEXT(); glImportSemaphoreWin32HandleEXT(glSemaphore, GL_HANDLE_TYPE_OPAQUE_WIN32_EXT, pb.get(0)); if (!glIsSemaphoreEXT(glSemaphore)) @@ -69,10 +80,50 @@ public VGSemaphore createSharedBinarySemaphore() { if (glGetError() != GL_NO_ERROR) throw new IllegalStateException(); - return new VGSemaphore(device, semaphore, glSemaphore); + return new VGSemaphore(device, semaphore, glSemaphore, pb.get(0)); + } + } + + private VGSemaphore createSharedBinarySemaphoreFd() { + try (var stack = stackPush()) { + LongBuffer res = stack.callocLong(1); + _CHECK_(vkCreateSemaphore(device, + VkSemaphoreCreateInfo.calloc(stack) + .sType$Default() + .pNext(VkExportSemaphoreCreateInfo.calloc(stack) + .sType$Default() + .handleTypes(EXTERNAL_SEMAPHORE_TYPE)), + null, res)); + long semaphore = res.get(0); + + IntBuffer fd = stack.callocInt(1); + _CHECK_(vkGetSemaphoreFdKHR(device, + VkSemaphoreGetFdInfoKHR.calloc(stack) + .sType$Default() + .semaphore(semaphore) + .handleType(EXTERNAL_SEMAPHORE_TYPE), + fd)); + + if (fd.get(0)== 0) { + throw new IllegalStateException(); + } + HandleDescriptorManger.add(fd.get(0)); + + int glSemaphore = glGenSemaphoresEXT(); + glImportSemaphoreFdEXT(glSemaphore, GL_HANDLE_TYPE_OPAQUE_FD_EXT, fd.get(0)); + if (!glIsSemaphoreEXT(glSemaphore)) + throw new IllegalStateException(); + if (glGetError() != GL_NO_ERROR) + throw new IllegalStateException(); + + return new VGSemaphore(device, semaphore, glSemaphore, fd.get(0)); } } + public VGSemaphore createSharedBinarySemaphore() { + return Vulkanite.IS_WINDOWS?createSharedBinarySemaphoreWin32():createSharedBinarySemaphoreFd(); + } + public VSemaphore createBinarySemaphore() { try (var stack = stackPush()) { LongBuffer res = stack.callocLong(1); diff --git a/src/main/java/me/cortex/vulkanite/lib/other/sync/VGSemaphore.java b/src/main/java/me/cortex/vulkanite/lib/other/sync/VGSemaphore.java index 20298cb..421398a 100644 --- a/src/main/java/me/cortex/vulkanite/lib/other/sync/VGSemaphore.java +++ b/src/main/java/me/cortex/vulkanite/lib/other/sync/VGSemaphore.java @@ -1,19 +1,24 @@ package me.cortex.vulkanite.lib.other.sync; +import me.cortex.vulkanite.lib.memory.HandleDescriptorManger; +import me.cortex.vulkanite.lib.memory.MemoryManager; import org.lwjgl.vulkan.VkDevice; import static org.lwjgl.opengl.EXTSemaphore.*; public class VGSemaphore extends VSemaphore { public final int glSemaphore; + private final long handleDescriptor; - public VGSemaphore(VkDevice device, long semaphore, int glSemaphore) { + public VGSemaphore(VkDevice device, long semaphore, int glSemaphore, long handleDescriptor) { super(device, semaphore); this.glSemaphore = glSemaphore; + this.handleDescriptor = handleDescriptor; } @Override public void free() { + HandleDescriptorManger.close(handleDescriptor); glDeleteSemaphoresEXT(glSemaphore); super.free(); } diff --git a/src/main/java/me/cortex/vulkanite/lib/pipeline/ComputePipelineBuilder.java b/src/main/java/me/cortex/vulkanite/lib/pipeline/ComputePipelineBuilder.java index b4b4a59..c511109 100644 --- a/src/main/java/me/cortex/vulkanite/lib/pipeline/ComputePipelineBuilder.java +++ b/src/main/java/me/cortex/vulkanite/lib/pipeline/ComputePipelineBuilder.java @@ -2,6 +2,7 @@ import me.cortex.vulkanite.lib.base.VContext; import me.cortex.vulkanite.lib.descriptors.VDescriptorSetLayout; +import me.cortex.vulkanite.lib.shader.ShaderModule; import org.lwjgl.vulkan.*; import java.nio.LongBuffer; diff --git a/src/main/java/me/cortex/vulkanite/lib/pipeline/RaytracePipelineBuilder.java b/src/main/java/me/cortex/vulkanite/lib/pipeline/RaytracePipelineBuilder.java index 4af7c4f..5c51b8c 100644 --- a/src/main/java/me/cortex/vulkanite/lib/pipeline/RaytracePipelineBuilder.java +++ b/src/main/java/me/cortex/vulkanite/lib/pipeline/RaytracePipelineBuilder.java @@ -3,6 +3,7 @@ import me.cortex.vulkanite.lib.base.VContext; import me.cortex.vulkanite.lib.descriptors.VDescriptorSetLayout; import me.cortex.vulkanite.lib.memory.VBuffer; +import me.cortex.vulkanite.lib.shader.ShaderModule; import org.lwjgl.system.MemoryUtil; import org.lwjgl.vulkan.*; @@ -143,9 +144,6 @@ public VRaytracePipeline build(VContext context, int maxDepth) { long groupBaseAlignment = props.shaderGroupBaseAlignment(); long handleSize = props.shaderGroupHandleSize(); long handleSizeAligned = alignUp(handleSize, props.shaderGroupHandleAlignment()); - if (handleSizeAligned != handleSize) { - throw new IllegalStateException("Painpoint, handleSizeAligned != handleSize"); - } int totalGroups = groupsArr.capacity(); @@ -157,7 +155,8 @@ public VRaytracePipeline build(VContext context, int maxDepth) { long callGroupBase = alignUp(hitGroupsBase + handleSizeAligned * hitGroupsCount, groupBaseAlignment); long callGroupCount = callGroups.size(); - long sbtSize = alignUp(callGroupBase + callGroupCount * handleSizeAligned, groupBaseAlignment); + // Pad an extra handle size at the end, so that even if we don't have call groups, the address is still in bounds + long sbtSize = alignUp(callGroupBase + callGroupCount * handleSizeAligned + handleSizeAligned, groupBaseAlignment); ByteBuffer handles = stack.malloc(totalGroups * (int)handleSize); _CHECK_(vkGetRayTracingShaderGroupHandlesKHR(context.device, pPipeline.get(0), 0, totalGroups, handles), @@ -166,27 +165,33 @@ public VRaytracePipeline build(VContext context, int maxDepth) { long aHandles = MemoryUtil.memAddress(handles); //TODO/FIXME: add alignment to gpu buffer - VBuffer sbtMap = context.memory.createBufferGlobal(sbtSize, + VBuffer sbtMap = context.memory.createBuffer(sbtSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR, VK_MEMORY_HEAP_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, - VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); + 0, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); long ptr = sbtMap.map(); // Groups in order of RayGen, Miss Groups, Hit Groups, and callable // 1. Copy ray gen - memCopy(aHandles, ptr + rgenBase, handleSize);//TODO: FIXME: FINISH + memCopy(aHandles, ptr + rgenBase, handleSize); aHandles += handleSize; // 2. Copy miss groups - memCopy(aHandles, ptr + missGroupBase, handleSize * missGroupCount); - aHandles += handleSize * missGroupCount; + for (int i = 0; i < missGroupCount; i++) { + memCopy(aHandles, ptr + missGroupBase + handleSizeAligned * i, handleSize); + aHandles += handleSize; + } // 3. Copy hit groups - memCopy(aHandles, ptr + hitGroupsBase, handleSize); - aHandles += handleSize * hitGroupsCount; + for (int i = 0; i < hitGroupsCount; i++) { + memCopy(aHandles, ptr + hitGroupsBase + handleSizeAligned * i, handleSize); + aHandles += handleSize; + } // 4. Copy callable - memCopy(aHandles, ptr + callGroupBase, handleSize); - aHandles += handleSize * missGroupCount; + for (int i = 0; i < callGroupCount; i++) { + memCopy(aHandles, ptr + callGroupBase + handleSizeAligned * i, handleSize); + aHandles += handleSize; + } sbtMap.unmap(); sbtMap.flush(); diff --git a/src/main/java/me/cortex/vulkanite/lib/pipeline/VRaytracePipeline.java b/src/main/java/me/cortex/vulkanite/lib/pipeline/VRaytracePipeline.java index 2ea9d27..fd74b4b 100644 --- a/src/main/java/me/cortex/vulkanite/lib/pipeline/VRaytracePipeline.java +++ b/src/main/java/me/cortex/vulkanite/lib/pipeline/VRaytracePipeline.java @@ -4,10 +4,9 @@ import me.cortex.vulkanite.lib.base.VContext; import me.cortex.vulkanite.lib.cmd.VCmdBuff; import me.cortex.vulkanite.lib.memory.VBuffer; -import me.cortex.vulkanite.lib.other.sync.VFence; +import me.cortex.vulkanite.lib.shader.ShaderModule; import org.lwjgl.vulkan.VkStridedDeviceAddressRegionKHR; -import java.util.List; import java.util.Set; import static org.lwjgl.vulkan.KHRRayTracingPipeline.VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR; @@ -18,7 +17,7 @@ public class VRaytracePipeline extends TrackedResourceObject { private final VContext context; private final long pipeline; private final long layout; - private final VBuffer stbMap; + private final VBuffer shader_binding_table; private final VkStridedDeviceAddressRegionKHR gen; private final VkStridedDeviceAddressRegionKHR miss; private final VkStridedDeviceAddressRegionKHR hit; @@ -35,7 +34,7 @@ public class VRaytracePipeline extends TrackedResourceObject { this.context = context; this.pipeline = pipeline; this.layout = layout; - this.stbMap = sbtMap; + this.shader_binding_table = sbtMap; this.gen = raygen; this.miss = miss; this.hit = hit; @@ -58,7 +57,7 @@ public void bindDSet(VCmdBuff cmd, long... descs) { public void free() { free0(); vkDestroyPipeline(context.device, pipeline, null); - stbMap.free(); + shader_binding_table.free(); gen.free(); miss.free(); hit.free(); diff --git a/src/main/java/me/cortex/vulkanite/lib/pipeline/VShader.java b/src/main/java/me/cortex/vulkanite/lib/shader/ShaderCompiler.java similarity index 63% rename from src/main/java/me/cortex/vulkanite/lib/pipeline/VShader.java rename to src/main/java/me/cortex/vulkanite/lib/shader/ShaderCompiler.java index 5ee62a4..a819639 100644 --- a/src/main/java/me/cortex/vulkanite/lib/pipeline/VShader.java +++ b/src/main/java/me/cortex/vulkanite/lib/shader/ShaderCompiler.java @@ -1,38 +1,15 @@ -package me.cortex.vulkanite.lib.pipeline; +package me.cortex.vulkanite.lib.shader; -import me.cortex.vulkanite.lib.base.TrackedResourceObject; -import me.cortex.vulkanite.lib.base.VContext; -import org.lwjgl.system.MemoryUtil; -import org.lwjgl.vulkan.VkShaderModuleCreateInfo; +import me.cortex.vulkanite.lib.shader.reflection.ShaderReflection; import java.nio.ByteBuffer; -import java.nio.LongBuffer; -import static me.cortex.vulkanite.lib.other.VUtil._CHECK_; -import static org.lwjgl.system.MemoryStack.stackPush; import static org.lwjgl.util.shaderc.Shaderc.*; +import static org.lwjgl.util.shaderc.Shaderc.shaderc_result_release; import static org.lwjgl.vulkan.KHRRayTracingPipeline.*; import static org.lwjgl.vulkan.VK10.*; -public class VShader extends TrackedResourceObject { - private final VContext ctx; - public final long module; - public final int stage; - - public VShader(VContext ctx, long module, int stage) { - this.ctx = ctx; - this.module = module; - this.stage = stage; - } - - public ShaderModule named() { - return named("main"); - } - - public ShaderModule named(String name) { - return new ShaderModule(this, name); - } - +public class ShaderCompiler { private static int vulkanStageToShadercKind(int stage) { switch (stage) { case VK_SHADER_STAGE_VERTEX_BIT: @@ -83,23 +60,4 @@ public static ByteBuffer compileShader(String filename, String source, int vulka shaderc_result_release(result); return ret; } - - public static VShader compileLoad(VContext ctx, String source, int stage) { - try (var stack = stackPush()) { - ByteBuffer code = compileShader("shader", source, stage); - - VkShaderModuleCreateInfo createInfo = VkShaderModuleCreateInfo.calloc(stack) - .sType$Default() - .pCode(code); - LongBuffer pShaderModule = stack.mallocLong(1); - _CHECK_(vkCreateShaderModule(ctx.device, createInfo, null, pShaderModule)); - return new VShader(ctx, pShaderModule.get(0), stage); - } - } - - @Override - public void free() { - free0(); - vkDestroyShaderModule(ctx.device, module, null); - } } diff --git a/src/main/java/me/cortex/vulkanite/lib/pipeline/ShaderModule.java b/src/main/java/me/cortex/vulkanite/lib/shader/ShaderModule.java similarity index 56% rename from src/main/java/me/cortex/vulkanite/lib/pipeline/ShaderModule.java rename to src/main/java/me/cortex/vulkanite/lib/shader/ShaderModule.java index 5a20718..7b70788 100644 --- a/src/main/java/me/cortex/vulkanite/lib/pipeline/ShaderModule.java +++ b/src/main/java/me/cortex/vulkanite/lib/shader/ShaderModule.java @@ -1,10 +1,11 @@ -package me.cortex.vulkanite.lib.pipeline; +package me.cortex.vulkanite.lib.shader; import org.lwjgl.system.MemoryStack; import org.lwjgl.vulkan.VkPipelineShaderStageCreateInfo; -public record ShaderModule(VShader shader, String name) { - void setupStruct(MemoryStack stack, VkPipelineShaderStageCreateInfo struct) { +public record ShaderModule( + VShader shader, String name) { + public void setupStruct(MemoryStack stack, VkPipelineShaderStageCreateInfo struct) { struct.sType$Default() .stage(shader.stage) .module(shader.module) diff --git a/src/main/java/me/cortex/vulkanite/lib/shader/VShader.java b/src/main/java/me/cortex/vulkanite/lib/shader/VShader.java new file mode 100644 index 0000000..524a728 --- /dev/null +++ b/src/main/java/me/cortex/vulkanite/lib/shader/VShader.java @@ -0,0 +1,53 @@ +package me.cortex.vulkanite.lib.shader; + +import me.cortex.vulkanite.lib.base.TrackedResourceObject; +import me.cortex.vulkanite.lib.base.VContext; +import org.lwjgl.vulkan.VkShaderModuleCreateInfo; + +import java.nio.ByteBuffer; +import java.nio.LongBuffer; + +import static me.cortex.vulkanite.lib.other.VUtil._CHECK_; +import static org.lwjgl.system.MemoryStack.stackPush; +import static org.lwjgl.util.shaderc.Shaderc.*; +import static org.lwjgl.vulkan.KHRRayTracingPipeline.*; +import static org.lwjgl.vulkan.VK10.*; + +public class VShader extends TrackedResourceObject { + private final VContext ctx; + public final long module; + public final int stage; + + public VShader(VContext ctx, long module, int stage) { + this.ctx = ctx; + this.module = module; + this.stage = stage; + } + + public ShaderModule named() { + return named("main"); + } + + public ShaderModule named(String name) { + return new ShaderModule(this, name); + } + + public static VShader compileLoad(VContext ctx, String source, int stage) { + try (var stack = stackPush()) { + ByteBuffer code = ShaderCompiler.compileShader("shader", source, stage); + + VkShaderModuleCreateInfo createInfo = VkShaderModuleCreateInfo.calloc(stack) + .sType$Default() + .pCode(code); + LongBuffer pShaderModule = stack.mallocLong(1); + _CHECK_(vkCreateShaderModule(ctx.device, createInfo, null, pShaderModule)); + return new VShader(ctx, pShaderModule.get(0), stage); + } + } + + @Override + public void free() { + free0(); + vkDestroyShaderModule(ctx.device, module, null); + } +} diff --git a/src/main/java/me/cortex/vulkanite/lib/shader/reflection/ResourceType.java b/src/main/java/me/cortex/vulkanite/lib/shader/reflection/ResourceType.java new file mode 100644 index 0000000..c02bd30 --- /dev/null +++ b/src/main/java/me/cortex/vulkanite/lib/shader/reflection/ResourceType.java @@ -0,0 +1,23 @@ +package me.cortex.vulkanite.lib.shader.reflection; + +import static org.lwjgl.util.spvc.Spvc.*; + +public enum ResourceType { + UNIFORM_BUFFER(SPVC_RESOURCE_TYPE_UNIFORM_BUFFER), + STORAGE_BUFFER(SPVC_RESOURCE_TYPE_STORAGE_BUFFER), + STAGE_INPUT(SPVC_RESOURCE_TYPE_STAGE_INPUT), + STAGE_OUTPUT(SPVC_RESOURCE_TYPE_STAGE_OUTPUT), + SUBPASS_INPUT(SPVC_RESOURCE_TYPE_SUBPASS_INPUT), + STORAGE_IMAGE(SPVC_RESOURCE_TYPE_STORAGE_IMAGE), + SAMPLED_IMAGE(SPVC_RESOURCE_TYPE_SAMPLED_IMAGE), + ATOMIC_COUNTER(SPVC_RESOURCE_TYPE_ATOMIC_COUNTER), + PUSH_CONSTANT(SPVC_RESOURCE_TYPE_PUSH_CONSTANT), + SEPARATE_IMAGE(SPVC_RESOURCE_TYPE_SEPARATE_IMAGE), + SEPARATE_SAMPLERS(SPVC_RESOURCE_TYPE_SEPARATE_SAMPLERS), + ACCELERATION_STRUCTURE(SPVC_RESOURCE_TYPE_ACCELERATION_STRUCTURE); + public final int id; + + ResourceType(int id) { + this.id = id; + } +} diff --git a/src/main/java/me/cortex/vulkanite/lib/shader/reflection/ShaderReflection.java b/src/main/java/me/cortex/vulkanite/lib/shader/reflection/ShaderReflection.java new file mode 100644 index 0000000..e1ff028 --- /dev/null +++ b/src/main/java/me/cortex/vulkanite/lib/shader/reflection/ShaderReflection.java @@ -0,0 +1,51 @@ +package me.cortex.vulkanite.lib.shader.reflection; + +import org.lwjgl.util.spvc.SpvcReflectedResource; + +import java.nio.ByteBuffer; + +import static org.lwjgl.system.MemoryStack.stackPush; +import static org.lwjgl.util.spvc.Spv.SpvDecorationBinding; +import static org.lwjgl.util.spvc.Spvc.*; + +public class ShaderReflection { + public ShaderReflection(ByteBuffer spirv) { + try (var stack = stackPush()) { + //Create context + var ptr = stack.mallocPointer(1); + var ptr2 = stack.mallocPointer(1); + _CHECK_(spvc_context_create(ptr)); + long context = ptr.get(0); + + //Parse the spir-v + _CHECK_(spvc_context_parse_spirv(context, spirv.asIntBuffer(), spirv.remaining()>>2, ptr)); + long ir = ptr.get(0); + + // Hand it off to a compiler instance and give it ownership of the IR. + _CHECK_(spvc_context_create_compiler(context, SPVC_BACKEND_NONE, ir, SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, ptr)); + long compiler = ptr.get(0); + + // Create resources from spir-v + _CHECK_(spvc_compiler_create_shader_resources(compiler, ptr)); + long resources = ptr.get(0); + + //Get reflection data + for (var type : ResourceType.values()) { + _CHECK_(spvc_resources_get_resource_list_for_type(resources, type.id, ptr, ptr2)); + var reflectedResources = SpvcReflectedResource.create(ptr.get(0), (int) ptr2.get(0)); + for (var reflect : reflectedResources) { + System.err.println(type.name()+" -> "+reflect.nameString() + " @ " + spvc_compiler_get_decoration(compiler, reflect.id(), SpvDecorationBinding)); + } + } + System.err.println(""); + //Destroy everything + spvc_context_destroy(context); + } + } + + private static void _CHECK_(int status) { + if (status != 0) { + throw new IllegalStateException("Got status: " + status); + } + } +} diff --git a/src/main/java/me/cortex/vulkanite/mixin/iris/MixinPackRenderTargetDirectives.java b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinPackRenderTargetDirectives.java new file mode 100644 index 0000000..81608b4 --- /dev/null +++ b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinPackRenderTargetDirectives.java @@ -0,0 +1,21 @@ +package me.cortex.vulkanite.mixin.iris; + +import com.google.common.collect.ImmutableSet; +import net.coderbot.iris.shaderpack.PackRenderTargetDirectives; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.util.Set; + +@Mixin(value = PackRenderTargetDirectives.class, remap = false) +public class MixinPackRenderTargetDirectives { + @Redirect(method = "", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/ImmutableSet$Builder;build()Lcom/google/common/collect/ImmutableSet;")) + private static ImmutableSet redirectBuild(ImmutableSet.Builder instance) { + ImmutableSet.Builder fake = new ImmutableSet.Builder<>(); + for (int i = 0; i < 10; i++) { + fake.add(i); + } + return fake.build(); + } +} diff --git a/src/main/java/me/cortex/vulkanite/mixin/iris/MixinStandardMacros.java b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinStandardMacros.java new file mode 100644 index 0000000..4b51cd1 --- /dev/null +++ b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinStandardMacros.java @@ -0,0 +1,19 @@ +package me.cortex.vulkanite.mixin.iris; + +import net.coderbot.iris.gl.shader.StandardMacros; +import net.coderbot.iris.shaderpack.StringPair; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import java.util.ArrayList; + +@Mixin(value = StandardMacros.class, remap = false) +public class MixinStandardMacros { + @Inject(method = "createStandardEnvironmentDefines", at = @At(value = "INVOKE", target = "Lnet/coderbot/iris/gl/shader/StandardMacros;define(Ljava/util/List;Ljava/lang/String;)V", ordinal = 0), locals = LocalCapture.CAPTURE_FAILHARD) + private static void injectVulkaniteDefine(CallbackInfoReturnable> cir, ArrayList defines) { + defines.add(new StringPair("VULKANITE", " ")); + } +} diff --git a/src/main/java/me/cortex/vulkanite/mixin/sodium/MixinRenderRegionManager.java b/src/main/java/me/cortex/vulkanite/mixin/sodium/MixinRenderRegionManager.java index 6b17c3e..4584301 100644 --- a/src/main/java/me/cortex/vulkanite/mixin/sodium/MixinRenderRegionManager.java +++ b/src/main/java/me/cortex/vulkanite/mixin/sodium/MixinRenderRegionManager.java @@ -1,8 +1,53 @@ package me.cortex.vulkanite.mixin.sodium; +import me.cortex.vulkanite.client.Vulkanite; +import me.jellysquid.mods.sodium.client.gl.arena.GlBufferArena; +import me.jellysquid.mods.sodium.client.gl.device.CommandList; +import me.jellysquid.mods.sodium.client.render.chunk.RenderSection; +import me.jellysquid.mods.sodium.client.render.chunk.compile.ChunkBuildOutput; +import me.jellysquid.mods.sodium.client.render.chunk.region.RenderRegion; import me.jellysquid.mods.sodium.client.render.chunk.region.RenderRegionManager; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; -@Mixin(RenderRegionManager.class) +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +//The process needs to go like this +//(This is for if a chunk mesh already exists) +//Make a copy of the old chunk mesh +// set that as the primary reference pointer +//Once the chunk update blas job is built and processed +// destroy the old pointer +@Mixin(value = RenderRegionManager.class, remap = false) public class MixinRenderRegionManager { + @Inject(method = "uploadMeshes(Lme/jellysquid/mods/sodium/client/gl/device/CommandList;Lme/jellysquid/mods/sodium/client/render/chunk/region/RenderRegion;Ljava/util/Collection;)V", + at = @At(value = "INVOKE", target = "Lme/jellysquid/mods/sodium/client/gl/arena/GlBufferArena;upload(Lme/jellysquid/mods/sodium/client/gl/device/CommandList;Ljava/util/stream/Stream;)Z", + shift = At.Shift.AFTER), locals = LocalCapture.CAPTURE_FAILHARD) + private void afterUpload(CommandList commandList, RenderRegion region, Collection results, CallbackInfo ci, ArrayList uploads, RenderRegion.DeviceResources resources, GlBufferArena arena) { + for (var res : results) { + //((IRenderSectionExtension)(res.render)).setArena(region.getResources().getGeometryArena()); + //((IRenderSectionExtension)(res.render)).getAllocations().clear(); + } + + for (PendingSectionUploadAccessor uploadObj : uploads) { + //((IRenderSectionExtension)(uploadObj.getSection())).getAllocations().add(uploadObj.getVertexUpload().getResult()); + } + } + + @Inject(method = "uploadMeshes(Lme/jellysquid/mods/sodium/client/gl/device/CommandList;Lme/jellysquid/mods/sodium/client/render/chunk/region/RenderRegion;Ljava/util/Collection;)V", + at = @At(value = "INVOKE", target = "Lme/jellysquid/mods/sodium/client/render/chunk/region/RenderRegion;refresh(Lme/jellysquid/mods/sodium/client/gl/device/CommandList;)V", + shift = At.Shift.AFTER)) + private void arenaBufferChanged(CommandList commandList, RenderRegion region, Collection results, CallbackInfo ci) { + List sectionsInRegion = new ArrayList<>(); + for (int id = 0; id < 256; id++) { + if (region.getSection(id) != null) { + sectionsInRegion.add(region.getSection(id)); + } + } + } } diff --git a/src/main/java/me/cortex/vulkanite/mixin/sodium/PendingSectionUploadAccessor.java b/src/main/java/me/cortex/vulkanite/mixin/sodium/PendingSectionUploadAccessor.java new file mode 100644 index 0000000..786322d --- /dev/null +++ b/src/main/java/me/cortex/vulkanite/mixin/sodium/PendingSectionUploadAccessor.java @@ -0,0 +1,19 @@ +package me.cortex.vulkanite.mixin.sodium; + +import me.jellysquid.mods.sodium.client.gl.arena.PendingUpload; +import me.jellysquid.mods.sodium.client.render.chunk.RenderSection; +import me.jellysquid.mods.sodium.client.render.chunk.data.BuiltSectionMeshParts; +import me.jellysquid.mods.sodium.client.render.chunk.region.RenderRegionManager; +import me.jellysquid.mods.sodium.client.render.chunk.terrain.TerrainRenderPass; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(targets = {"me.jellysquid.mods.sodium.client.render.chunk.region.RenderRegionManager$PendingSectionUpload"}, remap = false) +public interface PendingSectionUploadAccessor { + @Accessor + RenderSection getSection(); + @Accessor + TerrainRenderPass getPass(); + @Accessor + PendingUpload getVertexUpload(); +} diff --git a/src/main/java/me/cortex/vulkanite/mixin/sodium/MixinChunkBuildResult.java b/src/main/java/me/cortex/vulkanite/mixin/sodium/chunk/MixinChunkBuildResult.java similarity index 96% rename from src/main/java/me/cortex/vulkanite/mixin/sodium/MixinChunkBuildResult.java rename to src/main/java/me/cortex/vulkanite/mixin/sodium/chunk/MixinChunkBuildResult.java index ed547db..8fb8d21 100644 --- a/src/main/java/me/cortex/vulkanite/mixin/sodium/MixinChunkBuildResult.java +++ b/src/main/java/me/cortex/vulkanite/mixin/sodium/chunk/MixinChunkBuildResult.java @@ -1,4 +1,4 @@ -package me.cortex.vulkanite.mixin.sodium; +package me.cortex.vulkanite.mixin.sodium.chunk; import me.cortex.vulkanite.compat.GeometryData; import me.cortex.vulkanite.compat.IAccelerationBuildResult; diff --git a/src/main/java/me/cortex/vulkanite/mixin/sodium/MixinChunkRenderRebuildTask.java b/src/main/java/me/cortex/vulkanite/mixin/sodium/chunk/MixinChunkRenderRebuildTask.java similarity index 94% rename from src/main/java/me/cortex/vulkanite/mixin/sodium/MixinChunkRenderRebuildTask.java rename to src/main/java/me/cortex/vulkanite/mixin/sodium/chunk/MixinChunkRenderRebuildTask.java index 715de92..ce4ebce 100644 --- a/src/main/java/me/cortex/vulkanite/mixin/sodium/MixinChunkRenderRebuildTask.java +++ b/src/main/java/me/cortex/vulkanite/mixin/sodium/chunk/MixinChunkRenderRebuildTask.java @@ -1,6 +1,5 @@ -package me.cortex.vulkanite.mixin.sodium; +package me.cortex.vulkanite.mixin.sodium.chunk; -import me.cortex.vulkanite.client.Vulkanite; import me.cortex.vulkanite.compat.IAccelerationBuildResult; import me.cortex.vulkanite.compat.SodiumResultAdapter; import me.jellysquid.mods.sodium.client.render.chunk.compile.ChunkBuildContext; diff --git a/src/main/java/me/cortex/vulkanite/mixin/sodium/VertexFormatAccessor.java b/src/main/java/me/cortex/vulkanite/mixin/sodium/chunk/VertexFormatAccessor.java similarity index 89% rename from src/main/java/me/cortex/vulkanite/mixin/sodium/VertexFormatAccessor.java rename to src/main/java/me/cortex/vulkanite/mixin/sodium/chunk/VertexFormatAccessor.java index 46b13e5..01f6dca 100644 --- a/src/main/java/me/cortex/vulkanite/mixin/sodium/VertexFormatAccessor.java +++ b/src/main/java/me/cortex/vulkanite/mixin/sodium/chunk/VertexFormatAccessor.java @@ -1,4 +1,4 @@ -package me.cortex.vulkanite.mixin.sodium; +package me.cortex.vulkanite.mixin.sodium.chunk; import me.jellysquid.mods.sodium.client.render.chunk.compile.ChunkBuildBuffers; import me.jellysquid.mods.sodium.client.render.chunk.vertex.format.ChunkVertexType; diff --git a/src/main/java/me/cortex/vulkanite/mixin/sodium/MixinCommandList.java b/src/main/java/me/cortex/vulkanite/mixin/sodium/gl/MixinCommandList.java similarity index 90% rename from src/main/java/me/cortex/vulkanite/mixin/sodium/MixinCommandList.java rename to src/main/java/me/cortex/vulkanite/mixin/sodium/gl/MixinCommandList.java index 7818f5f..28618de 100644 --- a/src/main/java/me/cortex/vulkanite/mixin/sodium/MixinCommandList.java +++ b/src/main/java/me/cortex/vulkanite/mixin/sodium/gl/MixinCommandList.java @@ -1,4 +1,4 @@ -package me.cortex.vulkanite.mixin.sodium; +package me.cortex.vulkanite.mixin.sodium.gl; import me.cortex.vulkanite.client.Vulkanite; import me.cortex.vulkanite.compat.IVulkanContextGetter; diff --git a/src/main/java/me/cortex/vulkanite/mixin/sodium/MixinGLRenderDevice.java b/src/main/java/me/cortex/vulkanite/mixin/sodium/gl/MixinGLRenderDevice.java similarity index 95% rename from src/main/java/me/cortex/vulkanite/mixin/sodium/MixinGLRenderDevice.java rename to src/main/java/me/cortex/vulkanite/mixin/sodium/gl/MixinGLRenderDevice.java index 321b04b..7f4e8b7 100644 --- a/src/main/java/me/cortex/vulkanite/mixin/sodium/MixinGLRenderDevice.java +++ b/src/main/java/me/cortex/vulkanite/mixin/sodium/gl/MixinGLRenderDevice.java @@ -1,4 +1,4 @@ -package me.cortex.vulkanite.mixin.sodium; +package me.cortex.vulkanite.mixin.sodium.gl; import me.cortex.vulkanite.client.Vulkanite; import me.cortex.vulkanite.compat.IVkBuffer; diff --git a/src/main/java/me/cortex/vulkanite/mixin/sodium/MixinGlBufferArena.java b/src/main/java/me/cortex/vulkanite/mixin/sodium/gl/MixinGlBufferArena.java similarity index 90% rename from src/main/java/me/cortex/vulkanite/mixin/sodium/MixinGlBufferArena.java rename to src/main/java/me/cortex/vulkanite/mixin/sodium/gl/MixinGlBufferArena.java index f02f44a..819a3eb 100644 --- a/src/main/java/me/cortex/vulkanite/mixin/sodium/MixinGlBufferArena.java +++ b/src/main/java/me/cortex/vulkanite/mixin/sodium/gl/MixinGlBufferArena.java @@ -1,4 +1,4 @@ -package me.cortex.vulkanite.mixin.sodium; +package me.cortex.vulkanite.mixin.sodium.gl; import me.cortex.vulkanite.compat.IVulkanContextGetter; import me.cortex.vulkanite.compat.IVkBuffer; @@ -9,6 +9,7 @@ import me.jellysquid.mods.sodium.client.gl.buffer.GlMutableBuffer; import me.jellysquid.mods.sodium.client.gl.device.CommandList; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @@ -18,8 +19,9 @@ @Mixin(value = GlBufferArena.class, remap = false) public class MixinGlBufferArena { + @Unique private VGBuffer createBuffer(VContext ctx, long size) { - return ctx.memory.createSharedBuffer(size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + return ctx.memory.createSharedBuffer(size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); } @Redirect(method = "", at = @At(value = "INVOKE", target = "Lme/jellysquid/mods/sodium/client/gl/device/CommandList;allocateStorage(Lme/jellysquid/mods/sodium/client/gl/buffer/GlMutableBuffer;JLme/jellysquid/mods/sodium/client/gl/buffer/GlBufferUsage;)V")) diff --git a/src/main/java/me/cortex/vulkanite/mixin/sodium/MixinMutableBuffer.java b/src/main/java/me/cortex/vulkanite/mixin/sodium/gl/MixinMutableBuffer.java similarity index 95% rename from src/main/java/me/cortex/vulkanite/mixin/sodium/MixinMutableBuffer.java rename to src/main/java/me/cortex/vulkanite/mixin/sodium/gl/MixinMutableBuffer.java index 9b77cb4..2f9ec4f 100644 --- a/src/main/java/me/cortex/vulkanite/mixin/sodium/MixinMutableBuffer.java +++ b/src/main/java/me/cortex/vulkanite/mixin/sodium/gl/MixinMutableBuffer.java @@ -1,4 +1,4 @@ -package me.cortex.vulkanite.mixin.sodium; +package me.cortex.vulkanite.mixin.sodium.gl; import me.cortex.vulkanite.compat.IVkBuffer; import me.cortex.vulkanite.lib.memory.VGBuffer; diff --git a/src/main/resources/vulkanite.mixins.json b/src/main/resources/vulkanite.mixins.json index cee23e1..7849a2a 100644 --- a/src/main/resources/vulkanite.mixins.json +++ b/src/main/resources/vulkanite.mixins.json @@ -8,19 +8,23 @@ "iris.MixinPBRAtlasTexture", "iris.MixinProgramSet", "iris.MixinRenderTarget", + "iris.MixinPackRenderTargetDirectives", + "iris.MixinStandardMacros", "iris.MixinShaderPackSourceNames", "minecraft.MixinAbstractTexture", "minecraft.MixinMinecraftClient", "minecraft.MixinSpriteAtlasTexture", - "sodium.MixinChunkBuildResult", - "sodium.MixinChunkRenderRebuildTask", - "sodium.MixinCommandList", - "sodium.MixinGLRenderDevice", - "sodium.MixinMutableBuffer", "sodium.MixinRenderRegionManager", "sodium.MixinRenderSection", "sodium.MixinRenderSectionManager", - "sodium.VertexFormatAccessor" + "sodium.chunk.MixinChunkBuildResult", + "sodium.chunk.MixinChunkRenderRebuildTask", + "sodium.chunk.VertexFormatAccessor", + "sodium.gl.MixinCommandList", + "sodium.gl.MixinGlBufferArena", + "sodium.gl.MixinGLRenderDevice", + "sodium.gl.MixinMutableBuffer", + "sodium.PendingSectionUploadAccessor" ], "injectors": { "defaultRequire": 1