metadata calculation on c side of fluidsim
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-11-30 19:52:10 -05:00
parent f2fc2d2dc4
commit 03d583ee85
10 changed files with 142 additions and 34 deletions

View File

@ -15,6 +15,8 @@
"simulation.h": "c",
"chunk.h": "c",
"chunkmask.h": "c",
"metadatacalc.h": "c"
"metadatacalc.h": "c",
"immintrin.h": "c",
"stdint.h": "c"
}
}

View File

@ -1,3 +1,3 @@
#maven.buildNumber.plugin properties file
#Sat Nov 30 19:02:40 EST 2024
buildNumber=435
#Sat Nov 30 19:48:02 EST 2024
buildNumber=441

View File

@ -1,6 +1,8 @@
#ifndef CHUNK_H
#define CHUNK_H
#include <jni.h>
/**
* A chunk
*/
@ -14,6 +16,9 @@ typedef struct {
float * v0[27];
float * w0[27];
int chunkMask;
jobject chunkJRaw;
} Chunk;
#define DIM 18
#endif

View File

@ -1,10 +1,45 @@
#ifndef ENVIRONMENT_H
#define ENVIRONMENT_H
/**
* The List lookup table
*/
typedef struct {
jmethodID jListSize;
jmethodID jListGet;
jmethodID jListAdd;
} ListLookupTable;
/**
* The ServerFluidChunk lookup table
*/
typedef struct {
jfieldID dJId;
jfieldID d0JId;
jfieldID uJId;
jfieldID vJId;
jfieldID wJId;
jfieldID u0JId;
jfieldID v0JId;
jfieldID w0JId;
jfieldID chunkmaskJId;
jfieldID updatedId;
jfieldID totalDensityId;
} ServerFluidChunkLookupTable;
/**
* Lookup table for various java fields, methods, etc
*/
typedef struct {
ListLookupTable listTable;
ServerFluidChunkLookupTable serverFluidChunkTable;
} JNILookupTable;
/**
* Stores data about the simulation environment
*/
typedef struct {
JNILookupTable lookupTable;
float gravity;
} Environment;

View File

@ -7,11 +7,12 @@
/**
* Updates the metadata for all chunks
* @param env The java environment variable
* @param numChunks The number of chunks
* @param passedInChunks The chunks that were passed in
* @param environment The environment data
*/
void updateMetadata(int numChunks, Chunk ** passedInChunks, Environment * environment);
void updateMetadata(JNIEnv * env, int numChunks, Chunk ** passedInChunks, Environment * environment);

View File

