-
Notifications
You must be signed in to change notification settings - Fork 4
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
base: master
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 |
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 = "" |
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) | ||
|
||
|
||
|
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 |
---|---|---|
|
@@ -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) | ||
|
||
|
||
|
@@ -71,13 +72,21 @@ 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 | ||
print("encode_struct data: ", data) | ||
|
||
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])) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
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: | ||
|
@@ -94,7 +103,7 @@ 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())) | ||
|
||
print("encode_struct pad: ", pad_byte_array(arr).to_float32_array()) | ||
wardensdev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return pad_byte_array(arr) | ||
|
||
|
||
|
@@ -110,14 +119,19 @@ 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: | ||
|
||
print("decode_struct data: ", data.to_float32_array()) | ||
wardensdev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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) | ||
|
@@ -130,6 +144,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) | ||
|
@@ -138,5 +165,5 @@ func decode_struct(data: PackedByteArray) -> Array: | |
var integer = byte_array_to_int(data.slice(offset, offset + 4)) | ||
arr.push_back(integer) | ||
offset += 4 | ||
print("decode_struct arr: ", arr) | ||
wardensdev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return arr |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -106,7 +106,7 @@ func byte_array_to_uint(array: PackedByteArray) -> int: | |
return array.decode_u32(0) | ||
|
||
|
||
## Convert GLSL `dvec2` to Vector2 | ||
## Convert GLSL `vec2` to Vector2 | ||
func byte_array_to_vec2(array: PackedByteArray) -> Vector2: | ||
|
||
var dup = array.duplicate() | ||
|
@@ -139,10 +139,15 @@ func byte_array_to_vec3(array: PackedByteArray) -> Vector3: | |
|
||
|
||
## Convert a Vector3 to GLSL equivalent `dvec3, dvec4` format | ||
func vec3_to_byte_array(vector: Vector3) -> PackedByteArray: | ||
func dvec3_to_byte_array(vector: Vector3) -> PackedByteArray: | ||
|
||
return PackedFloat64Array([vector.x, vector.y, vector.z, 0.0]).to_byte_array() | ||
|
||
## Convert a Vector3 to GLSL equivalent `vec3, vec4` format | ||
func vec3_to_byte_array(vector: Vector3) -> PackedByteArray: | ||
|
||
return PackedFloat32Array([vector.x, vector.y, vector.z, 0.0]).to_byte_array() | ||
|
||
|
||
## Convert a Vector3i to GLSL equivalent `ivec3, ivec4` format | ||
func vec3i_to_byte_array(vector: Vector3i) -> PackedByteArray: | ||
|
@@ -151,6 +156,46 @@ func vec3i_to_byte_array(vector: Vector3i) -> PackedByteArray: | |
# because the alignment spec for GLSL vec3s requires 16bytes | ||
return PackedInt32Array([vector.x, vector.y, vector.z, 0]).to_byte_array() | ||
|
||
func vec2i_to_byte_array(vector: Vector2i) -> PackedByteArray: | ||
|
||
# We have to add a value for the "w" field for the vector, | ||
# because the alignment spec for GLSL vec2s requires 12bytes | ||
return PackedInt32Array([vector.x, vector.y, 0]).to_byte_array() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The component in the |
||
|
||
|
||
## Convert an array of Vector3s to GLSL equivalent `vec2[]` format | ||
func vec2_array_to_byte_array(array: PackedVector2Array): | ||
|
||
var bytes: PackedByteArray = PackedByteArray() | ||
|
||
for vector in array: | ||
var vec: Vector3 = Vector3() | ||
|
||
vec.x = vector.x | ||
vec.y = vector.y | ||
|
||
|
||
|
||
var float_arr = PackedFloat32Array([vec.x, vec.y]).to_byte_array() | ||
bytes.append_array(float_arr) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Vectors that are inside arrays in GLSL have their alignment rounded up to a multiple of 4 of the base alignment of its elements. So here, where we define |
||
|
||
return bytes | ||
|
||
## Convert GLSL `vec2[]` to an Array of Vector2s | ||
func byte_array_to_vec2_array(bytes: PackedByteArray) -> PackedVector2Array: | ||
|
||
var arr: PackedVector2Array = PackedVector2Array() | ||
|
||
for v in range((16 + bytes.size()) / 16.0): | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since the alignment of the elements in the array are rounded up to the alignment of a |
||
var vec = Vector2() | ||
|
||
vec.x = bytes.decode_float(0 + (v * 8.0)) | ||
vec.y = bytes.decode_float(4 + (v * 8.0)) | ||
arr.append(vec) | ||
|
||
return arr | ||
|
||
|
||
## Convert an array of Vector3s to GLSL equivalent `vec3[], vec4[]` format | ||
func vec3_array_to_byte_array(array: PackedVector3Array): | ||
|
@@ -167,7 +212,7 @@ func vec3_array_to_byte_array(array: PackedVector3Array): | |
|
||
# We have to add a value for the "w" field for the vector, | ||
# because the alignment spec for GLSL vec3s requires 16bytes | ||
var float_arr = PackedFloat32Array([vector.x, vector.y, vector.z, 0.0]).to_byte_array() | ||
var float_arr = PackedFloat32Array([vec.x, vec.y, vec.z, vec.w]).to_byte_array() | ||
bytes.append_array(float_arr) | ||
|
||
return bytes | ||
|
@@ -195,9 +240,17 @@ func byte_array_to_vec3_array(bytes: PackedByteArray) -> PackedVector3Array: | |
func float_array_to_byte_array_64(array: Array[float]) -> PackedByteArray: | ||
var bytes = PackedFloat64Array(array).to_byte_array() | ||
return bytes | ||
|
||
|
||
## Convert an array of Floats to GLSL equivalent `double[]` | ||
ReKylee marked this conversation as resolved.
Show resolved
Hide resolved
|
||
func int_array_to_byte_array_32(array: Array[int]) -> PackedByteArray: | ||
var bytes = PackedInt32Array(array).to_byte_array() | ||
return bytes | ||
|
||
## Convert a GLSL `double[]` to an Array of Floats | ||
func byte_array_64_to_float_array(array: PackedByteArray) -> Array[float]: | ||
return Array(array.to_float64_array()) | ||
|
||
## Convert a GLSL `int[]` to an Array of Ints | ||
func byte_array_32_to_int_array(array: PackedByteArray) -> Array[float]: | ||
ReKylee marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return Array(array.to_int32_array()) | ||
|
Uh oh!
There was an error while loading. Please reload this page.