Skip to content

Added Packed_*_Array support #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions addons/compute_worker/gpu_uniforms/gpu_packed_int32_array.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# GLSL data type encoding: `int`

extends GPUUniform
class_name GPU_PackedInt32Array

enum UNIFORM_TYPES{
UNIFORM_BUFFER,
STORAGE_BUFFER
}

## The initial data supplied to the uniform
@export var data: PackedInt32Array = PackedInt32Array()
## The size of the array as defined in the shader. Only used if `data` is not defined.
@export var array_size: int = 0
## The shader binding for this uniform
@export var binding: int = 0
## Type of uniform to create. `UNIFORM_BUFFER`s cannot be altered from within the shader
@export var uniform_type: UNIFORM_TYPES = UNIFORM_TYPES.UNIFORM_BUFFER

var data_rid: RID = RID()
var uniform: RDUniform = RDUniform.new()


func initialize(rd: RenderingDevice) -> RDUniform:

if data.is_empty():
if array_size > 0:
data.resize(array_size)
else:
printerr("You must define the uniform's `data` or `array_size`.")
return

# Create the buffer using our initial data
data_rid = create_rid(rd)

# Create RDUniform object using the provided binding id and data
return create_uniform()


func create_uniform() -> RDUniform:

match uniform_type:
UNIFORM_TYPES.UNIFORM_BUFFER:
uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_UNIFORM_BUFFER
UNIFORM_TYPES.STORAGE_BUFFER:
uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_STORAGE_BUFFER

uniform.binding = binding
uniform.add_id(data_rid)

return uniform


func create_rid(rd: RenderingDevice) -> RID:

var bytes = data.to_byte_array()

var buffer: RID = RID()

match uniform_type:
UNIFORM_TYPES.UNIFORM_BUFFER:
bytes = pad_byte_array_std140(bytes)
buffer = rd.uniform_buffer_create(bytes.size(), bytes)
UNIFORM_TYPES.STORAGE_BUFFER:
buffer = rd.storage_buffer_create(bytes.size(), bytes)

return buffer


func get_uniform_data(rd: RenderingDevice) -> PackedInt32Array:
var out := rd.buffer_get_data(data_rid)
return out.to_int32_array()


func set_uniform_data(rd: RenderingDevice, array: PackedInt32Array) -> void:
var sb_data = array.to_byte_array()
rd.buffer_update(data_rid, 0 , sb_data.size(), sb_data)


func pad_byte_array_std140(arr: PackedByteArray) -> PackedByteArray:

arr.resize(arr.size() * 2)
var next_offset = 0

for i in range(arr.size()):
if next_offset + 4 > arr.size():
break
arr.encode_double(next_offset + 4, 0.0)
next_offset += 16

return arr
10 changes: 10 additions & 0 deletions addons/compute_worker/gpu_uniforms/gpu_packed_int32_array.tres
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[gd_resource type="Resource" script_class="GPU_packed_int32_array" load_steps=2 format=3 uid="uid://b5uu7tqhsjaam"]

[ext_resource type="Script" path="res://addons/compute_worker/gpu_uniforms/gpu_packed_int32_array.gd" id="1_571yc"]

[resource]
script = ExtResource("1_571yc")
data = null
binding = 0
uniform_type = 0
alias = ""
79 changes: 79 additions & 0 deletions addons/compute_worker/gpu_uniforms/gpu_packed_vector2_array.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# GLSL data type encoding: `vec4[]`, `vec3[]`

extends GPUUniform
class_name GPU_PackedVector2Array

enum UNIFORM_TYPES{
UNIFORM_BUFFER,
STORAGE_BUFFER
}

## The initial data supplied to the uniform
@export var data: PackedVector2Array = PackedVector2Array()
## The size of the array as defined in the shader. Only used if `data` is not defined.
@export var array_size: int = 0
## The shader binding for this uniform
@export var binding: int = 0
## Type of uniform to create. `UNIFORM_BUFFER`s cannot be altered from within the shader
@export var uniform_type: UNIFORM_TYPES = UNIFORM_TYPES.UNIFORM_BUFFER

var data_rid: RID = RID()
var uniform: RDUniform = RDUniform.new()


func initialize(rd: RenderingDevice) -> RDUniform:

if data.is_empty():

assert(array_size > 0, "You must define the uniform's `data` or `array_size`.")

if array_size > 0:
data.resize(array_size)

# Create the buffer using our initial data
data_rid = create_rid(rd)

# Create RDUniform object using the provided binding id and data
return create_uniform()


func create_uniform() -> RDUniform:

match uniform_type:
UNIFORM_TYPES.UNIFORM_BUFFER:
uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_UNIFORM_BUFFER
UNIFORM_TYPES.STORAGE_BUFFER:
uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_STORAGE_BUFFER

uniform.binding = binding
uniform.add_id(data_rid)

return uniform


func create_rid(rd: RenderingDevice) -> RID:

var bytes = vec2_array_to_byte_array(data)

var buffer: RID = RID()

match uniform_type:
UNIFORM_TYPES.UNIFORM_BUFFER:
buffer = rd.uniform_buffer_create(bytes.size(), bytes)
UNIFORM_TYPES.STORAGE_BUFFER:
buffer = rd.storage_buffer_create(bytes.size(), bytes)

return buffer


func get_uniform_data(rd: RenderingDevice) -> PackedVector2Array:
var out := rd.buffer_get_data(data_rid)
return byte_array_to_vec2_array(out)