@ -25,14 +25,14 @@
//declarations
void readInChunks(JNIEnv * env, jobject chunkList);
void readInChunks(JNIEnv * env, jobject chunkList, Environment * environment);
int calculateChunkMask(JNIEnv * env, jobjectArray jrx);
uint32_t matrix_transform(JNIEnv * env, jobjectArray jrx);
//the list of chunks
Chunk ** javaChunkView = NULL;
Chunk ** chunkViewC = NULL;
//the number of chunks
int numChunks = 0;
@ -46,9 +46,9 @@ JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAccelerate
jobject chunkList,
jfloat dt
){
readInChunks(env,chunkList);
simulate(numChunks,javaChunkView,environment,dt);
updateMetadata(numChunks,javaChunkView,environment);
readInChunks(env,chunkList,environment);
simulate(numChunks,chunkViewC,environment,dt);
updateMetadata(env,numChunks,chunkViewC,environment);
}
/**
@ -60,14 +60,14 @@ JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAccelerate
){
//free the c view of the chunks
int storedChunks = stbds_arrlen(javaChunkView);
int storedChunks = stbds_arrlen(chunkViewC);
for(int i = 0; i < storedChunks; i++){
free(javaChunkView[i]);
free(chunkViewC[i]);
}
//free the dynamic array
stbds_arrfree(javaChunkView);
javaChunkView = NULL;
stbds_arrfree(chunkViewC);
chunkViewC = NULL;
numChunks = 0;
}
@ -79,33 +79,57 @@ JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAccelerate
jclass fluidSimClass,
jfloat gravity
){
//allocate if unallocated
if(environment == NULL){
environment = (Environment *)malloc(sizeof(Environment));
}
//store variables from java side
environment->gravity = gravity;
//store jni lookup tables
jclass listClass = (*env)->FindClass(env,"java/util/List");
jclass fluidSimStorageClass = (*env)->FindClass(env,"electrosphere/server/fluid/manager/ServerFluidChunk");
//JNIEnv *env, jclass clazz, const char *name, const char *sig
environment->lookupTable.listTable.jListSize = (*env)->GetMethodID(env, listClass, "size", "()I");
environment->lookupTable.listTable.jListGet = (*env)->GetMethodID(env, listClass, "get", "(I)Ljava/lang/Object;");
environment->lookupTable.listTable.jListAdd = (*env)->GetMethodID(env, listClass, "add", "(Ljava/lang/Object;)Z");
//ByteBuffer[]
environment->lookupTable.serverFluidChunkTable.dJId = (*env)->GetFieldID(env,fluidSimStorageClass,"bWeights","[Ljava/nio/ByteBuffer;");
environment->lookupTable.serverFluidChunkTable.d0JId = (*env)->GetFieldID(env,fluidSimStorageClass,"b0Weights","[Ljava/nio/ByteBuffer;");
environment->lookupTable.serverFluidChunkTable.uJId = (*env)->GetFieldID(env,fluidSimStorageClass,"bVelocityX","[Ljava/nio/ByteBuffer;");
environment->lookupTable.serverFluidChunkTable.vJId = (*env)->GetFieldID(env,fluidSimStorageClass,"bVelocityY","[Ljava/nio/ByteBuffer;");
environment->lookupTable.serverFluidChunkTable.wJId = (*env)->GetFieldID(env,fluidSimStorageClass,"bVelocityZ","[Ljava/nio/ByteBuffer;");
environment->lookupTable.serverFluidChunkTable.u0JId = (*env)->GetFieldID(env,fluidSimStorageClass,"b0VelocityX","[Ljava/nio/ByteBuffer;");
environment->lookupTable.serverFluidChunkTable.v0JId = (*env)->GetFieldID(env,fluidSimStorageClass,"b0VelocityY","[Ljava/nio/ByteBuffer;");
environment->lookupTable.serverFluidChunkTable.w0JId = (*env)->GetFieldID(env,fluidSimStorageClass,"b0VelocityZ","[Ljava/nio/ByteBuffer;");
environment->lookupTable.serverFluidChunkTable.chunkmaskJId = (*env)->GetFieldID(env,fluidSimStorageClass,"chunkMask","I");
environment->lookupTable.serverFluidChunkTable.totalDensityId = (*env)->GetFieldID(env,fluidSimStorageClass,"totalDensity","F");
environment->lookupTable.serverFluidChunkTable.updatedId = (*env)->GetFieldID(env,fluidSimStorageClass,"updated","Z");
}
/**
* Reads chunks into the dynamic array
*/
void readInChunks(JNIEnv * env, jobject chunkList){
void readInChunks(JNIEnv * env, jobject chunkList, Environment * environment){
jclass listClass = (*env)->FindClass(env,"java/util/List");
jclass fluidSimClass = (*env)->FindClass(env,"electrosphere/server/fluid/manager/ServerFluidChunk");
//JNIEnv *env, jclass clazz, const char *name, const char *sig
jmethodID jListSize = (*env)->GetMethodID(env, listClass, "size", "()I");
jmethodID jListGet = (*env)->GetMethodID(env, listClass, "get", "(I)Ljava/lang/Object;");
jmethodID jListAdd = (*env)->GetMethodID(env, listClass, "add", "(Ljava/lang/Object;)Z");
jmethodID jListSize = environment->lookupTable.listTable.jListSize;
jmethodID jListGet = environment->lookupTable.listTable.jListGet;
jmethodID jListAdd = environment->lookupTable.listTable.jListAdd;
//ByteBuffer[]
jfieldID dJId = (*env)->GetFieldID(env,fluidSimClass,"bWeights","[Ljava/nio/ByteBuffer;");
jfieldID d0JId = (*env)->GetFieldID(env,fluidSimClass,"b0Weights","[Ljava/nio/ByteBuffer;");
jfieldID uJId = (*env)->GetFieldID(env,fluidSimClass,"bVelocityX","[Ljava/nio/ByteBuffer;");
jfieldID vJId = (*env)->GetFieldID(env,fluidSimClass,"bVelocityY","[Ljava/nio/ByteBuffer;");
jfieldID wJId = (*env)->GetFieldID(env,fluidSimClass,"bVelocityZ","[Ljava/nio/ByteBuffer;");
jfieldID u0JId = (*env)->GetFieldID(env,fluidSimClass,"b0VelocityX","[Ljava/nio/ByteBuffer;");
jfieldID v0JId = (*env)->GetFieldID(env,fluidSimClass,"b0VelocityY","[Ljava/nio/ByteBuffer;");
jfieldID w0JId = (*env)->GetFieldID(env,fluidSimClass,"b0VelocityZ","[Ljava/nio/ByteBuffer;");
jfieldID chunkmaskJId = (*env)->GetFieldID(env,fluidSimClass,"chunkMask","I");
jfieldID dJId = environment->lookupTable.serverFluidChunkTable.dJId;
jfieldID d0JId = environment->lookupTable.serverFluidChunkTable.d0JId;
jfieldID uJId = environment->lookupTable.serverFluidChunkTable.uJId;
jfieldID vJId = environment->lookupTable.serverFluidChunkTable.vJId;
jfieldID wJId = environment->lookupTable.serverFluidChunkTable.wJId;
jfieldID u0JId = environment->lookupTable.serverFluidChunkTable.u0JId;
jfieldID v0JId = environment->lookupTable.serverFluidChunkTable.v0JId;
jfieldID w0JId = environment->lookupTable.serverFluidChunkTable.w0JId;
jfieldID chunkmaskJId = environment->lookupTable.serverFluidChunkTable.chunkmaskJId;
//the number of chunks
numChunks = (*env)->CallIntMethod(env,chunkList,jListSize);
@ -130,17 +154,17 @@ void readInChunks(JNIEnv * env, jobject chunkList){
(*env)->SetIntField(env,chunkJRaw,chunkmaskJId,chunkMask);
Chunk * newChunk;
if(i >= stbds_arrlen(javaChunkView)){
if(i >= stbds_arrlen(chunkViewC)){
// printf("allocate chunk %d\n",i);
// fflush(stdout);
newChunk = (Chunk *)malloc(sizeof(Chunk));
// printf("new chunk %p\n",newChunk);
// fflush(stdout);
stbds_arrput(javaChunkView,newChunk);
stbds_arrput(chunkViewC,newChunk);
// printf("new chunk %p\n",chunks[i]);
// fflush(stdout);
} else {
newChunk = javaChunkView[i];
newChunk = chunkViewC[i];
// printf("get chunk %d: %p\n",i,newChunk);
// fflush(stdout);
}
@ -153,6 +177,7 @@ void readInChunks(JNIEnv * env, jobject chunkList){
v0 = (*env)->GetObjectField(env,chunkJRaw,v0JId);
w0 = (*env)->GetObjectField(env,chunkJRaw,w0JId);
newChunk->chunkMask = chunkMask;
newChunk->chunkJRaw = chunkJRaw;
for(int j = 0; j < 27; j++){
if((chunkMask & CHUNK_INDEX_ARR[j]) > 0){
newChunk->d[j] = GET_ARR(env,jd,j);

View File

@ -1,18 +1,55 @@
#include <stdio.h>
#include <immintrin.h>
#include <stdint.h>
#include <math.h>
#include "../includes/utilities.h"
#include "../includes/chunkmask.h"
#include "../includes/metadatacalc.h"
#define UPDATE_THRESHOLD 0.1
/**
* Updates the metadata for all chunks
* @param env The java environment variable
* @param numChunks The number of chunks
* @param passedInChunks The chunks that were passed in
* @param environment The environment data
*/
void updateMetadata(int numChunks, Chunk ** passedInChunks, Environment * environment){
void updateMetadata(JNIEnv * env, int numChunks, Chunk ** passedInChunks, Environment * environment){
jfieldID totalDensityId = environment->lookupTable.serverFluidChunkTable.totalDensityId;
jfieldID updatedId = environment->lookupTable.serverFluidChunkTable.updatedId;
int N = DIM;
int i;
int x, y, z;
for(i = 0; i < numChunks; i++){
//get previous total density
Chunk * currentChunk = passedInChunks[i];
jobject jObj = currentChunk->chunkJRaw;
float prevDensity = (*env)->GetFloatField(env,jObj,totalDensityId);
//calculate new total density
//transform u direction
float sum = 0;
for(y=1; y<N-1; y++){
for(z=1; z<N-1; z++){
int n = 0;
//solve as much as possible vectorized
for(x = 1; x < N-1; x=x+8){
sum = sum + GET_ARR_RAW(currentChunk->d,CENTER_LOC)[IX(x,y,z)];
}
}
}
//update total density
if(fabs(sum - prevDensity) > UPDATE_THRESHOLD){
(*env)->SetBooleanField(env,jObj,updatedId,JNI_TRUE);
(*env)->SetFloatField(env,jObj,totalDensityId,sum);
} else {
(*env)->SetBooleanField(env,jObj,updatedId,JNI_FALSE);
}
}
}

View File

@ -4,6 +4,7 @@
#include "../includes/utilities.h"
#include "../includes/chunkmask.h"
#include "../includes/chunk.h"
#define BOUND_NO_DIR 0
@ -653,7 +654,6 @@ static inline void setBoundsToNeighborsRaw(
int vector_dir,
float ** neighborArray
){
int DIM = N;
float * target = GET_ARR_RAW(neighborArray,CENTER_LOC);
float * source;
//set the faces bounds
@ -709,7 +709,6 @@ static inline void copyNeighborsRaw(
int vector_dir,
float ** neighborArray
){
int DIM = N;
float * target = GET_ARR_RAW(neighborArray,CENTER_LOC);
float * source;

View File

@ -137,6 +137,11 @@ public class ServerFluidChunk {
*/
public boolean updated = false;
/**
* The total density of the chunk
*/
public float totalDensity = 0;
/**
* Constructor
* @param worldX The world x coordinate

View File

@ -280,7 +280,6 @@ public class ServerFluidManager {
*/
public void queue(int worldX, int worldY, int worldZ){
ServerFluidChunk fluidChunk = this.getChunk(worldX, worldY, worldZ);
fluidChunk.updated = true;
this.simulationQueue.add(fluidChunk);
}