vxgi optimizations (to-do: fix the stuttering again from the UBO lagging or something)
This commit is contained in:
parent
ec2122ab12
commit
682dd2c794
@ -109,7 +109,7 @@
|
||||
"invariant": {
|
||||
"default stage buffers": true,
|
||||
"default defer buffer destroy": true,
|
||||
"default command buffer immediate": true,
|
||||
"default command buffer immediate": false,
|
||||
"multithreaded recording": true
|
||||
},
|
||||
"pipelines": {
|
||||
@ -117,10 +117,10 @@
|
||||
"gui": true,
|
||||
"vsync": true, // vsync on vulkan side rather than engine-side
|
||||
"hdr": true,
|
||||
"vxgi": false,
|
||||
"vxgi": true,
|
||||
"culling": false,
|
||||
"bloom": true,
|
||||
"dof": true,
|
||||
"bloom": false,
|
||||
"dof": false,
|
||||
"rt": false,
|
||||
"fsr": false,
|
||||
"postProcess": false // "postProcess.chromab" // false
|
||||
@ -299,7 +299,7 @@
|
||||
"enabled": true
|
||||
},
|
||||
"imgui": {
|
||||
"enabled": true
|
||||
"enabled": false
|
||||
},
|
||||
"fsr": {
|
||||
"enabled": true,
|
||||
|
||||
@ -2,6 +2,10 @@
|
||||
float random(vec3 seed, int i){ return fract(sin(dot(vec4(seed,i), vec4(12.9898,78.233,45.164,94.673))) * 43758.5453); }
|
||||
float rand2(vec2 co){ return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 143758.5453); }
|
||||
float rand3(vec3 co){ return fract(sin(dot(co.xyz ,vec3(12.9898,78.233, 37.719))) * 143758.5453); }
|
||||
float interleavedGradientNoise(vec2 co) {
|
||||
vec3 seed = vec3(0.06711056, 0.00583715, 52.9829189);
|
||||
return fract(seed.z * fract(dot(co, seed.xy)));
|
||||
}
|
||||
//
|
||||
float mipLevel( in vec2 dx_vtc, in vec2 dy_vtc ) {
|
||||
const float delta_max_sqr = max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc));
|
||||
@ -44,7 +48,8 @@ void gammaCorrect( inout vec3 color, float gamma ) {
|
||||
}
|
||||
void toneMap( inout vec4 color, float exposure ) { toneMap(color.rgb, exposure); }
|
||||
void gammaCorrect( inout vec4 color, float gamma ) { gammaCorrect(color.rgb, gamma); }
|
||||
float luma( vec3 color ) { return dot(color, vec3(0.2126, 0.7152, 0.0722)); }
|
||||
float luma( vec3 color ) { return dot(color, vec3(0.2126, 0.7152, 0.0722)); } // REF 709
|
||||
float luminance( vec3 color ) { return dot(color, vec3(0.299, 0.587, 0.114)); } // REF 601
|
||||
//
|
||||
uint tea(uint val0, uint val1) {
|
||||
uint v0 = val0;
|
||||
|
||||
@ -94,19 +94,10 @@ layout (binding = 18) uniform sampler2D samplerTextures[TEXTURES];
|
||||
layout (binding = 19) uniform samplerCube samplerCubemaps[CUBEMAPS];
|
||||
layout (binding = 20) uniform sampler3D samplerNoise;
|
||||
#if VXGI
|
||||
layout (binding = 21) uniform usampler3D voxelDrawId[CASCADES];
|
||||
layout (binding = 22) uniform usampler3D voxelInstanceId[CASCADES];
|
||||
layout (binding = 23) uniform sampler3D voxelNormalX[CASCADES];
|
||||
layout (binding = 24) uniform sampler3D voxelNormalY[CASCADES];
|
||||
layout (binding = 25) uniform sampler3D voxelRadianceR[CASCADES];
|
||||
layout (binding = 26) uniform sampler3D voxelRadianceG[CASCADES];
|
||||
layout (binding = 27) uniform sampler3D voxelRadianceB[CASCADES];
|
||||
layout (binding = 28) uniform sampler3D voxelRadianceA[CASCADES];
|
||||
layout (binding = 29) uniform sampler3D voxelCount[CASCADES];
|
||||
layout (binding = 30) uniform sampler3D voxelOutput[CASCADES];
|
||||
layout (binding = 21) uniform sampler3D voxelOutput[CASCADES];
|
||||
#endif
|
||||
#if RT
|
||||
layout (binding = 31) uniform accelerationStructureEXT tlas;
|
||||
layout (binding = 22) uniform accelerationStructureEXT tlas;
|
||||
#endif
|
||||
|
||||
#if BUFFER_REFERENCE
|
||||
@ -296,7 +287,7 @@ void directLighting() {
|
||||
surface.material.albedo.rgb = radiance.rgb;
|
||||
surface.material.indirect.rgb = vec3(0);
|
||||
surface.fragment.rgb = radiance.rgb;
|
||||
surface.fragment.a = radiance.a;
|
||||
surface.fragment.a = 1; // radiance.a;
|
||||
//return;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -50,18 +50,11 @@ layout (std140, binding = 7) readonly buffer Lights {
|
||||
|
||||
layout (binding = 8) uniform sampler2D samplerTextures[TEXTURES];
|
||||
layout (binding = 9) uniform samplerCube samplerCubemaps[CUBEMAPS];
|
||||
layout (binding = 10) uniform sampler3D samplerNoise;
|
||||
|
||||
layout (binding = 11, r32ui) uniform readonly uimage3D voxelDrawId[CASCADES];
|
||||
layout (binding = 12, r32ui) uniform readonly uimage3D voxelInstanceId[CASCADES];
|
||||
layout (binding = 13, r32ui) uniform readonly uimage3D voxelNormalX[CASCADES];
|
||||
layout (binding = 14, r32ui) uniform readonly uimage3D voxelNormalY[CASCADES];
|
||||
layout (binding = 15, r32ui) uniform readonly uimage3D voxelRadianceR[CASCADES];
|
||||
layout (binding = 16, r32ui) uniform readonly uimage3D voxelRadianceG[CASCADES];
|
||||
layout (binding = 17, r32ui) uniform readonly uimage3D voxelRadianceB[CASCADES];
|
||||
layout (binding = 18, r32ui) uniform readonly uimage3D voxelRadianceA[CASCADES];
|
||||
layout (binding = 19, r32ui) uniform readonly uimage3D voxelCount[CASCADES];
|
||||
layout (binding = 20, rgba8) uniform writeonly image3D voxelOutput[CASCADES];
|
||||
layout (binding = 10, r32ui) uniform readonly uimage3D voxelId[CASCADES];
|
||||
layout (binding = 11, r32ui) uniform readonly uimage3D voxelNormal[CASCADES];
|
||||
layout (binding = 12, r32ui) uniform readonly uimage3D voxelRadiance[CASCADES];
|
||||
layout (binding = 13, rgba8) uniform writeonly image3D voxelOutput[CASCADES];
|
||||
|
||||
#include "../../common/functions.h"
|
||||
#include "../../common/light.h"
|
||||
@ -71,55 +64,27 @@ layout (binding = 20, rgba8) uniform writeonly image3D voxelOutput[CASCADES];
|
||||
void main() {
|
||||
const vec3 tUvw = gl_GlobalInvocationID.xzy;
|
||||
for ( uint CASCADE = 0; CASCADE < CASCADES; ++CASCADE ) {
|
||||
vec2 N_E = vec2(
|
||||
uintBitsToFloat(imageLoad(voxelNormalX[CASCADE], ivec3(tUvw) ).x),
|
||||
uintBitsToFloat(imageLoad(voxelNormalY[CASCADE], ivec3(tUvw) ).x)
|
||||
);
|
||||
|
||||
surface.normal.world = decodeNormals( N_E );
|
||||
surface.normal.eye = vec3( ubo.settings.vxgi.matrix * vec4( surface.normal.world, 0.0f ) );
|
||||
|
||||
surface.position.eye = (vec3(gl_GlobalInvocationID.xyz) / vec3(imageSize(voxelOutput[CASCADE])) * 2.0f - 1.0f) * cascadePower(CASCADE);
|
||||
surface.position.world = vec3( inverse(ubo.settings.vxgi.matrix) * vec4( surface.position.eye, 1.0f ) );
|
||||
|
||||
#if 0
|
||||
vec4 A = unpackUnorm4x8(imageLoad(voxelRadiance[CASCADE], ivec3(tUvw)).r);
|
||||
A.a = length(luma(A.rgb)) > 0.001 ? 1 : 0;
|
||||
imageStore(voxelOutput[CASCADE], ivec3(tUvw), A);
|
||||
#else
|
||||
surface.pass = 0; // PushConstant.pass;
|
||||
surface.fragment = vec4(0);
|
||||
surface.light = vec4(0);
|
||||
surface.motion = vec2(0);
|
||||
surface.material.indirect = vec4(0);
|
||||
|
||||
#if 0
|
||||
#if 0
|
||||
vec4 A = imageLoad(voxelOutput[CASCADE], ivec3(tUvw) );
|
||||
#else
|
||||
vec4 A = vec4(0);
|
||||
A.r = imageLoad(voxelRadianceR[CASCADE], ivec3(tUvw) ).r;
|
||||
A.g = imageLoad(voxelRadianceG[CASCADE], ivec3(tUvw) ).r;
|
||||
A.b = imageLoad(voxelRadianceB[CASCADE], ivec3(tUvw) ).r;
|
||||
A.a = imageLoad(voxelRadianceA[CASCADE], ivec3(tUvw) ).r;
|
||||
A /= 256.0;
|
||||
|
||||
uint count = imageLoad(voxelCount[CASCADE], ivec3(tUvw) ).r;
|
||||
if ( count > 0 ) A /= count;
|
||||
/*
|
||||
vec4 A = vec4(surface.normal.world, 1.0);
|
||||
*/
|
||||
#endif
|
||||
|
||||
surface.material.albedo = A;
|
||||
surface.fragment.rgb = surface.material.albedo.rgb;
|
||||
|
||||
const bool DISCARD_DUE_TO_DIVERGENCE = surface.material.albedo.a == 0;
|
||||
#else
|
||||
const uint packedID = imageLoad(voxelId[CASCADE], ivec3(tUvw) ).x;
|
||||
const uvec2 ID = uvec2(
|
||||
imageLoad(voxelDrawId[CASCADE], ivec3(tUvw) ).x,
|
||||
imageLoad(voxelInstanceId[CASCADE], ivec3(tUvw) ).x
|
||||
(packedID & 0xFFFF),
|
||||
(packedID >> 16)
|
||||
);
|
||||
const bool DISCARD_DUE_TO_DIVERGENCE = ID.x == 0 || ID.y == 0;
|
||||
|
||||
const uint drawID = ID.x == 0 ? 0 : ID.x - 1;
|
||||
const uint instanceID = ID.y == 0 ? 0 : ID.y - 1;
|
||||
|
||||
|
||||
// if ( ID.x == 0 || ID.y == 0 ) {
|
||||
#if 1
|
||||
if ( DISCARD_DUE_TO_DIVERGENCE ) {
|
||||
@ -138,15 +103,8 @@ void main() {
|
||||
#if 0
|
||||
vec4 A = imageLoad(voxelOutput[CASCADE], ivec3(tUvw) );
|
||||
#else
|
||||
vec4 A = vec4(0);
|
||||
A.r = imageLoad(voxelRadianceR[CASCADE], ivec3(tUvw) ).r;
|
||||
A.g = imageLoad(voxelRadianceG[CASCADE], ivec3(tUvw) ).r;
|
||||
A.b = imageLoad(voxelRadianceB[CASCADE], ivec3(tUvw) ).r;
|
||||
A.a = imageLoad(voxelRadianceA[CASCADE], ivec3(tUvw) ).r;
|
||||
A /= 256.0;
|
||||
|
||||
uint count = imageLoad(voxelCount[CASCADE], ivec3(tUvw) ).r;
|
||||
if ( count > 0 ) A /= count;
|
||||
vec4 A = unpackUnorm4x8(imageLoad(voxelRadiance[CASCADE], ivec3(tUvw)).r);
|
||||
A.a = 1.0;
|
||||
#endif
|
||||
|
||||
surface.material.albedo = A;
|
||||
@ -205,7 +163,6 @@ void main() {
|
||||
#endif
|
||||
}
|
||||
surface.fragment.rgb += surface.light.rgb;
|
||||
#endif
|
||||
|
||||
#if TONE_MAP
|
||||
toneMap(surface.fragment.rgb, ubo.settings.bloom.exposure);
|
||||
@ -214,14 +171,11 @@ void main() {
|
||||
gammaCorrect(surface.fragment.rgb, 1.0 / ubo.settings.bloom.gamma);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
imageStore(voxelOutput[CASCADE], ivec3(tUvw), vec4(surface.fragment.rgb, surface.material.albedo.a));
|
||||
#else
|
||||
if ( DISCARD_DUE_TO_DIVERGENCE ) {
|
||||
imageStore(voxelOutput[CASCADE], ivec3(tUvw), vec4(0));
|
||||
} else {
|
||||
imageStore(voxelOutput[CASCADE], ivec3(tUvw), vec4(surface.fragment.rgb, surface.material.albedo.a));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -37,16 +37,10 @@ layout (std140, binding = 12) readonly buffer Lights {
|
||||
Light lights[];
|
||||
};
|
||||
|
||||
layout (binding = 13, r32ui) uniform volatile uimage3D voxelDrawId[CASCADES];
|
||||
layout (binding = 14, r32ui) uniform volatile uimage3D voxelInstanceId[CASCADES];
|
||||
layout (binding = 15, r32ui) uniform volatile uimage3D voxelNormalX[CASCADES];
|
||||
layout (binding = 16, r32ui) uniform volatile uimage3D voxelNormalY[CASCADES];
|
||||
layout (binding = 17, r32ui) uniform volatile uimage3D voxelRadianceR[CASCADES];
|
||||
layout (binding = 18, r32ui) uniform volatile uimage3D voxelRadianceG[CASCADES];
|
||||
layout (binding = 19, r32ui) uniform volatile uimage3D voxelRadianceB[CASCADES];
|
||||
layout (binding = 20, r32ui) uniform volatile uimage3D voxelRadianceA[CASCADES];
|
||||
layout (binding = 21, r32ui) uniform volatile uimage3D voxelCount[CASCADES];
|
||||
layout (binding = 22, rgba8) uniform writeonly image3D voxelOutput[CASCADES];
|
||||
layout (binding = 13, r32ui) uniform volatile uimage3D voxelId[CASCADES];
|
||||
layout (binding = 14, r32ui) uniform volatile uimage3D voxelNormal[CASCADES];
|
||||
layout (binding = 15, r32ui) uniform volatile uimage3D voxelRadiance[CASCADES];
|
||||
layout (binding = 16, rgba8) uniform writeonly image3D voxelOutput[CASCADES];
|
||||
|
||||
layout (location = 0) flat in uvec4 inId;
|
||||
layout (location = 1) flat in vec4 inPOS0;
|
||||
@ -94,7 +88,8 @@ void main() {
|
||||
A.a = 1;
|
||||
// alpha mode BLEND
|
||||
} else if ( material.modeAlpha == 1 ) {
|
||||
|
||||
float dither = interleavedGradientNoise(gl_FragCoord.xy);
|
||||
// if ( A.a < dither ) discard;
|
||||
// alpha mode MASK
|
||||
} else if ( material.modeAlpha == 2 ) {
|
||||
if ( A.a < abs(material.factorAlphaCutoff) ) discard;
|
||||
@ -121,16 +116,13 @@ void main() {
|
||||
|
||||
const ivec3 uvw = ivec3(P * imageSize(voxelOutput[CASCADE]));
|
||||
|
||||
imageAtomicMax(voxelDrawId[CASCADE], ivec3(uvw), uint( drawID + 1 ) );
|
||||
imageAtomicMax(voxelInstanceId[CASCADE], ivec3(uvw), uint( instanceID + 1 ) );
|
||||
uint packedId = ( instanceID + 1 ) << 16 | ( drawID + 1 );
|
||||
imageAtomicMax(voxelId[CASCADE], ivec3(uvw), packedId);
|
||||
|
||||
vec2 N_E = encodeNormals( normalize( N ) );
|
||||
imageAtomicMin(voxelNormalX[CASCADE], ivec3(uvw), uint( floatBitsToUint( N_E.x ) ) );
|
||||
imageAtomicMin(voxelNormalY[CASCADE], ivec3(uvw), uint( floatBitsToUint( N_E.y ) ) );
|
||||
|
||||
imageAtomicAdd(voxelRadianceR[CASCADE], ivec3(uvw), uint( A.r * 256 ) );
|
||||
imageAtomicAdd(voxelRadianceG[CASCADE], ivec3(uvw), uint( A.g * 256 ) );
|
||||
imageAtomicAdd(voxelRadianceB[CASCADE], ivec3(uvw), uint( A.b * 256 ) );
|
||||
imageAtomicAdd(voxelRadianceA[CASCADE], ivec3(uvw), uint( A.a * 256 ) );
|
||||
imageAtomicAdd(voxelCount[CASCADE], ivec3(uvw), uint( 1 ) );
|
||||
uint packedNormal = packHalf2x16(N_E);
|
||||
imageAtomicMin(voxelNormal[CASCADE], uvw, packedNormal);
|
||||
|
||||
uint packedRadiance = packUnorm4x8(vec4(A.rgb, luminance(A.rgb)));
|
||||
imageAtomicMax(voxelRadiance[CASCADE], uvw, packedRadiance);
|
||||
}
|
||||
@ -5,15 +5,9 @@ namespace pod {
|
||||
uf::renderer::Texture3D noise;
|
||||
uf::renderer::TextureCube skybox;
|
||||
struct {
|
||||
uf::stl::vector<uf::renderer::Texture3D> drawId;
|
||||
uf::stl::vector<uf::renderer::Texture3D> instanceId;
|
||||
uf::stl::vector<uf::renderer::Texture3D> normalX;
|
||||
uf::stl::vector<uf::renderer::Texture3D> normalY;
|
||||
uf::stl::vector<uf::renderer::Texture3D> radianceR;
|
||||
uf::stl::vector<uf::renderer::Texture3D> radianceG;
|
||||
uf::stl::vector<uf::renderer::Texture3D> radianceB;
|
||||
uf::stl::vector<uf::renderer::Texture3D> radianceA;
|
||||
uf::stl::vector<uf::renderer::Texture3D> count;
|
||||
uf::stl::vector<uf::renderer::Texture3D> id;
|
||||
uf::stl::vector<uf::renderer::Texture3D> normal;
|
||||
uf::stl::vector<uf::renderer::Texture3D> radiance;
|
||||
uf::stl::vector<uf::renderer::Texture3D> output;
|
||||
} voxels;
|
||||
};
|
||||
|
||||
@ -59,6 +59,7 @@ namespace ext {
|
||||
VkImageViewType viewType = enums::Image::VIEW_TYPE_2D;
|
||||
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
VkImageUsageFlags usage = {};
|
||||
VkImageCreateFlags flags = {};
|
||||
VkDeviceMemory deviceMemory = VK_NULL_HANDLE;
|
||||
VkDescriptorImageInfo descriptor = {};
|
||||
VkFormat format = enums::Format::R8G8B8A8_UNORM;
|
||||
@ -102,29 +103,45 @@ namespace ext {
|
||||
const uf::stl::string& filename,
|
||||
VkFormat format = DefaultFormat,
|
||||
VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
|
||||
VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VkImageCreateFlags flags = {}
|
||||
);
|
||||
void loadFromFile(
|
||||
const uf::stl::string& filename,
|
||||
Device& device,
|
||||
VkFormat format = DefaultFormat,
|
||||
VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
|
||||
VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VkImageCreateFlags flags = {}
|
||||
);
|
||||
void loadFromImage(
|
||||
const uf::Image& image,
|
||||
Device& device,
|
||||
VkFormat format = DefaultFormat,
|
||||
VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
|
||||
VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VkImageCreateFlags flags = {}
|
||||
);
|
||||
void loadFromImage(
|
||||
const uf::Image& image,
|
||||
VkFormat format = DefaultFormat,
|
||||
VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
|
||||
VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VkImageCreateFlags flags = {}
|
||||
);
|
||||
void fromBuffers(
|
||||
void* buffer,
|
||||
VkDeviceSize bufferSize,
|
||||
VkFormat format,
|
||||
uint32_t texWidth,
|
||||
uint32_t texHeight,
|
||||
uint32_t texDepth,
|
||||
uint32_t layers,
|
||||
Device& device,
|
||||
VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VkImageCreateFlags flags = {}
|
||||
);
|
||||
void fromBuffers( void* buffer, VkDeviceSize bufferSize, VkFormat format, uint32_t texWidth, uint32_t texHeight, uint32_t texDepth, uint32_t layers, Device& device, VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT, VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL );
|
||||
void asRenderTarget( Device& device, uint32_t texWidth, uint32_t texHeight, VkFormat format = DefaultFormat );
|
||||
|
||||
Texture alias() const;
|
||||
@ -136,14 +153,14 @@ namespace ext {
|
||||
void update( uf::Image& image, VkImageLayout, uint32_t layer = 1 );
|
||||
void update( void*, VkDeviceSize, VkImageLayout, uint32_t layer = 1 );
|
||||
|
||||
inline void fromBuffers( void* buffer, VkDeviceSize bufferSize, VkFormat format, uint32_t texWidth, uint32_t texHeight, Device& device, VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT, VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL ) { return this->fromBuffers(buffer, bufferSize, format, texWidth, texHeight, 1, 1, device, usage, layout); }
|
||||
inline void fromBuffers( void* buffer, VkDeviceSize bufferSize, VkFormat format, uint32_t texWidth, uint32_t texHeight, Device& device, VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT, VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VkImageCreateFlags flags = {} ) { return this->fromBuffers(buffer, bufferSize, format, texWidth, texHeight, 1, 1, device, usage, layout, flags); }
|
||||
inline void update( uf::Image& image, uint32_t layer = 1 ) { return this->update(image, this->layout, layer); }
|
||||
inline void update( void* data, VkDeviceSize size, uint32_t layer = 1 ) { return this->update(data, size, this->layout, layer); }
|
||||
|
||||
void generateMipmaps(VkCommandBuffer commandBuffer, uint32_t layer = 0);
|
||||
|
||||
void fromBuffers( void* buffer, VkDeviceSize bufferSize, VkFormat format, uint32_t texWidth, uint32_t texHeight, uint32_t texDepth, uint32_t layers, VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT, VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL );
|
||||
inline void fromBuffers( void* buffer, VkDeviceSize bufferSize, VkFormat format, uint32_t texWidth, uint32_t texHeight, VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT, VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL ) { return this->fromBuffers(buffer, bufferSize, format, texWidth, texHeight, 1, 1, usage, layout); }
|
||||
void fromBuffers( void* buffer, VkDeviceSize bufferSize, VkFormat format, uint32_t texWidth, uint32_t texHeight, uint32_t texDepth, uint32_t layers, VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT, VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VkImageCreateFlags flags = {} );
|
||||
inline void fromBuffers( void* buffer, VkDeviceSize bufferSize, VkFormat format, uint32_t texWidth, uint32_t texHeight, VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT, VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VkImageCreateFlags flags = {} ) { return this->fromBuffers(buffer, bufferSize, format, texWidth, texHeight, 1, 1, usage, layout, flags); }
|
||||
};
|
||||
class UF_API Texture2D : public Texture {
|
||||
public:
|
||||
|
||||
@ -384,7 +384,9 @@ void ext::GuiGlyphBehavior::initialize( uf::Object& self ) {
|
||||
bool forced = payload["force"].as(false);
|
||||
|
||||
// override
|
||||
// metadata.sdf = false;
|
||||
#if UF_USE_OPENGL
|
||||
metadata.sdf = false;
|
||||
#endif
|
||||
metadataGui.scaling = "none";
|
||||
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
|
||||
@ -225,39 +225,11 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
|
||||
shader.setDescriptorCounts({
|
||||
{ "samplerTextures", maxTextures2D },
|
||||
{ "samplerCubemaps", maxTexturesCube },
|
||||
{ "voxelDrawId", maxCascades },
|
||||
{ "voxelInstanceId", maxCascades },
|
||||
{ "voxelNormalX", maxCascades },
|
||||
{ "voxelNormalY", maxCascades },
|
||||
{ "voxelRadianceR", maxCascades },
|
||||
{ "voxelRadianceG", maxCascades },
|
||||
{ "voxelRadianceB", maxCascades },
|
||||
{ "voxelRadianceA", maxCascades },
|
||||
{ "voxelCount", maxCascades },
|
||||
{ "voxelId", maxCascades },
|
||||
{ "voxelNormal", maxCascades },
|
||||
{ "voxelRadiance", maxCascades },
|
||||
{ "voxelOutput", maxCascades },
|
||||
});
|
||||
|
||||
/*
|
||||
uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants;
|
||||
for ( auto pair : shader.metadata.definitions.specializationConstants ) {
|
||||
auto& sc = pair.second;
|
||||
if ( sc.name == "TEXTURES" ) sc.value.ui = (specializationConstants[sc.index] = maxTextures2D);
|
||||
else if ( sc.name == "CUBEMAPS" ) sc.value.ui = (specializationConstants[sc.index] = maxTexturesCube);
|
||||
else if ( sc.name == "CASCADES" ) sc.value.ui = (specializationConstants[sc.index] = maxCascades);
|
||||
}
|
||||
for ( auto pair : shader.metadata.definitions.textures ) {
|
||||
auto& tx = pair.second;
|
||||
for ( auto& layout : shader.descriptorSetLayoutBindings ) {
|
||||
if ( layout.binding != tx.binding ) continue;
|
||||
if ( tx.name == "samplerTextures" ) layout.descriptorCount = maxTextures2D;
|
||||
else if ( tx.name == "samplerCubemaps" ) layout.descriptorCount = maxTexturesCube;
|
||||
else if ( tx.name == "voxelId" ) layout.descriptorCount = maxCascades;
|
||||
else if ( tx.name == "voxelUv" ) layout.descriptorCount = maxCascades;
|
||||
else if ( tx.name == "voxelNormal" ) layout.descriptorCount = maxCascades;
|
||||
else if ( tx.name == "voxelRadiance" ) layout.descriptorCount = maxCascades;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -740,26 +740,14 @@ void ext::ExtSceneBehavior::destroy( uf::Object& self ) {
|
||||
}
|
||||
if ( this->hasComponent<pod::SceneTextures>() ) {
|
||||
auto& sceneTextures = this->getComponent<pod::SceneTextures>();
|
||||
for ( auto& t : sceneTextures.voxels.drawId ) t.destroy();
|
||||
for ( auto& t : sceneTextures.voxels.instanceId ) t.destroy();
|
||||
for ( auto& t : sceneTextures.voxels.normalX ) t.destroy();
|
||||
for ( auto& t : sceneTextures.voxels.normalY ) t.destroy();
|
||||
for ( auto& t : sceneTextures.voxels.radianceR ) t.destroy();
|
||||
for ( auto& t : sceneTextures.voxels.radianceG ) t.destroy();
|
||||
for ( auto& t : sceneTextures.voxels.radianceB ) t.destroy();
|
||||
for ( auto& t : sceneTextures.voxels.radianceA ) t.destroy();
|
||||
for ( auto& t : sceneTextures.voxels.count ) t.destroy();
|
||||
for ( auto& t : sceneTextures.voxels.id ) t.destroy();
|
||||
for ( auto& t : sceneTextures.voxels.normal ) t.destroy();
|
||||
for ( auto& t : sceneTextures.voxels.radiance ) t.destroy();
|
||||
for ( auto& t : sceneTextures.voxels.output ) t.destroy();
|
||||
|
||||
sceneTextures.voxels.drawId.clear();
|
||||
sceneTextures.voxels.instanceId.clear();
|
||||
sceneTextures.voxels.normalX.clear();
|
||||
sceneTextures.voxels.normalY.clear();
|
||||
sceneTextures.voxels.radianceR.clear();
|
||||
sceneTextures.voxels.radianceG.clear();
|
||||
sceneTextures.voxels.radianceB.clear();
|
||||
sceneTextures.voxels.radianceA.clear();
|
||||
sceneTextures.voxels.count.clear();
|
||||
sceneTextures.voxels.id.clear();
|
||||
sceneTextures.voxels.normal.clear();
|
||||
sceneTextures.voxels.radiance.clear();
|
||||
sceneTextures.voxels.output.clear();
|
||||
|
||||
sceneTextures.noise.destroy();
|
||||
@ -1136,17 +1124,14 @@ void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, uf::renderer::Graphic
|
||||
|
||||
// attach VXGI voxels
|
||||
if ( uf::renderer::settings::pipelines::vxgi ) {
|
||||
for ( auto& t : sceneTextures.voxels.drawId ) textures3D.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.instanceId ) textures3D.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.normalX ) textures3D.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.normalY ) textures3D.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.radianceR ) textures3D.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.radianceG ) textures3D.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.radianceB ) textures3D.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.radianceA ) textures3D.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.count ) textures3D.emplace_back().aliasTexture(t);
|
||||
/*
|
||||
for ( auto& t : sceneTextures.voxels.id ) textures3D.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.normal ) textures3D.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.radiance ) textures3D.emplace_back().aliasTexture(t);
|
||||
*/
|
||||
for ( auto& t : sceneTextures.voxels.output ) textures3D.emplace_back().aliasTexture(t);
|
||||
}
|
||||
|
||||
// bind textures
|
||||
while ( textures2D.size() < metadata.max.textures2D ) textures2D.emplace_back().aliasTexture(uf::renderer::Texture2D::empty);
|
||||
while ( texturesCube.size() < metadata.max.texturesCube ) texturesCube.emplace_back().aliasTexture(uf::renderer::TextureCube::empty);
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
#include "../scene/behavior.h"
|
||||
#include <uf/engine/ext.h>
|
||||
|
||||
#define ALIAS_OUTPUT_TO_RADIANCE 1
|
||||
|
||||
UF_BEHAVIOR_REGISTER_CPP(ext::VoxelizerSceneBehavior)
|
||||
UF_BEHAVIOR_TRAITS_CPP(ext::VoxelizerSceneBehavior, ticks = true, renders = false, thread = "")
|
||||
@ -35,44 +36,46 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) {
|
||||
|
||||
for ( size_t i = 0; i < metadata.cascades; ++i ) {
|
||||
const bool HDR = false;
|
||||
auto& drawId = sceneTextures.voxels.drawId.emplace_back();
|
||||
drawId.sampler.descriptor.filter.min = uf::renderer::enums::Filter::NEAREST;
|
||||
drawId.sampler.descriptor.filter.mag = uf::renderer::enums::Filter::NEAREST;
|
||||
drawId.fromBuffers( NULL, 0, uf::renderer::enums::Format::R32_UINT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
|
||||
|
||||
auto& instanceId = sceneTextures.voxels.instanceId.emplace_back();
|
||||
instanceId.sampler.descriptor.filter.min = uf::renderer::enums::Filter::NEAREST;
|
||||
instanceId.sampler.descriptor.filter.mag = uf::renderer::enums::Filter::NEAREST;
|
||||
instanceId.fromBuffers( NULL, 0, uf::renderer::enums::Format::R32_UINT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
|
||||
auto& id = sceneTextures.voxels.id.emplace_back();
|
||||
id.sampler.descriptor.filter.min = uf::renderer::enums::Filter::NEAREST;
|
||||
id.sampler.descriptor.filter.mag = uf::renderer::enums::Filter::NEAREST;
|
||||
id.fromBuffers( NULL, 0, uf::renderer::enums::Format::R32_UINT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
|
||||
|
||||
auto& normalX = sceneTextures.voxels.normalX.emplace_back();
|
||||
normalX.fromBuffers( NULL, 0, uf::renderer::enums::Format::R32_UINT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
|
||||
|
||||
auto& normalY = sceneTextures.voxels.normalY.emplace_back();
|
||||
normalY.fromBuffers( NULL, 0, uf::renderer::enums::Format::R32_UINT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
|
||||
auto& normal = sceneTextures.voxels.normal.emplace_back();
|
||||
normal.fromBuffers( NULL, 0, uf::renderer::enums::Format::R32_UINT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
|
||||
|
||||
auto& radianceR = sceneTextures.voxels.radianceR.emplace_back();
|
||||
radianceR.fromBuffers( NULL, 0, uf::renderer::enums::Format::R32_UINT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
|
||||
auto& radiance = sceneTextures.voxels.radiance.emplace_back();
|
||||
radiance.fromBuffers( NULL, 0, uf::renderer::enums::Format::R32_UINT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
|
||||
|
||||
auto& radianceG = sceneTextures.voxels.radianceG.emplace_back();
|
||||
radianceG.fromBuffers( NULL, 0, uf::renderer::enums::Format::R32_UINT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
|
||||
|
||||
auto& radianceB = sceneTextures.voxels.radianceB.emplace_back();
|
||||
radianceB.fromBuffers( NULL, 0, uf::renderer::enums::Format::R32_UINT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
|
||||
|
||||
auto& radianceA = sceneTextures.voxels.radianceA.emplace_back();
|
||||
radianceA.fromBuffers( NULL, 0, uf::renderer::enums::Format::R32_UINT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
|
||||
|
||||
auto& count = sceneTextures.voxels.count.emplace_back();
|
||||
count.fromBuffers( NULL, 0, uf::renderer::enums::Format::R32_UINT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
|
||||
|
||||
auto& output = sceneTextures.voxels.output.emplace_back();
|
||||
/*
|
||||
if ( metadata.filtering == "NEAREST" ) {
|
||||
output.sampler.descriptor.filter.min = uf::renderer::enums::Filter::NEAREST;
|
||||
output.sampler.descriptor.filter.mag = uf::renderer::enums::Filter::NEAREST;
|
||||
}
|
||||
*/
|
||||
// output.fromBuffers( NULL, 0, uf::renderer::settings::pipelines::hdr ? uf::renderer::enums::Format::HDR : uf::renderer::enums::Format::SDR, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
|
||||
#if ALIAS_OUTPUT_TO_RADIANCE
|
||||
output.aliasTexture( radiance );
|
||||
{
|
||||
VkImageViewCreateInfo viewCreateInfo = {};
|
||||
viewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
viewCreateInfo.image = radiance.image;
|
||||
viewCreateInfo.viewType = radiance.viewType;
|
||||
viewCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
viewCreateInfo.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
|
||||
viewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
viewCreateInfo.subresourceRange.baseMipLevel = 0;
|
||||
viewCreateInfo.subresourceRange.levelCount = radiance.mips;
|
||||
viewCreateInfo.subresourceRange.baseArrayLayer = 0;
|
||||
viewCreateInfo.subresourceRange.layerCount = 1;
|
||||
|
||||
VK_CHECK_RESULT(vkCreateImageView(uf::renderer::device.logicalDevice, &viewCreateInfo, nullptr, &output.view));
|
||||
VK_REGISTER_HANDLE( output.view );
|
||||
}
|
||||
#else
|
||||
output.fromBuffers( NULL, 0, uf::renderer::enums::Format::R8G8B8A8_UNORM, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
|
||||
#endif
|
||||
}
|
||||
// initialize render mode
|
||||
{
|
||||
@ -120,15 +123,9 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) {
|
||||
for ( size_t i = 0; i < maxTexturesCube; ++i ) renderMode.blitter.material.textures.emplace_back().aliasTexture(uf::renderer::TextureCube::empty);
|
||||
for ( size_t i = 0; i < maxTextures3D; ++i ) renderMode.blitter.material.textures.emplace_back().aliasTexture(uf::renderer::Texture3D::empty);
|
||||
|
||||
for ( auto& t : sceneTextures.voxels.drawId ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.instanceId ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.normalX ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.normalY ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.radianceR ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.radianceG ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.radianceB ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.radianceA ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.count ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.id ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.normal ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.radiance ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.output ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
|
||||
|
||||
renderMode.bindCallback( renderMode.CALLBACK_BEGIN, [&]( VkCommandBuffer commandBuffer, size_t _ ){
|
||||
@ -141,15 +138,9 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) {
|
||||
subresourceRange.layerCount = 1;
|
||||
|
||||
VkClearColorValue clearColor = { 0.0, 0.0, 0.0, 0.0 };
|
||||
for ( auto& t : sceneTextures.voxels.drawId ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
||||
for ( auto& t : sceneTextures.voxels.instanceId ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
||||
for ( auto& t : sceneTextures.voxels.normalX ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
||||
for ( auto& t : sceneTextures.voxels.normalY ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
||||
for ( auto& t : sceneTextures.voxels.radianceR ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
||||
for ( auto& t : sceneTextures.voxels.radianceG ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
||||
for ( auto& t : sceneTextures.voxels.radianceB ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
||||
for ( auto& t : sceneTextures.voxels.radianceA ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
||||
for ( auto& t : sceneTextures.voxels.count ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
||||
for ( auto& t : sceneTextures.voxels.id ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
||||
for ( auto& t : sceneTextures.voxels.normal ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
||||
for ( auto& t : sceneTextures.voxels.radiance ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
||||
for ( auto& t : sceneTextures.voxels.output ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
||||
});
|
||||
|
||||
@ -287,15 +278,16 @@ void ext::VoxelizerSceneBehavior::tick( uf::Object& self ) {
|
||||
}
|
||||
void ext::VoxelizerSceneBehavior::render( uf::Object& self ){}
|
||||
void ext::VoxelizerSceneBehavior::destroy( uf::Object& self ){
|
||||
#if UF_USE_VULKAN
|
||||
/*
|
||||
if ( this->hasComponent<uf::renderer::RenderTargetRenderMode>() ) {
|
||||
auto& renderMode = this->getComponent<uf::renderer::RenderTargetRenderMode>();
|
||||
|
||||
uf::renderer::removeRenderMode( &renderMode, false );
|
||||
// this->deleteComponent<uf::renderer::RenderTargetRenderMode>();
|
||||
#if ALIAS_OUTPUT_TO_RADIANCE
|
||||
auto& sceneTextures = this->getComponent<pod::SceneTextures>();
|
||||
for ( auto& t : sceneTextures.voxels.output ) {
|
||||
ext::vulkan::mutex.lock();
|
||||
auto& texture = uf::renderer::device.transient.textures.emplace_back();
|
||||
ext::vulkan::mutex.unlock();
|
||||
|
||||
texture.device = &uf::renderer::device;
|
||||
texture.view = t.view;
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
void ext::VoxelizerSceneBehavior::Metadata::serialize( uf::Object& self, uf::Serializer& serializer ) {
|
||||
|
||||
@ -80,20 +80,23 @@ namespace {
|
||||
for ( auto& key : storage.texture2Ds.keys ) graphic.material.textures.emplace_back().aliasTexture( storage.texture2Ds.map[key] );
|
||||
|
||||
// bind scene's voxel texture
|
||||
#if UF_USE_VULKAN
|
||||
#if 0 && UF_USE_VULKAN
|
||||
if ( uf::renderer::settings::pipelines::vxgi ) {
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& sceneTextures = scene.getComponent<pod::SceneTextures>();
|
||||
for ( auto& t : sceneTextures.voxels.drawId ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.instanceId ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.normalX ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.normalY ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.radianceR ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.radianceG ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.radianceB ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.radianceA ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.count ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.id ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.normal ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.radiance ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.output ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||
/*
|
||||
auto& shader = graphic.material.getShader("fragment", uf::renderer::settings::pipelines::names::vxgi);
|
||||
shader.textures.clear();
|
||||
|
||||
for ( auto& t : sceneTextures.voxels.id ) shader.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.normal ) shader.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.radiance ) shader.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.output ) shader.textures.emplace_back().aliasTexture(t);
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -219,21 +222,9 @@ namespace {
|
||||
graphic.material.attachShader(geometryShaderFilename, uf::renderer::enums::Shader::GEOMETRY, uf::renderer::settings::pipelines::names::vxgi);
|
||||
}
|
||||
|
||||
uint32_t voxelTypes = 0;
|
||||
if ( !sceneTextures.voxels.drawId.empty() ) ++voxelTypes;
|
||||
if ( !sceneTextures.voxels.instanceId.empty() ) ++voxelTypes;
|
||||
if ( !sceneTextures.voxels.normalX.empty() ) ++voxelTypes;
|
||||
if ( !sceneTextures.voxels.normalY.empty() ) ++voxelTypes;
|
||||
if ( !sceneTextures.voxels.radianceR.empty() ) ++voxelTypes;
|
||||
if ( !sceneTextures.voxels.radianceG.empty() ) ++voxelTypes;
|
||||
if ( !sceneTextures.voxels.radianceB.empty() ) ++voxelTypes;
|
||||
if ( !sceneTextures.voxels.radianceA.empty() ) ++voxelTypes;
|
||||
if ( !sceneTextures.voxels.count.empty() ) ++voxelTypes;
|
||||
if ( !sceneTextures.voxels.output.empty() ) ++voxelTypes;
|
||||
|
||||
uint32_t maxTextures = texture2Ds;
|
||||
uint32_t maxCascades = texture3Ds / voxelTypes;
|
||||
|
||||
uint32_t maxCascades = sceneTextures.voxels.id.size();
|
||||
|
||||
// fragment shader
|
||||
{
|
||||
auto& shader = graphic.material.getShader("fragment", uf::renderer::settings::pipelines::names::vxgi);
|
||||
@ -243,17 +234,16 @@ namespace {
|
||||
});
|
||||
shader.setDescriptorCounts({
|
||||
{ "samplerTextures", maxTextures },
|
||||
{ "voxelDrawId", maxCascades },
|
||||
{ "voxelInstanceId", maxCascades },
|
||||
{ "voxelNormalX", maxCascades },
|
||||
{ "voxelNormalY", maxCascades },
|
||||
{ "voxelRadianceR", maxCascades },
|
||||
{ "voxelRadianceG", maxCascades },
|
||||
{ "voxelRadianceB", maxCascades },
|
||||
{ "voxelRadianceA", maxCascades },
|
||||
{ "voxelCount", maxCascades },
|
||||
{ "voxelId", maxCascades },
|
||||
{ "voxelNormal", maxCascades },
|
||||
{ "voxelRadiance", maxCascades },
|
||||
{ "voxelOutput", maxCascades },
|
||||
});
|
||||
|
||||
for ( auto& t : sceneTextures.voxels.id ) shader.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.normal ) shader.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.radiance ) shader.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.output ) shader.textures.emplace_back().aliasTexture(t);
|
||||
}
|
||||
}
|
||||
// baking pipeline
|
||||
|
||||
@ -273,17 +273,17 @@ for ( auto& p : m.primitives ) {
|
||||
};
|
||||
|
||||
float r = 1.0f / (deltaTriUV[0].x * deltaTriUV[1].y - deltaTriUV[0].y * deltaTriUV[1].x);
|
||||
auto tangent_tri = (deltaTriPosition[0] * deltaTriUV[1].y - deltaTriPosition[1] * deltaTriUV[0].y) * r;
|
||||
auto bitangent_tri = (deltaTriPosition[1] * deltaTriUV[0].x - deltaTriPosition[0] * deltaTriUV[1].x) * r;
|
||||
auto tangent_tri = (deltaTriPosition[0] * deltaTriUV[1].y - deltaTriPosition[1] * deltaTriUV[0].y) * r;
|
||||
auto bitangent_tri = (deltaTriPosition[1] * deltaTriUV[0].x - deltaTriPosition[0] * deltaTriUV[1].x) * r;
|
||||
|
||||
for ( auto i = 0; i < 3; ++i ) {
|
||||
auto& normal = meshlet.vertices[indices[0]].normal;
|
||||
auto& tangent = meshlet.vertices[indices[0]].tangent;
|
||||
for ( auto i = 0; i < 3; ++i ) {
|
||||
auto& normal = meshlet.vertices[indices[0]].normal;
|
||||
auto& tangent = meshlet.vertices[indices[0]].tangent;
|
||||
tangent = uf::vector::normalize(tangent_tri - normal * uf::vector::dot(normal, tangent_tri));
|
||||
|
||||
if (uf::vector::dot(uf::vector::cross(normal, tangent), bitangent_tri) < 0.0f)
|
||||
tangent = tangent * -1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for ( size_t i = 0; i < meshlet.vertices.size() / 3; ++i ) {
|
||||
@ -313,17 +313,17 @@ for ( auto& p : m.primitives ) {
|
||||
};
|
||||
|
||||
float r = 1.0f / (deltaTriUV[0].x * deltaTriUV[1].y - deltaTriUV[0].y * deltaTriUV[1].x);
|
||||
auto tangent_tri = (deltaTriPosition[0] * deltaTriUV[1].y - deltaTriPosition[1] * deltaTriUV[0].y) * r;
|
||||
auto bitangent_tri = (deltaTriPosition[1] * deltaTriUV[0].x - deltaTriPosition[0] * deltaTriUV[1].x) * r;
|
||||
auto tangent_tri = (deltaTriPosition[0] * deltaTriUV[1].y - deltaTriPosition[1] * deltaTriUV[0].y) * r;
|
||||
auto bitangent_tri = (deltaTriPosition[1] * deltaTriUV[0].x - deltaTriPosition[0] * deltaTriUV[1].x) * r;
|
||||
|
||||
for ( auto i = 0; i < 3; ++i ) {
|
||||
auto& normal = meshlet.vertices[indices[0]].normal;
|
||||
auto& tangent = meshlet.vertices[indices[0]].tangent;
|
||||
for ( auto i = 0; i < 3; ++i ) {
|
||||
auto& normal = meshlet.vertices[indices[0]].normal;
|
||||
auto& tangent = meshlet.vertices[indices[0]].tangent;
|
||||
tangent = uf::vector::normalize(tangent_tri - normal * uf::vector::dot(normal, tangent_tri));
|
||||
|
||||
if (uf::vector::dot(uf::vector::cross(normal, tangent), bitangent_tri) < 0.0f)
|
||||
tangent = tangent * -1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -173,10 +173,12 @@ void ext::imgui::tick() {
|
||||
auto& renderMode = uf::renderer::getRenderMode("Gui", true);
|
||||
|
||||
// check if rendermode changed
|
||||
#if UF_USE_VULKAN
|
||||
if ( ::boundRenderMode != &renderMode ) {
|
||||
::shutdownRenderer();
|
||||
::initRenderer();
|
||||
}
|
||||
#endif
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.DeltaTime = uf::physics::time::delta;
|
||||
|
||||
@ -19,6 +19,7 @@ namespace {
|
||||
struct Pair {
|
||||
bool aliased = false;
|
||||
size_t index = 0;
|
||||
size_t size = 0;
|
||||
};
|
||||
uf::stl::vector<void*> local;
|
||||
uf::stl::vector<void*> aliases;
|
||||
@ -105,7 +106,7 @@ void ext::opengl::Device::initialize() {
|
||||
#endif
|
||||
#if UF_USE_OPENGL_FIXED_FUNCTION
|
||||
{
|
||||
::buffers::type.emplace_back(::buffers::Pair{.aliased = false, .index = 0});
|
||||
::buffers::type.emplace_back(::buffers::Pair{.aliased = false, .index = 0, .size = 0});
|
||||
::buffers::local.emplace_back((void*) NULL);
|
||||
}
|
||||
#endif
|
||||
@ -172,7 +173,7 @@ GLuint ext::opengl::Device::createBuffer( enums::Buffer::type_t usage, GLsizeipt
|
||||
#else
|
||||
// CPU-based buffer
|
||||
index = ::buffers::type.size();
|
||||
::buffers::type.emplace_back( ::buffers::Pair{.aliased = aliased, .index = index} );
|
||||
::buffers::type.emplace_back( ::buffers::Pair{.aliased = aliased, .index = index, .size = size} );
|
||||
|
||||
if ( aliased ) {
|
||||
::buffers::aliases.emplace_back( data );
|
||||
@ -215,11 +216,11 @@ void ext::opengl::Device::destroyBuffer( GLuint& index ) {
|
||||
auto& buffer = ::buffers::local[type.index];
|
||||
if ( buffer ) {
|
||||
#if UF_MEMORYPOOL_INVALID_FREE
|
||||
uf::memoryPool::global.free( buffer );
|
||||
uf::memoryPool::global.free( buffer, type.size );
|
||||
#else
|
||||
uf::MemoryPool* memoryPool = uf::memoryPool::global.size() > 0 ? &uf::memoryPool::global : NULL;
|
||||
if ( memoryPool ) memoryPool->free( buffer );
|
||||
else free( buffer );
|
||||
if ( memoryPool ) memoryPool->free( buffer, type.size );
|
||||
else free( buffer, type.size );
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1226,13 +1226,13 @@ void ext::vulkan::Graphic::generateBottomAccelerationStructures() {
|
||||
uf::stl::vector<VkAccelerationStructureBuildRangeInfoKHR> asBuildOffsetInfo;
|
||||
VkBuildAccelerationStructureFlagsKHR flags{};
|
||||
|
||||
VkAccelerationStructureBuildGeometryInfoKHR buildInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR};
|
||||
VkAccelerationStructureBuildSizesInfoKHR sizeInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR};
|
||||
VkAccelerationStructureBuildGeometryInfoKHR buildInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR};
|
||||
VkAccelerationStructureBuildSizesInfoKHR sizeInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR};
|
||||
|
||||
const VkAccelerationStructureBuildRangeInfoKHR* rangeInfo;
|
||||
uf::renderer::AccelerationStructure as;
|
||||
|
||||
uf::renderer::AccelerationStructure previous;
|
||||
const VkAccelerationStructureBuildRangeInfoKHR* rangeInfo;
|
||||
uf::renderer::AccelerationStructure as;
|
||||
|
||||
uf::renderer::AccelerationStructure previous;
|
||||
};
|
||||
uf::stl::vector<BlasData> blasDatas;
|
||||
|
||||
@ -1297,7 +1297,7 @@ void ext::vulkan::Graphic::generateBottomAccelerationStructures() {
|
||||
triangles.indexData.deviceAddress = indexBufferAddress;
|
||||
|
||||
VkAccelerationStructureBuildRangeInfoKHR& offset = blasData.asBuildOffsetInfo.emplace_back();
|
||||
offset.firstVertex = vertexInput.first;
|
||||
offset.firstVertex = vertexInput.first;
|
||||
offset.primitiveCount = vertexInput.count / 3;
|
||||
offset.primitiveOffset = indexInput.first * indexInput.size;
|
||||
offset.transformOffset = 0;
|
||||
@ -1334,7 +1334,7 @@ void ext::vulkan::Graphic::generateBottomAccelerationStructures() {
|
||||
triangles.indexData.deviceAddress = indexBufferAddress;
|
||||
|
||||
VkAccelerationStructureBuildRangeInfoKHR& offset = blasData.asBuildOffsetInfo.emplace_back();
|
||||
offset.firstVertex = vertexInput.first;
|
||||
offset.firstVertex = vertexInput.first;
|
||||
offset.primitiveCount = vertexInput.count / 3;
|
||||
offset.primitiveOffset = indexInput.first * indexInput.size;
|
||||
offset.transformOffset = 0;
|
||||
@ -1715,7 +1715,7 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect
|
||||
buildInfo.dstAccelerationStructure = tlas.handle;
|
||||
buildInfo.scratchData.deviceAddress = scratchBuffer.getAddress();
|
||||
|
||||
VkAccelerationStructureBuildRangeInfoKHR buildOffsetInfo{countInstance, 0, 0, 0};
|
||||
VkAccelerationStructureBuildRangeInfoKHR buildOffsetInfo{countInstance, 0, 0, 0};
|
||||
const VkAccelerationStructureBuildRangeInfoKHR* rangeInfo = &buildOffsetInfo;
|
||||
|
||||
auto commandBuffer = device.fetchCommandBuffer(uf::renderer::QueueEnum::COMPUTE);
|
||||
|
||||
@ -329,15 +329,9 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
shader.setDescriptorCounts({
|
||||
{ "samplerTextures", maxTextures2D },
|
||||
{ "samplerCubemaps", maxTexturesCube },
|
||||
{ "voxelDrawId", maxCascades },
|
||||
{ "voxelInstanceId", maxCascades },
|
||||
{ "voxelNormalX", maxCascades },
|
||||
{ "voxelNormalY", maxCascades },
|
||||
{ "voxelRadianceR", maxCascades },
|
||||
{ "voxelRadianceG", maxCascades },
|
||||
{ "voxelRadianceB", maxCascades },
|
||||
{ "voxelRadianceA", maxCascades },
|
||||
{ "voxelCount", maxCascades },
|
||||
{ "voxelId", maxCascades },
|
||||
{ "voxelNormal", maxCascades },
|
||||
{ "voxelRadiance", maxCascades },
|
||||
{ "voxelOutput", maxCascades },
|
||||
});
|
||||
|
||||
|
||||
@ -316,6 +316,7 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
|
||||
{uf::io::resolveURI(fragmentShaderFilename), VK_SHADER_STAGE_FRAGMENT_BIT}
|
||||
});
|
||||
}
|
||||
|
||||
if ( metadata.type == uf::renderer::settings::pipelines::names::vxgi ) {
|
||||
auto& shader = blitter.material.getShader("compute");
|
||||
|
||||
@ -333,17 +334,21 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
|
||||
shader.setDescriptorCounts({
|
||||
{ "samplerTextures", maxTextures2D },
|
||||
{ "samplerCubemaps", maxTexturesCube },
|
||||
{ "voxelDrawId", maxCascades },
|
||||
{ "voxelInstanceId", maxCascades },
|
||||
{ "voxelNormalX", maxCascades },
|
||||
{ "voxelNormalY", maxCascades },
|
||||
{ "voxelRadianceR", maxCascades },
|
||||
{ "voxelRadianceG", maxCascades },
|
||||
{ "voxelRadianceB", maxCascades },
|
||||
{ "voxelRadianceA", maxCascades },
|
||||
{ "voxelCount", maxCascades },
|
||||
{ "voxelId", maxCascades },
|
||||
{ "voxelNormal", maxCascades },
|
||||
{ "voxelRadiance", maxCascades },
|
||||
{ "voxelOutput", maxCascades },
|
||||
});
|
||||
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& sceneTextures = scene.getComponent<pod::SceneTextures>();
|
||||
|
||||
shader.textures.clear();
|
||||
|
||||
for ( auto& t : sceneTextures.voxels.id ) shader.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.normal ) shader.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.radiance ) shader.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.output ) shader.textures.emplace_back().aliasTexture(t);
|
||||
} else if ( metadata.type == uf::renderer::settings::pipelines::names::rt ) {
|
||||
#if 0
|
||||
auto& shader = blitter.material.getShader("fragment");
|
||||
|
||||
@ -36,14 +36,14 @@ namespace {
|
||||
}
|
||||
if ( image == VK_NULL_HANDLE ) continue;
|
||||
subresourceRange.baseMipLevel = 0;
|
||||
subresourceRange.levelCount = 1;
|
||||
subresourceRange.levelCount = 1;
|
||||
subresourceRange.aspectMask = descriptor.name == "depth" ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
uf::renderer::Texture::setImageLayout( commandBuffer, image, layout, descriptor.layout, subresourceRange );
|
||||
if ( mips > 1 ) {
|
||||
subresourceRange.baseMipLevel = 1;
|
||||
subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||
uf::renderer::Texture::setImageLayout( commandBuffer, image, initialLayout, descriptor.layout, subresourceRange );
|
||||
}
|
||||
subresourceRange.baseMipLevel = 1;
|
||||
subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||
uf::renderer::Texture::setImageLayout( commandBuffer, image, initialLayout, descriptor.layout, subresourceRange );
|
||||
}
|
||||
}
|
||||
}
|
||||
void transitionAttachmentsFrom(
|
||||
@ -83,14 +83,14 @@ namespace {
|
||||
}
|
||||
if ( image == VK_NULL_HANDLE ) continue;
|
||||
subresourceRange.baseMipLevel = 0;
|
||||
subresourceRange.levelCount = 1;
|
||||
subresourceRange.levelCount = 1;
|
||||
subresourceRange.aspectMask = descriptor.name == "depth" ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
uf::renderer::Texture::setImageLayout( commandBuffer, image, descriptor.layout, layout, subresourceRange );
|
||||
if ( mips > 1 ) {
|
||||
subresourceRange.baseMipLevel = 1;
|
||||
subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||
uf::renderer::Texture::setImageLayout( commandBuffer, image, descriptor.layout, initialLayout, subresourceRange );
|
||||
}
|
||||
subresourceRange.baseMipLevel = 1;
|
||||
subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||
uf::renderer::Texture::setImageLayout( commandBuffer, image, descriptor.layout, initialLayout, subresourceRange );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -371,35 +371,39 @@ void ext::vulkan::Texture::loadFromFile(
|
||||
const uf::stl::string& filename,
|
||||
VkFormat format,
|
||||
VkImageUsageFlags usage,
|
||||
VkImageLayout layout
|
||||
VkImageLayout layout,
|
||||
VkImageCreateFlags flags
|
||||
) {
|
||||
return loadFromFile( filename, ext::vulkan::device, format, usage, layout );
|
||||
return loadFromFile( filename, ext::vulkan::device, format, usage, layout, flags );
|
||||
}
|
||||
void ext::vulkan::Texture::loadFromFile(
|
||||
const uf::stl::string& filename,
|
||||
Device& device,
|
||||
VkFormat format,
|
||||
VkImageUsageFlags usage,
|
||||
VkImageLayout layout
|
||||
VkImageLayout layout,
|
||||
VkImageCreateFlags flags
|
||||
) {
|
||||
uf::Image image;
|
||||
image.open( filename );
|
||||
return loadFromImage( image, device, format, usage, layout );
|
||||
return loadFromImage( image, device, format, usage, layout, flags );
|
||||
}
|
||||
void ext::vulkan::Texture::loadFromImage(
|
||||
const uf::Image& image,
|
||||
VkFormat format,
|
||||
VkImageUsageFlags usage,
|
||||
VkImageLayout layout
|
||||
VkImageLayout layout,
|
||||
VkImageCreateFlags flags
|
||||
) {
|
||||
return loadFromImage( image, ext::vulkan::device, format, usage, layout );
|
||||
return loadFromImage( image, ext::vulkan::device, format, usage, layout, flags );
|
||||
}
|
||||
void ext::vulkan::Texture::loadFromImage(
|
||||
const uf::Image& image,
|
||||
Device& device,
|
||||
VkFormat format,
|
||||
VkImageUsageFlags usage,
|
||||
VkImageLayout layout
|
||||
VkImageLayout layout,
|
||||
VkImageCreateFlags flags
|
||||
) {
|
||||
/*
|
||||
switch ( format ) {
|
||||
@ -474,7 +478,8 @@ void ext::vulkan::Texture::loadFromImage(
|
||||
1,
|
||||
device,
|
||||
usage,
|
||||
layout
|
||||
layout,
|
||||
flags
|
||||
);
|
||||
}
|
||||
|
||||
@ -487,9 +492,10 @@ void ext::vulkan::Texture::fromBuffers(
|
||||
uint32_t texDepth,
|
||||
uint32_t layers,
|
||||
VkImageUsageFlags usage,
|
||||
VkImageLayout layout
|
||||
VkImageLayout layout,
|
||||
VkImageCreateFlags flags
|
||||
) {
|
||||
return this->fromBuffers( buffer, bufferSize, format, texWidth, texHeight, texDepth, layers, ext::vulkan::device, usage, layout );
|
||||
return this->fromBuffers( buffer, bufferSize, format, texWidth, texHeight, texDepth, layers, ext::vulkan::device, usage, layout, flags );
|
||||
}
|
||||
|
||||
|
||||
@ -503,11 +509,13 @@ void ext::vulkan::Texture::fromBuffers(
|
||||
uint32_t layers,
|
||||
Device& device,
|
||||
VkImageUsageFlags usage,
|
||||
VkImageLayout layout
|
||||
VkImageLayout layout,
|
||||
VkImageCreateFlags flags
|
||||
) {
|
||||
this->initialize(device, texWidth, texHeight, texDepth, layers);
|
||||
this->layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
this->initialize( device, texWidth, texHeight, texDepth, layers );
|
||||
this->usage = usage;
|
||||
this->layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
this->flags = flags;
|
||||
|
||||
if ( this->mips == 0 ) {
|
||||
this->mips = 1;
|
||||
@ -545,6 +553,7 @@ void ext::vulkan::Texture::fromBuffers(
|
||||
imageCreateInfo.initialLayout = this->layout;
|
||||
imageCreateInfo.extent = { width, height, depth };
|
||||
imageCreateInfo.usage = this->usage;
|
||||
imageCreateInfo.flags = this->flags;
|
||||
// Ensure that the TRANSFER_SRC bit is set for mip creation
|
||||
if ( this->mips > 1 && !(imageCreateInfo.usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT)) {
|
||||
imageCreateInfo.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||
@ -555,7 +564,7 @@ void ext::vulkan::Texture::fromBuffers(
|
||||
}
|
||||
// Ensure cube maps get the compat flag bit
|
||||
if ( this->viewType == ext::vulkan::enums::Image::VIEW_TYPE_CUBE || this->viewType == ext::vulkan::enums::Image::VIEW_TYPE_CUBE_ARRAY ) {
|
||||
imageCreateInfo.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
|
||||
imageCreateInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
|
||||
}
|
||||
|
||||
VmaAllocationCreateInfo allocInfo = {};
|
||||
@ -955,8 +964,8 @@ void ext::vulkan::Texture::generateMipmaps( VkCommandBuffer commandBuffer, uint3
|
||||
);
|
||||
|
||||
if (mipWidth > 1) mipWidth /= 2;
|
||||
if (mipHeight > 1) mipHeight /= 2;
|
||||
if (mipDepth > 1) mipDepth /= 2;
|
||||
if (mipHeight > 1) mipHeight /= 2;
|
||||
if (mipDepth > 1) mipDepth /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
#if UF_USE_XATLAS
|
||||
#include <xatlas/xatlas.h>
|
||||
|
||||
#define UF_XATLAS_UNWRAP_MULTITHREAD 1 // prone to crashing
|
||||
#define UF_XATLAS_UNWRAP_MULTITHREAD 1
|
||||
|
||||
size_t ext::xatlas::unwrap( pod::Graph& graph ) {
|
||||
struct Entry {
|
||||
@ -56,50 +56,49 @@ size_t ext::xatlas::unwrap( pod::Graph& graph ) {
|
||||
if ( !should ) continue;
|
||||
|
||||
source = mesh;
|
||||
source.updateDescriptor();
|
||||
source.updateDescriptor();
|
||||
|
||||
for ( size_t viewIdx = 0; viewIdx < source.buffer_views.size(); ++viewIdx ) {
|
||||
const auto& view = source.buffer_views[viewIdx];
|
||||
for ( size_t viewIdx = 0; viewIdx < source.buffer_views.size(); ++viewIdx ) {
|
||||
const auto& view = source.buffer_views[viewIdx];
|
||||
|
||||
size_t atlasID = 0;
|
||||
if ( view.indirectIndex != -1 ) {
|
||||
pod::DrawCommand* drawCommands = (pod::DrawCommand*) mesh.getBuffer(mesh.indirect).data();
|
||||
atlasID = drawCommands[view.indirectIndex].auxID;
|
||||
}
|
||||
size_t atlasID = 0;
|
||||
if ( view.indirectIndex != -1 ) {
|
||||
pod::DrawCommand* drawCommands = (pod::DrawCommand*) mesh.getBuffer(mesh.indirect).data();
|
||||
atlasID = drawCommands[view.indirectIndex].auxID;
|
||||
}
|
||||
|
||||
auto& atlas = atlases[atlasID];
|
||||
auto& entry = atlas.entries.emplace_back();
|
||||
entry.index = index;
|
||||
entry.commandID = viewIdx;
|
||||
auto& atlas = atlases[atlasID];
|
||||
auto& entry = atlas.entries.emplace_back();
|
||||
entry.index = index;
|
||||
entry.commandID = viewIdx;
|
||||
|
||||
auto& decl = entry.decl;
|
||||
auto posView = view["position"];
|
||||
auto uvView = view["uv"];
|
||||
auto idxView = view["index"];
|
||||
auto& decl = entry.decl;
|
||||
auto posView = view["position"];
|
||||
auto uvView = view["uv"];
|
||||
auto idxView = view["index"];
|
||||
|
||||
UF_ASSERT( posView.valid() && uvView.valid() );
|
||||
UF_ASSERT( posView.valid() && uvView.valid() );
|
||||
|
||||
decl.vertexCount = view.vertex.count;
|
||||
decl.vertexPositionData = posView.data(view.vertex.first);
|
||||
decl.vertexPositionStride = posView.stride();
|
||||
decl.vertexUvData = uvView.data(view.vertex.first);
|
||||
decl.vertexUvStride = uvView.stride();
|
||||
decl.vertexCount = view.vertex.count;
|
||||
decl.vertexPositionData = posView.data(view.vertex.first);
|
||||
decl.vertexPositionStride = posView.stride();
|
||||
decl.vertexUvData = uvView.data(view.vertex.first);
|
||||
decl.vertexUvStride = uvView.stride();
|
||||
|
||||
if ( idxView.valid() ) {
|
||||
decl.indexCount = view.index.count;
|
||||
// Pass view.index.first to offset the index pointer!
|
||||
decl.indexData = idxView.data(view.index.first);
|
||||
if ( idxView.valid() ) {
|
||||
decl.indexCount = view.index.count;
|
||||
decl.indexData = idxView.data(view.index.first);
|
||||
|
||||
switch ( idxView.attribute.descriptor.size ) {
|
||||
case 1: UF_EXCEPTION("xatlas does not support 8-bit indices"); break;
|
||||
case 2: decl.indexFormat = ::xatlas::IndexFormat::UInt16; break;
|
||||
case 4: decl.indexFormat = ::xatlas::IndexFormat::UInt32; break;
|
||||
default: UF_EXCEPTION("unsupported index type"); break;
|
||||
}
|
||||
} else {
|
||||
decl.indexCount = 0;
|
||||
}
|
||||
}
|
||||
switch ( idxView.attribute.descriptor.size ) {
|
||||
case 1: UF_EXCEPTION("xatlas does not support 8-bit indices"); break;
|
||||
case 2: decl.indexFormat = ::xatlas::IndexFormat::UInt16; break;
|
||||
case 4: decl.indexFormat = ::xatlas::IndexFormat::UInt32; break;
|
||||
default: UF_EXCEPTION("unsupported index type"); break;
|
||||
}
|
||||
} else {
|
||||
decl.indexCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::xatlas::ChartOptions chartOptions{};
|
||||
@ -236,70 +235,63 @@ size_t ext::xatlas::unwrap( pod::Graph& graph ) {
|
||||
|
||||
// update vertices
|
||||
for ( auto& pair : atlases ) {
|
||||
auto& atlas = pair.second;
|
||||
auto& atlas = pair.second;
|
||||
|
||||
for ( auto i = 0; i < atlas.pointer->meshCount; i++ ) {
|
||||
auto& xmesh = atlas.pointer->meshes[i];
|
||||
auto& entry = atlas.entries[i];
|
||||
for ( auto i = 0; i < atlas.pointer->meshCount; i++ ) {
|
||||
auto& xmesh = atlas.pointer->meshes[i];
|
||||
auto& entry = atlas.entries[i];
|
||||
|
||||
auto& name = graph.meshes[entry.index];
|
||||
auto& mesh = storage.meshes[name];
|
||||
auto& source = sources[entry.index];
|
||||
auto& name = graph.meshes[entry.index];
|
||||
auto& mesh = storage.meshes[name];
|
||||
auto& source = sources[entry.index];
|
||||
|
||||
if ( source.vertex.count == 0 ) continue;
|
||||
if ( source.vertex.count == 0 ) continue;
|
||||
|
||||
// Grab the read-only view from our unmodified source mesh
|
||||
const auto& srcView = source.buffer_views[entry.commandID];
|
||||
const auto& srcView = source.buffer_views[entry.commandID];
|
||||
|
||||
// We dynamically calculate the destination offsets using the updated draw commands
|
||||
// Or if it's direct, it's just 0.
|
||||
size_t dstVertexFirst = 0;
|
||||
size_t dstIndexFirst = 0;
|
||||
if ( mesh.indirect.count > 0 ) {
|
||||
pod::DrawCommand* drawCommands = (pod::DrawCommand*) mesh.getBuffer(mesh.indirect).data();
|
||||
dstVertexFirst = drawCommands[entry.commandID].vertexID;
|
||||
dstIndexFirst = drawCommands[entry.commandID].indexID;
|
||||
}
|
||||
size_t dstVertexFirst = 0;
|
||||
size_t dstIndexFirst = 0;
|
||||
if ( mesh.indirect.count > 0 ) {
|
||||
pod::DrawCommand* drawCommands = (pod::DrawCommand*) mesh.getBuffer(mesh.indirect).data();
|
||||
dstVertexFirst = drawCommands[entry.commandID].vertexID;
|
||||
dstIndexFirst = drawCommands[entry.commandID].indexID;
|
||||
}
|
||||
|
||||
// 1. Copy over the vertices based on the xref mapping
|
||||
for ( auto j = 0; j < xmesh.vertexCount; ++j ) {
|
||||
auto& vertex = xmesh.vertexArray[j];
|
||||
uint32_t ref = vertex.xref; // original vertex index relative to the sub-mesh
|
||||
for ( auto j = 0; j < xmesh.vertexCount; ++j ) {
|
||||
auto& vertex = xmesh.vertexArray[j];
|
||||
uint32_t ref = vertex.xref; // original vertex index relative to the sub-mesh
|
||||
|
||||
for ( auto attrIdx = 0; attrIdx < mesh.vertex.attributes.size(); ++attrIdx ) {
|
||||
auto srcAttribute = srcView.vertex.attributes[attrIdx];
|
||||
auto dstAttribute = mesh.vertex.attributes[attrIdx];
|
||||
for ( auto attrIdx = 0; attrIdx < mesh.vertex.attributes.size(); ++attrIdx ) {
|
||||
auto srcAttribute = srcView.vertex.attributes[attrIdx];
|
||||
auto dstAttribute = mesh.vertex.attributes[attrIdx];
|
||||
|
||||
uint8_t* dstPtr = static_cast<uint8_t*>(dstAttribute.pointer) + dstAttribute.stride * (dstVertexFirst + j);
|
||||
uint8_t* dstPtr = static_cast<uint8_t*>(dstAttribute.pointer) + dstAttribute.stride * (dstVertexFirst + j);
|
||||
|
||||
if ( dstAttribute.descriptor.name == "st" ) {
|
||||
// Write new lightmap STs!
|
||||
pod::Vector2f& st = *(pod::Vector2f*)dstPtr;
|
||||
st = pod::Vector2f{ vertex.uv[0] / atlas.pointer->width, vertex.uv[1] / atlas.pointer->height };
|
||||
} else {
|
||||
// Copy original vertex data
|
||||
const uint8_t* srcPtr = static_cast<const uint8_t*>(srcAttribute.pointer) + srcAttribute.stride * (srcView.vertex.first + ref);
|
||||
memcpy(dstPtr, srcPtr, srcAttribute.descriptor.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( dstAttribute.descriptor.name == "st" ) {
|
||||
pod::Vector2f& st = *(pod::Vector2f*)dstPtr;
|
||||
st = pod::Vector2f{ vertex.uv[0] / atlas.pointer->width, vertex.uv[1] / atlas.pointer->height };
|
||||
} else {
|
||||
const uint8_t* srcPtr = static_cast<const uint8_t*>(srcAttribute.pointer) + srcAttribute.stride * (srcView.vertex.first + ref);
|
||||
memcpy(dstPtr, srcPtr, srcAttribute.descriptor.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Write new indices
|
||||
if ( mesh.index.count ) {
|
||||
uf::Mesh::Attribute indexAttribute = mesh.index.attributes.front();
|
||||
uint8_t* dstIndexPtr = static_cast<uint8_t*>(indexAttribute.pointer) + indexAttribute.stride * dstIndexFirst;
|
||||
if ( mesh.index.count ) {
|
||||
uf::Mesh::Attribute indexAttribute = mesh.index.attributes.front();
|
||||
uint8_t* dstIndexPtr = static_cast<uint8_t*>(indexAttribute.pointer) + indexAttribute.stride * dstIndexFirst;
|
||||
|
||||
for ( auto idx = 0; idx < xmesh.indexCount; ++idx ) {
|
||||
switch ( mesh.index.size ) {
|
||||
case 1: (( uint8_t*) dstIndexPtr)[idx] = (uint8_t) xmesh.indexArray[idx]; break;
|
||||
case 2: ((uint16_t*) dstIndexPtr)[idx] = (uint16_t) xmesh.indexArray[idx]; break;
|
||||
case 4: ((uint32_t*) dstIndexPtr)[idx] = (uint32_t) xmesh.indexArray[idx]; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
mesh.updateDescriptor();
|
||||
}
|
||||
}
|
||||
for ( auto idx = 0; idx < xmesh.indexCount; ++idx ) {
|
||||
switch ( mesh.index.size ) {
|
||||
case 1: (( uint8_t*) dstIndexPtr)[idx] = (uint8_t) xmesh.indexArray[idx]; break;
|
||||
case 2: ((uint16_t*) dstIndexPtr)[idx] = (uint16_t) xmesh.indexArray[idx]; break;
|
||||
case 4: ((uint32_t*) dstIndexPtr)[idx] = (uint32_t) xmesh.indexArray[idx]; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
mesh.updateDescriptor();
|
||||
}
|
||||
}
|
||||
|
||||
// cleanup
|
||||
size_t atlasCount = 0;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -57,10 +57,10 @@ namespace {
|
||||
}
|
||||
}
|
||||
LRESULT CALLBACK globalOnEvent(spec::win32::Window::handle_t handle, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
#if UF_USE_IMGUI
|
||||
#if UF_USE_IMGUI
|
||||
if (ImGui_ImplWin32_WndProcHandler(handle, message, wParam, lParam))
|
||||
return true;
|
||||
#endif
|
||||
return true;
|
||||
#endif
|
||||
if (message == WM_CREATE) {
|
||||
LONG_PTR window = (LONG_PTR)reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams;
|
||||
SetWindowLongPtrW(handle, GWLP_USERDATA, window);
|
||||
|
||||
@ -6,8 +6,8 @@
|
||||
|
||||
namespace {
|
||||
size_t writeFunction(void *ptr, size_t size, size_t nmemb, uf::stl::string* data) {
|
||||
data->append((char*) ptr, size * nmemb);
|
||||
return size * nmemb;
|
||||
data->append((char*) ptr, size * nmemb);
|
||||
return size * nmemb;
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,5 +39,5 @@ uf::Http uf::http::get( const uf::stl::string& url ) {
|
||||
curl_easy_cleanup(curl);
|
||||
curl = NULL;
|
||||
#endif
|
||||
return http;
|
||||
return http;
|
||||
}
|
||||
@ -190,11 +190,11 @@ uf::stl::vector<uint8_t>& uf::io::readAsBuffer( uf::stl::vector<uint8_t>& buffer
|
||||
|
||||
// Read each range
|
||||
size_t currentOffset = 0;
|
||||
for (const auto& r : ranges) {
|
||||
is.seekg(r.start, std::ios::beg);
|
||||
is.read(reinterpret_cast<char*>(buffer.data() + currentOffset), r.len);
|
||||
currentOffset += static_cast<size_t>(is.gcount());
|
||||
}
|
||||
for (const auto& r : ranges) {
|
||||
is.seekg(r.start, std::ios::beg);
|
||||
is.read(reinterpret_cast<char*>(buffer.data() + currentOffset), r.len);
|
||||
currentOffset += static_cast<size_t>(is.gcount());
|
||||
}
|
||||
}
|
||||
|
||||
uf::stl::string expected;
|
||||
|
||||
@ -3,18 +3,18 @@
|
||||
// credit: https://github.com/zeux/meshoptimizer/blob/master/src/quantization.cpp
|
||||
uint16_t UF_API uf::quant::quantize_f32u16( float v ) {
|
||||
union { float f; uint32_t ui; } u = {v};
|
||||
uint32_t ui = u.ui;
|
||||
uint32_t ui = u.ui;
|
||||
|
||||
int s = (ui >> 16) & 0x8000;
|
||||
int em = ui & 0x7fffffff;
|
||||
int s = (ui >> 16) & 0x8000;
|
||||
int em = ui & 0x7fffffff;
|
||||
|
||||
int h = (em - (112 << 23) + (1 << 12)) >> 13;
|
||||
h = (em < (113 << 23)) ? 0 : h;
|
||||
h = (em >= (143 << 23)) ? 0x7c00 : h;
|
||||
h = (em > (255 << 23)) ? 0x7e00 : h;
|
||||
int h = (em - (112 << 23) + (1 << 12)) >> 13;
|
||||
h = (em < (113 << 23)) ? 0 : h;
|
||||
h = (em >= (143 << 23)) ? 0x7c00 : h;
|
||||
h = (em > (255 << 23)) ? 0x7e00 : h;
|
||||
|
||||
uint16_t res = (s | h);
|
||||
return res;
|
||||
uint16_t res = (s | h);
|
||||
return res;
|
||||
}
|
||||
float UF_API uf::quant::dequantize_u16f32( uint16_t h ) {
|
||||
uint32_t s = unsigned(h & 0x8000) << 16;
|
||||
|
||||
@ -10,78 +10,78 @@ static const int B64index[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 };
|
||||
|
||||
static const uint8_t base64_table[65] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
uf::stl::string uf::base64::encode( const uint8_t* src, size_t len ) {
|
||||
uint8_t *out, *pos;
|
||||
const uint8_t *end, *in;
|
||||
uint8_t *out, *pos;
|
||||
const uint8_t *end, *in;
|
||||
|
||||
size_t olen;
|
||||
size_t olen;
|
||||
|
||||
olen = 4*((len + 2) / 3);
|
||||
olen = 4*((len + 2) / 3);
|
||||
|
||||
if (olen < len)
|
||||
return uf::stl::string();
|
||||
if (olen < len)
|
||||
return uf::stl::string();
|
||||
|
||||
uf::stl::string outStr;
|
||||
outStr.resize(olen);
|
||||
out = (uint8_t*)&outStr[0];
|
||||
uf::stl::string outStr;
|
||||
outStr.resize(olen);
|
||||
out = (uint8_t*)&outStr[0];
|
||||
|
||||
end = src + len;
|
||||
in = src;
|
||||
pos = out;
|
||||
while (end - in >= 3) {
|
||||
*pos++ = base64_table[in[0] >> 2];
|
||||
*pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
|
||||
*pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
|
||||
*pos++ = base64_table[in[2] & 0x3f];
|
||||
in += 3;
|
||||
}
|
||||
end = src + len;
|
||||
in = src;
|
||||
pos = out;
|
||||
while (end - in >= 3) {
|
||||
*pos++ = base64_table[in[0] >> 2];
|
||||
*pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
|
||||
*pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
|
||||
*pos++ = base64_table[in[2] & 0x3f];
|
||||
in += 3;
|
||||
}
|
||||
|
||||
if (end - in) {
|
||||
*pos++ = base64_table[in[0] >> 2];
|
||||
if (end - in == 1) {
|
||||
*pos++ = base64_table[(in[0] & 0x03) << 4];
|
||||
*pos++ = '=';
|
||||
}
|
||||
else {
|
||||
*pos++ = base64_table[((in[0] & 0x03) << 4) |
|
||||
(in[1] >> 4)];
|
||||
*pos++ = base64_table[(in[1] & 0x0f) << 2];
|
||||
}
|
||||
*pos++ = '=';
|
||||
}
|
||||
if (end - in) {
|
||||
*pos++ = base64_table[in[0] >> 2];
|
||||
if (end - in == 1) {
|
||||
*pos++ = base64_table[(in[0] & 0x03) << 4];
|
||||
*pos++ = '=';
|
||||
}
|
||||
else {
|
||||
*pos++ = base64_table[((in[0] & 0x03) << 4) |
|
||||
(in[1] >> 4)];
|
||||
*pos++ = base64_table[(in[1] & 0x0f) << 2];
|
||||
}
|
||||
*pos++ = '=';
|
||||
}
|
||||
|
||||
return outStr;
|
||||
return outStr;
|
||||
}
|
||||
|
||||
// uf::stl::vector<uint8_t> uf::base64::decode( const uint8_t* data, size_t len ) {
|
||||
uf::stl::vector<uint8_t> uf::base64::decode( const uf::stl::string& data ) {
|
||||
size_t len = data.size();
|
||||
uint8_t* p = (uint8_t*) &data[0];
|
||||
int pad = len > 0 && (len % 4 || p[len - 1] == '=');
|
||||
const size_t L = ((len + 3) / 4 - pad) * 4;
|
||||
uf::stl::vector<uint8_t> str(L / 4 * 3 + pad, '\0');
|
||||
uint8_t* p = (uint8_t*) &data[0];
|
||||
int pad = len > 0 && (len % 4 || p[len - 1] == '=');
|
||||
const size_t L = ((len + 3) / 4 - pad) * 4;
|
||||
uf::stl::vector<uint8_t> str(L / 4 * 3 + pad, '\0');
|
||||
|
||||
for (size_t i = 0, j = 0; i < L; i += 4)
|
||||
{
|
||||
int n = B64index[p[i]] << 18 | B64index[p[i + 1]] << 12 | B64index[p[i + 2]] << 6 | B64index[p[i + 3]];
|
||||
str[j++] = n >> 16;
|
||||
str[j++] = n >> 8 & 0xFF;
|
||||
str[j++] = n & 0xFF;
|
||||
}
|
||||
if (pad)
|
||||
{
|
||||
int n = B64index[p[L]] << 18 | B64index[p[L + 1]] << 12;
|
||||
str[str.size() - 1] = n >> 16;
|
||||
for (size_t i = 0, j = 0; i < L; i += 4)
|
||||
{
|
||||
int n = B64index[p[i]] << 18 | B64index[p[i + 1]] << 12 | B64index[p[i + 2]] << 6 | B64index[p[i + 3]];
|
||||
str[j++] = n >> 16;
|
||||
str[j++] = n >> 8 & 0xFF;
|
||||
str[j++] = n & 0xFF;
|
||||
}
|
||||
if (pad)
|
||||
{
|
||||
int n = B64index[p[L]] << 18 | B64index[p[L + 1]] << 12;
|
||||
str[str.size() - 1] = n >> 16;
|
||||
|
||||
if (len > L + 2 && p[L + 2] != '=')
|
||||
{
|
||||
n |= B64index[p[L + 2]] << 6;
|
||||
str.push_back(n >> 8 & 0xFF);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
if (len > L + 2 && p[L + 2] != '=')
|
||||
{
|
||||
n |= B64index[p[L + 2]] << 6;
|
||||
str.push_back(n >> 8 & 0xFF);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
uf::stl::string uf::string::base64::encode( const uf::stl::string& input ) {
|
||||
@ -95,9 +95,9 @@ uf::stl::string uf::string::base64::decode( const uf::stl::string& input ) {
|
||||
/*
|
||||
|
||||
static const uf::stl::string base64_chars =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
|
||||
static inline bool is_base64(uint8_t c) {
|
||||
@ -112,34 +112,34 @@ uf::stl::string uf::base64::encode(const uint8_t* buf, std::size_t bufLen) {
|
||||
uint8_t char_array_4[4];
|
||||
|
||||
while (bufLen--) {
|
||||
char_array_3[i++] = *(buf++);
|
||||
if (i == 3) {
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||
char_array_3[i++] = *(buf++);
|
||||
if (i == 3) {
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||
|
||||
for(i = 0; (i <4) ; i++)
|
||||
ret += base64_chars[char_array_4[i]];
|
||||
i = 0;
|
||||
}
|
||||
for(i = 0; (i <4) ; i++)
|
||||
ret += base64_chars[char_array_4[i]];
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i)
|
||||
{
|
||||
for(j = i; j < 3; j++)
|
||||
char_array_3[j] = '\0';
|
||||
for(j = i; j < 3; j++)
|
||||
char_array_3[j] = '\0';
|
||||
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||
|
||||
for (j = 0; (j < i + 1); j++)
|
||||
ret += base64_chars[char_array_4[j]];
|
||||
for (j = 0; (j < i + 1); j++)
|
||||
ret += base64_chars[char_array_4[j]];
|
||||
|
||||
while((i++ < 3))
|
||||
ret += '=';
|
||||
while((i++ < 3))
|
||||
ret += '=';
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -154,33 +154,33 @@ uf::stl::vector<uint8_t> uf::base64::decode(const uf::stl::string& encoded_strin
|
||||
uf::stl::vector<uint8_t> ret;
|
||||
|
||||
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
|
||||
char_array_4[i++] = encoded_string[in_]; in_++;
|
||||
if (i ==4) {
|
||||
for (i = 0; i <4; i++)
|
||||
char_array_4[i] = base64_chars.find(char_array_4[i]);
|
||||
char_array_4[i++] = encoded_string[in_]; in_++;
|
||||
if (i ==4) {
|
||||
for (i = 0; i <4; i++)
|
||||
char_array_4[i] = base64_chars.find(char_array_4[i]);
|
||||
|
||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||
|
||||
for (i = 0; (i < 3); i++)
|
||||
ret.push_back(char_array_3[i]);
|
||||
i = 0;
|
||||
}
|
||||
for (i = 0; (i < 3); i++)
|
||||
ret.push_back(char_array_3[i]);
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for (j = i; j <4; j++)
|
||||
char_array_4[j] = 0;
|
||||
for (j = i; j <4; j++)
|
||||
char_array_4[j] = 0;
|
||||
|
||||
for (j = 0; j <4; j++)
|
||||
char_array_4[j] = base64_chars.find(char_array_4[j]);
|
||||
for (j = 0; j <4; j++)
|
||||
char_array_4[j] = base64_chars.find(char_array_4[j]);
|
||||
|
||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||
|
||||
for (j = 0; (j < i - 1); j++) ret.push_back(char_array_3[j]);
|
||||
for (j = 0; (j < i - 1); j++) ret.push_back(char_array_3[j]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@ -9,10 +9,10 @@ namespace {
|
||||
|
||||
int status = -4;
|
||||
std::unique_ptr<char, void(*)(void*)> demangled{
|
||||
abi::__cxa_demangle(mangled.c_str(), NULL, NULL, &status),
|
||||
std::free
|
||||
};
|
||||
return ( status == 0 ) ? demangled.get() : mangled;
|
||||
abi::__cxa_demangle(mangled.c_str(), NULL, NULL, &status),
|
||||
std::free
|
||||
};
|
||||
return ( status == 0 ) ? demangled.get() : mangled;
|
||||
/*
|
||||
int status;
|
||||
char* pointer = abi::__cxa_demangle(mangled.c_str(), 0, 0, &status);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user