func set_uniform_data(rd: RenderingDevice, array: PackedVector2Array) -> void:
var sb_data = vec2_array_to_byte_array(array)
rd.buffer_update(data_rid, 0 , sb_data.size(), sb_data)



11 changes: 11 additions & 0 deletions addons/compute_worker/gpu_uniforms/gpu_packed_vector2_array.tres
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[gd_resource type="Resource" script_class="GPU_PackedVector2Array" load_steps=2 format=3 uid="uid://c1pyh5mnrbuwm"]

[ext_resource type="Script" path="res://addons/compute_worker/gpu_uniforms/gpu_packed_vector2_array.gd" id="1_cmbw3"]

[resource]
script = ExtResource("1_cmbw3")
data = null
array_size = 0
binding = 0
uniform_type = 0
alias = ""
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# GLSL data type encoding: `vec4[]`, `vec3[]`
# GLSL data type encoding: `vec3[]`

extends GPUUniform
class_name GPU_PackedVector3Array
Expand Down
33 changes: 28 additions & 5 deletions addons/compute_worker/gpu_uniforms/gpu_struct.gd
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ func create_rid(rd: RenderingDevice) -> RID:

func get_uniform_data(rd: RenderingDevice):
var out := rd.buffer_get_data(data_rid)

return decode_struct(out)


Expand All @@ -71,13 +72,20 @@ func set_uniform_data(rd: RenderingDevice, data: Array) -> void:
## Encode the contents of the passed in `data` Array to PackedByteArray.
## Contents of `data` must match the order and data types defined in `struct_data`.
func encode_struct(data: Array, init: bool = false) -> PackedByteArray:

var arr: PackedByteArray = PackedByteArray()
var data_index = 0

for type_obj in struct_data:

match typeof(type_obj):
TYPE_PACKED_VECTOR3_ARRAY:
arr.append_array(vec3_array_to_byte_array(data[data_index]))
TYPE_PACKED_VECTOR2_ARRAY:
arr.append_array(vec2_array_to_byte_array(data[data_index]))
TYPE_VECTOR2I:
arr.append_array(vec2i_to_byte_array(data[data_index]))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TYPE_VECTOR2I and TYPE_VECTOR2 require different alignments when inside a struct. Like with arrays, alignments for struct members are rounded up to the alignment of a vec4. So for these two types, we'll need separate functions to get the byte arrays with the extra padding (+2 components).

TYPE_VECTOR2:
arr.append_array(vec2_to_byte_array(data[data_index]))
TYPE_VECTOR3I:
arr.append_array(vec3i_to_byte_array(data[data_index]))
TYPE_COLOR:
Expand All @@ -94,7 +102,6 @@ func encode_struct(data: Array, init: bool = false) -> PackedByteArray:
if !init:
if pad_byte_array(arr).size() != byte_length && uniform.uniform_type == RenderingDevice.UNIFORM_TYPE_UNIFORM_BUFFER:
printerr("Data for uniform: " + str(alias) + " does not match struct requirements. Needs: " + str(byte_length) + " was given: " + str(arr.size()))

return pad_byte_array(arr)


Expand All @@ -110,14 +117,18 @@ func pad_byte_array(arr: PackedByteArray):
## Decode the contents of the passed in PackedByteArray to an Array matching
## the order and data types defined in `struct_data`.
func decode_struct(data: PackedByteArray) -> Array:

var arr: Array = []

var offset: int = 0

for i in range(struct_data.size()):

match typeof(struct_data[i]):

TYPE_PACKED_VECTOR3_ARRAY:
var arr_size = struct_data[i].size()
var pvec3arr = byte_array_to_vec3_array(data.slice(offset, offset + 16*arr_size))
arr.push_back(pvec3arr)
offset += 16*arr_size
TYPE_VECTOR3I:
var vec = byte_array_to_vec3(data.slice(offset, offset + 32))
arr.push_back(vec)
Expand All @@ -130,6 +141,19 @@ func decode_struct(data: PackedByteArray) -> Array:
var vec = byte_array_to_vec3(data.slice(offset, offset + 32))
arr.push_back(vec)
offset += 32
TYPE_PACKED_VECTOR2_ARRAY:
var arr_size = struct_data[i].size()
var pvec2arr = byte_array_to_vec2_array(data.slice(offset, offset + 16*arr_size))
arr.push_back(pvec2arr)
offset += 16*arr_size
TYPE_VECTOR2I:
var vec = byte_array_to_vec2(data.slice(offset, offset + 16))
arr.push_back(vec)
offset += 16
TYPE_VECTOR2:
var vec = byte_array_to_vec2(data.slice(offset, offset + 16))
arr.push_back(vec)
offset += 16
TYPE_FLOAT:
var flo = byte_array_to_float(data.slice(offset, offset + 8))
arr.push_back(flo)
Expand All @@ -138,5 +162,4 @@ func decode_struct(data: PackedByteArray) -> Array:
var integer = byte_array_to_int(data.slice(offset, offset + 4))
arr.push_back(integer)
offset += 4

return arr
3 changes: 1 addition & 2 deletions addons/compute_worker/gpu_uniforms/gpu_struct_array.gd
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,9 @@ func create_rid(rd: RenderingDevice) -> RID:
return buffer


func get_uniform_data(rd: RenderingDevice) -> Array[Array]:
func get_uniform_data(rd: RenderingDevice):

var out := rd.buffer_get_data(data_rid)

var arr: Array = []

@warning_ignore("integer_division")
Expand Down
Loading